extension_updater.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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/updater/extension_downloader.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_details.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_source.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "crypto/sha2.h" 315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_registry.h" 32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/pending_extension_manager.h" 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/pref_names.h" 3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "extensions/common/constants.h" 35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h" 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/common/extension_set.h" 373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::RandDouble; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::RandInt; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 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. 554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifdef NDEBUG 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMinUpdateFrequencySeconds = 30; 574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxUpdateFrequencySeconds = 60 * 60 * 24 * 7; // 7 days 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Require at least 5 seconds between consecutive non-succesful extension update 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// checks. 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kMinUpdateThrottleTime = 5; 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// When we've computed a days value, we want to make sure we don't send a 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// negative value (due to the system clock being set backwards, etc.), since -1 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// is a special sentinel value that means "never pinged", and other negative 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// values don't make sense. 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int SanitizeDays(int days) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (days < 0) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return days; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Calculates the value to use for the ping days parameter. 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CalculatePingDays(const Time& last_ping_day) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int days = extensions::ManifestFetchData::kNeverPinged; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!last_ping_day.is_null()) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) days = SanitizeDays((Time::Now() - last_ping_day).InDays()); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return days; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int CalculateActivePingDays(const Time& last_active_ping_day, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool hasActiveBit) { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!hasActiveBit) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last_active_ping_day.is_null()) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return extensions::ManifestFetchData::kNeverPinged; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SanitizeDays((Time::Now() - last_active_ping_day).InDays()); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ExtensionUpdater::CheckParams::CheckParams() 9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) : install_immediately(false) {} 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ExtensionUpdater::CheckParams::~CheckParams() {} 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ExtensionUpdater::FetchedCRXFile::FetchedCRXFile( 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& i, 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& p, 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool file_ownership_passed, 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& u, 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::set<int>& request_ids) 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : extension_id(i), 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path(p), 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) file_ownership_passed(file_ownership_passed), 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) download_url(u), 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_ids(request_ids) {} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)ExtensionUpdater::FetchedCRXFile::FetchedCRXFile() 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : path(), file_ownership_passed(true), download_url() {} 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionUpdater::FetchedCRXFile::~FetchedCRXFile() {} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ExtensionUpdater::InProgressCheck::InProgressCheck() 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : install_immediately(false) {} 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ExtensionUpdater::InProgressCheck::~InProgressCheck() {} 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ExtensionUpdater::ThrottleInfo { 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ThrottleInfo() 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : in_progress(true), 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) throttle_delay(kMinUpdateThrottleTime), 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) check_start(Time::Now()) {} 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool in_progress; 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int throttle_delay; 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Time check_start; 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionUpdater::ExtensionUpdater(ExtensionServiceInterface* service, 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionPrefs* extension_prefs, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefService* prefs, 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int frequency_seconds, 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionCache* cache) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : alive_(false), 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) weak_ptr_factory_(this), 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_(service), frequency_seconds_(frequency_seconds), 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) will_check_soon_(false), extension_prefs_(extension_prefs), 14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) prefs_(prefs), profile_(profile), 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) next_request_id_(0), 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) crx_install_is_running_(false), 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_cache_(cache) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_GE(frequency_seconds_, 5); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LE(frequency_seconds_, kMaxUpdateFrequencySeconds); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef NDEBUG 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In Release mode we enforce that update checks don't happen too often. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frequency_seconds_ = std::max(frequency_seconds_, kMinUpdateFrequencySeconds); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frequency_seconds_ = std::min(frequency_seconds_, kMaxUpdateFrequencySeconds); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED, 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::NotificationService::AllBrowserContextsAndSources()); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionUpdater::~ExtensionUpdater() { 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stop(); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The overall goal here is to balance keeping clients up to date while 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// avoiding a thundering herd against update servers. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TimeDelta ExtensionUpdater::DetermineFirstCheckDelay() { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If someone's testing with a quick frequency, just allow it. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (frequency_seconds_ < kStartupWaitSeconds) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TimeDelta::FromSeconds(frequency_seconds_); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we've never scheduled a check before, start at frequency_seconds_. 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!prefs_->HasPrefPath(pref_names::kNextUpdateCheck)) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TimeDelta::FromSeconds(frequency_seconds_); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If it's been a long time since our last actual check, we want to do one 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // relatively soon. 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time now = Time::Now(); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time last = Time::FromInternalValue(prefs_->GetInt64( 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref_names::kLastUpdateCheck)); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int days = (now - last).InDays(); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (days >= 30) { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait 5-10 minutes. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TimeDelta::FromSeconds(RandInt(kStartupWaitSeconds, 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kStartupWaitSeconds * 2)); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (days >= 14) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait 10-20 minutes. 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TimeDelta::FromSeconds(RandInt(kStartupWaitSeconds * 2, 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kStartupWaitSeconds * 4)); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (days >= 3) { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait 20-40 minutes. 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TimeDelta::FromSeconds(RandInt(kStartupWaitSeconds * 4, 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kStartupWaitSeconds * 8)); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read the persisted next check time, and use that if it isn't too soon. 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise pick something random. 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time saved_next = Time::FromInternalValue(prefs_->GetInt64( 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref_names::kNextUpdateCheck)); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time earliest = now + TimeDelta::FromSeconds(kStartupWaitSeconds); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (saved_next >= earliest) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return saved_next - now; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TimeDelta::FromSeconds(RandInt(kStartupWaitSeconds, 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frequency_seconds_)); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUpdater::Start() { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!alive_); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If these are NULL, then that means we've been called after Stop() 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // has been called. 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(service_); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(extension_prefs_); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(prefs_); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(profile_); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!weak_ptr_factory_.HasWeakPtrs()); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alive_ = true; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure our prefs are registered, then schedule the first check. 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleNextCheck(DetermineFirstCheckDelay()); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUpdater::Stop() { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.InvalidateWeakPtrs(); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) alive_ = false; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_ = NULL; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_ = NULL; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefs_ = NULL; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_ = NULL; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timer_.Stop(); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) will_check_soon_ = false; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) downloader_.reset(); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUpdater::ScheduleNextCheck(const TimeDelta& target_delay) { 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!timer_.IsRunning()); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(target_delay >= TimeDelta::FromSeconds(1)); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add +/- 10% random jitter. 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double delay_ms = target_delay.InMillisecondsF(); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double jitter_factor = (RandDouble() * .2) - 0.1; 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delay_ms += delay_ms * jitter_factor; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta actual_delay = TimeDelta::FromMilliseconds( 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<int64>(delay_ms)); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save the time of next check. 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time next = Time::Now() + actual_delay; 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) prefs_->SetInt64(pref_names::kNextUpdateCheck, next.ToInternalValue()); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timer_.Start(FROM_HERE, actual_delay, this, &ExtensionUpdater::TimerFired); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUpdater::TimerFired() { 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckNow(default_params_); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the user has overridden the update frequency, don't bother reporting 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this. 26068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (frequency_seconds_ == extensions::kDefaultUpdateFrequencySeconds) { 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Time last = Time::FromInternalValue(prefs_->GetInt64( 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref_names::kLastUpdateCheck)); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (last.ToInternalValue() != 0) { 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use counts rather than time so we can use minutes rather than millis. 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_COUNTS("Extensions.UpdateCheckGap", 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (Time::Now() - last).InMinutes(), 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta::FromSeconds(kStartupWaitSeconds).InMinutes(), 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta::FromDays(40).InMinutes(), 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50); // 50 buckets seems to be the default. 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save the last check time, and schedule the next check. 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 now = Time::Now().ToInternalValue(); 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) prefs_->SetInt64(pref_names::kLastUpdateCheck, now); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleNextCheck(TimeDelta::FromSeconds(frequency_seconds_)); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUpdater::CheckSoon() { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (will_check_soon_) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (BrowserThread::PostTask( 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::UI, FROM_HERE, 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&ExtensionUpdater::DoCheckSoon, 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) weak_ptr_factory_.GetWeakPtr()))) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) will_check_soon_ = true; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionUpdater::WillCheckSoon() const { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return will_check_soon_; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUpdater::DoCheckSoon() { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(will_check_soon_); 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckNow(default_params_); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) will_check_soon_ = false; 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionUpdater::AddToDownloader( 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const ExtensionSet* extensions, 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::list<std::string>& pending_ids, 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int request_id) { 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InProgressCheck& request = requests_in_progress_[request_id]; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ExtensionSet::const_iterator extension_iter = extensions->begin(); 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_iter != extensions->end(); ++extension_iter) { 3107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const Extension& extension = *extension_iter->get(); 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!Manifest::IsAutoUpdateableLocation(extension.location())) { 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << "Extension " << extension.id() << " is not auto updateable"; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An extension might be overwritten by policy, and have its update url 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // changed. Make sure existing extensions aren't fetched again, if a 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pending fetch for an extension with the same id already exists. 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::list<std::string>::const_iterator pending_id_iter = std::find( 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_ids.begin(), pending_ids.end(), extension.id()); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pending_id_iter == pending_ids.end()) { 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (downloader_->AddExtension(extension, request_id)) 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.in_progress_ids_.push_back(extension.id()); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionUpdater::CheckNow(const CheckParams& params) { 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int request_id = next_request_id_++; 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(2) << "Starting update check " << request_id; 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (params.ids.empty()) 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyStarted(); 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InProgressCheck& request = requests_in_progress_[request_id]; 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.callback = params.callback; 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.install_immediately = params.install_immediately; 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!downloader_.get()) { 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) downloader_.reset( 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ExtensionDownloader(this, profile_->GetRequestContext())); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add fetch records for extensions that should be fetched by an update URL. 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These extensions are not yet installed. They come from group policy 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and external install sources. 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PendingExtensionManager* pending_extension_manager = 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) service_->pending_extension_manager(); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::list<std::string> pending_ids; 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (params.ids.empty()) { 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If no extension ids are specified, check for updates for all extensions. 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_extension_manager->GetPendingIdsForUpdateCheck(&pending_ids); 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::list<std::string>::const_iterator iter; 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (iter = pending_ids.begin(); iter != pending_ids.end(); ++iter) { 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PendingExtensionInfo* info = pending_extension_manager->GetById( 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *iter); 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!Manifest::IsAutoUpdateableLocation(info->install_source())) { 3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(2) << "Extension " << *iter << " is not auto updateable"; 3632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (downloader_->AddPendingExtension(*iter, info->update_url(), 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_id)) 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.in_progress_ids_.push_back(*iter); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionRegistry* registry = ExtensionRegistry::Get(profile_); 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddToDownloader(®istry->enabled_extensions(), pending_ids, request_id); 3725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) AddToDownloader(®istry->disabled_extensions(), pending_ids, request_id); 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::list<std::string>::const_iterator it = params.ids.begin(); 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != params.ids.end(); ++it) { 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension = service_->GetExtensionById(*it, true); 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(extension); 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (downloader_->AddExtension(*extension, request_id)) 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.in_progress_ids_.push_back(extension->id()); 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // StartAllPending() might call OnExtensionDownloadFailed/Finished before 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // it returns, which would cause NotifyIfFinished to incorrectly try to 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // send out a notification. So check before we call StartAllPending if any 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // extensions are going to be updated, and use that to figure out if 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // NotifyIfFinished should be called. 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool noChecks = request.in_progress_ids_.empty(); 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // StartAllPending() will call OnExtensionDownloadFailed or 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // OnExtensionDownloadFinished for each extension that was checked. 3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) downloader_->StartAllPending(extension_cache_); 3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (noChecks) 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyIfFinished(request_id); 3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ExtensionUpdater::CheckExtensionSoon(const std::string& extension_id, 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FinishedCallback& callback) { 4002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool have_throttle_info = ContainsKey(throttle_info_, extension_id); 4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ThrottleInfo& info = throttle_info_[extension_id]; 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (have_throttle_info) { 4032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We already had a ThrottleInfo object for this extension, check if the 4042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // update check request should be allowed. 4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If another check is in progress, don't start a new check. 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (info.in_progress) 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Time now = Time::Now(); 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Time last = info.check_start; 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If somehow time moved back, we don't want to infinitely keep throttling. 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (now < last) { 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) last = now; 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info.check_start = now; 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Time earliest = last + TimeDelta::FromSeconds(info.throttle_delay); 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If check is too soon, throttle. 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (now < earliest) 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(mek): Somehow increase time between allowing checks when checks 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // are repeatedly throttled and don't result in updates being installed. 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // It's okay to start a check, update values. 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info.check_start = now; 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) info.in_progress = true; 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckParams params; 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.ids.push_back(extension_id); 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) params.callback = base::Bind(&ExtensionUpdater::ExtensionCheckFinished, 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) weak_ptr_factory_.GetWeakPtr(), 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_id, callback); 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CheckNow(params); 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionUpdater::ExtensionCheckFinished( 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& extension_id, 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FinishedCallback& callback) { 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::map<std::string, ThrottleInfo>::iterator it = 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) throttle_info_.find(extension_id); 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (it != throttle_info_.end()) { 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it->second.in_progress = false; 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback.Run(); 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionUpdater::OnExtensionDownloadFailed( 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& id, 4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Error error, 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PingResult& ping, 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::set<int>& request_ids) { 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdatePingData(id, ping); 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool install_immediately = false; 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::set<int>::const_iterator it = request_ids.begin(); 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != request_ids.end(); ++it) { 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InProgressCheck& request = requests_in_progress_[*it]; 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) install_immediately |= request.install_immediately; 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.in_progress_ids_.remove(id); 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyIfFinished(*it); 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This method is called if no updates were found. However a previous update 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // check might have queued an update for this extension already. If a 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // current update check has |install_immediately| set the previously 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // queued update should be installed now. 4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (install_immediately && service_->GetPendingExtensionUpdate(id)) 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) service_->FinishDelayedInstallation(id); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionUpdater::OnExtensionDownloadFinished( 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& id, 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& path, 4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool file_ownership_passed, 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GURL& download_url, 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& version, 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const PingResult& ping, 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::set<int>& request_ids) { 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdatePingData(id, ping); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(2) << download_url << " written to " << path.value(); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FetchedCRXFile fetched(id, path, file_ownership_passed, download_url, 4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_ids); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetched_crx_files_.push(fetched); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MaybeInstallCRXFile() removes extensions from |in_progress_ids_| after 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // starting the crx installer. 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MaybeInstallCRXFile(); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionUpdater::GetPingDataForExtension( 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id, 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ManifestFetchData::PingData* ping_data) { 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ping_data->rollcall_days = CalculatePingDays( 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_->LastPingDay(id)); 5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ping_data->is_enabled = service_->IsExtensionEnabled(id); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ping_data->active_days = 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CalculateActivePingDays(extension_prefs_->LastActivePingDay(id), 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_->GetActiveBit(id)); 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ExtensionUpdater::GetUpdateUrlData(const std::string& id) { 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 51190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return extension::GetUpdateURLData(extension_prefs_, id); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionUpdater::IsExtensionPending(const std::string& id) { 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return service_->pending_extension_manager()->IsIdPending(id); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionUpdater::GetExtensionExistingVersion(const std::string& id, 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string* version) { 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = service_->GetExtensionById(id, true); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension) 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* update = service_->GetPendingExtensionUpdate(id); 5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (update) 5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *version = update->VersionString(); 5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *version = extension->VersionString(); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUpdater::UpdatePingData(const std::string& id, 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PingResult& ping_result) { 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(alive_); 53668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (ping_result.did_ping) 53768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) extension_prefs_->SetLastPingDay(id, ping_result.day_start); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension_prefs_->GetActiveBit(id)) { 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_->SetActiveBit(id, false); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_->SetLastActivePingDay(id, ping_result.day_start); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUpdater::MaybeInstallCRXFile() { 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (crx_install_is_running_ || fetched_crx_files_.empty()) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::set<int> request_ids; 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!fetched_crx_files_.empty() && !crx_install_is_running_) { 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const FetchedCRXFile& crx_file = fetched_crx_files_.top(); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(2) << "updating " << crx_file.extension_id 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " with " << crx_file.path.value(); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The ExtensionService is now responsible for cleaning up the temp file 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // at |crx_file.path|. 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrxInstaller* installer = NULL; 5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (service_->UpdateExtension(crx_file.extension_id, 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crx_file.path, 5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) crx_file.file_ownership_passed, 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crx_file.download_url, 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &installer)) { 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) crx_install_is_running_ = true; 5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) current_crx_file_ = crx_file; 5662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::set<int>::const_iterator it = crx_file.request_ids.begin(); 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != crx_file.request_ids.end(); ++it) { 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InProgressCheck& request = requests_in_progress_[*it]; 5702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (request.install_immediately) { 5712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) installer->set_install_wait_for_idle(false); 5722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 5732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Source parameter ensures that we only see the completion event for the 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the installer we started. 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_CRX_INSTALLER_DONE, 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<CrxInstaller>(installer)); 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::set<int>::const_iterator it = crx_file.request_ids.begin(); 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != crx_file.request_ids.end(); ++it) { 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InProgressCheck& request = requests_in_progress_[*it]; 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.in_progress_ids_.remove(crx_file.extension_id); 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request_ids.insert(crx_file.request_ids.begin(), 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) crx_file.request_ids.end()); 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fetched_crx_files_.pop(); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::set<int>::const_iterator it = request_ids.begin(); 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != request_ids.end(); ++it) { 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyIfFinished(*it); 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUpdater::Observe(int type, 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (type) { 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case chrome::NOTIFICATION_CRX_INSTALLER_DONE: { 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // No need to listen for CRX_INSTALLER_DONE anymore. 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registrar_.Remove(this, 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::NOTIFICATION_CRX_INSTALLER_DONE, 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source); 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) crx_install_is_running_ = false; 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const FetchedCRXFile& crx_file = current_crx_file_; 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (std::set<int>::const_iterator it = crx_file.request_ids.begin(); 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != crx_file.request_ids.end(); ++it) { 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InProgressCheck& request = requests_in_progress_[*it]; 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.in_progress_ids_.remove(crx_file.extension_id); 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyIfFinished(*it); 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If any files are available to update, start one. 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MaybeInstallCRXFile(); 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_INSTALLED: { 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension = 624c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::Details<const InstalledExtensionInfo>(details)->extension; 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (extension) 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) throttle_info_.erase(extension->id()); 6272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED(); 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionUpdater::NotifyStarted() { 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current()->Notify( 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_EXTENSION_UPDATING_STARTED, 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile_), 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::NoDetails()); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionUpdater::NotifyIfFinished(int request_id) { 6422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(ContainsKey(requests_in_progress_, request_id)); 6432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const InProgressCheck& request = requests_in_progress_[request_id]; 6442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (request.in_progress_ids_.empty()) { 6452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(2) << "Finished update check " << request_id; 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!request.callback.is_null()) 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request.callback.Run(); 6482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) requests_in_progress_.erase(request_id); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace extensions 653