1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/browser/extensions/install_tracker.h" 6 7#include "base/bind.h" 8#include "chrome/browser/chrome_notification_types.h" 9#include "chrome/browser/extensions/install_tracker_factory.h" 10#include "content/public/browser/notification_service.h" 11#include "extensions/browser/extension_prefs.h" 12#include "extensions/browser/extension_registry.h" 13#include "extensions/browser/pref_names.h" 14 15namespace extensions { 16 17InstallTracker::InstallTracker(content::BrowserContext* browser_context, 18 extensions::ExtensionPrefs* prefs) 19 : extension_registry_observer_(this) { 20 registrar_.Add(this, 21 extensions::NOTIFICATION_EXTENSION_UPDATE_DISABLED, 22 content::Source<content::BrowserContext>(browser_context)); 23 registrar_.Add(this, 24 chrome::NOTIFICATION_APP_INSTALLED_TO_APPLIST, 25 content::Source<content::BrowserContext>(browser_context)); 26 extension_registry_observer_.Add(ExtensionRegistry::Get(browser_context)); 27 28 // Prefs may be null in tests. 29 if (prefs) { 30 AppSorting* sorting = prefs->app_sorting(); 31 registrar_.Add(this, 32 chrome::NOTIFICATION_APP_LAUNCHER_REORDERED, 33 content::Source<AppSorting>(sorting)); 34 pref_change_registrar_.Init(prefs->pref_service()); 35 pref_change_registrar_.Add( 36 pref_names::kExtensions, 37 base::Bind(&InstallTracker::OnAppsReordered, base::Unretained(this))); 38 } 39} 40 41InstallTracker::~InstallTracker() { 42} 43 44// static 45InstallTracker* InstallTracker::Get(content::BrowserContext* context) { 46 return InstallTrackerFactory::GetForBrowserContext(context); 47} 48 49void InstallTracker::AddObserver(InstallObserver* observer) { 50 observers_.AddObserver(observer); 51} 52 53void InstallTracker::RemoveObserver(InstallObserver* observer) { 54 observers_.RemoveObserver(observer); 55} 56 57const ActiveInstallData* InstallTracker::GetActiveInstall( 58 const std::string& extension_id) const { 59 ActiveInstallsMap::const_iterator install_data = 60 active_installs_.find(extension_id); 61 if (install_data == active_installs_.end()) 62 return NULL; 63 else 64 return &(install_data->second); 65} 66 67void InstallTracker::AddActiveInstall(const ActiveInstallData& install_data) { 68 DCHECK(!install_data.extension_id.empty()); 69 DCHECK(active_installs_.find(install_data.extension_id) == 70 active_installs_.end()); 71 active_installs_.insert( 72 std::make_pair(install_data.extension_id, install_data)); 73} 74 75void InstallTracker::RemoveActiveInstall(const std::string& extension_id) { 76 active_installs_.erase(extension_id); 77} 78 79void InstallTracker::OnBeginExtensionInstall( 80 const InstallObserver::ExtensionInstallParams& params) { 81 ActiveInstallsMap::iterator install_data = 82 active_installs_.find(params.extension_id); 83 if (install_data == active_installs_.end()) { 84 ActiveInstallData install_data(params.extension_id); 85 install_data.is_ephemeral = params.is_ephemeral; 86 active_installs_.insert(std::make_pair(params.extension_id, install_data)); 87 } 88 89 FOR_EACH_OBSERVER(InstallObserver, observers_, 90 OnBeginExtensionInstall(params)); 91} 92 93void InstallTracker::OnBeginExtensionDownload(const std::string& extension_id) { 94 FOR_EACH_OBSERVER( 95 InstallObserver, observers_, OnBeginExtensionDownload(extension_id)); 96} 97 98void InstallTracker::OnDownloadProgress(const std::string& extension_id, 99 int percent_downloaded) { 100 ActiveInstallsMap::iterator install_data = 101 active_installs_.find(extension_id); 102 if (install_data != active_installs_.end()) { 103 install_data->second.percent_downloaded = percent_downloaded; 104 } else { 105 NOTREACHED(); 106 } 107 108 FOR_EACH_OBSERVER(InstallObserver, observers_, 109 OnDownloadProgress(extension_id, percent_downloaded)); 110} 111 112void InstallTracker::OnBeginCrxInstall(const std::string& extension_id) { 113 FOR_EACH_OBSERVER( 114 InstallObserver, observers_, OnBeginCrxInstall(extension_id)); 115} 116 117void InstallTracker::OnFinishCrxInstall(const std::string& extension_id, 118 bool success) { 119 FOR_EACH_OBSERVER( 120 InstallObserver, observers_, OnFinishCrxInstall(extension_id, success)); 121} 122 123void InstallTracker::OnInstallFailure( 124 const std::string& extension_id) { 125 RemoveActiveInstall(extension_id); 126 FOR_EACH_OBSERVER(InstallObserver, observers_, 127 OnInstallFailure(extension_id)); 128} 129 130void InstallTracker::Shutdown() { 131 FOR_EACH_OBSERVER(InstallObserver, observers_, OnShutdown()); 132} 133 134void InstallTracker::Observe(int type, 135 const content::NotificationSource& source, 136 const content::NotificationDetails& details) { 137 switch (type) { 138 case extensions::NOTIFICATION_EXTENSION_UPDATE_DISABLED: { 139 const Extension* extension = 140 content::Details<const Extension>(details).ptr(); 141 FOR_EACH_OBSERVER( 142 InstallObserver, observers_, OnDisabledExtensionUpdated(extension)); 143 break; 144 } 145 case chrome::NOTIFICATION_APP_LAUNCHER_REORDERED: { 146 FOR_EACH_OBSERVER(InstallObserver, observers_, OnAppsReordered()); 147 break; 148 } 149 case chrome::NOTIFICATION_APP_INSTALLED_TO_APPLIST: { 150 const std::string& extension_id( 151 *content::Details<const std::string>(details).ptr()); 152 FOR_EACH_OBSERVER(InstallObserver, observers_, 153 OnAppInstalledToAppList(extension_id)); 154 break; 155 } 156 default: 157 NOTREACHED(); 158 } 159} 160 161void InstallTracker::OnExtensionInstalled( 162 content::BrowserContext* browser_context, 163 const Extension* extension, 164 bool is_update) { 165 RemoveActiveInstall(extension->id()); 166} 167 168void InstallTracker::OnAppsReordered() { 169 FOR_EACH_OBSERVER(InstallObserver, observers_, OnAppsReordered()); 170} 171 172} // namespace extensions 173