- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / extension_service.cc
1 // Copyright (c) 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/extension_service.h"
6
7 #include <algorithm>
8 #include <iterator>
9 #include <set>
10
11 #include "base/basictypes.h"
12 #include "base/bind.h"
13 #include "base/callback.h"
14 #include "base/command_line.h"
15 #include "base/file_util.h"
16 #include "base/logging.h"
17 #include "base/metrics/histogram.h"
18 #include "base/prefs/pref_service.h"
19 #include "base/stl_util.h"
20 #include "base/strings/string_number_conversions.h"
21 #include "base/strings/string_util.h"
22 #include "base/strings/stringprintf.h"
23 #include "base/strings/utf_string_conversions.h"
24 #include "base/threading/sequenced_worker_pool.h"
25 #include "base/threading/thread_restrictions.h"
26 #include "base/time/time.h"
27 #include "base/values.h"
28 #include "base/version.h"
29 #include "chrome/browser/app_mode/app_mode_utils.h"
30 #include "chrome/browser/browser_process.h"
31 #include "chrome/browser/chrome_notification_types.h"
32 #include "chrome/browser/extensions/api/app_runtime/app_runtime_api.h"
33 #include "chrome/browser/extensions/api/declarative/rules_registry_service.h"
34 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
35 #include "chrome/browser/extensions/api/profile_keyed_api_factory.h"
36 #include "chrome/browser/extensions/api/runtime/runtime_api.h"
37 #include "chrome/browser/extensions/api/storage/settings_frontend.h"
38 #include "chrome/browser/extensions/component_loader.h"
39 #include "chrome/browser/extensions/crx_installer.h"
40 #include "chrome/browser/extensions/data_deleter.h"
41 #include "chrome/browser/extensions/event_router.h"
42 #include "chrome/browser/extensions/extension_disabled_ui.h"
43 #include "chrome/browser/extensions/extension_error_reporter.h"
44 #include "chrome/browser/extensions/extension_error_ui.h"
45 #include "chrome/browser/extensions/extension_host.h"
46 #include "chrome/browser/extensions/extension_install_ui.h"
47 #include "chrome/browser/extensions/extension_process_manager.h"
48 #include "chrome/browser/extensions/extension_sorting.h"
49 #include "chrome/browser/extensions/extension_special_storage_policy.h"
50 #include "chrome/browser/extensions/extension_sync_service.h"
51 #include "chrome/browser/extensions/extension_system.h"
52 #include "chrome/browser/extensions/extension_util.h"
53 #include "chrome/browser/extensions/external_install_ui.h"
54 #include "chrome/browser/extensions/external_provider_impl.h"
55 #include "chrome/browser/extensions/external_provider_interface.h"
56 #include "chrome/browser/extensions/installed_loader.h"
57 #include "chrome/browser/extensions/management_policy.h"
58 #include "chrome/browser/extensions/pending_extension_manager.h"
59 #include "chrome/browser/extensions/permissions_updater.h"
60 #include "chrome/browser/extensions/unpacked_installer.h"
61 #include "chrome/browser/extensions/update_observer.h"
62 #include "chrome/browser/extensions/updater/extension_updater.h"
63 #include "chrome/browser/profiles/profile.h"
64 #include "chrome/browser/profiles/profile_manager.h"
65 #include "chrome/browser/ui/webui/favicon_source.h"
66 #include "chrome/browser/ui/webui/ntp/thumbnail_source.h"
67 #include "chrome/browser/ui/webui/theme_source.h"
68 #include "chrome/common/chrome_switches.h"
69 #include "chrome/common/chrome_version_info.h"
70 #include "chrome/common/crash_keys.h"
71 #include "chrome/common/extensions/background_info.h"
72 #include "chrome/common/extensions/extension.h"
73 #include "chrome/common/extensions/extension_constants.h"
74 #include "chrome/common/extensions/extension_file_util.h"
75 #include "chrome/common/extensions/extension_messages.h"
76 #include "chrome/common/extensions/feature_switch.h"
77 #include "chrome/common/extensions/features/feature_channel.h"
78 #include "chrome/common/extensions/incognito_handler.h"
79 #include "chrome/common/extensions/manifest_handlers/app_isolation_info.h"
80 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
81 #include "chrome/common/extensions/manifest_handlers/shared_module_info.h"
82 #include "chrome/common/extensions/manifest_url_handler.h"
83 #include "chrome/common/extensions/permissions/permissions_data.h"
84 #include "chrome/common/pref_names.h"
85 #include "chrome/common/url_constants.h"
86 #include "components/startup_metric_utils/startup_metric_utils.h"
87 #include "content/public/browser/browser_thread.h"
88 #include "content/public/browser/devtools_agent_host.h"
89 #include "content/public/browser/notification_service.h"
90 #include "content/public/browser/notification_types.h"
91 #include "content/public/browser/render_process_host.h"
92 #include "content/public/browser/site_instance.h"
93 #include "content/public/browser/storage_partition.h"
94 #include "content/public/browser/url_data_source.h"
95 #include "extensions/common/constants.h"
96 #include "extensions/common/error_utils.h"
97 #include "extensions/common/extensions_client.h"
98 #include "extensions/common/manifest.h"
99 #include "extensions/common/manifest_constants.h"
100 #include "extensions/common/permissions/permission_message_provider.h"
101 #include "grit/generated_resources.h"
102 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
103 #include "ui/base/webui/web_ui_util.h"
104 #include "url/gurl.h"
105 #include "webkit/browser/database/database_tracker.h"
106 #include "webkit/browser/database/database_util.h"
107
108 #if defined(OS_CHROMEOS)
109 #include "chrome/browser/chromeos/extensions/install_limiter.h"
110 #include "webkit/browser/fileapi/file_system_backend.h"
111 #include "webkit/browser/fileapi/file_system_context.h"
112 #endif
113
114 using content::BrowserContext;
115 using content::BrowserThread;
116 using content::DevToolsAgentHost;
117 using extensions::CrxInstaller;
118 using extensions::Extension;
119 using extensions::ExtensionIdSet;
120 using extensions::ExtensionInfo;
121 using extensions::FeatureSwitch;
122 using extensions::ManagementPolicy;
123 using extensions::Manifest;
124 using extensions::PermissionMessage;
125 using extensions::PermissionMessages;
126 using extensions::PermissionSet;
127 using extensions::SharedModuleInfo;
128 using extensions::UnloadedExtensionInfo;
129
130 namespace errors = extensions::manifest_errors;
131
132 namespace {
133
134 // Histogram values for logging events related to externally installed
135 // extensions.
136 enum ExternalExtensionEvent {
137   EXTERNAL_EXTENSION_INSTALLED = 0,
138   EXTERNAL_EXTENSION_IGNORED,
139   EXTERNAL_EXTENSION_REENABLED,
140   EXTERNAL_EXTENSION_UNINSTALLED,
141   EXTERNAL_EXTENSION_BUCKET_BOUNDARY,
142 };
143
144 // Prompt the user this many times before considering an extension acknowledged.
145 static const int kMaxExtensionAcknowledgePromptCount = 3;
146
147 // Wait this many seconds after an extensions becomes idle before updating it.
148 static const int kUpdateIdleDelay = 5;
149
150 // Wait this many seconds before trying to garbage collect extensions again.
151 static const int kGarbageCollectRetryDelay = 30;
152
153 // Wait this many seconds after startup to see if there are any extensions
154 // which can be garbage collected.
155 static const int kGarbageCollectStartupDelay = 30;
156
157 static bool IsSharedModule(const Extension* extension) {
158   return SharedModuleInfo::IsSharedModule(extension);
159 }
160
161 static bool IsCWSSharedModule(const Extension* extension) {
162   return extension->from_webstore() && IsSharedModule(extension);
163 }
164
165 class SharedModuleProvider : public extensions::ManagementPolicy::Provider {
166  public:
167   SharedModuleProvider() {}
168   virtual ~SharedModuleProvider() {}
169
170   virtual std::string GetDebugPolicyProviderName() const OVERRIDE {
171     return "SharedModuleProvider";
172   }
173
174   virtual bool UserMayModifySettings(const Extension* extension,
175                                      string16* error) const OVERRIDE {
176     return !IsCWSSharedModule(extension);
177   }
178
179   virtual bool MustRemainEnabled(const Extension* extension,
180                                  string16* error) const OVERRIDE {
181     return IsCWSSharedModule(extension);
182   }
183
184  private:
185   DISALLOW_COPY_AND_ASSIGN(SharedModuleProvider);
186 };
187
188
189 }  // namespace
190
191 ExtensionService::ExtensionRuntimeData::ExtensionRuntimeData()
192     : background_page_ready(false),
193       being_upgraded(false),
194       has_used_webrequest(false) {
195 }
196
197 ExtensionService::ExtensionRuntimeData::~ExtensionRuntimeData() {
198 }
199
200 // ExtensionService.
201
202 void ExtensionService::CheckExternalUninstall(const std::string& id) {
203   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
204
205   // Check if the providers know about this extension.
206   extensions::ProviderCollection::const_iterator i;
207   for (i = external_extension_providers_.begin();
208        i != external_extension_providers_.end(); ++i) {
209     DCHECK(i->get()->IsReady());
210     if (i->get()->HasExtension(id))
211       return;  // Yup, known extension, don't uninstall.
212   }
213
214   // We get the list of external extensions to check from preferences.
215   // It is possible that an extension has preferences but is not loaded.
216   // For example, an extension that requires experimental permissions
217   // will not be loaded if the experimental command line flag is not used.
218   // In this case, do not uninstall.
219   if (!GetInstalledExtension(id)) {
220     // We can't call UninstallExtension with an unloaded/invalid
221     // extension ID.
222     LOG(WARNING) << "Attempted uninstallation of unloaded/invalid extension "
223                  << "with id: " << id;
224     return;
225   }
226   UninstallExtension(id, true, NULL);
227 }
228
229 void ExtensionService::SetFileTaskRunnerForTesting(
230     base::SequencedTaskRunner* task_runner) {
231   file_task_runner_ = task_runner;
232 }
233
234 void ExtensionService::ClearProvidersForTesting() {
235   external_extension_providers_.clear();
236 }
237
238 void ExtensionService::AddProviderForTesting(
239     extensions::ExternalProviderInterface* test_provider) {
240   CHECK(test_provider);
241   external_extension_providers_.push_back(
242       linked_ptr<extensions::ExternalProviderInterface>(test_provider));
243 }
244
245 bool ExtensionService::OnExternalExtensionUpdateUrlFound(
246     const std::string& id,
247     const GURL& update_url,
248     Manifest::Location location,
249     int creation_flags,
250     bool mark_acknowledged) {
251   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
252   CHECK(Extension::IdIsValid(id));
253
254   const Extension* extension = GetExtensionById(id, true);
255   if (extension) {
256     // Already installed. Skip this install if the current location has
257     // higher priority than |location|.
258     Manifest::Location current = extension->location();
259     if (current == Manifest::GetHigherPriorityLocation(current, location))
260       return false;
261     // Otherwise, overwrite the current installation.
262   }
263
264   // Add |id| to the set of pending extensions.  If it can not be added,
265   // then there is already a pending record from a higher-priority install
266   // source.  In this case, signal that this extension will not be
267   // installed by returning false.
268   if (!pending_extension_manager()->AddFromExternalUpdateUrl(
269           id, update_url, location, creation_flags, mark_acknowledged)) {
270     return false;
271   }
272
273   update_once_all_providers_are_ready_ = true;
274   return true;
275 }
276
277 const Extension* ExtensionService::GetInstalledApp(const GURL& url) const {
278   const Extension* extension = extensions_.GetExtensionOrAppByURL(url);
279   return (extension && extension->is_app()) ? extension : NULL;
280 }
281
282 bool ExtensionService::IsInstalledApp(const GURL& url) const {
283   return !!GetInstalledApp(url);
284 }
285
286 // static
287 // This function is used to implement the command-line switch
288 // --uninstall-extension, and to uninstall an extension via sync.  The LOG
289 // statements within this function are used to inform the user if the uninstall
290 // cannot be done.
291 bool ExtensionService::UninstallExtensionHelper(
292     ExtensionService* extensions_service,
293     const std::string& extension_id) {
294   // We can't call UninstallExtension with an invalid extension ID.
295   if (!extensions_service->GetInstalledExtension(extension_id)) {
296     LOG(WARNING) << "Attempted uninstallation of non-existent extension with "
297                  << "id: " << extension_id;
298     return false;
299   }
300
301   // The following call to UninstallExtension will not allow an uninstall of a
302   // policy-controlled extension.
303   string16 error;
304   if (!extensions_service->UninstallExtension(extension_id, false, &error)) {
305     LOG(WARNING) << "Cannot uninstall extension with id " << extension_id
306                  << ": " << error;
307     return false;
308   }
309
310   return true;
311 }
312
313 ExtensionService::ExtensionService(Profile* profile,
314                                    const CommandLine* command_line,
315                                    const base::FilePath& install_directory,
316                                    extensions::ExtensionPrefs* extension_prefs,
317                                    extensions::Blacklist* blacklist,
318                                    bool autoupdate_enabled,
319                                    bool extensions_enabled,
320                                    extensions::OneShotEvent* ready)
321     : extensions::Blacklist::Observer(blacklist),
322       profile_(profile),
323       system_(extensions::ExtensionSystem::Get(profile)),
324       extension_prefs_(extension_prefs),
325       blacklist_(blacklist),
326       settings_frontend_(extensions::SettingsFrontend::Create(profile)),
327       extension_sync_service_(NULL),
328       pending_extension_manager_(*this),
329       install_directory_(install_directory),
330       extensions_enabled_(extensions_enabled),
331       show_extensions_prompts_(true),
332       install_updates_when_idle_(true),
333       ready_(ready),
334       toolbar_model_(this),
335       menu_manager_(profile),
336       update_once_all_providers_are_ready_(false),
337       browser_terminating_(false),
338       installs_delayed_for_gc_(false),
339       is_first_run_(false) {
340 #if defined(OS_CHROMEOS)
341   disable_garbage_collection_ = false;
342 #endif
343   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
344
345   // Figure out if extension installation should be enabled.
346   if (command_line->HasSwitch(switches::kDisableExtensions) ||
347       profile->GetPrefs()->GetBoolean(prefs::kDisableExtensions)) {
348     extensions_enabled_ = false;
349   }
350
351   registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING,
352                  content::NotificationService::AllBrowserContextsAndSources());
353   registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED,
354                  content::NotificationService::AllBrowserContextsAndSources());
355   registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED,
356                  content::NotificationService::AllBrowserContextsAndSources());
357   registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED,
358                  content::NotificationService::AllBrowserContextsAndSources());
359   registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED,
360                  content::NotificationService::AllBrowserContextsAndSources());
361   pref_change_registrar_.Init(profile->GetPrefs());
362   base::Closure callback =
363       base::Bind(&ExtensionService::OnExtensionInstallPrefChanged,
364                  base::Unretained(this));
365   pref_change_registrar_.Add(prefs::kExtensionInstallAllowList, callback);
366   pref_change_registrar_.Add(prefs::kExtensionInstallDenyList, callback);
367   pref_change_registrar_.Add(prefs::kExtensionAllowedTypes, callback);
368
369   // Set up the ExtensionUpdater
370   if (autoupdate_enabled) {
371     int update_frequency = extensions::kDefaultUpdateFrequencySeconds;
372     if (command_line->HasSwitch(switches::kExtensionsUpdateFrequency)) {
373       base::StringToInt(command_line->GetSwitchValueASCII(
374           switches::kExtensionsUpdateFrequency),
375           &update_frequency);
376     }
377     updater_.reset(new extensions::ExtensionUpdater(this,
378                                                     extension_prefs,
379                                                     profile->GetPrefs(),
380                                                     profile,
381                                                     update_frequency));
382   }
383
384   component_loader_.reset(
385       new extensions::ComponentLoader(this,
386                                       profile->GetPrefs(),
387                                       g_browser_process->local_state()));
388
389   if (extensions_enabled_) {
390     extensions::ExternalProviderImpl::CreateExternalProviders(
391         this, profile_, &external_extension_providers_);
392   }
393
394   // Set this as the ExtensionService for extension sorting to ensure it
395   // cause syncs if required.
396   is_first_run_ = !extension_prefs_->SetAlertSystemFirstRun();
397
398 #if defined(ENABLE_EXTENSIONS)
399   extension_action_storage_manager_.reset(
400       new extensions::ExtensionActionStorageManager(profile_));
401 #endif
402
403   shared_module_policy_provider_.reset(new SharedModuleProvider);
404
405   // How long is the path to the Extensions directory?
406   UMA_HISTOGRAM_CUSTOM_COUNTS("Extensions.ExtensionRootPathLength",
407                               install_directory_.value().length(), 0, 500, 100);
408 }
409
410 const ExtensionSet* ExtensionService::extensions() const {
411   return &extensions_;
412 }
413
414 const ExtensionSet* ExtensionService::disabled_extensions() const {
415   return &disabled_extensions_;
416 }
417
418 const ExtensionSet* ExtensionService::terminated_extensions() const {
419   return &terminated_extensions_;
420 }
421
422 const ExtensionSet* ExtensionService::blacklisted_extensions() const {
423   return &blacklisted_extensions_;
424 }
425
426 const ExtensionSet* ExtensionService::delayed_installs() const {
427   return &delayed_installs_;
428 }
429
430 scoped_ptr<const ExtensionSet>
431     ExtensionService::GenerateInstalledExtensionsSet() const {
432   scoped_ptr<ExtensionSet> installed_extensions(new ExtensionSet());
433   installed_extensions->InsertAll(extensions_);
434   installed_extensions->InsertAll(disabled_extensions_);
435   installed_extensions->InsertAll(terminated_extensions_);
436   installed_extensions->InsertAll(blacklisted_extensions_);
437   return installed_extensions.PassAs<const ExtensionSet>();
438 }
439
440 extensions::PendingExtensionManager*
441     ExtensionService::pending_extension_manager() {
442   return &pending_extension_manager_;
443 }
444
445 ExtensionService::~ExtensionService() {
446   // No need to unload extensions here because they are profile-scoped, and the
447   // profile is in the process of being deleted.
448
449   extensions::ProviderCollection::const_iterator i;
450   for (i = external_extension_providers_.begin();
451        i != external_extension_providers_.end(); ++i) {
452     extensions::ExternalProviderInterface* provider = i->get();
453     provider->ServiceShutdown();
454   }
455 }
456
457 void ExtensionService::Shutdown() {
458   system_->management_policy()->UnregisterProvider(
459       shared_module_policy_provider_.get());
460 }
461
462 const Extension* ExtensionService::GetExtensionById(
463     const std::string& id, bool include_disabled) const {
464   int include_mask = INCLUDE_ENABLED;
465   if (include_disabled) {
466     // Include blacklisted extensions here because there are hundreds of
467     // callers of this function, and many might assume that this includes those
468     // that have been disabled due to blacklisting.
469     include_mask |= INCLUDE_DISABLED | INCLUDE_BLACKLISTED;
470   }
471   return GetExtensionById(id, include_mask);
472 }
473
474 GURL ExtensionService::GetSiteForExtensionId(const std::string& extension_id) {
475   return content::SiteInstance::GetSiteForURL(
476       profile_,
477       Extension::GetBaseURLFromExtensionId(extension_id));
478 }
479
480 const Extension* ExtensionService::GetExtensionById(
481     const std::string& id, int include_mask) const {
482   std::string lowercase_id = StringToLowerASCII(id);
483   if (include_mask & INCLUDE_ENABLED) {
484     const Extension* extension = extensions_.GetByID(lowercase_id);
485     if (extension)
486       return extension;
487   }
488   if (include_mask & INCLUDE_DISABLED) {
489     const Extension* extension = disabled_extensions_.GetByID(lowercase_id);
490     if (extension)
491       return extension;
492   }
493   if (include_mask & INCLUDE_TERMINATED) {
494     const Extension* extension = terminated_extensions_.GetByID(lowercase_id);
495     if (extension)
496       return extension;
497   }
498   if (include_mask & INCLUDE_BLACKLISTED) {
499     const Extension* extension = blacklisted_extensions_.GetByID(lowercase_id);
500     if (extension)
501       return extension;
502   }
503   return NULL;
504 }
505
506 void ExtensionService::Init() {
507   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
508
509   DCHECK(!is_ready());  // Can't redo init.
510   DCHECK_EQ(extensions_.size(), 0u);
511
512   const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
513   if (cmd_line->HasSwitch(switches::kInstallFromWebstore) ||
514       cmd_line->HasSwitch(switches::kLimitedInstallFromWebstore)) {
515     // The sole purpose of this launch is to install a new extension from CWS
516     // and immediately terminate: loading already installed extensions is
517     // unnecessary and may interfere with the inline install dialog (e.g. if an
518     // extension listens to onStartup and opens a window).
519     SetReadyAndNotifyListeners();
520   } else {
521     // LoadAllExtensions() calls OnLoadedInstalledExtensions().
522     component_loader_->LoadAll();
523     extensions::InstalledLoader(this).LoadAllExtensions();
524
525     ReconcileKnownDisabled();
526
527     // Attempt to re-enable extensions whose only disable reason is reloading.
528     std::vector<std::string> extensions_to_enable;
529     for (ExtensionSet::const_iterator iter = disabled_extensions_.begin();
530         iter != disabled_extensions_.end(); ++iter) {
531       const Extension* e = iter->get();
532       if (extension_prefs_->GetDisableReasons(e->id()) ==
533           Extension::DISABLE_RELOAD) {
534         extensions_to_enable.push_back(e->id());
535       }
536     }
537     for (std::vector<std::string>::iterator it = extensions_to_enable.begin();
538          it != extensions_to_enable.end(); ++it) {
539       EnableExtension(*it);
540     }
541
542     // Finish install (if possible) of extensions that were still delayed while
543     // the browser was shut down.
544     scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> delayed_info(
545         extension_prefs_->GetAllDelayedInstallInfo());
546     for (size_t i = 0; i < delayed_info->size(); ++i) {
547       ExtensionInfo* info = delayed_info->at(i).get();
548       scoped_refptr<const Extension> extension(NULL);
549       if (info->extension_manifest) {
550         std::string error;
551         extension = Extension::Create(
552             info->extension_path,
553             info->extension_location,
554             *info->extension_manifest,
555             extension_prefs_->GetDelayedInstallCreationFlags(
556                 info->extension_id),
557             info->extension_id,
558             &error);
559         if (extension.get())
560           delayed_installs_.Insert(extension);
561       }
562     }
563     MaybeFinishDelayedInstallations();
564
565     scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> delayed_info2(
566         extension_prefs_->GetAllDelayedInstallInfo());
567     UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateOnLoad",
568                              delayed_info2->size() - delayed_info->size());
569
570     SetReadyAndNotifyListeners();
571
572     // TODO(erikkay) this should probably be deferred to a future point
573     // rather than running immediately at startup.
574     CheckForExternalUpdates();
575
576     base::MessageLoop::current()->PostDelayedTask(
577         FROM_HERE,
578         base::Bind(&ExtensionService::GarbageCollectExtensions, AsWeakPtr()),
579         base::TimeDelta::FromSeconds(kGarbageCollectStartupDelay));
580
581     if (extension_prefs_->NeedsStorageGarbageCollection()) {
582       GarbageCollectIsolatedStorage();
583       extension_prefs_->SetNeedsStorageGarbageCollection(false);
584     }
585     system_->management_policy()->RegisterProvider(
586         shared_module_policy_provider_.get());
587   }
588 }
589
590 bool ExtensionService::UpdateExtension(const std::string& id,
591                                        const base::FilePath& extension_path,
592                                        const GURL& download_url,
593                                        CrxInstaller** out_crx_installer) {
594   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
595   if (browser_terminating_) {
596     LOG(WARNING) << "Skipping UpdateExtension due to browser shutdown";
597     // Leak the temp file at extension_path. We don't want to add to the disk
598     // I/O burden at shutdown, we can't rely on the I/O completing anyway, and
599     // the file is in the OS temp directory which should be cleaned up for us.
600     return false;
601   }
602
603   const extensions::PendingExtensionInfo* pending_extension_info =
604       pending_extension_manager()->GetById(id);
605
606   const Extension* extension = GetInstalledExtension(id);
607   if (!pending_extension_info && !extension) {
608     LOG(WARNING) << "Will not update extension " << id
609                  << " because it is not installed or pending";
610     // Delete extension_path since we're not creating a CrxInstaller
611     // that would do it for us.
612     if (!GetFileTaskRunner()->PostTask(
613             FROM_HERE,
614             base::Bind(
615                 &extension_file_util::DeleteFile, extension_path, false)))
616       NOTREACHED();
617
618     return false;
619   }
620
621   // We want a silent install only for non-pending extensions and
622   // pending extensions that have install_silently set.
623   scoped_ptr<ExtensionInstallPrompt> client;
624   if (pending_extension_info && !pending_extension_info->install_silently())
625     client.reset(ExtensionInstallUI::CreateInstallPromptWithProfile(profile_));
626
627   scoped_refptr<CrxInstaller> installer(
628       CrxInstaller::Create(this, client.Pass()));
629   installer->set_expected_id(id);
630   int creation_flags = Extension::NO_FLAGS;
631   if (pending_extension_info) {
632     installer->set_install_source(pending_extension_info->install_source());
633     if (pending_extension_info->install_silently())
634       installer->set_allow_silent_install(true);
635     creation_flags = pending_extension_info->creation_flags();
636     if (pending_extension_info->mark_acknowledged())
637       AcknowledgeExternalExtension(id);
638   } else if (extension) {
639     installer->set_install_source(extension->location());
640   }
641   // If the extension was installed from or has migrated to the webstore, or
642   // its auto-update URL is from the webstore, treat it as a webstore install.
643   // Note that we ignore some older extensions with blank auto-update URLs
644   // because we are mostly concerned with restrictions on NaCl extensions,
645   // which are newer.
646   if ((extension && extension->from_webstore()) ||
647       (extension && extensions::ManifestURL::UpdatesFromGallery(extension)) ||
648       (!extension && extension_urls::IsWebstoreUpdateUrl(
649            pending_extension_info->update_url()))) {
650     creation_flags |= Extension::FROM_WEBSTORE;
651   }
652
653   // Bookmark apps being updated is kind of a contradiction, but that's because
654   // we mark the default apps as bookmark apps, and they're hosted in the web
655   // store, thus they can get updated. See http://crbug.com/101605 for more
656   // details.
657   if (extension && extension->from_bookmark())
658     creation_flags |= Extension::FROM_BOOKMARK;
659
660   if (extension && extension->was_installed_by_default())
661     creation_flags |= Extension::WAS_INSTALLED_BY_DEFAULT;
662
663   installer->set_creation_flags(creation_flags);
664
665   installer->set_delete_source(true);
666   installer->set_download_url(download_url);
667   installer->set_install_cause(extension_misc::INSTALL_CAUSE_UPDATE);
668   installer->InstallCrx(extension_path);
669
670   if (out_crx_installer)
671     *out_crx_installer = installer.get();
672
673   return true;
674 }
675
676 void ExtensionService::ReloadExtension(const std::string extension_id) {
677   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
678
679   // If the extension is already reloading, don't reload again.
680   if (extension_prefs_->GetDisableReasons(extension_id) &
681       Extension::DISABLE_RELOAD) {
682     return;
683   }
684
685   base::FilePath path;
686   const Extension* current_extension = GetExtensionById(extension_id, false);
687
688   // Disable the extension if it's loaded. It might not be loaded if it crashed.
689   if (current_extension) {
690     // If the extension has an inspector open for its background page, detach
691     // the inspector and hang onto a cookie for it, so that we can reattach
692     // later.
693     // TODO(yoz): this is not incognito-safe!
694     ExtensionProcessManager* manager = system_->process_manager();
695     extensions::ExtensionHost* host =
696         manager->GetBackgroundHostForExtension(extension_id);
697     if (host && DevToolsAgentHost::HasFor(host->render_view_host())) {
698       // Look for an open inspector for the background page.
699       scoped_refptr<DevToolsAgentHost> agent_host =
700           DevToolsAgentHost::GetOrCreateFor(host->render_view_host());
701       agent_host->DisconnectRenderViewHost();
702       orphaned_dev_tools_[extension_id] = agent_host;
703     }
704
705     path = current_extension->path();
706     // BeingUpgraded is set back to false when the extension is added.
707     SetBeingUpgraded(current_extension, true);
708     DisableExtension(extension_id, Extension::DISABLE_RELOAD);
709     reloading_extensions_.insert(extension_id);
710   } else {
711     path = unloaded_extension_paths_[extension_id];
712   }
713
714   if (delayed_installs_.Contains(extension_id)) {
715     FinishDelayedInstallation(extension_id);
716     return;
717   }
718
719   // If we're reloading a component extension, use the component extension
720   // loader's reloader.
721   if (component_loader_->Exists(extension_id)) {
722     SetBeingReloaded(extension_id, true);
723     component_loader_->Reload(extension_id);
724     SetBeingReloaded(extension_id, false);
725     return;
726   }
727
728   // Check the installed extensions to see if what we're reloading was already
729   // installed.
730   SetBeingReloaded(extension_id, true);
731   scoped_ptr<ExtensionInfo> installed_extension(
732       extension_prefs_->GetInstalledExtensionInfo(extension_id));
733   if (installed_extension.get() &&
734       installed_extension->extension_manifest.get()) {
735     extensions::InstalledLoader(this).Load(*installed_extension, false);
736   } else {
737     // Otherwise, the extension is unpacked (location LOAD).
738     // We should always be able to remember the extension's path. If it's not in
739     // the map, someone failed to update |unloaded_extension_paths_|.
740     CHECK(!path.empty());
741     extensions::UnpackedInstaller::Create(this)->Load(path);
742   }
743   // When reloading is done, mark this extension as done reloading.
744   SetBeingReloaded(extension_id, false);
745 }
746
747 bool ExtensionService::UninstallExtension(
748     std::string extension_id,
749     bool external_uninstall,
750     string16* error) {
751   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
752
753   scoped_refptr<const Extension> extension(GetInstalledExtension(extension_id));
754
755   // Callers should not send us nonexistent extensions.
756   CHECK(extension.get());
757
758   // Policy change which triggers an uninstall will always set
759   // |external_uninstall| to true so this is the only way to uninstall
760   // managed extensions.
761   if (!external_uninstall &&
762       !system_->management_policy()->UserMayModifySettings(
763         extension.get(), error)) {
764     content::NotificationService::current()->Notify(
765         chrome::NOTIFICATION_EXTENSION_UNINSTALL_NOT_ALLOWED,
766         content::Source<Profile>(profile_),
767         content::Details<const Extension>(extension.get()));
768     return false;
769   }
770
771   syncer::SyncChange sync_change;
772   if (extension_sync_service_) {
773      sync_change = extension_sync_service_->PrepareToSyncUninstallExtension(
774         extension.get(), is_ready());
775   }
776
777   if (IsUnacknowledgedExternalExtension(extension.get())) {
778     UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent",
779                               EXTERNAL_EXTENSION_UNINSTALLED,
780                               EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
781     if (extensions::ManifestURL::UpdatesFromGallery(extension.get())) {
782       UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventWebstore",
783                                 EXTERNAL_EXTENSION_UNINSTALLED,
784                                 EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
785     } else {
786       UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventNonWebstore",
787                                 EXTERNAL_EXTENSION_UNINSTALLED,
788                                 EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
789     }
790   }
791   UMA_HISTOGRAM_ENUMERATION("Extensions.UninstallType",
792                             extension->GetType(), 100);
793   RecordPermissionMessagesHistogram(extension.get(),
794                                     "Extensions.Permissions_Uninstall");
795
796   // Unload before doing more cleanup to ensure that nothing is hanging on to
797   // any of these resources.
798   UnloadExtension(extension_id, UnloadedExtensionInfo::REASON_UNINSTALL);
799
800   // Tell the backend to start deleting installed extensions on the file thread.
801   if (!Manifest::IsUnpackedLocation(extension->location())) {
802     if (!GetFileTaskRunner()->PostTask(
803             FROM_HERE,
804             base::Bind(
805                 &extension_file_util::UninstallExtension,
806                 install_directory_,
807                 extension_id)))
808       NOTREACHED();
809   }
810
811   GURL launch_web_url_origin(
812       extensions::AppLaunchInfo::GetLaunchWebURL(extension.get()).GetOrigin());
813   bool is_storage_isolated =
814       extensions::AppIsolationInfo::HasIsolatedStorage(extension.get());
815
816   if (is_storage_isolated) {
817     BrowserContext::AsyncObliterateStoragePartition(
818         profile_,
819         GetSiteForExtensionId(extension_id),
820         base::Bind(&ExtensionService::OnNeedsToGarbageCollectIsolatedStorage,
821                    AsWeakPtr()));
822   } else {
823     if (extension->is_hosted_app() &&
824         !profile_->GetExtensionSpecialStoragePolicy()->
825             IsStorageProtected(launch_web_url_origin)) {
826       extensions::DataDeleter::StartDeleting(
827           profile_, extension_id, launch_web_url_origin);
828     }
829     extensions::DataDeleter::StartDeleting(profile_, extension_id,
830                                            extension->url());
831   }
832
833   UntrackTerminatedExtension(extension_id);
834
835   // Notify interested parties that we've uninstalled this extension.
836   content::NotificationService::current()->Notify(
837       chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
838       content::Source<Profile>(profile_),
839       content::Details<const Extension>(extension.get()));
840
841   if (extension_sync_service_) {
842     extension_sync_service_->ProcessSyncUninstallExtension(extension_id,
843                                                            sync_change);
844   }
845
846   delayed_installs_.Remove(extension_id);
847
848   PruneSharedModulesOnUninstall(extension.get());
849
850   extension_prefs_->OnExtensionUninstalled(extension_id, extension->location(),
851                                            external_uninstall);
852
853   // Track the uninstallation.
854   UMA_HISTOGRAM_ENUMERATION("Extensions.ExtensionUninstalled", 1, 2);
855
856   return true;
857 }
858
859 bool ExtensionService::IsExtensionEnabled(
860     const std::string& extension_id) const {
861   if (extensions_.Contains(extension_id) ||
862       terminated_extensions_.Contains(extension_id)) {
863     return true;
864   }
865
866   if (disabled_extensions_.Contains(extension_id) ||
867       blacklisted_extensions_.Contains(extension_id)) {
868     return false;
869   }
870
871   // If the extension hasn't been loaded yet, check the prefs for it. Assume
872   // enabled unless otherwise noted.
873   return !extension_prefs_->IsExtensionDisabled(extension_id) &&
874          !extension_prefs_->IsExternalExtensionUninstalled(extension_id);
875 }
876
877 bool ExtensionService::IsExternalExtensionUninstalled(
878     const std::string& extension_id) const {
879   return extension_prefs_->IsExternalExtensionUninstalled(extension_id);
880 }
881
882 bool ExtensionService::IsExtensionEnabledForLauncher(
883     const std::string& extension_id) const {
884   return IsExtensionEnabled(extension_id) &&
885       !GetTerminatedExtension(extension_id);
886 }
887
888 void ExtensionService::EnableExtension(const std::string& extension_id) {
889   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
890
891   if (IsExtensionEnabled(extension_id))
892     return;
893   const Extension* extension = disabled_extensions_.GetByID(extension_id);
894
895   ManagementPolicy* policy = system_->management_policy();
896   if (extension && policy->MustRemainDisabled(extension, NULL, NULL)) {
897     UMA_HISTOGRAM_COUNTS_100("Extensions.EnableDeniedByPolicy", 1);
898     return;
899   }
900
901   extension_prefs_->SetExtensionState(extension_id, Extension::ENABLED);
902   extension_prefs_->ClearDisableReasons(extension_id);
903
904   // This can happen if sync enables an extension that is not
905   // installed yet.
906   if (!extension)
907     return;
908
909   if (IsUnacknowledgedExternalExtension(extension)) {
910     UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent",
911                               EXTERNAL_EXTENSION_REENABLED,
912                               EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
913     if (extensions::ManifestURL::UpdatesFromGallery(extension)) {
914       UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventWebstore",
915                                 EXTERNAL_EXTENSION_REENABLED,
916                                 EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
917     } else {
918       UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventNonWebstore",
919                                 EXTERNAL_EXTENSION_REENABLED,
920                                 EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
921     }
922     AcknowledgeExternalExtension(extension->id());
923   }
924
925   // Move it over to the enabled list.
926   extensions_.Insert(make_scoped_refptr(extension));
927   disabled_extensions_.Remove(extension->id());
928
929   NotifyExtensionLoaded(extension);
930
931   // Notify listeners that the extension was enabled.
932   content::NotificationService::current()->Notify(
933       chrome::NOTIFICATION_EXTENSION_ENABLED,
934       content::Source<Profile>(profile_),
935       content::Details<const Extension>(extension));
936
937   if (extension_sync_service_)
938     extension_sync_service_->SyncEnableExtension(*extension);
939 }
940
941 void ExtensionService::DisableExtension(
942     const std::string& extension_id,
943     Extension::DisableReason disable_reason) {
944   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
945
946   // The extension may have been disabled already.
947   if (!IsExtensionEnabled(extension_id))
948     return;
949
950   const Extension* extension = GetInstalledExtension(extension_id);
951   // |extension| can be NULL if sync disables an extension that is not
952   // installed yet.
953   if (extension &&
954       disable_reason != Extension::DISABLE_RELOAD &&
955       !system_->management_policy()->UserMayModifySettings(extension, NULL)) {
956     return;
957   }
958
959   extension_prefs_->SetExtensionState(extension_id, Extension::DISABLED);
960   extension_prefs_->AddDisableReason(extension_id, disable_reason);
961
962   int include_mask = INCLUDE_EVERYTHING & ~INCLUDE_DISABLED;
963   extension = GetExtensionById(extension_id, include_mask);
964   if (!extension)
965     return;
966
967   // Reset the background_page_ready flag
968   if (extensions::BackgroundInfo::HasBackgroundPage(extension))
969     extension_runtime_data_[extension->id()].background_page_ready = false;
970
971   // Move it over to the disabled list. Don't send a second unload notification
972   // for terminated extensions being disabled.
973   disabled_extensions_.Insert(make_scoped_refptr(extension));
974   if (extensions_.Contains(extension->id())) {
975     extensions_.Remove(extension->id());
976     NotifyExtensionUnloaded(extension, UnloadedExtensionInfo::REASON_DISABLE);
977   } else {
978     terminated_extensions_.Remove(extension->id());
979   }
980
981   if (extension_sync_service_)
982     extension_sync_service_->SyncDisableExtension(*extension);
983 }
984
985 void ExtensionService::DisableUserExtensions(
986     const std::vector<std::string>& except_ids) {
987   extensions::ManagementPolicy* management_policy =
988       system_->management_policy();
989   extensions::ExtensionList to_disable;
990
991   for (ExtensionSet::const_iterator extension = extensions_.begin();
992       extension != extensions_.end(); ++extension) {
993     if (management_policy->UserMayModifySettings(extension->get(), NULL))
994       to_disable.push_back(*extension);
995   }
996   for (ExtensionSet::const_iterator extension = terminated_extensions_.begin();
997       extension != terminated_extensions_.end(); ++extension) {
998     if (management_policy->UserMayModifySettings(extension->get(), NULL))
999       to_disable.push_back(*extension);
1000   }
1001
1002   for (extensions::ExtensionList::const_iterator extension = to_disable.begin();
1003       extension != to_disable.end(); ++extension) {
1004     if ((*extension)->was_installed_by_default() &&
1005         extension_urls::IsWebstoreUpdateUrl(
1006             extensions::ManifestURL::GetUpdateURL(*extension)))
1007       continue;
1008     const std::string& id = (*extension)->id();
1009     if (except_ids.end() == std::find(except_ids.begin(), except_ids.end(), id))
1010       DisableExtension(id, extensions::Extension::DISABLE_USER_ACTION);
1011   }
1012 }
1013
1014 void ExtensionService::GrantPermissionsAndEnableExtension(
1015     const Extension* extension) {
1016   GrantPermissions(extension);
1017   RecordPermissionMessagesHistogram(
1018       extension, "Extensions.Permissions_ReEnable");
1019   extension_prefs_->SetDidExtensionEscalatePermissions(extension, false);
1020   EnableExtension(extension->id());
1021 }
1022
1023 void ExtensionService::GrantPermissions(const Extension* extension) {
1024   CHECK(extension);
1025   extensions::PermissionsUpdater perms_updater(profile());
1026   perms_updater.GrantActivePermissions(extension);
1027 }
1028
1029 // static
1030 void ExtensionService::RecordPermissionMessagesHistogram(
1031     const Extension* extension, const char* histogram) {
1032   // Since this is called from multiple sources, and since the histogram macros
1033   // use statics, we need to manually lookup the histogram ourselves.
1034   base::HistogramBase* counter = base::LinearHistogram::FactoryGet(
1035       histogram,
1036       1,
1037       PermissionMessage::kEnumBoundary,
1038       PermissionMessage::kEnumBoundary + 1,
1039       base::HistogramBase::kUmaTargetedHistogramFlag);
1040
1041   PermissionMessages permissions =
1042       extensions::PermissionsData::GetPermissionMessages(extension);
1043   if (permissions.empty()) {
1044     counter->Add(PermissionMessage::kNone);
1045   } else {
1046     for (PermissionMessages::iterator it = permissions.begin();
1047          it != permissions.end(); ++it)
1048       counter->Add(it->id());
1049   }
1050 }
1051
1052 void ExtensionService::NotifyExtensionLoaded(const Extension* extension) {
1053   // The ChromeURLRequestContexts need to be first to know that the extension
1054   // was loaded, otherwise a race can arise where a renderer that is created
1055   // for the extension may try to load an extension URL with an extension id
1056   // that the request context doesn't yet know about. The profile is responsible
1057   // for ensuring its URLRequestContexts appropriately discover the loaded
1058   // extension.
1059   system_->RegisterExtensionWithRequestContexts(extension);
1060
1061   // Tell renderers about the new extension, unless it's a theme (renderers
1062   // don't need to know about themes).
1063   if (!extension->is_theme()) {
1064     for (content::RenderProcessHost::iterator i(
1065             content::RenderProcessHost::AllHostsIterator());
1066          !i.IsAtEnd(); i.Advance()) {
1067       content::RenderProcessHost* host = i.GetCurrentValue();
1068       Profile* host_profile =
1069           Profile::FromBrowserContext(host->GetBrowserContext());
1070       if (host_profile->GetOriginalProfile() ==
1071           profile_->GetOriginalProfile()) {
1072         std::vector<ExtensionMsg_Loaded_Params> loaded_extensions(
1073             1, ExtensionMsg_Loaded_Params(extension));
1074         host->Send(
1075             new ExtensionMsg_Loaded(loaded_extensions));
1076       }
1077     }
1078   }
1079
1080   // Tell subsystems that use the EXTENSION_LOADED notification about the new
1081   // extension.
1082   //
1083   // NOTE: It is important that this happen after notifying the renderers about
1084   // the new extensions so that if we navigate to an extension URL in
1085   // NOTIFICATION_EXTENSION_LOADED, the renderer is guaranteed to know about it.
1086   content::NotificationService::current()->Notify(
1087       chrome::NOTIFICATION_EXTENSION_LOADED,
1088       content::Source<Profile>(profile_),
1089       content::Details<const Extension>(extension));
1090
1091   // Tell a random-ass collection of other subsystems about the new extension.
1092   // TODO(aa): What should we do with all this goop? Can it move into the
1093   // relevant objects via EXTENSION_LOADED?
1094
1095   profile_->GetExtensionSpecialStoragePolicy()->
1096       GrantRightsForExtension(extension);
1097
1098   UpdateActiveExtensionsInCrashReporter();
1099
1100   // If the extension has permission to load chrome://favicon/ resources we need
1101   // to make sure that the FaviconSource is registered with the
1102   // ChromeURLDataManager.
1103   if (extensions::PermissionsData::HasHostPermission(
1104           extension, GURL(chrome::kChromeUIFaviconURL))) {
1105     FaviconSource* favicon_source = new FaviconSource(profile_,
1106                                                       FaviconSource::FAVICON);
1107     content::URLDataSource::Add(profile_, favicon_source);
1108   }
1109
1110 #if !defined(OS_ANDROID)
1111   // Same for chrome://theme/ resources.
1112   if (extensions::PermissionsData::HasHostPermission(
1113           extension, GURL(chrome::kChromeUIThemeURL))) {
1114     ThemeSource* theme_source = new ThemeSource(profile_);
1115     content::URLDataSource::Add(profile_, theme_source);
1116   }
1117 #endif
1118
1119   // Same for chrome://thumb/ resources.
1120   if (extensions::PermissionsData::HasHostPermission(
1121           extension, GURL(chrome::kChromeUIThumbnailURL))) {
1122     ThumbnailSource* thumbnail_source = new ThumbnailSource(profile_, false);
1123     content::URLDataSource::Add(profile_, thumbnail_source);
1124   }
1125 }
1126
1127 void ExtensionService::NotifyExtensionUnloaded(
1128     const Extension* extension,
1129     UnloadedExtensionInfo::Reason reason) {
1130   UnloadedExtensionInfo details(extension, reason);
1131   content::NotificationService::current()->Notify(
1132       chrome::NOTIFICATION_EXTENSION_UNLOADED,
1133       content::Source<Profile>(profile_),
1134       content::Details<UnloadedExtensionInfo>(&details));
1135
1136   for (content::RenderProcessHost::iterator i(
1137           content::RenderProcessHost::AllHostsIterator());
1138        !i.IsAtEnd(); i.Advance()) {
1139     content::RenderProcessHost* host = i.GetCurrentValue();
1140     Profile* host_profile =
1141         Profile::FromBrowserContext(host->GetBrowserContext());
1142     if (host_profile->GetOriginalProfile() == profile_->GetOriginalProfile())
1143       host->Send(new ExtensionMsg_Unloaded(extension->id()));
1144   }
1145
1146   system_->UnregisterExtensionWithRequestContexts(extension->id(), reason);
1147   profile_->GetExtensionSpecialStoragePolicy()->
1148       RevokeRightsForExtension(extension);
1149
1150 #if defined(OS_CHROMEOS)
1151   // Revoke external file access for the extension from its file system context.
1152   // It is safe to access the extension's storage partition at this point. The
1153   // storage partition may get destroyed only after the extension gets unloaded.
1154   GURL site = extensions::ExtensionSystem::Get(profile_)->extension_service()->
1155       GetSiteForExtensionId(extension->id());
1156   fileapi::FileSystemContext* filesystem_context =
1157       BrowserContext::GetStoragePartitionForSite(profile_, site)->
1158           GetFileSystemContext();
1159   if (filesystem_context && filesystem_context->external_backend()) {
1160     filesystem_context->external_backend()->
1161         RevokeAccessForExtension(extension->id());
1162   }
1163 #endif
1164
1165   UpdateActiveExtensionsInCrashReporter();
1166 }
1167
1168 Profile* ExtensionService::profile() {
1169   return profile_;
1170 }
1171
1172 extensions::ExtensionPrefs* ExtensionService::extension_prefs() {
1173   return extension_prefs_;
1174 }
1175
1176 const extensions::ExtensionPrefs* ExtensionService::extension_prefs() const {
1177   return extension_prefs_;
1178 }
1179
1180 extensions::SettingsFrontend* ExtensionService::settings_frontend() {
1181   return settings_frontend_.get();
1182 }
1183
1184 extensions::ContentSettingsStore* ExtensionService::GetContentSettingsStore() {
1185   return extension_prefs()->content_settings_store();
1186 }
1187
1188 bool ExtensionService::is_ready() {
1189   return ready_->is_signaled();
1190 }
1191
1192 base::SequencedTaskRunner* ExtensionService::GetFileTaskRunner() {
1193   if (file_task_runner_.get())
1194     return file_task_runner_.get();
1195
1196   // We should be able to interrupt any part of extension install process during
1197   // shutdown. SKIP_ON_SHUTDOWN ensures that not started extension install tasks
1198   // will be ignored/deleted while we will block on started tasks.
1199   std::string token("ext_install-");
1200   token.append(profile_->GetPath().AsUTF8Unsafe());
1201   file_task_runner_ = BrowserThread::GetBlockingPool()->
1202       GetSequencedTaskRunnerWithShutdownBehavior(
1203         BrowserThread::GetBlockingPool()->GetNamedSequenceToken(token),
1204         base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
1205   return file_task_runner_.get();
1206 }
1207
1208 extensions::ExtensionUpdater* ExtensionService::updater() {
1209   return updater_.get();
1210 }
1211
1212 void ExtensionService::CheckManagementPolicy() {
1213   std::vector<std::string> to_unload;
1214   std::map<std::string, Extension::DisableReason> to_disable;
1215
1216   // Loop through the extensions list, finding extensions we need to unload or
1217   // disable.
1218   for (ExtensionSet::const_iterator iter = extensions_.begin();
1219        iter != extensions_.end(); ++iter) {
1220     const Extension* extension = (iter->get());
1221     if (!system_->management_policy()->UserMayLoad(extension, NULL))
1222       to_unload.push_back(extension->id());
1223     Extension::DisableReason disable_reason = Extension::DISABLE_NONE;
1224     if (system_->management_policy()->MustRemainDisabled(
1225             extension, &disable_reason, NULL))
1226       to_disable[extension->id()] = disable_reason;
1227   }
1228
1229   for (size_t i = 0; i < to_unload.size(); ++i)
1230     UnloadExtension(to_unload[i], UnloadedExtensionInfo::REASON_DISABLE);
1231
1232   for (std::map<std::string, Extension::DisableReason>::const_iterator i =
1233            to_disable.begin(); i != to_disable.end(); ++i)
1234     DisableExtension(i->first, i->second);
1235 }
1236
1237 void ExtensionService::CheckForUpdatesSoon() {
1238   if (updater()) {
1239     if (AreAllExternalProvidersReady()) {
1240       updater()->CheckSoon();
1241     } else {
1242       // Sync can start updating before all the external providers are ready
1243       // during startup. Start the update as soon as those providers are ready,
1244       // but not before.
1245       update_once_all_providers_are_ready_ = true;
1246     }
1247   } else {
1248     LOG(WARNING) << "CheckForUpdatesSoon() called with auto-update turned off";
1249   }
1250 }
1251
1252 void ExtensionService::OnExtensionMoved(
1253     const std::string& moved_extension_id,
1254     const std::string& predecessor_extension_id,
1255     const std::string& successor_extension_id) {
1256   extension_prefs_->extension_sorting()->OnExtensionMoved(
1257       moved_extension_id,
1258       predecessor_extension_id,
1259       successor_extension_id);
1260
1261   const Extension* extension = GetInstalledExtension(moved_extension_id);
1262   if (extension_sync_service_ && extension) {
1263     extension_sync_service_->SyncExtensionChangeIfNeeded(*extension);
1264   }
1265 }
1266
1267 // Some extensions will autoupdate themselves externally from Chrome.  These
1268 // are typically part of some larger client application package.  To support
1269 // these, the extension will register its location in the the preferences file
1270 // (and also, on Windows, in the registry) and this code will periodically
1271 // check that location for a .crx file, which it will then install locally if
1272 // a new version is available.
1273 // Errors are reported through ExtensionErrorReporter. Succcess is not
1274 // reported.
1275 void ExtensionService::CheckForExternalUpdates() {
1276   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1277
1278   // Note that this installation is intentionally silent (since it didn't
1279   // go through the front-end).  Extensions that are registered in this
1280   // way are effectively considered 'pre-bundled', and so implicitly
1281   // trusted.  In general, if something has HKLM or filesystem access,
1282   // they could install an extension manually themselves anyway.
1283
1284   // Ask each external extension provider to give us a call back for each
1285   // extension they know about. See OnExternalExtension(File|UpdateUrl)Found.
1286   extensions::ProviderCollection::const_iterator i;
1287   for (i = external_extension_providers_.begin();
1288        i != external_extension_providers_.end(); ++i) {
1289     extensions::ExternalProviderInterface* provider = i->get();
1290     provider->VisitRegisteredExtension();
1291   }
1292
1293   // Do any required work that we would have done after completion of all
1294   // providers.
1295   if (external_extension_providers_.empty()) {
1296     OnAllExternalProvidersReady();
1297   }
1298 }
1299
1300 void ExtensionService::OnExternalProviderReady(
1301     const extensions::ExternalProviderInterface* provider) {
1302   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1303   CHECK(provider->IsReady());
1304
1305   // An external provider has finished loading.  We only take action
1306   // if all of them are finished. So we check them first.
1307   if (AreAllExternalProvidersReady())
1308     OnAllExternalProvidersReady();
1309 }
1310
1311 bool ExtensionService::AreAllExternalProvidersReady() const {
1312   extensions::ProviderCollection::const_iterator i;
1313   for (i = external_extension_providers_.begin();
1314        i != external_extension_providers_.end(); ++i) {
1315     if (!i->get()->IsReady())
1316       return false;
1317   }
1318   return true;
1319 }
1320
1321 void ExtensionService::OnAllExternalProvidersReady() {
1322   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1323   base::TimeDelta elapsed = base::Time::Now() - profile_->GetStartTime();
1324   UMA_HISTOGRAM_TIMES("Extension.ExternalProvidersReadyAfter", elapsed);
1325
1326   // Install any pending extensions.
1327   if (update_once_all_providers_are_ready_ && updater()) {
1328     update_once_all_providers_are_ready_ = false;
1329     updater()->CheckNow(extensions::ExtensionUpdater::CheckParams());
1330   }
1331
1332   // Uninstall all the unclaimed extensions.
1333   scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> extensions_info(
1334       extension_prefs_->GetInstalledExtensionsInfo());
1335   for (size_t i = 0; i < extensions_info->size(); ++i) {
1336     ExtensionInfo* info = extensions_info->at(i).get();
1337     if (Manifest::IsExternalLocation(info->extension_location))
1338       CheckExternalUninstall(info->extension_id);
1339   }
1340   IdentifyAlertableExtensions();
1341 }
1342
1343 void ExtensionService::IdentifyAlertableExtensions() {
1344   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1345
1346   // Build up the lists of extensions that require acknowledgment. If this is
1347   // the first time, grandfather extensions that would have caused
1348   // notification.
1349   extension_error_ui_.reset(ExtensionErrorUI::Create(this));
1350
1351   bool did_show_alert = false;
1352   if (PopulateExtensionErrorUI(extension_error_ui_.get())) {
1353     if (!is_first_run_) {
1354       CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1355       did_show_alert = extension_error_ui_->ShowErrorInBubbleView();
1356     } else {
1357       // First run. Just acknowledge all the extensions, silently, by
1358       // shortcutting the display of the UI and going straight to the
1359       // callback for pressing the Accept button.
1360       HandleExtensionAlertAccept();
1361     }
1362   }
1363
1364   UpdateExternalExtensionAlert();
1365
1366   if (!did_show_alert)
1367     extension_error_ui_.reset();
1368 }
1369
1370 bool ExtensionService::PopulateExtensionErrorUI(
1371     ExtensionErrorUI* extension_error_ui) {
1372   bool needs_alert = false;
1373
1374   // Extensions that are blacklisted.
1375   for (ExtensionSet::const_iterator it = blacklisted_extensions_.begin();
1376        it != blacklisted_extensions_.end(); ++it) {
1377     std::string id = (*it)->id();
1378     if (!extension_prefs_->IsBlacklistedExtensionAcknowledged(id)) {
1379       extension_error_ui->AddBlacklistedExtension(id);
1380       needs_alert = true;
1381     }
1382   }
1383
1384   for (ExtensionSet::const_iterator iter = extensions_.begin();
1385        iter != extensions_.end(); ++iter) {
1386     const Extension* e = iter->get();
1387
1388     // Extensions disabled by policy. Note: this no longer includes blacklisted
1389     // extensions, though we still show the same UI.
1390     if (!system_->management_policy()->UserMayLoad(e, NULL)) {
1391       if (!extension_prefs_->IsBlacklistedExtensionAcknowledged(e->id())) {
1392         extension_error_ui->AddBlacklistedExtension(e->id());
1393         needs_alert = true;
1394       }
1395     }
1396   }
1397
1398   return needs_alert;
1399 }
1400
1401 void ExtensionService::HandleExtensionAlertClosed() {
1402   const ExtensionIdSet* extension_ids =
1403       extension_error_ui_->get_blacklisted_extension_ids();
1404   for (ExtensionIdSet::const_iterator iter = extension_ids->begin();
1405        iter != extension_ids->end(); ++iter) {
1406     extension_prefs_->AcknowledgeBlacklistedExtension(*iter);
1407   }
1408   extension_error_ui_.reset();
1409 }
1410
1411 void ExtensionService::HandleExtensionAlertAccept() {
1412   extension_error_ui_->Close();
1413 }
1414
1415 void ExtensionService::AcknowledgeExternalExtension(const std::string& id) {
1416   extension_prefs_->AcknowledgeExternalExtension(id);
1417   UpdateExternalExtensionAlert();
1418 }
1419
1420 bool ExtensionService::IsUnacknowledgedExternalExtension(
1421     const Extension* extension) {
1422   if (!FeatureSwitch::prompt_for_external_extensions()->IsEnabled())
1423     return false;
1424
1425   return (Manifest::IsExternalLocation(extension->location()) &&
1426           !extension_prefs_->IsExternalExtensionAcknowledged(extension->id()) &&
1427           !(extension_prefs_->GetDisableReasons(extension->id()) &
1428                 Extension::DISABLE_SIDELOAD_WIPEOUT));
1429 }
1430
1431 void ExtensionService::ReconcileKnownDisabled() {
1432   ExtensionIdSet known_disabled_ids = extension_prefs_->GetKnownDisabled();
1433   if (known_disabled_ids.empty()) {
1434     if (!disabled_extensions_.is_empty()) {
1435       extension_prefs_->SetKnownDisabled(disabled_extensions_.GetIDs());
1436       UMA_HISTOGRAM_BOOLEAN("Extensions.KnownDisabledInitialized", true);
1437     }
1438   } else {
1439     // Both |known_disabled_ids| and |extensions_| are ordered (by definition
1440     // of std::map and std::set). Iterate forward over both sets in parallel
1441     // to find matching IDs and disable the corresponding extensions.
1442     ExtensionSet::const_iterator extensions_it = extensions_.begin();
1443     ExtensionIdSet::const_iterator known_disabled_ids_it =
1444         known_disabled_ids.begin();
1445     int known_disabled_count = 0;
1446     while (extensions_it != extensions_.end() &&
1447            known_disabled_ids_it != known_disabled_ids.end()) {
1448       const std::string& extension_id = extensions_it->get()->id();
1449       const int comparison = extension_id.compare(*known_disabled_ids_it);
1450       if (comparison < 0) {
1451         ++extensions_it;
1452       } else if (comparison > 0) {
1453         ++known_disabled_ids_it;
1454       } else {
1455         ++known_disabled_count;
1456         // Advance |extensions_it| immediately as it will be invalidated upon
1457         // disabling the extension it points to.
1458         ++extensions_it;
1459         ++known_disabled_ids_it;
1460         DisableExtension(extension_id, Extension::DISABLE_KNOWN_DISABLED);
1461       }
1462     }
1463     UMA_HISTOGRAM_COUNTS_100("Extensions.KnownDisabledReDisabled",
1464                              known_disabled_count);
1465   }
1466
1467   // Update the list of known disabled to reflect every change to
1468   // |disabled_extensions_| from this point forward.
1469   disabled_extensions_.set_modification_callback(
1470       base::Bind(&extensions::ExtensionPrefs::SetKnownDisabled,
1471                  base::Unretained(extension_prefs_)));
1472 }
1473
1474 void ExtensionService::HandleExtensionAlertDetails() {
1475   extension_error_ui_->ShowExtensions();
1476   // ShowExtensions may cause the error UI to close synchronously, e.g. if it
1477   // causes a navigation.
1478   if (extension_error_ui_)
1479     extension_error_ui_->Close();
1480 }
1481
1482 void ExtensionService::UpdateExternalExtensionAlert() {
1483   if (!FeatureSwitch::prompt_for_external_extensions()->IsEnabled())
1484     return;
1485
1486   const Extension* extension = NULL;
1487   for (ExtensionSet::const_iterator iter = disabled_extensions_.begin();
1488        iter != disabled_extensions_.end(); ++iter) {
1489     const Extension* e = iter->get();
1490     if (IsUnacknowledgedExternalExtension(e)) {
1491       extension = e;
1492       break;
1493     }
1494   }
1495
1496   if (extension) {
1497     if (!extensions::HasExternalInstallError(this)) {
1498       if (extension_prefs_->IncrementAcknowledgePromptCount(extension->id()) >
1499               kMaxExtensionAcknowledgePromptCount) {
1500         // Stop prompting for this extension, and check if there's another
1501         // one that needs prompting.
1502         extension_prefs_->AcknowledgeExternalExtension(extension->id());
1503         UpdateExternalExtensionAlert();
1504         UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent",
1505                                   EXTERNAL_EXTENSION_IGNORED,
1506                                   EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
1507         if (extensions::ManifestURL::UpdatesFromGallery(extension)) {
1508           UMA_HISTOGRAM_ENUMERATION(
1509               "Extensions.ExternalExtensionEventWebstore",
1510               EXTERNAL_EXTENSION_IGNORED,
1511               EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
1512         } else {
1513           UMA_HISTOGRAM_ENUMERATION(
1514               "Extensions.ExternalExtensionEventNonWebstore",
1515               EXTERNAL_EXTENSION_IGNORED,
1516               EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
1517         }
1518         return;
1519       }
1520       if (is_first_run_)
1521         extension_prefs_->SetExternalInstallFirstRun(extension->id());
1522       // first_run is true if the extension was installed during a first run
1523       // (even if it's post-first run now).
1524       bool first_run = extension_prefs_->IsExternalInstallFirstRun(
1525           extension->id());
1526       extensions::AddExternalInstallError(this, extension, first_run);
1527     }
1528   } else {
1529     extensions::RemoveExternalInstallError(this);
1530   }
1531 }
1532
1533 void ExtensionService::UnloadExtension(
1534     const std::string& extension_id,
1535     UnloadedExtensionInfo::Reason reason) {
1536   // Make sure the extension gets deleted after we return from this function.
1537   int include_mask = INCLUDE_EVERYTHING & ~INCLUDE_TERMINATED;
1538   scoped_refptr<const Extension> extension(
1539       GetExtensionById(extension_id, include_mask));
1540
1541   // This method can be called via PostTask, so the extension may have been
1542   // unloaded by the time this runs.
1543   if (!extension.get()) {
1544     // In case the extension may have crashed/uninstalled. Allow the profile to
1545     // clean up its RequestContexts.
1546     system_->UnregisterExtensionWithRequestContexts(extension_id, reason);
1547     return;
1548   }
1549
1550   // If uninstalling let RuntimeEventRouter know.
1551   if (reason == UnloadedExtensionInfo::REASON_UNINSTALL)
1552     extensions::RuntimeEventRouter::OnExtensionUninstalled(
1553         profile_, extension_id);
1554
1555   // Keep information about the extension so that we can reload it later
1556   // even if it's not permanently installed.
1557   unloaded_extension_paths_[extension->id()] = extension->path();
1558
1559   // Clean up if the extension is meant to be enabled after a reload.
1560   reloading_extensions_.erase(extension->id());
1561
1562   // Clean up runtime data.
1563   extension_runtime_data_.erase(extension_id);
1564
1565   if (disabled_extensions_.Contains(extension->id())) {
1566     disabled_extensions_.Remove(extension->id());
1567     // Make sure the profile cleans up its RequestContexts when an already
1568     // disabled extension is unloaded (since they are also tracking the disabled
1569     // extensions).
1570     system_->UnregisterExtensionWithRequestContexts(extension_id, reason);
1571   } else {
1572     // Remove the extension from our list.
1573     extensions_.Remove(extension->id());
1574     NotifyExtensionUnloaded(extension.get(), reason);
1575   }
1576
1577   content::NotificationService::current()->Notify(
1578       chrome::NOTIFICATION_EXTENSION_REMOVED,
1579       content::Source<Profile>(profile_),
1580       content::Details<const Extension>(extension.get()));
1581 }
1582
1583 void ExtensionService::RemoveComponentExtension(
1584     const std::string& extension_id) {
1585   scoped_refptr<const Extension> extension(
1586       GetExtensionById(extension_id, false));
1587   UnloadExtension(extension_id, UnloadedExtensionInfo::REASON_UNINSTALL);
1588   content::NotificationService::current()->Notify(
1589       chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
1590       content::Source<Profile>(profile_),
1591       content::Details<const Extension>(extension.get()));
1592 }
1593
1594 void ExtensionService::UnloadAllExtensions() {
1595   profile_->GetExtensionSpecialStoragePolicy()->RevokeRightsForAllExtensions();
1596
1597   extensions_.Clear();
1598   disabled_extensions_.Clear();
1599   terminated_extensions_.Clear();
1600   extension_runtime_data_.clear();
1601
1602   // TODO(erikkay) should there be a notification for this?  We can't use
1603   // EXTENSION_UNLOADED since that implies that the extension has been disabled
1604   // or uninstalled, and UnloadAll is just part of shutdown.
1605 }
1606
1607 void ExtensionService::ReloadExtensions() {
1608   UnloadAllExtensions();
1609   component_loader_->LoadAll();
1610   extensions::InstalledLoader(this).LoadAllExtensions();
1611   // Don't call SetReadyAndNotifyListeners() since tests call this multiple
1612   // times.
1613 }
1614
1615 void ExtensionService::GarbageCollectExtensions() {
1616 #if defined(OS_CHROMEOS)
1617   if (disable_garbage_collection_)
1618     return;
1619 #endif
1620
1621   if (extension_prefs_->pref_service()->ReadOnly())
1622     return;
1623
1624   if (pending_extension_manager()->HasPendingExtensions()) {
1625     // Don't garbage collect while there are pending installations, which may
1626     // be using the temporary installation directory. Try to garbage collect
1627     // again later.
1628     base::MessageLoop::current()->PostDelayedTask(
1629         FROM_HERE,
1630         base::Bind(&ExtensionService::GarbageCollectExtensions, AsWeakPtr()),
1631         base::TimeDelta::FromSeconds(kGarbageCollectRetryDelay));
1632     return;
1633   }
1634
1635   scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> info(
1636       extension_prefs_->GetInstalledExtensionsInfo());
1637
1638   std::multimap<std::string, base::FilePath> extension_paths;
1639   for (size_t i = 0; i < info->size(); ++i)
1640     extension_paths.insert(std::make_pair(info->at(i)->extension_id,
1641                                           info->at(i)->extension_path));
1642
1643   info = extension_prefs_->GetAllDelayedInstallInfo();
1644   for (size_t i = 0; i < info->size(); ++i)
1645     extension_paths.insert(std::make_pair(info->at(i)->extension_id,
1646                                           info->at(i)->extension_path));
1647
1648   if (!GetFileTaskRunner()->PostTask(
1649           FROM_HERE,
1650           base::Bind(
1651               &extension_file_util::GarbageCollectExtensions,
1652               install_directory_,
1653               extension_paths))) {
1654     NOTREACHED();
1655   }
1656 }
1657
1658 void ExtensionService::SetReadyAndNotifyListeners() {
1659   ready_->Signal();
1660   content::NotificationService::current()->Notify(
1661       chrome::NOTIFICATION_EXTENSIONS_READY,
1662       content::Source<Profile>(profile_),
1663       content::NotificationService::NoDetails());
1664 }
1665
1666 void ExtensionService::OnLoadedInstalledExtensions() {
1667   if (updater_)
1668     updater_->Start();
1669
1670   OnBlacklistUpdated();
1671 }
1672
1673 void ExtensionService::AddExtension(const Extension* extension) {
1674   // TODO(jstritar): We may be able to get rid of this branch by overriding the
1675   // default extension state to DISABLED when the --disable-extensions flag
1676   // is set (http://crbug.com/29067).
1677   if (!extensions_enabled() &&
1678       !extension->is_theme() &&
1679       extension->location() != Manifest::COMPONENT &&
1680       !Manifest::IsExternalLocation(extension->location())) {
1681     return;
1682   }
1683
1684   bool is_extension_upgrade = false;
1685   bool is_extension_installed = false;
1686   const Extension* old = GetInstalledExtension(extension->id());
1687   if (old) {
1688     is_extension_installed = true;
1689     int version_compare_result =
1690         extension->version()->CompareTo(*(old->version()));
1691     is_extension_upgrade = version_compare_result > 0;
1692     // Other than for unpacked extensions, CrxInstaller should have guaranteed
1693     // that we aren't downgrading.
1694     if (!Manifest::IsUnpackedLocation(extension->location()))
1695       CHECK_GE(version_compare_result, 0);
1696   }
1697   SetBeingUpgraded(extension, is_extension_upgrade);
1698
1699   // The extension is now loaded, remove its data from unloaded extension map.
1700   unloaded_extension_paths_.erase(extension->id());
1701
1702   // If a terminated extension is loaded, remove it from the terminated list.
1703   UntrackTerminatedExtension(extension->id());
1704
1705   // If the extension was disabled for a reload, then enable it.
1706   bool reloading = reloading_extensions_.erase(extension->id()) > 0;
1707
1708   // Check if the extension's privileges have changed and mark the
1709   // extension disabled if necessary.
1710   CheckPermissionsIncrease(extension, is_extension_installed);
1711
1712   if (is_extension_installed && !reloading) {
1713     // To upgrade an extension in place, unload the old one and then load the
1714     // new one.  ReloadExtension disables the extension, which is sufficient.
1715     UnloadExtension(extension->id(), UnloadedExtensionInfo::REASON_UPDATE);
1716   }
1717
1718   if (extension_prefs_->IsExtensionBlacklisted(extension->id())) {
1719     // Only prefs is checked for the blacklist. We rely on callers to check the
1720     // blacklist before calling into here, e.g. CrxInstaller checks before
1721     // installation then threads through the install and pending install flow
1722     // of this class, and we check when loading installed extensions.
1723     blacklisted_extensions_.Insert(extension);
1724   } else if (!reloading &&
1725              extension_prefs_->IsExtensionDisabled(extension->id())) {
1726     disabled_extensions_.Insert(extension);
1727     if (extension_sync_service_)
1728       extension_sync_service_->SyncExtensionChangeIfNeeded(*extension);
1729     content::NotificationService::current()->Notify(
1730         chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED,
1731         content::Source<Profile>(profile_),
1732         content::Details<const Extension>(extension));
1733
1734     // Show the extension disabled error if a permissions increase was the
1735     // only reason it was disabled.
1736     if (extension_prefs_->GetDisableReasons(extension->id()) ==
1737         Extension::DISABLE_PERMISSIONS_INCREASE) {
1738       extensions::AddExtensionDisabledError(this, extension);
1739     }
1740   } else if (reloading) {
1741     // Replace the old extension with the new version.
1742     CHECK(!disabled_extensions_.Insert(extension));
1743     EnableExtension(extension->id());
1744   } else {
1745     // All apps that are displayed in the launcher are ordered by their ordinals
1746     // so we must ensure they have valid ordinals.
1747     if (extension->RequiresSortOrdinal()) {
1748       if (!extension->ShouldDisplayInNewTabPage()) {
1749         extension_prefs_->extension_sorting()->MarkExtensionAsHidden(
1750             extension->id());
1751       }
1752       extension_prefs_->extension_sorting()->EnsureValidOrdinals(
1753           extension->id(), syncer::StringOrdinal());
1754     }
1755
1756     extensions_.Insert(extension);
1757     if (extension_sync_service_)
1758       extension_sync_service_->SyncExtensionChangeIfNeeded(*extension);
1759     NotifyExtensionLoaded(extension);
1760   }
1761   SetBeingUpgraded(extension, false);
1762 }
1763
1764 void ExtensionService::AddComponentExtension(const Extension* extension) {
1765   const std::string old_version_string(
1766       extension_prefs_->GetVersionString(extension->id()));
1767   const Version old_version(old_version_string);
1768
1769   if (!old_version.IsValid() || !old_version.Equals(*extension->version())) {
1770     VLOG(1) << "Component extension " << extension->name() << " ("
1771         << extension->id() << ") installing/upgrading from '"
1772         << old_version_string << "' to " << extension->version()->GetString();
1773
1774     AddNewOrUpdatedExtension(extension,
1775                              Extension::ENABLED_COMPONENT,
1776                              extensions::Blacklist::NOT_BLACKLISTED,
1777                              syncer::StringOrdinal());
1778     return;
1779   }
1780
1781   AddExtension(extension);
1782 }
1783
1784 void ExtensionService::UpdateActivePermissions(const Extension* extension) {
1785   // If the extension has used the optional permissions API, it will have a
1786   // custom set of active permissions defined in the extension prefs. Here,
1787   // we update the extension's active permissions based on the prefs.
1788   scoped_refptr<PermissionSet> active_permissions =
1789       extension_prefs()->GetActivePermissions(extension->id());
1790
1791   if (active_permissions.get()) {
1792     // We restrict the active permissions to be within the bounds defined in the
1793     // extension's manifest.
1794     //  a) active permissions must be a subset of optional + default permissions
1795     //  b) active permissions must contains all default permissions
1796     scoped_refptr<PermissionSet> total_permissions =
1797         PermissionSet::CreateUnion(
1798             extensions::PermissionsData::GetRequiredPermissions(extension),
1799             extensions::PermissionsData::GetOptionalPermissions(extension));
1800
1801     // Make sure the active permissions contain no more than optional + default.
1802     scoped_refptr<PermissionSet> adjusted_active =
1803         PermissionSet::CreateIntersection(
1804             total_permissions.get(), active_permissions.get());
1805
1806     // Make sure the active permissions contain the default permissions.
1807     adjusted_active = PermissionSet::CreateUnion(
1808         extensions::PermissionsData::GetRequiredPermissions(extension),
1809         adjusted_active.get());
1810
1811     extensions::PermissionsUpdater perms_updater(profile());
1812     perms_updater.UpdateActivePermissions(extension, adjusted_active.get());
1813   }
1814 }
1815
1816 void ExtensionService::CheckPermissionsIncrease(const Extension* extension,
1817                                                 bool is_extension_installed) {
1818   UpdateActivePermissions(extension);
1819
1820   // We keep track of all permissions the user has granted each extension.
1821   // This allows extensions to gracefully support backwards compatibility
1822   // by including unknown permissions in their manifests. When the user
1823   // installs the extension, only the recognized permissions are recorded.
1824   // When the unknown permissions become recognized (e.g., through browser
1825   // upgrade), we can prompt the user to accept these new permissions.
1826   // Extensions can also silently upgrade to less permissions, and then
1827   // silently upgrade to a version that adds these permissions back.
1828   //
1829   // For example, pretend that Chrome 10 includes a permission "omnibox"
1830   // for an API that adds suggestions to the omnibox. An extension can
1831   // maintain backwards compatibility while still having "omnibox" in the
1832   // manifest. If a user installs the extension on Chrome 9, the browser
1833   // will record the permissions it recognized, not including "omnibox."
1834   // When upgrading to Chrome 10, "omnibox" will be recognized and Chrome
1835   // will disable the extension and prompt the user to approve the increase
1836   // in privileges. The extension could then release a new version that
1837   // removes the "omnibox" permission. When the user upgrades, Chrome will
1838   // still remember that "omnibox" had been granted, so that if the
1839   // extension once again includes "omnibox" in an upgrade, the extension
1840   // can upgrade without requiring this user's approval.
1841   int disable_reasons = extension_prefs_->GetDisableReasons(extension->id());
1842
1843   bool auto_grant_permission =
1844       (!is_extension_installed && extension->was_installed_by_default()) ||
1845       chrome::IsRunningInForcedAppMode();
1846   // Silently grant all active permissions to default apps only on install.
1847   // After install they should behave like other apps.
1848   // Silently grant all active permissions to apps install in kiosk mode on both
1849   // install and update.
1850   if (auto_grant_permission)
1851     GrantPermissions(extension);
1852
1853   bool is_privilege_increase = false;
1854   // We only need to compare the granted permissions to the current permissions
1855   // if the extension is not allowed to silently increase its permissions.
1856   if (!extensions::PermissionsData::CanSilentlyIncreasePermissions(extension) &&
1857       !auto_grant_permission) {
1858     // Add all the recognized permissions if the granted permissions list
1859     // hasn't been initialized yet.
1860     scoped_refptr<PermissionSet> granted_permissions =
1861         extension_prefs_->GetGrantedPermissions(extension->id());
1862     CHECK(granted_permissions.get());
1863
1864     // Here, we check if an extension's privileges have increased in a manner
1865     // that requires the user's approval. This could occur because the browser
1866     // upgraded and recognized additional privileges, or an extension upgrades
1867     // to a version that requires additional privileges.
1868     is_privilege_increase =
1869         extensions::PermissionMessageProvider::Get()->IsPrivilegeIncrease(
1870                 granted_permissions,
1871                 extension->GetActivePermissions().get(),
1872                 extension->GetType());
1873   }
1874
1875   if (is_extension_installed) {
1876     // If the extension was already disabled, suppress any alerts for becoming
1877     // disabled on permissions increase.
1878     bool previously_disabled =
1879         extension_prefs_->IsExtensionDisabled(extension->id());
1880     // Legacy disabled extensions do not have a disable reason. Infer that if
1881     // there was no permission increase, it was likely disabled by the user.
1882     if (previously_disabled && disable_reasons == Extension::DISABLE_NONE &&
1883         !extension_prefs_->DidExtensionEscalatePermissions(extension->id())) {
1884       disable_reasons |= Extension::DISABLE_USER_ACTION;
1885     }
1886     // Extensions that came to us disabled from sync need a similar inference,
1887     // except based on the new version's permissions.
1888     if (previously_disabled &&
1889         disable_reasons == Extension::DISABLE_UNKNOWN_FROM_SYNC) {
1890       // Remove the DISABLE_UNKNOWN_FROM_SYNC reason.
1891       extension_prefs_->ClearDisableReasons(extension->id());
1892       if (!is_privilege_increase)
1893         disable_reasons |= Extension::DISABLE_USER_ACTION;
1894     }
1895     disable_reasons &= ~Extension::DISABLE_UNKNOWN_FROM_SYNC;
1896   }
1897
1898   // Extension has changed permissions significantly. Disable it. A
1899   // notification should be sent by the caller.
1900   if (is_privilege_increase) {
1901     disable_reasons |= Extension::DISABLE_PERMISSIONS_INCREASE;
1902     if (!extension_prefs_->DidExtensionEscalatePermissions(extension->id())) {
1903       RecordPermissionMessagesHistogram(
1904           extension, "Extensions.Permissions_AutoDisable");
1905     }
1906     extension_prefs_->SetExtensionState(extension->id(), Extension::DISABLED);
1907     extension_prefs_->SetDidExtensionEscalatePermissions(extension, true);
1908   }
1909   if (disable_reasons != Extension::DISABLE_NONE) {
1910     extension_prefs_->AddDisableReason(
1911         extension->id(),
1912         static_cast<Extension::DisableReason>(disable_reasons));
1913   }
1914 }
1915
1916 void ExtensionService::UpdateActiveExtensionsInCrashReporter() {
1917   std::set<std::string> extension_ids;
1918   for (ExtensionSet::const_iterator iter = extensions_.begin();
1919        iter != extensions_.end(); ++iter) {
1920     const Extension* extension = iter->get();
1921     if (!extension->is_theme() && extension->location() != Manifest::COMPONENT)
1922       extension_ids.insert(extension->id());
1923   }
1924
1925   crash_keys::SetActiveExtensions(extension_ids);
1926 }
1927
1928 ExtensionService::ImportStatus ExtensionService::CheckImports(
1929     const extensions::Extension* extension,
1930     std::list<SharedModuleInfo::ImportInfo>* missing_modules,
1931     std::list<SharedModuleInfo::ImportInfo>* outdated_modules) {
1932   DCHECK(extension);
1933   DCHECK(missing_modules && missing_modules->empty());
1934   DCHECK(outdated_modules && outdated_modules->empty());
1935   ImportStatus status = IMPORT_STATUS_OK;
1936   if (SharedModuleInfo::ImportsModules(extension)) {
1937     const std::vector<SharedModuleInfo::ImportInfo>& imports =
1938         SharedModuleInfo::GetImports(extension);
1939     std::vector<SharedModuleInfo::ImportInfo>::const_iterator i;
1940     for (i = imports.begin(); i != imports.end(); ++i) {
1941       Version version_required(i->minimum_version);
1942       const Extension* imported_module =
1943           GetExtensionById(i->extension_id, true);
1944       if (!imported_module) {
1945         if (extension->from_webstore()) {
1946           status = IMPORT_STATUS_UNSATISFIED;
1947           missing_modules->push_back(*i);
1948         } else {
1949           return IMPORT_STATUS_UNRECOVERABLE;
1950         }
1951       } else if (!SharedModuleInfo::IsSharedModule(imported_module)) {
1952         return IMPORT_STATUS_UNRECOVERABLE;
1953       } else if (version_required.IsValid() &&
1954                  imported_module->version()->CompareTo(version_required) < 0) {
1955         if (imported_module->from_webstore()) {
1956           outdated_modules->push_back(*i);
1957           status = IMPORT_STATUS_UNSATISFIED;
1958         } else {
1959           return IMPORT_STATUS_UNRECOVERABLE;
1960         }
1961       }
1962     }
1963   }
1964   return status;
1965 }
1966
1967 ExtensionService::ImportStatus ExtensionService::SatisfyImports(
1968     const Extension* extension) {
1969   std::list<SharedModuleInfo::ImportInfo> noinstalled;
1970   std::list<SharedModuleInfo::ImportInfo> outdated;
1971   ImportStatus status = CheckImports(extension, &noinstalled, &outdated);
1972   if (status == IMPORT_STATUS_UNRECOVERABLE)
1973     return status;
1974   if (status == IMPORT_STATUS_UNSATISFIED) {
1975     std::list<SharedModuleInfo::ImportInfo>::const_iterator iter;
1976     for (iter = noinstalled.begin(); iter != noinstalled.end(); ++iter) {
1977       pending_extension_manager()->AddFromExtensionImport(
1978           iter->extension_id,
1979           extension_urls::GetWebstoreUpdateUrl(),
1980           IsSharedModule);
1981     }
1982     CheckForUpdatesSoon();
1983   }
1984   return status;
1985 }
1986
1987 scoped_ptr<const ExtensionSet>
1988     ExtensionService::GetDependentExtensions(const Extension* extension) {
1989   scoped_ptr<ExtensionSet> dependents(new ExtensionSet());
1990   scoped_ptr<ExtensionSet> set_to_check(new ExtensionSet());
1991   if (SharedModuleInfo::IsSharedModule(extension)) {
1992     set_to_check->InsertAll(disabled_extensions_);
1993     set_to_check->InsertAll(delayed_installs_);
1994     set_to_check->InsertAll(extensions_);
1995     for (ExtensionSet::const_iterator iter = set_to_check->begin();
1996          iter != set_to_check->end(); ++iter) {
1997       if (SharedModuleInfo::ImportsExtensionById(iter->get(),
1998                                                  extension->id())) {
1999         dependents->Insert(*iter);
2000       }
2001     }
2002   }
2003   return dependents.PassAs<const ExtensionSet>();
2004 }
2005
2006 void ExtensionService::PruneSharedModulesOnUninstall(
2007     const Extension* extension) {
2008   if (SharedModuleInfo::ImportsModules(extension)) {
2009     const std::vector<SharedModuleInfo::ImportInfo>& imports =
2010         SharedModuleInfo::GetImports(extension);
2011     std::vector<SharedModuleInfo::ImportInfo>::const_iterator i;
2012     for (i = imports.begin(); i != imports.end(); ++i) {
2013       const Extension* imported_module =
2014           GetExtensionById(i->extension_id, true);
2015       if (imported_module && imported_module->from_webstore()) {
2016         scoped_ptr<const ExtensionSet> dependents =
2017             GetDependentExtensions(imported_module);
2018         if (dependents->size() == 0) {
2019           UninstallExtension(i->extension_id, true, NULL);
2020         }
2021       }
2022     }
2023   }
2024 }
2025
2026 void ExtensionService::OnExtensionInstalled(
2027     const Extension* extension,
2028     const syncer::StringOrdinal& page_ordinal,
2029     bool has_requirement_errors,
2030     extensions::Blacklist::BlacklistState blacklist_state,
2031     bool wait_for_idle) {
2032   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2033
2034   const std::string& id = extension->id();
2035   bool initial_enable = ShouldEnableOnInstall(extension);
2036   const extensions::PendingExtensionInfo* pending_extension_info = NULL;
2037   if ((pending_extension_info = pending_extension_manager()->GetById(id))) {
2038     if (!pending_extension_info->ShouldAllowInstall(extension)) {
2039       pending_extension_manager()->Remove(id);
2040
2041       LOG(WARNING) << "ShouldAllowInstall() returned false for "
2042                    << id << " of type " << extension->GetType()
2043                    << " and update URL "
2044                    << extensions::ManifestURL::GetUpdateURL(extension).spec()
2045                    << "; not installing";
2046
2047       // Delete the extension directory since we're not going to
2048       // load it.
2049       if (!GetFileTaskRunner()->PostTask(
2050               FROM_HERE,
2051               base::Bind(&extension_file_util::DeleteFile,
2052                          extension->path(), true))) {
2053         NOTREACHED();
2054       }
2055       return;
2056     }
2057
2058     pending_extension_manager()->Remove(id);
2059   } else {
2060     // We explicitly want to re-enable an uninstalled external
2061     // extension; if we're here, that means the user is manually
2062     // installing the extension.
2063     if (IsExternalExtensionUninstalled(id)) {
2064       initial_enable = true;
2065     }
2066   }
2067
2068   // Unsupported requirements overrides the management policy.
2069   if (has_requirement_errors) {
2070     initial_enable = false;
2071     extension_prefs_->AddDisableReason(
2072         id, Extension::DISABLE_UNSUPPORTED_REQUIREMENT);
2073   // If the extension was disabled because of unsupported requirements but
2074   // now supports all requirements after an update and there are not other
2075   // disable reasons, enable it.
2076   } else if (extension_prefs_->GetDisableReasons(id) ==
2077       Extension::DISABLE_UNSUPPORTED_REQUIREMENT) {
2078     initial_enable = true;
2079     extension_prefs_->ClearDisableReasons(id);
2080   }
2081
2082   if (blacklist_state == extensions::Blacklist::BLACKLISTED_MALWARE) {
2083     // Installation of a blacklisted extension can happen from sync, policy,
2084     // etc, where to maintain consistency we need to install it, just never
2085     // load it (see AddExtension). Usually it should be the job of callers to
2086     // incercept blacklisted extension earlier (e.g. CrxInstaller, before even
2087     // showing the install dialogue).
2088     extension_prefs()->AcknowledgeBlacklistedExtension(id);
2089     UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.SilentInstall",
2090                               extension->location(),
2091                               Manifest::NUM_LOCATIONS);
2092   }
2093
2094   if (!GetInstalledExtension(extension->id())) {
2095     UMA_HISTOGRAM_ENUMERATION("Extensions.InstallType",
2096                               extension->GetType(), 100);
2097     UMA_HISTOGRAM_ENUMERATION("Extensions.InstallSource",
2098                               extension->location(), Manifest::NUM_LOCATIONS);
2099     RecordPermissionMessagesHistogram(
2100         extension, "Extensions.Permissions_Install");
2101   } else {
2102     UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateType",
2103                               extension->GetType(), 100);
2104     UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateSource",
2105                               extension->location(), Manifest::NUM_LOCATIONS);
2106   }
2107
2108   // Certain extension locations are specific enough that we can
2109   // auto-acknowledge any extension that came from one of them.
2110   if (Manifest::IsPolicyLocation(extension->location()))
2111     AcknowledgeExternalExtension(extension->id());
2112   const Extension::State initial_state =
2113       initial_enable ? Extension::ENABLED : Extension::DISABLED;
2114   if (ShouldDelayExtensionUpdate(id, wait_for_idle)) {
2115     extension_prefs_->SetDelayedInstallInfo(
2116         extension,
2117         initial_state,
2118         blacklist_state,
2119         extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IDLE,
2120         page_ordinal);
2121
2122     // Transfer ownership of |extension|.
2123     delayed_installs_.Insert(extension);
2124
2125     // Notify extension of available update.
2126     extensions::RuntimeEventRouter::DispatchOnUpdateAvailableEvent(
2127         profile_, id, extension->manifest()->value());
2128
2129     // Notify observers that app update is available.
2130     FOR_EACH_OBSERVER(extensions::UpdateObserver, update_observers_,
2131                       OnAppUpdateAvailable(extension->id()));
2132     return;
2133   }
2134
2135   ImportStatus status = SatisfyImports(extension);
2136   if (installs_delayed_for_gc()) {
2137     extension_prefs_->SetDelayedInstallInfo(
2138         extension,
2139         initial_state,
2140         blacklist_state,
2141         extensions::ExtensionPrefs::DELAY_REASON_GC,
2142         page_ordinal);
2143     delayed_installs_.Insert(extension);
2144   } else if (status != IMPORT_STATUS_OK) {
2145     if (status == IMPORT_STATUS_UNSATISFIED) {
2146       extension_prefs_->SetDelayedInstallInfo(
2147           extension,
2148           initial_state,
2149           blacklist_state,
2150           extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
2151           page_ordinal);
2152       delayed_installs_.Insert(extension);
2153     }
2154   } else {
2155     AddNewOrUpdatedExtension(extension,
2156                              initial_state,
2157                              blacklist_state,
2158                              page_ordinal);
2159   }
2160 }
2161
2162 void ExtensionService::AddNewOrUpdatedExtension(
2163     const Extension* extension,
2164     Extension::State initial_state,
2165     extensions::Blacklist::BlacklistState blacklist_state,
2166     const syncer::StringOrdinal& page_ordinal) {
2167   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2168   extension_prefs_->OnExtensionInstalled(extension,
2169                                          initial_state,
2170                                          blacklist_state,
2171                                          page_ordinal);
2172   delayed_installs_.Remove(extension->id());
2173   FinishInstallation(extension);
2174 }
2175
2176 void ExtensionService::MaybeFinishDelayedInstallation(
2177     const std::string& extension_id) {
2178   // Check if the extension already got installed.
2179   if (!delayed_installs_.Contains(extension_id))
2180     return;
2181   extensions::ExtensionPrefs::DelayReason reason =
2182       extension_prefs_->GetDelayedInstallReason(extension_id);
2183
2184   // Check if the extension is idle. DELAY_REASON_NONE is used for older
2185   // preferences files that will not have set this field but it was previously
2186   // only used for idle updates.
2187   if ((reason == extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IDLE ||
2188        reason == extensions::ExtensionPrefs::DELAY_REASON_NONE) &&
2189        is_ready() && !IsExtensionIdle(extension_id))
2190     return;
2191
2192   const Extension* extension = delayed_installs_.GetByID(extension_id);
2193   if (reason == extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS) {
2194     ImportStatus status = SatisfyImports(extension);
2195     if (status != IMPORT_STATUS_OK) {
2196       if (status == IMPORT_STATUS_UNRECOVERABLE) {
2197         delayed_installs_.Remove(extension_id);
2198         // Make sure no version of the extension is actually installed, (i.e.,
2199         // that this delayed install was not an update).
2200         CHECK(!extension_prefs_->GetInstalledExtensionInfo(extension_id).get());
2201         extension_prefs_->DeleteExtensionPrefs(extension_id);
2202       }
2203       return;
2204     }
2205   }
2206
2207   FinishDelayedInstallation(extension_id);
2208 }
2209
2210 void ExtensionService::FinishDelayedInstallation(
2211     const std::string& extension_id) {
2212   scoped_refptr<const Extension> extension(
2213       GetPendingExtensionUpdate(extension_id));
2214   CHECK(extension.get());
2215   delayed_installs_.Remove(extension_id);
2216
2217   if (!extension_prefs_->FinishDelayedInstallInfo(extension_id))
2218     NOTREACHED();
2219
2220   FinishInstallation(extension.get());
2221 }
2222
2223 void ExtensionService::FinishInstallation(const Extension* extension) {
2224   const extensions::Extension* existing_extension =
2225       GetInstalledExtension(extension->id());
2226   bool is_update = false;
2227   std::string old_name;
2228   if (existing_extension) {
2229     is_update = true;
2230     old_name = existing_extension->name();
2231   }
2232   extensions::InstalledExtensionInfo details(extension, is_update, old_name);
2233   content::NotificationService::current()->Notify(
2234       chrome::NOTIFICATION_EXTENSION_INSTALLED,
2235       content::Source<Profile>(profile_),
2236       content::Details<const extensions::InstalledExtensionInfo>(&details));
2237
2238   bool unacknowledged_external = IsUnacknowledgedExternalExtension(extension);
2239
2240   // Unpacked extensions default to allowing file access, but if that has been
2241   // overridden, don't reset the value.
2242   if (Manifest::ShouldAlwaysAllowFileAccess(extension->location()) &&
2243       !extension_prefs_->HasAllowFileAccessSetting(extension->id())) {
2244     extension_prefs_->SetAllowFileAccess(extension->id(), true);
2245   }
2246
2247   AddExtension(extension);
2248
2249   // If this is a new external extension that was disabled, alert the user
2250   // so he can reenable it. We do this last so that it has already been
2251   // added to our list of extensions.
2252   if (unacknowledged_external && !is_update) {
2253     UpdateExternalExtensionAlert();
2254     UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEvent",
2255                               EXTERNAL_EXTENSION_INSTALLED,
2256                               EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
2257     if (extensions::ManifestURL::UpdatesFromGallery(extension)) {
2258       UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventWebstore",
2259                                 EXTERNAL_EXTENSION_INSTALLED,
2260                                 EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
2261     } else {
2262       UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalExtensionEventNonWebstore",
2263                                 EXTERNAL_EXTENSION_INSTALLED,
2264                                 EXTERNAL_EXTENSION_BUCKET_BOUNDARY);
2265     }
2266   }
2267
2268   // Check extensions that may have been delayed only because this shared module
2269   // was not available.
2270   if (SharedModuleInfo::IsSharedModule(extension)) {
2271     MaybeFinishDelayedInstallations();
2272   }
2273 }
2274
2275 const Extension* ExtensionService::GetPendingExtensionUpdate(
2276     const std::string& id) const {
2277   return delayed_installs_.GetByID(id);
2278 }
2279
2280 void ExtensionService::TrackTerminatedExtension(const Extension* extension) {
2281   if (!terminated_extensions_.Contains(extension->id()))
2282     terminated_extensions_.Insert(make_scoped_refptr(extension));
2283
2284   UnloadExtension(extension->id(), UnloadedExtensionInfo::REASON_TERMINATE);
2285 }
2286
2287 void ExtensionService::UntrackTerminatedExtension(const std::string& id) {
2288   std::string lowercase_id = StringToLowerASCII(id);
2289   const Extension* extension = terminated_extensions_.GetByID(lowercase_id);
2290   terminated_extensions_.Remove(lowercase_id);
2291   if (extension) {
2292     content::NotificationService::current()->Notify(
2293         chrome::NOTIFICATION_EXTENSION_REMOVED,
2294         content::Source<Profile>(profile_),
2295         content::Details<const Extension>(extension));
2296   }
2297 }
2298
2299 const Extension* ExtensionService::GetTerminatedExtension(
2300     const std::string& id) const {
2301   return GetExtensionById(id, INCLUDE_TERMINATED);
2302 }
2303
2304 const Extension* ExtensionService::GetInstalledExtension(
2305     const std::string& id) const {
2306   int include_mask = INCLUDE_ENABLED |
2307                      INCLUDE_DISABLED |
2308                      INCLUDE_TERMINATED |
2309                      INCLUDE_BLACKLISTED;
2310   return GetExtensionById(id, include_mask);
2311 }
2312
2313 bool ExtensionService::ExtensionBindingsAllowed(const GURL& url) {
2314   // Allow bindings for all packaged extensions and component hosted apps.
2315   const Extension* extension = extensions_.GetExtensionOrAppByURL(url);
2316   return extension && (!extension->is_hosted_app() ||
2317                        extension->location() == Manifest::COMPONENT);
2318 }
2319
2320 bool ExtensionService::ShouldBlockUrlInBrowserTab(GURL* url) {
2321   const Extension* extension = extensions_.GetExtensionOrAppByURL(*url);
2322   if (extension && extension->is_platform_app()) {
2323     *url = GURL(chrome::kExtensionInvalidRequestURL);
2324     return true;
2325   }
2326
2327   return false;
2328 }
2329
2330 bool ExtensionService::OnExternalExtensionFileFound(
2331          const std::string& id,
2332          const Version* version,
2333          const base::FilePath& path,
2334          Manifest::Location location,
2335          int creation_flags,
2336          bool mark_acknowledged) {
2337   CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2338   CHECK(Extension::IdIsValid(id));
2339   if (extension_prefs_->IsExternalExtensionUninstalled(id))
2340     return false;
2341
2342   // Before even bothering to unpack, check and see if we already have this
2343   // version. This is important because these extensions are going to get
2344   // installed on every startup.
2345   const Extension* existing = GetExtensionById(id, true);
2346
2347   if (existing) {
2348     // The default apps will have the location set as INTERNAL. Since older
2349     // default apps are installed as EXTERNAL, we override them. However, if the
2350     // app is already installed as internal, then do the version check.
2351     // TODO(grv) : Remove after Q1-2013.
2352     bool is_default_apps_migration =
2353         (location == Manifest::INTERNAL &&
2354          Manifest::IsExternalLocation(existing->location()));
2355
2356     if (!is_default_apps_migration) {
2357       DCHECK(version);
2358
2359       switch (existing->version()->CompareTo(*version)) {
2360         case -1:  // existing version is older, we should upgrade
2361           break;
2362         case 0:  // existing version is same, do nothing
2363           return false;
2364         case 1:  // existing version is newer, uh-oh
2365           LOG(WARNING) << "Found external version of extension " << id
2366                        << "that is older than current version. Current version "
2367                        << "is: " << existing->VersionString() << ". New "
2368                        << "version is: " << version->GetString()
2369                        << ". Keeping current version.";
2370           return false;
2371       }
2372     }
2373   }
2374
2375   // If the extension is already pending, don't start an install.
2376   if (!pending_extension_manager()->AddFromExternalFile(
2377           id, location, *version, creation_flags, mark_acknowledged)) {
2378     return false;
2379   }
2380
2381   // no client (silent install)
2382   scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(this));
2383   installer->set_install_source(location);
2384   installer->set_expected_id(id);
2385   installer->set_expected_version(*version);
2386   installer->set_install_cause(extension_misc::INSTALL_CAUSE_EXTERNAL_FILE);
2387   installer->set_creation_flags(creation_flags);
2388 #if defined(OS_CHROMEOS)
2389   extensions::InstallLimiter::Get(profile_)->Add(installer, path);
2390 #else
2391   installer->InstallCrx(path);
2392 #endif
2393
2394   // Depending on the source, a new external extension might not need a user
2395   // notification on installation. For such extensions, mark them acknowledged
2396   // now to suppress the notification.
2397   if (mark_acknowledged)
2398     AcknowledgeExternalExtension(id);
2399
2400   return true;
2401 }
2402
2403 void ExtensionService::ReportExtensionLoadError(
2404     const base::FilePath& extension_path,
2405     const std::string &error,
2406     bool be_noisy) {
2407   content::NotificationService::current()->Notify(
2408       chrome::NOTIFICATION_EXTENSION_LOAD_ERROR,
2409       content::Source<Profile>(profile_),
2410       content::Details<const std::string>(&error));
2411
2412   std::string path_str = UTF16ToUTF8(extension_path.LossyDisplayName());
2413   string16 message = UTF8ToUTF16(base::StringPrintf(
2414       "Could not load extension from '%s'. %s",
2415       path_str.c_str(), error.c_str()));
2416   ExtensionErrorReporter::GetInstance()->ReportError(message, be_noisy);
2417 }
2418
2419 void ExtensionService::DidCreateRenderViewForBackgroundPage(
2420     extensions::ExtensionHost* host) {
2421   OrphanedDevTools::iterator iter =
2422       orphaned_dev_tools_.find(host->extension_id());
2423   if (iter == orphaned_dev_tools_.end())
2424     return;
2425
2426   iter->second->ConnectRenderViewHost(host->render_view_host());
2427   orphaned_dev_tools_.erase(iter);
2428 }
2429
2430 void ExtensionService::Observe(int type,
2431                                const content::NotificationSource& source,
2432                                const content::NotificationDetails& details) {
2433   switch (type) {
2434     case chrome::NOTIFICATION_APP_TERMINATING:
2435       // Shutdown has started. Don't start any more extension installs.
2436       // (We cannot use ExtensionService::Shutdown() for this because it
2437       // happens too late in browser teardown.)
2438       browser_terminating_ = true;
2439       break;
2440     case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED: {
2441       if (profile_ !=
2442           content::Source<Profile>(source).ptr()->GetOriginalProfile()) {
2443         break;
2444       }
2445
2446       extensions::ExtensionHost* host =
2447           content::Details<extensions::ExtensionHost>(details).ptr();
2448
2449       // Mark the extension as terminated and Unload it. We want it to
2450       // be in a consistent state: either fully working or not loaded
2451       // at all, but never half-crashed.  We do it in a PostTask so
2452       // that other handlers of this notification will still have
2453       // access to the Extension and ExtensionHost.
2454       base::MessageLoop::current()->PostTask(
2455           FROM_HERE,
2456           base::Bind(
2457               &ExtensionService::TrackTerminatedExtension,
2458               AsWeakPtr(),
2459               host->extension()));
2460       break;
2461     }
2462     case content::NOTIFICATION_RENDERER_PROCESS_CREATED: {
2463       content::RenderProcessHost* process =
2464           content::Source<content::RenderProcessHost>(source).ptr();
2465       Profile* host_profile =
2466           Profile::FromBrowserContext(process->GetBrowserContext());
2467       if (!profile_->IsSameProfile(host_profile->GetOriginalProfile()))
2468           break;
2469
2470       // Extensions need to know the channel for API restrictions.
2471       process->Send(new ExtensionMsg_SetChannel(
2472           extensions::GetCurrentChannel()));
2473
2474       // Platform apps need to know the system font.
2475       scoped_ptr<base::DictionaryValue> fonts(new base::DictionaryValue);
2476       webui::SetFontAndTextDirection(fonts.get());
2477       std::string font_family, font_size;
2478       fonts->GetString("fontfamily", &font_family);
2479       fonts->GetString("fontsize", &font_size);
2480       process->Send(new ExtensionMsg_SetSystemFont(
2481           font_family, font_size));
2482
2483       // Valid extension function names, used to setup bindings in renderer.
2484       std::vector<std::string> function_names;
2485       ExtensionFunctionDispatcher::GetAllFunctionNames(&function_names);
2486       process->Send(new ExtensionMsg_SetFunctionNames(function_names));
2487
2488       // Scripting whitelist. This is modified by tests and must be communicated
2489       // to renderers.
2490       process->Send(new ExtensionMsg_SetScriptingWhitelist(
2491           extensions::ExtensionsClient::Get()->GetScriptingWhitelist()));
2492
2493       // Loaded extensions.
2494       std::vector<ExtensionMsg_Loaded_Params> loaded_extensions;
2495       for (ExtensionSet::const_iterator iter = extensions_.begin();
2496            iter != extensions_.end(); ++iter) {
2497         // Renderers don't need to know about themes.
2498         if (!(*iter)->is_theme())
2499           loaded_extensions.push_back(ExtensionMsg_Loaded_Params(iter->get()));
2500       }
2501       process->Send(new ExtensionMsg_Loaded(loaded_extensions));
2502       break;
2503     }
2504     case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: {
2505       content::RenderProcessHost* process =
2506           content::Source<content::RenderProcessHost>(source).ptr();
2507       Profile* host_profile =
2508           Profile::FromBrowserContext(process->GetBrowserContext());
2509       if (!profile_->IsSameProfile(host_profile->GetOriginalProfile()))
2510           break;
2511
2512       if (process_map_.Contains(process->GetID())) {
2513         // An extension process was terminated, this might have resulted in an
2514         // app or extension becoming idle.
2515         std::set<std::string> extension_ids =
2516             process_map_.GetExtensionsInProcess(process->GetID());
2517         for (std::set<std::string>::const_iterator it = extension_ids.begin();
2518              it != extension_ids.end(); ++it) {
2519           if (delayed_installs_.Contains(*it)) {
2520             base::MessageLoop::current()->PostDelayedTask(
2521                 FROM_HERE,
2522                 base::Bind(&ExtensionService::MaybeFinishDelayedInstallation,
2523                            AsWeakPtr(), *it),
2524                 base::TimeDelta::FromSeconds(kUpdateIdleDelay));
2525           }
2526         }
2527       }
2528
2529       process_map_.RemoveAllFromProcess(process->GetID());
2530       BrowserThread::PostTask(
2531           BrowserThread::IO, FROM_HERE,
2532           base::Bind(&ExtensionInfoMap::UnregisterAllExtensionsInProcess,
2533                      system_->info_map(),
2534                      process->GetID()));
2535       break;
2536     }
2537     case chrome::NOTIFICATION_UPGRADE_RECOMMENDED: {
2538       // Notify extensions that chrome update is available.
2539       extensions::RuntimeEventRouter::DispatchOnBrowserUpdateAvailableEvent(
2540           profile_);
2541
2542       // Notify observers that chrome update is available.
2543       FOR_EACH_OBSERVER(extensions::UpdateObserver, update_observers_,
2544                         OnChromeUpdateAvailable());
2545       break;
2546     }
2547
2548     default:
2549       NOTREACHED() << "Unexpected notification type.";
2550   }
2551 }
2552
2553 void ExtensionService::OnExtensionInstallPrefChanged() {
2554   IdentifyAlertableExtensions();
2555   CheckManagementPolicy();
2556 }
2557
2558 bool ExtensionService::HasApps() const {
2559   return !GetAppIds().empty();
2560 }
2561
2562 ExtensionIdSet ExtensionService::GetAppIds() const {
2563   ExtensionIdSet result;
2564   for (ExtensionSet::const_iterator it = extensions_.begin();
2565        it != extensions_.end(); ++it) {
2566     if ((*it)->is_app() && (*it)->location() != Manifest::COMPONENT)
2567       result.insert((*it)->id());
2568   }
2569
2570   return result;
2571 }
2572
2573 bool ExtensionService::IsBackgroundPageReady(const Extension* extension) const {
2574   if (!extensions::BackgroundInfo::HasPersistentBackgroundPage(extension))
2575     return true;
2576   ExtensionRuntimeDataMap::const_iterator it =
2577       extension_runtime_data_.find(extension->id());
2578   return it == extension_runtime_data_.end() ? false :
2579                                                it->second.background_page_ready;
2580 }
2581
2582 void ExtensionService::SetBackgroundPageReady(const Extension* extension) {
2583   DCHECK(extensions::BackgroundInfo::HasBackgroundPage(extension));
2584   extension_runtime_data_[extension->id()].background_page_ready = true;
2585   content::NotificationService::current()->Notify(
2586       chrome::NOTIFICATION_EXTENSION_BACKGROUND_PAGE_READY,
2587       content::Source<const Extension>(extension),
2588       content::NotificationService::NoDetails());
2589 }
2590
2591 bool ExtensionService::IsBeingUpgraded(const Extension* extension) const {
2592   ExtensionRuntimeDataMap::const_iterator it =
2593       extension_runtime_data_.find(extension->id());
2594   return it == extension_runtime_data_.end() ? false :
2595                                                it->second.being_upgraded;
2596 }
2597
2598 void ExtensionService::SetBeingUpgraded(const Extension* extension,
2599                                         bool value) {
2600   extension_runtime_data_[extension->id()].being_upgraded = value;
2601 }
2602
2603 bool ExtensionService::IsBeingReloaded(
2604     const std::string& extension_id) const {
2605   return ContainsKey(extensions_being_reloaded_, extension_id);
2606 }
2607
2608 void ExtensionService::SetBeingReloaded(const std::string& extension_id,
2609                                         bool isBeingReloaded) {
2610   if (isBeingReloaded)
2611     extensions_being_reloaded_.insert(extension_id);
2612   else
2613     extensions_being_reloaded_.erase(extension_id);
2614 }
2615
2616 bool ExtensionService::HasUsedWebRequest(const Extension* extension) const {
2617   ExtensionRuntimeDataMap::const_iterator it =
2618       extension_runtime_data_.find(extension->id());
2619   return it == extension_runtime_data_.end() ? false :
2620                                                it->second.has_used_webrequest;
2621 }
2622
2623 void ExtensionService::SetHasUsedWebRequest(const Extension* extension,
2624                                             bool value) {
2625   extension_runtime_data_[extension->id()].has_used_webrequest = value;
2626 }
2627
2628 bool ExtensionService::ShouldEnableOnInstall(const Extension* extension) {
2629   // Extensions installed by policy can't be disabled. So even if a previous
2630   // installation disabled the extension, make sure it is now enabled.
2631   if (system_->management_policy()->MustRemainEnabled(extension, NULL))
2632     return true;
2633
2634   if (extension_prefs_->IsExtensionDisabled(extension->id()))
2635     return false;
2636
2637   if (FeatureSwitch::prompt_for_external_extensions()->IsEnabled()) {
2638     // External extensions are initially disabled. We prompt the user before
2639     // enabling them. Hosted apps are excepted because they are not dangerous
2640     // (they need to be launched by the user anyway).
2641     if (extension->GetType() != Manifest::TYPE_HOSTED_APP &&
2642         Manifest::IsExternalLocation(extension->location()) &&
2643         !extension_prefs_->IsExternalExtensionAcknowledged(extension->id())) {
2644       return false;
2645     }
2646   }
2647
2648   return true;
2649 }
2650
2651 bool ExtensionService::IsExtensionIdle(const std::string& extension_id) const {
2652   ExtensionProcessManager* process_manager = system_->process_manager();
2653   DCHECK(process_manager);
2654   extensions::ExtensionHost* host =
2655       process_manager->GetBackgroundHostForExtension(extension_id);
2656   if (host)
2657     return false;
2658
2659   content::SiteInstance* site_instance = process_manager->GetSiteInstanceForURL(
2660       Extension::GetBaseURLFromExtensionId(extension_id));
2661   if (site_instance && site_instance->HasProcess()) {
2662     return false;
2663   }
2664
2665   return process_manager->GetRenderViewHostsForExtension(extension_id).empty();
2666 }
2667
2668 bool ExtensionService::ShouldDelayExtensionUpdate(
2669     const std::string& extension_id,
2670     bool wait_for_idle) const {
2671   const char kOnUpdateAvailableEvent[] = "runtime.onUpdateAvailable";
2672
2673   // If delayed updates are globally disabled, or just for this extension,
2674   // don't delay.
2675   if (!install_updates_when_idle_ || !wait_for_idle)
2676     return false;
2677
2678   const Extension* old = GetInstalledExtension(extension_id);
2679   // If there is no old extension, this is not an update, so don't delay.
2680   if (!old)
2681     return false;
2682
2683   if (extensions::BackgroundInfo::HasPersistentBackgroundPage(old)) {
2684     // Delay installation if the extension listens for the onUpdateAvailable
2685     // event.
2686     return system_->event_router()->ExtensionHasEventListener(
2687         extension_id, kOnUpdateAvailableEvent);
2688   } else {
2689     // Delay installation if the extension is not idle.
2690     return !IsExtensionIdle(extension_id);
2691   }
2692 }
2693
2694 void ExtensionService::GarbageCollectIsolatedStorage() {
2695   scoped_ptr<base::hash_set<base::FilePath> > active_paths(
2696       new base::hash_set<base::FilePath>());
2697   for (ExtensionSet::const_iterator it = extensions_.begin();
2698        it != extensions_.end(); ++it) {
2699     if (extensions::AppIsolationInfo::HasIsolatedStorage(it->get())) {
2700       active_paths->insert(BrowserContext::GetStoragePartitionForSite(
2701           profile_, GetSiteForExtensionId((*it)->id()))->GetPath());
2702     }
2703   }
2704
2705   DCHECK(!installs_delayed_for_gc());
2706   set_installs_delayed_for_gc(true);
2707   BrowserContext::GarbageCollectStoragePartitions(
2708       profile_, active_paths.Pass(),
2709       base::Bind(&ExtensionService::OnGarbageCollectIsolatedStorageFinished,
2710                  AsWeakPtr()));
2711 }
2712
2713 void ExtensionService::OnGarbageCollectIsolatedStorageFinished() {
2714   set_installs_delayed_for_gc(false);
2715   MaybeFinishDelayedInstallations();
2716 }
2717
2718 void ExtensionService::MaybeFinishDelayedInstallations() {
2719   std::vector<std::string> to_be_installed;
2720   for (ExtensionSet::const_iterator it = delayed_installs_.begin();
2721        it != delayed_installs_.end();
2722        ++it) {
2723     to_be_installed.push_back((*it)->id());
2724   }
2725   for (std::vector<std::string>::const_iterator it = to_be_installed.begin();
2726        it != to_be_installed.end();
2727        ++it) {
2728     MaybeFinishDelayedInstallation(*it);
2729   }
2730 }
2731
2732 void ExtensionService::OnNeedsToGarbageCollectIsolatedStorage() {
2733   extension_prefs_->SetNeedsStorageGarbageCollection(true);
2734 }
2735
2736 void ExtensionService::OnBlacklistUpdated() {
2737   blacklist_->GetMalwareIDs(
2738       GenerateInstalledExtensionsSet()->GetIDs(),
2739       base::Bind(&ExtensionService::ManageBlacklist, AsWeakPtr()));
2740 }
2741
2742 void ExtensionService::ManageBlacklist(const std::set<std::string>& updated) {
2743   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2744
2745   std::set<std::string> before = blacklisted_extensions_.GetIDs();
2746   std::set<std::string> no_longer_blacklisted =
2747       base::STLSetDifference<std::set<std::string> >(before, updated);
2748   std::set<std::string> not_yet_blacklisted =
2749       base::STLSetDifference<std::set<std::string> >(updated, before);
2750
2751   for (std::set<std::string>::iterator it = no_longer_blacklisted.begin();
2752        it != no_longer_blacklisted.end(); ++it) {
2753     scoped_refptr<const Extension> extension =
2754         blacklisted_extensions_.GetByID(*it);
2755     if (!extension.get()) {
2756       NOTREACHED() << "Extension " << *it << " no longer blacklisted, "
2757                    << "but it was never blacklisted.";
2758       continue;
2759     }
2760     blacklisted_extensions_.Remove(*it);
2761     extension_prefs_->SetExtensionBlacklisted(extension->id(), false);
2762     AddExtension(extension.get());
2763     UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.UnblacklistInstalled",
2764                               extension->location(),
2765                               Manifest::NUM_LOCATIONS);
2766   }
2767
2768   for (std::set<std::string>::iterator it = not_yet_blacklisted.begin();
2769        it != not_yet_blacklisted.end(); ++it) {
2770     scoped_refptr<const Extension> extension = GetInstalledExtension(*it);
2771     if (!extension.get()) {
2772       NOTREACHED() << "Extension " << *it << " needs to be "
2773                    << "blacklisted, but it's not installed.";
2774       continue;
2775     }
2776     blacklisted_extensions_.Insert(extension);
2777     extension_prefs_->SetExtensionBlacklisted(extension->id(), true);
2778     UnloadExtension(*it, UnloadedExtensionInfo::REASON_BLACKLIST);
2779     UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.BlacklistInstalled",
2780                               extension->location(), Manifest::NUM_LOCATIONS);
2781   }
2782
2783   IdentifyAlertableExtensions();
2784 }
2785
2786 void ExtensionService::AddUpdateObserver(extensions::UpdateObserver* observer) {
2787   update_observers_.AddObserver(observer);
2788 }
2789
2790 void ExtensionService::RemoveUpdateObserver(
2791     extensions::UpdateObserver* observer) {
2792   update_observers_.RemoveObserver(observer);
2793 }