extension_service.cc revision 116680a4aac90f2aa7413d9095a592090648e557
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <iterator> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/sequenced_worker_pool.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h" 18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h" 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/api/extension_action/extension_action_api.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/component_loader.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/data_deleter.h" 24cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/extensions/extension_assets_manager.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_disabled_ui.h" 26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/extensions/extension_error_controller.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_install_ui.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_special_storage_policy.h" 291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "chrome/browser/extensions/extension_sync_service.h" 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/extensions/extension_util.h" 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/extensions/external_install_manager.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/external_provider_impl.h" 33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/extensions/install_verifier.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/installed_loader.h" 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/extensions/pending_extension_manager.h" 36c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "chrome/browser/extensions/shared_module_service.h" 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "chrome/browser/extensions/updater/extension_cache.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 39f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/webui/extensions/extension_icon_source.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/favicon_source.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/ntp/thumbnail_source.h" 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/theme_source.h" 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h" 4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "chrome/common/crash_keys.h" 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/common/extensions/extension_constants.h" 46ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch#include "chrome/common/extensions/features/feature_channel.h" 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/manifest_url_handler.h" 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 5058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "components/startup_metric_utils/startup_metric_utils.h" 51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "content/public/browser/devtools_agent_host.h" 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_process_host.h" 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/public/browser/storage_partition.h" 55f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/event_router.h" 5623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "extensions/browser/extension_host.h" 57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/browser/extension_prefs.h" 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_registry.h" 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h" 60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "extensions/browser/install_flag.h" 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/pref_names.h" 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/runtime_data.h" 63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "extensions/browser/update_observer.h" 64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "extensions/common/extension_messages.h" 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/feature_switch.h" 66a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "extensions/common/file_util.h" 67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "extensions/common/manifest_constants.h" 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/background_info.h" 69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/common/one_shot_event.h" 708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "extensions/common/permissions/permission_message_provider.h" 71f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/permissions/permissions_data.h" 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/extensions/install_limiter.h" 757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "webkit/browser/fileapi/file_system_backend.h" 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "webkit/browser/fileapi/file_system_context.h" 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// TODO(thestig): Eventually remove the #ifdefs when ExtensionService is no 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// longer used on mobile. 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS) 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/extensions/crx_installer.h" 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/extensions/permissions_updater.h" 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/extensions/unpacked_installer.h" 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/browser/extensions/updater/extension_updater.h" 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserContext; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::DevToolsAgentHost; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::CrxInstaller; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::ExtensionIdSet; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::ExtensionInfo; 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using extensions::ExtensionRegistry; 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using extensions::ExtensionSet; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::FeatureSwitch; 98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using extensions::InstallVerifier; 99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using extensions::ManagementPolicy; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using extensions::Manifest; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::PermissionMessage; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::PermissionMessages; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::PermissionSet; 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochusing extensions::SharedModuleInfo; 105c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdochusing extensions::SharedModuleService; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using extensions::UnloadedExtensionInfo; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 108d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace errors = extensions::manifest_errors; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Wait this many seconds after an extensions becomes idle before updating it. 113116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst int kUpdateIdleDelay = 5; 1143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ExtensionService. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::CheckExternalUninstall(const std::string& id) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check if the providers know about this extension. 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ProviderCollection::const_iterator i; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = external_extension_providers_.begin(); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != external_extension_providers_.end(); ++i) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(i->get()->IsReady()); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (i->get()->HasExtension(id)) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; // Yup, known extension, don't uninstall. 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We get the list of external extensions to check from preferences. 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It is possible that an extension has preferences but is not loaded. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For example, an extension that requires experimental permissions 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will not be loaded if the experimental command line flag is not used. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In this case, do not uninstall. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetInstalledExtension(id)) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We can't call UninstallExtension with an unloaded/invalid 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension ID. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Attempted uninstallation of unloaded/invalid extension " 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "with id: " << id; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch UninstallExtension(id, UNINSTALL_REASON_ORPHANED_EXTERNAL_EXTENSION, NULL); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionService::SetFileTaskRunnerForTesting( 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SequencedTaskRunner* task_runner) { 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_task_runner_ = task_runner; 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::ClearProvidersForTesting() { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) external_extension_providers_.clear(); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::AddProviderForTesting( 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ExternalProviderInterface* test_provider) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(test_provider); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) external_extension_providers_.push_back( 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) linked_ptr<extensions::ExternalProviderInterface>(test_provider)); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionService::OnExternalExtensionUpdateUrlFound( 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id, 164effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const std::string& install_parameter, 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& update_url, 1664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) Manifest::Location location, 1674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int creation_flags, 1684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool mark_acknowledged) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(Extension::IdIsValid(id)); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (Manifest::IsExternalLocation(location)) { 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // All extensions that are not user specific can be cached. 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extensions::ExtensionCache::GetInstance()->AllowCaching(id); 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = GetExtensionById(id, true); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension) { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Already installed. Skip this install if the current location has 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // higher priority than |location|. 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Manifest::Location current = extension->location(); 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (current == Manifest::GetHigherPriorityLocation(current, location)) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise, overwrite the current installation. 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add |id| to the set of pending extensions. If it can not be added, 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // then there is already a pending record from a higher-priority install 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // source. In this case, signal that this extension will not be 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // installed by returning false. 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pending_extension_manager()->AddFromExternalUpdateUrl( 192effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch id, 193effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch install_parameter, 194effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch update_url, 195effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch location, 196effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch creation_flags, 197effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch mark_acknowledged)) { 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) update_once_all_providers_are_ready_ = true; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 206116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// This function is used to uninstall an extension via sync. The LOG statements 207116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// within this function are used to inform the user if the uninstall cannot be 208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// done. 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionService::UninstallExtensionHelper( 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionService* extensions_service, 211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string& extension_id, 212116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch UninstallReason reason) { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We can't call UninstallExtension with an invalid extension ID. 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extensions_service->GetInstalledExtension(extension_id)) { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Attempted uninstallation of non-existent extension with " 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "id: " << extension_id; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The following call to UninstallExtension will not allow an uninstall of a 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // policy-controlled extension. 222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) base::string16 error; 223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!extensions_service->UninstallExtension(extension_id, reason, &error)) { 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Cannot uninstall extension with id " << extension_id 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ": " << error; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionService::ExtensionService(Profile* profile, 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CommandLine* command_line, 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& install_directory, 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ExtensionPrefs* extension_prefs, 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::Blacklist* blacklist, 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool autoupdate_enabled, 23890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool extensions_enabled, 23990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) extensions::OneShotEvent* ready) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : extensions::Blacklist::Observer(blacklist), 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) profile_(profile), 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_(extensions::ExtensionSystem::Get(profile)), 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_(extension_prefs), 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) blacklist_(blacklist), 2451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) extension_sync_service_(NULL), 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_(extensions::ExtensionRegistry::Get(profile)), 247cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) pending_extension_manager_(profile), 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) install_directory_(install_directory), 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions_enabled_(extensions_enabled), 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) show_extensions_prompts_(true), 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) install_updates_when_idle_(true), 25290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ready_(ready), 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) update_once_all_providers_are_ready_(false), 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_terminating_(false), 255eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch installs_delayed_for_gc_(false), 256e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch is_first_run_(false), 257c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch shared_module_service_(new extensions::SharedModuleService(profile_)) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Figure out if extension installation should be enabled. 261a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (extensions::ExtensionsBrowserClient::Get()->AreExtensionsDisabled( 262a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) *command_line, profile)) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions_enabled_ = false; 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_APP_TERMINATING, 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::AllBrowserContextsAndSources()); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED, 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::AllBrowserContextsAndSources()); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::AllBrowserContextsAndSources()); 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) registrar_.Add(this, chrome::NOTIFICATION_UPGRADE_RECOMMENDED, 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::NotificationService::AllBrowserContextsAndSources()); 273cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) registrar_.Add(this, 274cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED, 275cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) content::Source<Profile>(profile_)); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_change_registrar_.Init(profile->GetPrefs()); 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Closure callback = 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&ExtensionService::OnExtensionInstallPrefChanged, 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Unretained(this)); 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref_change_registrar_.Add(extensions::pref_names::kInstallAllowList, 2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback); 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref_change_registrar_.Add(extensions::pref_names::kInstallDenyList, 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) callback); 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pref_change_registrar_.Add(extensions::pref_names::kAllowedTypes, callback); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 286116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up the ExtensionUpdater 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (autoupdate_enabled) { 28968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) int update_frequency = extensions::kDefaultUpdateFrequencySeconds; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (command_line->HasSwitch(switches::kExtensionsUpdateFrequency)) { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::StringToInt(command_line->GetSwitchValueASCII( 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switches::kExtensionsUpdateFrequency), 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &update_frequency); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) updater_.reset(new extensions::ExtensionUpdater( 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this, 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_prefs, 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile->GetPrefs(), 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile, 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) update_frequency, 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extensions::ExtensionCache::GetInstance())); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) component_loader_.reset( 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new extensions::ComponentLoader(this, 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile->GetPrefs(), 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) g_browser_process->local_state(), 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile)); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extensions_enabled_) { 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::ExternalProviderImpl::CreateExternalProviders( 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, profile_, &external_extension_providers_); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 316f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Set this as the ExtensionService for app sorting to ensure it causes syncs 317f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // if required. 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) is_first_run_ = !extension_prefs_->SetAlertSystemFirstRun(); 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 320c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch error_controller_.reset( 321c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch new extensions::ExtensionErrorController(profile_, is_first_run_)); 322116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch external_install_manager_.reset( 323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new extensions::ExternalInstallManager(profile_, is_first_run_)); 324c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(ENABLE_EXTENSIONS) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_action_storage_manager_.reset( 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new extensions::ExtensionActionStorageManager(profile_)); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // How long is the path to the Extensions directory? 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_COUNTS("Extensions.ExtensionRootPathLength", 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) install_directory_.value().length(), 0, 500, 100); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const ExtensionSet* ExtensionService::extensions() const { 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return ®istry_->enabled_extensions(); 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)extensions::PendingExtensionManager* 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionService::pending_extension_manager() { 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return &pending_extension_manager_; 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ExtensionService::~ExtensionService() { 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No need to unload extensions here because they are profile-scoped, and the 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // profile is in the process of being deleted. 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ProviderCollection::const_iterator i; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = external_extension_providers_.begin(); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != external_extension_providers_.end(); ++i) { 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ExternalProviderInterface* provider = i->get(); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) provider->ServiceShutdown(); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::Shutdown() { 3573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) system_->management_policy()->UnregisterProvider( 3583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) shared_module_policy_provider_.get()); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Extension* ExtensionService::GetExtensionById( 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id, bool include_disabled) const { 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int include_mask = ExtensionRegistry::ENABLED; 3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (include_disabled) { 3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Include blacklisted extensions here because there are hundreds of 3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // callers of this function, and many might assume that this includes those 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // that have been disabled due to blacklisting. 3685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) include_mask |= ExtensionRegistry::DISABLED | 3695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionRegistry::BLACKLISTED; 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return registry_->GetExtensionById(id, include_mask); 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::Init() { 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 377f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Time begin_time = base::Time::Now(); 378f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 37990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) DCHECK(!is_ready()); // Can't redo init. 3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK_EQ(registry_->enabled_extensions().size(), 0u); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (cmd_line->HasSwitch(switches::kInstallFromWebstore) || 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cmd_line->HasSwitch(switches::kLimitedInstallFromWebstore)) { 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The sole purpose of this launch is to install a new extension from CWS 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // and immediately terminate: loading already installed extensions is 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // unnecessary and may interfere with the inline install dialog (e.g. if an 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // extension listens to onStartup and opens a window). 389c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SetReadyAndNotifyListeners(); 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 391eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // LoadAllExtensions() calls OnLoadedInstalledExtensions(). 392eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch component_loader_->LoadAll(); 393eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch extensions::InstalledLoader(this).LoadAllExtensions(); 394eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Attempt to re-enable extensions whose only disable reason is reloading. 3963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) std::vector<std::string> extensions_to_enable; 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ExtensionSet& disabled_extensions = registry_->disabled_extensions(); 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (ExtensionSet::const_iterator iter = disabled_extensions.begin(); 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter != disabled_extensions.end(); ++iter) { 4003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const Extension* e = iter->get(); 4013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (extension_prefs_->GetDisableReasons(e->id()) == 4023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) Extension::DISABLE_RELOAD) { 4033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) extensions_to_enable.push_back(e->id()); 4043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) for (std::vector<std::string>::iterator it = extensions_to_enable.begin(); 4073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) it != extensions_to_enable.end(); ++it) { 4083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) EnableExtension(*it); 4093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 411eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Finish install (if possible) of extensions that were still delayed while 412eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // the browser was shut down. 413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> delayed_info( 414eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch extension_prefs_->GetAllDelayedInstallInfo()); 415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (size_t i = 0; i < delayed_info->size(); ++i) { 416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ExtensionInfo* info = delayed_info->at(i).get(); 417eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_refptr<const Extension> extension(NULL); 418eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (info->extension_manifest) { 419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::string error; 420eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch extension = Extension::Create( 421eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch info->extension_path, 422eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch info->extension_location, 423eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *info->extension_manifest, 424eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch extension_prefs_->GetDelayedInstallCreationFlags( 425eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch info->extension_id), 426eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch info->extension_id, 427eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &error); 428eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (extension.get()) 429eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delayed_installs_.Insert(extension); 430eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 431eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 432eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MaybeFinishDelayedInstallations(); 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 434eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> delayed_info2( 435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch extension_prefs_->GetAllDelayedInstallInfo()); 436eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateOnLoad", 437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delayed_info2->size() - delayed_info->size()); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 439eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SetReadyAndNotifyListeners(); 440eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // TODO(erikkay) this should probably be deferred to a future point 442eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // rather than running immediately at startup. 443eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CheckForExternalUpdates(); 444eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LoadGreylistFromPrefs(); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 447f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 448f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UMA_HISTOGRAM_TIMES("Extensions.ExtensionServiceInitTime", 449f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Time::Now() - begin_time); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionService::LoadGreylistFromPrefs() { 45323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_ptr<ExtensionSet> all_extensions = 45423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) registry_->GenerateInstalledExtensionsSet(); 4555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (ExtensionSet::const_iterator it = all_extensions->begin(); 4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != all_extensions->end(); ++it) { 4585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extensions::BlacklistState state = 4595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_prefs_->GetExtensionBlacklistState((*it)->id()); 4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (state == extensions::BLACKLISTED_SECURITY_VULNERABILITY || 4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) state == extensions::BLACKLISTED_POTENTIALLY_UNWANTED || 4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) state == extensions::BLACKLISTED_CWS_POLICY_VIOLATION) 4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) greylist_.Insert(*it); 4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionService::UpdateExtension(const std::string& id, 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& extension_path, 4695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) bool file_ownership_passed, 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CrxInstaller** out_crx_installer) { 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 472116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser_terminating_) { 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Skipping UpdateExtension due to browser shutdown"; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Leak the temp file at extension_path. We don't want to add to the disk 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // I/O burden at shutdown, we can't rely on the I/O completing anyway, and 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the file is in the OS temp directory which should be cleaned up for us. 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const extensions::PendingExtensionInfo* pending_extension_info = 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_extension_manager()->GetById(id); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension = GetInstalledExtension(id); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pending_extension_info && !extension) { 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Will not update extension " << id 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " because it is not installed or pending"; 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete extension_path since we're not creating a CrxInstaller 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that would do it for us. 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!GetFileTaskRunner()->PostTask( 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind( 493a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch &extensions::file_util::DeleteFile, extension_path, false))) 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We want a silent install only for non-pending extensions and 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // pending extensions that have install_silently set. 501ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch scoped_ptr<ExtensionInstallPrompt> client; 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pending_extension_info && !pending_extension_info->install_silently()) 503ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch client.reset(ExtensionInstallUI::CreateInstallPromptWithProfile(profile_)); 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch scoped_refptr<CrxInstaller> installer( 506ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch CrxInstaller::Create(this, client.Pass())); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer->set_expected_id(id); 5084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) int creation_flags = Extension::NO_FLAGS; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pending_extension_info) { 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer->set_install_source(pending_extension_info->install_source()); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pending_extension_info->install_silently()) 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer->set_allow_silent_install(true); 513cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (pending_extension_info->remote_install()) 514cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) installer->set_grant_permissions(false); 5154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) creation_flags = pending_extension_info->creation_flags(); 5164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (pending_extension_info->mark_acknowledged()) 517116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch external_install_manager_->AcknowledgeExternalExtension(id); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (extension) { 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer->set_install_source(extension->location()); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the extension was installed from or has migrated to the webstore, or 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // its auto-update URL is from the webstore, treat it as a webstore install. 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that we ignore some older extensions with blank auto-update URLs 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // because we are mostly concerned with restrictions on NaCl extensions, 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // which are newer. 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((extension && extension->from_webstore()) || 527868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) (extension && extensions::ManifestURL::UpdatesFromGallery(extension)) || 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (!extension && extension_urls::IsWebstoreUpdateUrl( 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_extension_info->update_url()))) { 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) creation_flags |= Extension::FROM_WEBSTORE; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Bookmark apps being updated is kind of a contradiction, but that's because 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we mark the default apps as bookmark apps, and they're hosted in the web 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // store, thus they can get updated. See http://crbug.com/101605 for more 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // details. 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension && extension->from_bookmark()) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) creation_flags |= Extension::FROM_BOOKMARK; 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension && extension->was_installed_by_default()) 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) creation_flags |= Extension::WAS_INSTALLED_BY_DEFAULT; 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 54323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (extension && extension->was_installed_by_oem()) 54423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) creation_flags |= Extension::WAS_INSTALLED_BY_OEM; 54523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 546116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (extension && extension->was_installed_by_custodian()) 547116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch creation_flags |= Extension::WAS_INSTALLED_BY_CUSTODIAN; 548116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 549f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (extension) { 550cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) installer->set_is_ephemeral(extension_prefs_->IsEphemeralApp(id)); 5516d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) installer->set_do_not_sync(extension_prefs_->DoNotSync(id)); 552f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 5535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer->set_creation_flags(creation_flags); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) installer->set_delete_source(file_ownership_passed); 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer->set_install_cause(extension_misc::INSTALL_CAUSE_UPDATE); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer->InstallCrx(extension_path); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (out_crx_installer) 561868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *out_crx_installer = installer.get(); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 564116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#else 565116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 566116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 569116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ExtensionService::ReloadExtensionImpl( 570cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // "transient" because the process of reloading may cause the reference 571cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // to become invalid. Instead, use |extension_id|, a copy. 572116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string& transient_extension_id, 573116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool be_noisy) { 574116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS) 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the extension is already reloading, don't reload again. 578cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (extension_prefs_->GetDisableReasons(transient_extension_id) & 5792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Extension::DISABLE_RELOAD) { 5802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 5812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 583cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Ignore attempts to reload a blacklisted extension. Sometimes this can 584cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // happen in a convoluted reload sequence triggered by the termination of a 585cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // blacklisted extension and a naive attempt to reload it. For an example see 586cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // http://crbug.com/373842. 587cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (registry_->blacklisted_extensions().Contains(transient_extension_id)) 588cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return; 589cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath path; 591cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 592cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) std::string extension_id = transient_extension_id; 593cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const Extension* transient_current_extension = 594cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetExtensionById(extension_id, false); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Disable the extension if it's loaded. It might not be loaded if it crashed. 597cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (transient_current_extension) { 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the extension has an inspector open for its background page, detach 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the inspector and hang onto a cookie for it, so that we can reattach 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // later. 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(yoz): this is not incognito-safe! 602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extensions::ProcessManager* manager = system_->process_manager(); 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ExtensionHost* host = 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) manager->GetBackgroundHostForExtension(extension_id); 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (host && DevToolsAgentHost::HasFor(host->render_view_host())) { 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Look for an open inspector for the background page. 6077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_refptr<DevToolsAgentHost> agent_host = 6087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DevToolsAgentHost::GetOrCreateFor(host->render_view_host()); 6097dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch agent_host->DisconnectRenderViewHost(); 6107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch orphaned_dev_tools_[extension_id] = agent_host; 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 613cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) path = transient_current_extension->path(); 614ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch // BeingUpgraded is set back to false when the extension is added. 615cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) system_->runtime_data()->SetBeingUpgraded(transient_current_extension, 616cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) true); 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DisableExtension(extension_id, Extension::DISABLE_RELOAD); 618c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) reloading_extensions_.insert(extension_id); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 620f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) std::map<std::string, base::FilePath>::const_iterator iter = 621f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) unloaded_extension_paths_.find(extension_id); 622f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (iter == unloaded_extension_paths_.end()) { 623f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return; 624f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) path = unloaded_extension_paths_[extension_id]; 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 628cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) transient_current_extension = NULL; 629cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 630eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (delayed_installs_.Contains(extension_id)) { 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FinishDelayedInstallation(extension_id); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we're reloading a component extension, use the component extension 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // loader's reloader. 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (component_loader_->Exists(extension_id)) { 638eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SetBeingReloaded(extension_id, true); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) component_loader_->Reload(extension_id); 640eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SetBeingReloaded(extension_id, false); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check the installed extensions to see if what we're reloading was already 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // installed. 646eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SetBeingReloaded(extension_id, true); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ExtensionInfo> installed_extension( 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_->GetInstalledExtensionInfo(extension_id)); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (installed_extension.get() && 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installed_extension->extension_manifest.get()) { 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::InstalledLoader(this).Load(*installed_extension, false); 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise, the extension is unpacked (location LOAD). 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should always be able to remember the extension's path. If it's not in 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the map, someone failed to update |unloaded_extension_paths_|. 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(!path.empty()); 657116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_refptr<extensions::UnpackedInstaller> unpacked_installer = 658116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extensions::UnpackedInstaller::Create(this); 659116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch unpacked_installer->set_be_noisy_on_failure(be_noisy); 660116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch unpacked_installer->Load(path); 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 662eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // When reloading is done, mark this extension as done reloading. 663eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch SetBeingReloaded(extension_id, false); 664116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif // defined(ENABLE_EXTENSIONS) 665116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 666116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 667116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ExtensionService::ReloadExtension(const std::string& extension_id) { 668116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ReloadExtensionImpl(extension_id, true); // be_noisy 669116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 670116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 671116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ExtensionService::ReloadExtensionWithQuietFailure( 672116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const std::string& extension_id) { 673116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ReloadExtensionImpl(extension_id, false); // be_noisy 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 676cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ExtensionService::UninstallExtension( 677cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // "transient" because the process of uninstalling may cause the reference 678cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // to become invalid. Instead, use |extenson->id()|. 679cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& transient_extension_id, 680116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch UninstallReason reason, 681cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::string16* error) { 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 684cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) scoped_refptr<const Extension> extension = 685cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) GetInstalledExtension(transient_extension_id); 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Callers should not send us nonexistent extensions. 688868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CHECK(extension.get()); 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Policy change which triggers an uninstall will always set 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |external_uninstall| to true so this is the only way to uninstall 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // managed extensions. 693c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Shared modules being uninstalled will also set |external_uninstall| to true 694c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // so that we can guarantee users don't uninstall a shared module. 695c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // (crbug.com/273300) 696c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // TODO(rdevlin.cronin): This is probably not right. We should do something 697c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // else, like include an enum IS_INTERNAL_UNINSTALL or IS_USER_UNINSTALL so 698c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // we don't do this. 699116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch bool external_uninstall = 700116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (reason == UNINSTALL_REASON_INTERNAL_MANAGEMENT) || 701116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (reason == UNINSTALL_REASON_ORPHANED_EXTERNAL_EXTENSION) || 702116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (reason == UNINSTALL_REASON_ORPHANED_SHARED_MODULE); 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!external_uninstall && 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !system_->management_policy()->UserMayModifySettings( 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension.get(), error)) { 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current()->Notify( 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_EXTENSION_UNINSTALL_NOT_ALLOWED, 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile_), 709868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content::Details<const Extension>(extension.get())); 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncChange sync_change; 7141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (extension_sync_service_) { 7151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) sync_change = extension_sync_service_->PrepareToSyncUninstallExtension( 7161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) extension.get(), is_ready()); 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 719a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) system_->install_verifier()->Remove(extension->id()); 720f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Extensions.UninstallType", 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension->GetType(), 100); 723868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) RecordPermissionMessagesHistogram(extension.get(), 72446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) "Extensions.Permissions_Uninstall2"); 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unload before doing more cleanup to ensure that nothing is hanging on to 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // any of these resources. 728cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) UnloadExtension(extension->id(), UnloadedExtensionInfo::REASON_UNINSTALL); 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tell the backend to start deleting installed extensions on the file thread. 7312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!Manifest::IsUnpackedLocation(extension->location())) { 7322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!GetFileTaskRunner()->PostTask( 7332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 734cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) base::Bind(&ExtensionService::UninstallExtensionOnFileThread, 735cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension->id(), 736cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) profile_, 737a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch install_directory_, 738cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension->path()))) 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 742f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) extensions::DataDeleter::StartDeleting(profile_, extension.get()); 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 744cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) UntrackTerminatedExtension(extension->id()); 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Notify interested parties that we've uninstalled this extension. 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current()->Notify( 748cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED, 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile_), 750868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) content::Details<const Extension>(extension.get())); 751cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ExtensionRegistry::Get(profile_)->TriggerOnUninstalled(extension.get()); 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (extension_sync_service_) { 754cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension_sync_service_->ProcessSyncUninstallExtension(extension->id(), 7551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) sync_change); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 758cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) delayed_installs_.Remove(extension->id()); 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 760cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension_prefs_->OnExtensionUninstalled( 761cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension->id(), extension->location(), external_uninstall); 762d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Track the uninstallation. 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Extensions.ExtensionUninstalled", 1, 2); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 769cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static 770cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ExtensionService::UninstallExtensionOnFileThread( 771cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const std::string& id, 772cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Profile* profile, 773cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const base::FilePath& install_dir, 774cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const base::FilePath& extension_path) { 775cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extensions::ExtensionAssetsManager* assets_manager = 776cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extensions::ExtensionAssetsManager::GetInstance(); 777cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) assets_manager->UninstallExtension(id, profile, install_dir, extension_path); 778cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 779cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionService::IsExtensionEnabled( 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id) const { 7825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (registry_->enabled_extensions().Contains(extension_id) || 7835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->terminated_extensions().Contains(extension_id)) { 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (registry_->disabled_extensions().Contains(extension_id) || 7885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->blacklisted_extensions().Contains(extension_id)) { 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the extension hasn't been loaded yet, check the prefs for it. Assume 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // enabled unless otherwise noted. 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return !extension_prefs_->IsExtensionDisabled(extension_id) && 795cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) !extension_prefs_->IsExtensionBlacklisted(extension_id) && 7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !extension_prefs_->IsExternalExtensionUninstalled(extension_id); 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::EnableExtension(const std::string& extension_id) { 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsExtensionEnabled(extension_id)) 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const Extension* extension = 8055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->disabled_extensions().GetByID(extension_id); 806f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 807f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ManagementPolicy* policy = system_->management_policy(); 808f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (extension && policy->MustRemainDisabled(extension, NULL, NULL)) { 809f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UMA_HISTOGRAM_COUNTS_100("Extensions.EnableDeniedByPolicy", 1); 810f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 811f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_->SetExtensionState(extension_id, Extension::ENABLED); 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_->ClearDisableReasons(extension_id); 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This can happen if sync enables an extension that is not 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // installed yet. 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension) 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Move it over to the enabled list. 8225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->AddEnabled(make_scoped_refptr(extension)); 8235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->RemoveDisabled(extension->id()); 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyExtensionLoaded(extension); 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Notify listeners that the extension was enabled. 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current()->Notify( 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_EXTENSION_ENABLED, 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile_), 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<const Extension>(extension)); 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8331e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (extension_sync_service_) 8341e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) extension_sync_service_->SyncEnableExtension(*extension); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::DisableExtension( 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Extension::DisableReason disable_reason) { 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The extension may have been disabled already. 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IsExtensionEnabled(extension_id)) 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension = GetInstalledExtension(extension_id); 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |extension| can be NULL if sync disables an extension that is not 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // installed yet. 849116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // EXTERNAL_COMPONENT extensions are not generally modifiable by users, but 850116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // can be uninstalled by the browser if the user sets extension-specific 851116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // preferences. 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension && 853eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch disable_reason != Extension::DISABLE_RELOAD && 854116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch !system_->management_policy()->UserMayModifySettings(extension, NULL) && 855116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extension->location() != Manifest::EXTERNAL_COMPONENT) { 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_->SetExtensionState(extension_id, Extension::DISABLED); 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_->AddDisableReason(extension_id, disable_reason); 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int include_mask = 8635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionRegistry::EVERYTHING & ~ExtensionRegistry::DISABLED; 8645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension = registry_->GetExtensionById(extension_id, include_mask); 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension) 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // The extension is either enabled or terminated. 8695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(registry_->enabled_extensions().Contains(extension->id()) || 8705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->terminated_extensions().Contains(extension->id())); 871c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Move it over to the disabled list. Don't send a second unload notification 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for terminated extensions being disabled. 8745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->AddDisabled(make_scoped_refptr(extension)); 8755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (registry_->enabled_extensions().Contains(extension->id())) { 8765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->RemoveEnabled(extension->id()); 8771e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) NotifyExtensionUnloaded(extension, UnloadedExtensionInfo::REASON_DISABLE); 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->RemoveTerminated(extension->id()); 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (extension_sync_service_) 8831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) extension_sync_service_->SyncDisableExtension(*extension); 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ExtensionService::DisableUserExtensions( 8877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::vector<std::string>& except_ids) { 8887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) extensions::ManagementPolicy* management_policy = 8897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) system_->management_policy(); 8907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) extensions::ExtensionList to_disable; 8917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 8925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ExtensionSet& enabled_set = registry_->enabled_extensions(); 8935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (ExtensionSet::const_iterator extension = enabled_set.begin(); 8945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension != enabled_set.end(); ++extension) { 895116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (management_policy->UserMayModifySettings(extension->get(), NULL)) 8967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) to_disable.push_back(*extension); 8977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 8985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ExtensionSet& terminated_set = registry_->terminated_extensions(); 8995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (ExtensionSet::const_iterator extension = terminated_set.begin(); 9005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension != terminated_set.end(); ++extension) { 901116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (management_policy->UserMayModifySettings(extension->get(), NULL)) 9027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) to_disable.push_back(*extension); 9037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 9047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 9057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) for (extensions::ExtensionList::const_iterator extension = to_disable.begin(); 9067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) extension != to_disable.end(); ++extension) { 9073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch if ((*extension)->was_installed_by_default() && 9083240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch extension_urls::IsWebstoreUpdateUrl( 9093240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch extensions::ManifestURL::GetUpdateURL(*extension))) 9103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch continue; 9117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& id = (*extension)->id(); 9127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (except_ids.end() == std::find(except_ids.begin(), except_ids.end(), id)) 9137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch DisableExtension(id, extensions::Extension::DISABLE_USER_ACTION); 9147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) } 9157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)} 9167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::GrantPermissionsAndEnableExtension( 9182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension) { 9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GrantPermissions(extension); 92046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RecordPermissionMessagesHistogram(extension, 92146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) "Extensions.Permissions_ReEnable2"); 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EnableExtension(extension->id()); 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionService::GrantPermissions(const Extension* extension) { 927116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS) 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(extension); 9296d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) extensions::PermissionsUpdater(profile()).GrantActivePermissions(extension); 930116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::RecordPermissionMessagesHistogram( 93590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const Extension* extension, const char* histogram) { 9362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Since this is called from multiple sources, and since the histogram macros 9372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // use statics, we need to manually lookup the histogram ourselves. 9382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::HistogramBase* counter = base::LinearHistogram::FactoryGet( 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) histogram, 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PermissionMessage::kEnumBoundary, 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PermissionMessage::kEnumBoundary + 1, 9432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::HistogramBase::kUmaTargetedHistogramFlag); 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 94590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PermissionMessages permissions = 94646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension->permissions_data()->GetPermissionMessages(); 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (permissions.empty()) { 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter->Add(PermissionMessage::kNone); 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (PermissionMessages::iterator it = permissions.begin(); 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != permissions.end(); ++it) 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) counter->Add(it->id()); 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::NotifyExtensionLoaded(const Extension* extension) { 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The ChromeURLRequestContexts need to be first to know that the extension 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // was loaded, otherwise a race can arise where a renderer that is created 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for the extension may try to load an extension URL with an extension id 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that the request context doesn't yet know about. The profile is responsible 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for ensuring its URLRequestContexts appropriately discover the loaded 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension. 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_->RegisterExtensionWithRequestContexts(extension); 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tell renderers about the new extension, unless it's a theme (renderers 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // don't need to know about themes). 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension->is_theme()) { 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (content::RenderProcessHost::iterator i( 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost::AllHostsIterator()); 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !i.IsAtEnd(); i.Advance()) { 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost* host = i.GetCurrentValue(); 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* host_profile = 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile::FromBrowserContext(host->GetBrowserContext()); 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host_profile->GetOriginalProfile() == 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->GetOriginalProfile()) { 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<ExtensionMsg_Loaded_Params> loaded_extensions( 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1, ExtensionMsg_Loaded_Params(extension)); 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host->Send( 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ExtensionMsg_Loaded(loaded_extensions)); 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Tell subsystems that use the EXTENSION_LOADED notification about the new 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension. 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: It is important that this happen after notifying the renderers about 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the new extensions so that if we navigate to an extension URL in 9890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // ExtensionRegistryObserver::OnLoaded or 9900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch // NOTIFICATION_EXTENSION_LOADED_DEPRECATED, the 991effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // renderer is guaranteed to know about it. 992effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch registry_->TriggerOnLoaded(extension); 993effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current()->Notify( 9950529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile_), 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<const Extension>(extension)); 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 999effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // TODO(kalman): Convert ExtensionSpecialStoragePolicy to a 1000effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // BrowserContextKeyedService and use ExtensionRegistryObserver. 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->GetExtensionSpecialStoragePolicy()-> 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GrantRightsForExtension(extension); 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1004effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // TODO(kalman): This is broken. The crash reporter is process-wide so doesn't 1005effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // work properly multi-profile. Besides which, it should be using 1006effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // ExtensionRegistryObserver. See http://crbug.com/355029. 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateActiveExtensionsInCrashReporter(); 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 100946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const extensions::PermissionsData* permissions_data = 101046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension->permissions_data(); 101146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the extension has permission to load chrome://favicon/ resources we need 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to make sure that the FaviconSource is registered with the 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ChromeURLDataManager. 101546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (permissions_data->HasHostPermission(GURL(chrome::kChromeUIFaviconURL))) { 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FaviconSource* favicon_source = new FaviconSource(profile_, 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FaviconSource::FAVICON); 10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::URLDataSource::Add(profile_, favicon_source); 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_ANDROID) 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Same for chrome://theme/ resources. 102346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (permissions_data->HasHostPermission(GURL(chrome::kChromeUIThemeURL))) { 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ThemeSource* theme_source = new ThemeSource(profile_); 10252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::URLDataSource::Add(profile_, theme_source); 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Same for chrome://thumb/ resources. 102946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (permissions_data->HasHostPermission( 103046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) GURL(chrome::kChromeUIThumbnailURL))) { 1031d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ThumbnailSource* thumbnail_source = new ThumbnailSource(profile_, false); 10322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::URLDataSource::Add(profile_, thumbnail_source); 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#endif 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::NotifyExtensionUnloaded( 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension, 10391e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) UnloadedExtensionInfo::Reason reason) { 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnloadedExtensionInfo details(extension, reason); 10410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 10420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch registry_->TriggerOnUnloaded(extension, reason); 10430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current()->Notify( 104523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile_), 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<UnloadedExtensionInfo>(&details)); 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (content::RenderProcessHost::iterator i( 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost::AllHostsIterator()); 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !i.IsAtEnd(); i.Advance()) { 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost* host = i.GetCurrentValue(); 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* host_profile = 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile::FromBrowserContext(host->GetBrowserContext()); 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (host_profile->GetOriginalProfile() == profile_->GetOriginalProfile()) 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host->Send(new ExtensionMsg_Unloaded(extension->id())); 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_->UnregisterExtensionWithRequestContexts(extension->id(), reason); 1060effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1061effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // TODO(kalman): Convert ExtensionSpecialStoragePolicy to a 1062effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // BrowserContextKeyedService and use ExtensionRegistryObserver. 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->GetExtensionSpecialStoragePolicy()-> 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RevokeRightsForExtension(extension); 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS) 10672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Revoke external file access for the extension from its file system context. 10682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // It is safe to access the extension's storage partition at this point. The 10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // storage partition may get destroyed only after the extension gets unloaded. 1070a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) GURL site = 1071a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extensions::util::GetSiteForExtensionId(extension->id(), profile_); 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fileapi::FileSystemContext* filesystem_context = 10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserContext::GetStoragePartitionForSite(profile_, site)-> 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GetFileSystemContext(); 10757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (filesystem_context && filesystem_context->external_backend()) { 10767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch filesystem_context->external_backend()-> 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RevokeAccessForExtension(extension->id()); 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1081effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // TODO(kalman): This is broken. The crash reporter is process-wide so doesn't 1082effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // work properly multi-profile. Besides which, it should be using 1083effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // ExtensionRegistryObserver::OnExtensionLoaded. See http://crbug.com/355029. 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateActiveExtensionsInCrashReporter(); 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)content::BrowserContext* ExtensionService::GetBrowserContext() const { 10885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Implemented in the .cc file to avoid adding a profile.h dependency to 10895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // extension_service.h. 10905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return profile_; 10915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 10925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionService::is_ready() { 109490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return ready_->is_signaled(); 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)base::SequencedTaskRunner* ExtensionService::GetFileTaskRunner() { 1098868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (file_task_runner_.get()) 1099868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return file_task_runner_.get(); 11002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We should be able to interrupt any part of extension install process during 11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // shutdown. SKIP_ON_SHUTDOWN ensures that not started extension install tasks 11032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // will be ignored/deleted while we will block on started tasks. 11042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string token("ext_install-"); 11052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) token.append(profile_->GetPath().AsUTF8Unsafe()); 11062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) file_task_runner_ = BrowserThread::GetBlockingPool()-> 11072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetSequencedTaskRunnerWithShutdownBehavior( 11082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BrowserThread::GetBlockingPool()->GetNamedSequenceToken(token), 11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); 1110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return file_task_runner_.get(); 11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::CheckManagementPolicy() { 1114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::vector<std::string> to_unload; 1115f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::map<std::string, Extension::DisableReason> to_disable; 11162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Loop through the extensions list, finding extensions we need to unload or 1118f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // disable. 11195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ExtensionSet& extensions = registry_->enabled_extensions(); 11205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (ExtensionSet::const_iterator iter = extensions.begin(); 11215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter != extensions.end(); ++iter) { 11227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const Extension* extension = (iter->get()); 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!system_->management_policy()->UserMayLoad(extension, NULL)) 1124f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) to_unload.push_back(extension->id()); 1125f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) Extension::DisableReason disable_reason = Extension::DISABLE_NONE; 1126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (system_->management_policy()->MustRemainDisabled( 1127f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extension, &disable_reason, NULL)) 1128f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) to_disable[extension->id()] = disable_reason; 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1131f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (size_t i = 0; i < to_unload.size(); ++i) 1132f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) UnloadExtension(to_unload[i], UnloadedExtensionInfo::REASON_DISABLE); 1133f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 1134f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) for (std::map<std::string, Extension::DisableReason>::const_iterator i = 1135f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) to_disable.begin(); i != to_disable.end(); ++i) 1136f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DisableExtension(i->first, i->second); 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::CheckForUpdatesSoon() { 1140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS) 1141c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // This can legitimately happen in unit tests. 1142c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (!updater_.get()) 1143c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch return; 1144c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 1145c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (AreAllExternalProvidersReady()) { 1146c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch updater_->CheckSoon(); 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1148c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // Sync can start updating before all the external providers are ready 1149c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // during startup. Start the update as soon as those providers are ready, 1150c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch // but not before. 1151c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch update_once_all_providers_are_ready_ = true; 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Some extensions will autoupdate themselves externally from Chrome. These 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// are typically part of some larger client application package. To support 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// these, the extension will register its location in the the preferences file 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (and also, on Windows, in the registry) and this code will periodically 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// check that location for a .crx file, which it will then install locally if 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a new version is available. 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Errors are reported through ExtensionErrorReporter. Succcess is not 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reported. 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::CheckForExternalUpdates() { 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that this installation is intentionally silent (since it didn't 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // go through the front-end). Extensions that are registered in this 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // way are effectively considered 'pre-bundled', and so implicitly 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // trusted. In general, if something has HKLM or filesystem access, 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // they could install an extension manually themselves anyway. 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ask each external extension provider to give us a call back for each 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension they know about. See OnExternalExtension(File|UpdateUrl)Found. 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ProviderCollection::const_iterator i; 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = external_extension_providers_.begin(); 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != external_extension_providers_.end(); ++i) { 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ExternalProviderInterface* provider = i->get(); 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) provider->VisitRegisteredExtension(); 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do any required work that we would have done after completion of all 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // providers. 1184c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (external_extension_providers_.empty()) 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnAllExternalProvidersReady(); 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::OnExternalProviderReady( 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const extensions::ExternalProviderInterface* provider) { 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(provider->IsReady()); 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // An external provider has finished loading. We only take action 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if all of them are finished. So we check them first. 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (AreAllExternalProvidersReady()) 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnAllExternalProvidersReady(); 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionService::AreAllExternalProvidersReady() const { 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ProviderCollection::const_iterator i; 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = external_extension_providers_.begin(); 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != external_extension_providers_.end(); ++i) { 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!i->get()->IsReady()) 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::OnAllExternalProvidersReady() { 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS) 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta elapsed = base::Time::Now() - profile_->GetStartTime(); 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_TIMES("Extension.ExternalProvidersReadyAfter", elapsed); 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Install any pending extensions. 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (update_once_all_providers_are_ready_ && updater()) { 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) update_once_all_providers_are_ready_ = false; 12185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extensions::ExtensionUpdater::CheckParams params; 12195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) params.callback = external_updates_finished_callback_; 12205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) updater()->CheckNow(params); 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Uninstall all the unclaimed extensions. 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<extensions::ExtensionPrefs::ExtensionsInfo> extensions_info( 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_->GetInstalledExtensionsInfo()); 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < extensions_info->size(); ++i) { 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ExtensionInfo* info = extensions_info->at(i).get(); 12282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Manifest::IsExternalLocation(info->extension_location)) 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckExternalUninstall(info->extension_id); 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1232c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch error_controller_->ShowErrorIfNeeded(); 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch external_install_manager_->UpdateExternalExtensionAlert(); 1235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::UnloadExtension( 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id, 12401e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) UnloadedExtensionInfo::Reason reason) { 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure the extension gets deleted after we return from this function. 12425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int include_mask = 12435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionRegistry::EVERYTHING & ~ExtensionRegistry::TERMINATED; 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<const Extension> extension( 12455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->GetExtensionById(extension_id, include_mask)); 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This method can be called via PostTask, so the extension may have been 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // unloaded by the time this runs. 1249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!extension.get()) { 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // In case the extension may have crashed/uninstalled. Allow the profile to 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // clean up its RequestContexts. 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_->UnregisterExtensionWithRequestContexts(extension_id, reason); 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Keep information about the extension so that we can reload it later 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // even if it's not permanently installed. 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unloaded_extension_paths_[extension->id()] = extension->path(); 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Clean up if the extension is meant to be enabled after a reload. 1261c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) reloading_extensions_.erase(extension->id()); 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (registry_->disabled_extensions().Contains(extension->id())) { 12645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->RemoveDisabled(extension->id()); 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure the profile cleans up its RequestContexts when an already 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // disabled extension is unloaded (since they are also tracking the disabled 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extensions). 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_->UnregisterExtensionWithRequestContexts(extension_id, reason); 12695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Don't send the unloaded notification. It was sent when the extension 12705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // was disabled. 1271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } else { 12725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Remove the extension from the enabled list. 12735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->RemoveEnabled(extension->id()); 1274a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) NotifyExtensionUnloaded(extension.get(), reason); 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1277a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) content::NotificationService::current()->Notify( 1278a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) chrome::NOTIFICATION_EXTENSION_REMOVED, 1279a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) content::Source<Profile>(profile_), 1280a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) content::Details<const Extension>(extension.get())); 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 128358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void ExtensionService::RemoveComponentExtension( 128458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& extension_id) { 128558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scoped_refptr<const Extension> extension( 128658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) GetExtensionById(extension_id, false)); 12871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) UnloadExtension(extension_id, UnloadedExtensionInfo::REASON_UNINSTALL); 1288cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (extension.get()) { 1289cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) content::NotificationService::current()->Notify( 1290cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome::NOTIFICATION_EXTENSION_UNINSTALLED_DEPRECATED, 1291cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) content::Source<Profile>(profile_), 1292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) content::Details<const Extension>(extension.get())); 1293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ExtensionRegistry::Get(profile_)->TriggerOnUninstalled(extension.get()); 1294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 129558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 129658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 12975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionService::UnloadAllExtensionsForTest() { 12985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UnloadAllExtensionsInternal(); 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionService::ReloadExtensionsForTest() { 13025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Calling UnloadAllExtensionsForTest here triggers a false-positive presubmit 13035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // warning about calling test code in production. 13045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UnloadAllExtensionsInternal(); 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) component_loader_->LoadAll(); 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::InstalledLoader(this).LoadAllExtensions(); 130790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Don't call SetReadyAndNotifyListeners() since tests call this multiple 130890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // times. 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1311c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExtensionService::SetReadyAndNotifyListeners() { 131290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ready_->Signal(); 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current()->Notify( 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_EXTENSIONS_READY, 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile_), 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::NoDetails()); 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExtensionService::OnLoadedInstalledExtensions() { 1320116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS) 1321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (updater_) 1322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) updater_->Start(); 1323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OnBlacklistUpdated(); 1325116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif 1326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::AddExtension(const Extension* extension) { 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(jstritar): We may be able to get rid of this branch by overriding the 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // default extension state to DISABLED when the --disable-extensions flag 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is set (http://crbug.com/29067). 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extensions_enabled() && 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !extension->is_theme() && 13342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension->location() != Manifest::COMPONENT && 13352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !Manifest::IsExternalLocation(extension->location())) { 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool is_extension_upgrade = false; 1340ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool is_extension_installed = false; 1341ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch const Extension* old = GetInstalledExtension(extension->id()); 1342ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (old) { 1343ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch is_extension_installed = true; 1344ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch int version_compare_result = 1345ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch extension->version()->CompareTo(*(old->version())); 1346ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch is_extension_upgrade = version_compare_result > 0; 1347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Other than for unpacked extensions, CrxInstaller should have guaranteed 1348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // that we aren't downgrading. 1349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!Manifest::IsUnpackedLocation(extension->location())) 1350ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch CHECK_GE(version_compare_result, 0); 1351c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 13525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) system_->runtime_data()->SetBeingUpgraded(extension, is_extension_upgrade); 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The extension is now loaded, remove its data from unloaded extension map. 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unloaded_extension_paths_.erase(extension->id()); 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If a terminated extension is loaded, remove it from the terminated list. 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UntrackTerminatedExtension(extension->id()); 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the extension was disabled for a reload, then enable it. 1361c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool reloading = reloading_extensions_.erase(extension->id()) > 0; 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1363c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Check if the extension's privileges have changed and mark the 1364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // extension disabled if necessary. 1365ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch CheckPermissionsIncrease(extension, is_extension_installed); 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1367ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (is_extension_installed && !reloading) { 1368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // To upgrade an extension in place, unload the old one and then load the 1369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // new one. ReloadExtension disables the extension, which is sufficient. 13701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) UnloadExtension(extension->id(), UnloadedExtensionInfo::REASON_UPDATE); 1371c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (extension_prefs_->IsExtensionBlacklisted(extension->id())) { 13742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Only prefs is checked for the blacklist. We rely on callers to check the 13752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // blacklist before calling into here, e.g. CrxInstaller checks before 1376a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // installation then threads through the install and pending install flow 1377a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // of this class, and we check when loading installed extensions. 13785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->AddBlacklisted(extension); 1379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (!reloading && 1380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension_prefs_->IsExtensionDisabled(extension->id())) { 13815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->AddDisabled(extension); 13821e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (extension_sync_service_) 13831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) extension_sync_service_->SyncExtensionChangeIfNeeded(*extension); 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current()->Notify( 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_EXTENSION_UPDATE_DISABLED, 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile_), 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<const Extension>(extension)); 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1389cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Show the extension disabled error if a permissions increase or a remote 1390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // installation is the reason it was disabled, and no other reasons exist. 1391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) int reasons = extension_prefs_->GetDisableReasons(extension->id()); 1392cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const int kReasonMask = Extension::DISABLE_PERMISSIONS_INCREASE | 1393cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Extension::DISABLE_REMOTE_INSTALL; 1394cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (reasons & kReasonMask && !(reasons & ~kReasonMask)) { 1395cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extensions::AddExtensionDisabledError( 1396cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) this, 1397cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension, 1398cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension_prefs_->HasDisableReason( 1399cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension->id(), Extension::DISABLE_REMOTE_INSTALL)); 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1401c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (reloading) { 1402c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Replace the old extension with the new version. 14035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CHECK(!registry_->AddDisabled(extension)); 1404c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EnableExtension(extension->id()); 14052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 14062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // All apps that are displayed in the launcher are ordered by their ordinals 14072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // so we must ensure they have valid ordinals. 14082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (extension->RequiresSortOrdinal()) { 14092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!extension->ShouldDisplayInNewTabPage()) { 1410f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extension_prefs_->app_sorting()->MarkExtensionAsHidden(extension->id()); 14112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extension_prefs_->app_sorting()->EnsureValidOrdinals( 14132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension->id(), syncer::StringOrdinal()); 14142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 14152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->AddEnabled(extension); 14171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (extension_sync_service_) 14181e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) extension_sync_service_->SyncExtensionChangeIfNeeded(*extension); 14192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NotifyExtensionLoaded(extension); 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) system_->runtime_data()->SetBeingUpgraded(extension, false); 14222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 14232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionService::AddComponentExtension(const Extension* extension) { 14252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string old_version_string( 14262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_prefs_->GetVersionString(extension->id())); 14272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Version old_version(old_version_string); 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) VLOG(1) << "AddComponentExtension " << extension->name(); 14302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!old_version.IsValid() || !old_version.Equals(*extension->version())) { 14312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Component extension " << extension->name() << " (" 14322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << extension->id() << ") installing/upgrading from '" 14332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << old_version_string << "' to " << extension->version()->GetString(); 14342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddNewOrUpdatedExtension(extension, 14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Extension::ENABLED_COMPONENT, 1437f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) extensions::kInstallFlagNone, 1438effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch syncer::StringOrdinal(), 1439effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch std::string()); 14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddExtension(extension); 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ExtensionService::CheckPermissionsIncrease(const Extension* extension, 1447ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch bool is_extension_installed) { 1448116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS) 1449116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch extensions::PermissionsUpdater(profile_).InitializePermissions(extension); 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We keep track of all permissions the user has granted each extension. 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This allows extensions to gracefully support backwards compatibility 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // by including unknown permissions in their manifests. When the user 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // installs the extension, only the recognized permissions are recorded. 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When the unknown permissions become recognized (e.g., through browser 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // upgrade), we can prompt the user to accept these new permissions. 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extensions can also silently upgrade to less permissions, and then 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // silently upgrade to a version that adds these permissions back. 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For example, pretend that Chrome 10 includes a permission "omnibox" 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for an API that adds suggestions to the omnibox. An extension can 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // maintain backwards compatibility while still having "omnibox" in the 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // manifest. If a user installs the extension on Chrome 9, the browser 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will record the permissions it recognized, not including "omnibox." 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When upgrading to Chrome 10, "omnibox" will be recognized and Chrome 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // will disable the extension and prompt the user to approve the increase 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in privileges. The extension could then release a new version that 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // removes the "omnibox" permission. When the user upgrades, Chrome will 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // still remember that "omnibox" had been granted, so that if the 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension once again includes "omnibox" in an upgrade, the extension 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // can upgrade without requiring this user's approval. 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int disable_reasons = extension_prefs_->GetDisableReasons(extension->id()); 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 147490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool auto_grant_permission = 14751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) (!is_extension_installed && extension->was_installed_by_default()) || 1476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) extensions::ExtensionsBrowserClient::Get()->IsRunningInForcedAppMode(); 1477c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Silently grant all active permissions to default apps only on install. 1478c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // After install they should behave like other apps. 147990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Silently grant all active permissions to apps install in kiosk mode on both 148090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // install and update. 148190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (auto_grant_permission) 1482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GrantPermissions(extension); 1483c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1484c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool is_privilege_increase = false; 1485c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We only need to compare the granted permissions to the current permissions 1486c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // if the extension is not allowed to silently increase its permissions. 148790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (!extensions::PermissionsData::CanSilentlyIncreasePermissions(extension) && 148890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) !auto_grant_permission) { 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add all the recognized permissions if the granted permissions list 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // hasn't been initialized yet. 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<PermissionSet> granted_permissions = 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_->GetGrantedPermissions(extension->id()); 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(granted_permissions.get()); 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Here, we check if an extension's privileges have increased in a manner 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that requires the user's approval. This could occur because the browser 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // upgraded and recognized additional privileges, or an extension upgrades 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to a version that requires additional privileges. 14998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) is_privilege_increase = 15008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) extensions::PermissionMessageProvider::Get()->IsPrivilegeIncrease( 150146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) granted_permissions, 150246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension->permissions_data()->active_permissions().get(), 150346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) extension->GetType()); 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1506ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch if (is_extension_installed) { 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the extension was already disabled, suppress any alerts for becoming 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // disabled on permissions increase. 1509c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) bool previously_disabled = 1510c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extension_prefs_->IsExtensionDisabled(extension->id()); 15112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Legacy disabled extensions do not have a disable reason. Infer that if 15122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // there was no permission increase, it was likely disabled by the user. 15132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (previously_disabled && disable_reasons == Extension::DISABLE_NONE && 1514c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) !extension_prefs_->DidExtensionEscalatePermissions(extension->id())) { 15152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) disable_reasons |= Extension::DISABLE_USER_ACTION; 15162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Extensions that came to us disabled from sync need a similar inference, 15182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // except based on the new version's permissions. 15192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (previously_disabled && 15202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) disable_reasons == Extension::DISABLE_UNKNOWN_FROM_SYNC) { 15212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Remove the DISABLE_UNKNOWN_FROM_SYNC reason. 15222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_prefs_->ClearDisableReasons(extension->id()); 15232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!is_privilege_increase) 15242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) disable_reasons |= Extension::DISABLE_USER_ACTION; 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1526c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) disable_reasons &= ~Extension::DISABLE_UNKNOWN_FROM_SYNC; 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extension has changed permissions significantly. Disable it. A 1530cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // notification should be sent by the caller. If the extension is already 1531cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // disabled because it was installed remotely, don't add another disable 1532cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // reason, but instead always set the "did escalate permissions" flag, to 1533cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // ensure enabling it will always show a warning. 1534cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (disable_reasons == Extension::DISABLE_REMOTE_INSTALL) { 1535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension_prefs_->SetDidExtensionEscalatePermissions(extension, true); 1536cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } else if (is_privilege_increase) { 15372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) disable_reasons |= Extension::DISABLE_PERMISSIONS_INCREASE; 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!extension_prefs_->DidExtensionEscalatePermissions(extension->id())) { 153946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RecordPermissionMessagesHistogram(extension, 154046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) "Extensions.Permissions_AutoDisable2"); 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) extension_prefs_->SetExtensionState(extension->id(), Extension::DISABLED); 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_->SetDidExtensionEscalatePermissions(extension, true); 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (disable_reasons != Extension::DISABLE_NONE) { 15462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_prefs_->AddDisableReason( 15472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension->id(), 1548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static_cast<Extension::DisableReason>(disable_reasons)); 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1550116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif // defined(ENABLE_EXTENSIONS) 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::UpdateActiveExtensionsInCrashReporter() { 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<std::string> extension_ids; 15555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ExtensionSet& extensions = registry_->enabled_extensions(); 15565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (ExtensionSet::const_iterator iter = extensions.begin(); 15575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter != extensions.end(); ++iter) { 15587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) const Extension* extension = iter->get(); 15592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!extension->is_theme() && extension->location() != Manifest::COMPONENT) 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_ids.insert(extension->id()); 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1563effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // TODO(kalman): This is broken. ExtensionService is per-profile. 1564effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // crash_keys::SetActiveExtensions is per-process. See 1565effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch // http://crbug.com/355029. 156658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) crash_keys::SetActiveExtensions(extension_ids); 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::OnExtensionInstalled( 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* extension, 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncer::StringOrdinal& page_ordinal, 1572f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int install_flags) { 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id = extension->id(); 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool initial_enable = ShouldEnableOnInstall(extension); 1577effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch std::string install_parameter; 1578116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch const extensions::PendingExtensionInfo* pending_extension_info = 1579116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch pending_extension_manager()->GetById(id); 1580116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (pending_extension_info) { 1581868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!pending_extension_info->ShouldAllowInstall(extension)) { 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_extension_manager()->Remove(id); 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "ShouldAllowInstall() returned false for " 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << id << " of type " << extension->GetType() 15862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " and update URL " 15872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << extensions::ManifestURL::GetUpdateURL(extension).spec() 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "; not installing"; 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Delete the extension directory since we're not going to 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // load it. 15922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!GetFileTaskRunner()->PostTask( 15932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, 1594a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch base::Bind(&extensions::file_util::DeleteFile, 1595a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch extension->path(), 1596a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch true))) { 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1602effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch install_parameter = pending_extension_info->install_parameter(); 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_extension_manager()->Remove(id); 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We explicitly want to re-enable an uninstalled external 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extension; if we're here, that means the user is manually 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // installing the extension. 1608effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (extension_prefs_->IsExternalExtensionUninstalled(id)) { 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initial_enable = true; 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Unsupported requirements overrides the management policy. 1614f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (install_flags & extensions::kInstallFlagHasRequirementErrors) { 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initial_enable = false; 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_->AddDisableReason( 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id, Extension::DISABLE_UNSUPPORTED_REQUIREMENT); 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the extension was disabled because of unsupported requirements but 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // now supports all requirements after an update and there are not other 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // disable reasons, enable it. 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (extension_prefs_->GetDisableReasons(id) == 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Extension::DISABLE_UNSUPPORTED_REQUIREMENT) { 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initial_enable = true; 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension_prefs_->ClearDisableReasons(id); 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1627f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (install_flags & extensions::kInstallFlagIsBlacklistedForMalware) { 1628a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // Installation of a blacklisted extension can happen from sync, policy, 1629a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // etc, where to maintain consistency we need to install it, just never 1630a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // load it (see AddExtension). Usually it should be the job of callers to 1631a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // incercept blacklisted extension earlier (e.g. CrxInstaller, before even 1632a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // showing the install dialogue). 1633a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) extension_prefs_->AcknowledgeBlacklistedExtension(id); 1634a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.SilentInstall", 1635a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extension->location(), 1636a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Manifest::NUM_LOCATIONS); 1637a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 1638a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 16392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!GetInstalledExtension(extension->id())) { 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Extensions.InstallType", 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extension->GetType(), 100); 16422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Extensions.InstallSource", 16432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension->location(), Manifest::NUM_LOCATIONS); 164446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RecordPermissionMessagesHistogram(extension, 164546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) "Extensions.Permissions_Install2"); 16462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 16472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateType", 16482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension->GetType(), 100); 16492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Extensions.UpdateSource", 16502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension->location(), Manifest::NUM_LOCATIONS); 16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension::State initial_state = 16542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) initial_enable ? Extension::ENABLED : Extension::DISABLED; 1655f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (ShouldDelayExtensionUpdate( 1656f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) id, 1657f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) !!(install_flags & extensions::kInstallFlagInstallImmediately))) { 1658a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extension_prefs_->SetDelayedInstallInfo( 1659a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extension, 1660a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) initial_state, 1661f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) install_flags, 1662a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IDLE, 1663effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch page_ordinal, 1664effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch install_parameter); 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Transfer ownership of |extension|. 1667eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delayed_installs_.Insert(extension); 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Notify observers that app update is available. 16702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER(extensions::UpdateObserver, update_observers_, 1671a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) OnAppUpdateAvailable(extension)); 16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch extensions::SharedModuleService::ImportStatus status = 1676c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch shared_module_service_->SatisfyImports(extension); 1677e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch if (installs_delayed_for_gc_) { 1678a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extension_prefs_->SetDelayedInstallInfo( 1679a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extension, 1680a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) initial_state, 1681f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) install_flags, 1682a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extensions::ExtensionPrefs::DELAY_REASON_GC, 1683effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch page_ordinal, 1684effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch install_parameter); 16852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delayed_installs_.Insert(extension); 1686c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } else if (status != SharedModuleService::IMPORT_STATUS_OK) { 1687c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (status == SharedModuleService::IMPORT_STATUS_UNSATISFIED) { 1688a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extension_prefs_->SetDelayedInstallInfo( 1689a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) extension, 1690a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) initial_state, 1691f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) install_flags, 1692eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS, 1693effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch page_ordinal, 1694effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch install_parameter); 1695eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delayed_installs_.Insert(extension); 1696eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 16972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1698a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) AddNewOrUpdatedExtension(extension, 1699a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) initial_state, 1700f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) install_flags, 1701effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch page_ordinal, 1702effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch install_parameter); 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionService::AddNewOrUpdatedExtension( 17072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* extension, 17082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Extension::State initial_state, 1709f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) int install_flags, 1710effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const syncer::StringOrdinal& page_ordinal, 1711effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const std::string& install_parameter) { 17122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1713cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool was_ephemeral = extension_prefs_->IsEphemeralApp(extension->id()); 1714f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) extension_prefs_->OnExtensionInstalled( 1715f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) extension, initial_state, page_ordinal, install_flags, install_parameter); 1716a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) delayed_installs_.Remove(extension->id()); 1717effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch if (InstallVerifier::NeedsVerification(*extension)) 1718effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch system_->install_verifier()->VerifyExtension(extension->id()); 1719cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FinishInstallation(extension, was_ephemeral); 17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionService::MaybeFinishDelayedInstallation( 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& extension_id) { 1724eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Check if the extension already got installed. 1725eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!delayed_installs_.Contains(extension_id)) 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1727eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch extensions::ExtensionPrefs::DelayReason reason = 1728eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch extension_prefs_->GetDelayedInstallReason(extension_id); 1729eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1730eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Check if the extension is idle. DELAY_REASON_NONE is used for older 1731eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // preferences files that will not have set this field but it was previously 1732eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // only used for idle updates. 1733eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if ((reason == extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IDLE || 1734eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reason == extensions::ExtensionPrefs::DELAY_REASON_NONE) && 17355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) is_ready() && !extensions::util::IsExtensionIdle(extension_id, profile_)) 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1738eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const Extension* extension = delayed_installs_.GetByID(extension_id); 1739eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (reason == extensions::ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS) { 1740c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch extensions::SharedModuleService::ImportStatus status = 1741c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch shared_module_service_->SatisfyImports(extension); 1742c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (status != SharedModuleService::IMPORT_STATUS_OK) { 1743c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (status == SharedModuleService::IMPORT_STATUS_UNRECOVERABLE) { 1744eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delayed_installs_.Remove(extension_id); 1745eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Make sure no version of the extension is actually installed, (i.e., 1746eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // that this delayed install was not an update). 1747eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch CHECK(!extension_prefs_->GetInstalledExtensionInfo(extension_id).get()); 1748eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch extension_prefs_->DeleteExtensionPrefs(extension_id); 1749eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1750eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 1751eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1752eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1753eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 17542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FinishDelayedInstallation(extension_id); 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionService::FinishDelayedInstallation( 17582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& extension_id) { 17592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<const Extension> extension( 17602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetPendingExtensionUpdate(extension_id)); 1761868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) CHECK(extension.get()); 1762eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch delayed_installs_.Remove(extension_id); 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1764cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool was_ephemeral = extension_prefs_->IsEphemeralApp(extension->id()); 17652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!extension_prefs_->FinishDelayedInstallInfo(extension_id)) 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1768cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) FinishInstallation(extension.get(), was_ephemeral); 17692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 17702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1771cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ExtensionService::FinishInstallation( 1772cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const Extension* extension, bool was_ephemeral) { 177390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) const extensions::Extension* existing_extension = 177490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) GetInstalledExtension(extension->id()); 177590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool is_update = false; 177690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) std::string old_name; 177790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (existing_extension) { 177890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) is_update = true; 177990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) old_name = existing_extension->name(); 178090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 1781cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) bool from_ephemeral = 1782cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) was_ephemeral && !extension_prefs_->IsEphemeralApp(extension->id()); 1783cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extensions::InstalledExtensionInfo details( 1784cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension, is_update, from_ephemeral, old_name); 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::current()->Notify( 1786116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch chrome::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED, 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(profile_), 1788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::Details<const extensions::InstalledExtensionInfo>(&details)); 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1790f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) registry_->TriggerOnWillBeInstalled( 1791cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension, is_update, from_ephemeral, old_name); 1792cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 17932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Unpacked extensions default to allowing file access, but if that has been 17942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // overridden, don't reset the value. 17952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Manifest::ShouldAlwaysAllowFileAccess(extension->location()) && 17962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) !extension_prefs_->HasAllowFileAccessSetting(extension->id())) { 17972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_prefs_->SetAllowFileAccess(extension->id(), true); 17982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 17992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 18002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddExtension(extension); 18012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1802f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Notify observers that need to know when an installation is complete. 1803116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch registry_->TriggerOnInstalled(extension, is_update); 1804eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1805eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Check extensions that may have been delayed only because this shared module 1806eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // was not available. 1807116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (SharedModuleInfo::IsSharedModule(extension)) 1808eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MaybeFinishDelayedInstallations(); 18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1811cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ExtensionService::PromoteEphemeralApp( 1812cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const extensions::Extension* extension, bool is_from_sync) { 1813cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) DCHECK(GetInstalledExtension(extension->id()) && 1814cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension_prefs_->IsEphemeralApp(extension->id())); 1815cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1816cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!is_from_sync) { 1817cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (extension->RequiresSortOrdinal()) { 1818cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Reset the sort ordinals of the app to ensure it is added to the default 1819cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // position, like newly installed apps would. 1820cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension_prefs_->app_sorting()->ClearOrdinals(extension->id()); 1821cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension_prefs_->app_sorting()->EnsureValidOrdinals( 1822cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension->id(), syncer::StringOrdinal()); 1823cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 1824cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1825f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Cached ephemeral apps may be updated and disabled due to permissions 1826f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // increase. The app can be enabled as the install was user-acknowledged. 1827f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (extension_prefs_->DidExtensionEscalatePermissions(extension->id())) 1828f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) GrantPermissionsAndEnableExtension(extension); 1829cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 1830cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1831cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Remove the ephemeral flags from the preferences. 1832cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension_prefs_->OnEphemeralAppPromoted(extension->id()); 1833cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1834cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Fire install-related events to allow observers to handle the promotion 1835cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // of the ephemeral app. 1836cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extensions::InstalledExtensionInfo details( 1837cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension, 1838cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) true /* is update */, 1839cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) true /* from ephemeral */, 1840cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension->name() /* old name */); 1841cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) content::NotificationService::current()->Notify( 1842116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch chrome::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED, 1843cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) content::Source<Profile>(profile_), 1844cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) content::Details<const extensions::InstalledExtensionInfo>(&details)); 1845cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1846cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) registry_->TriggerOnWillBeInstalled( 1847cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension, 1848cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) true /* is update */, 1849cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) true /* from ephemeral */, 1850cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension->name() /* old name */); 1851cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1852cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (registry_->enabled_extensions().Contains(extension->id())) { 1853cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) content::NotificationService::current()->Notify( 1854cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, 1855cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) content::Source<Profile>(profile_), 1856cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) content::Details<const Extension>(extension)); 1857cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1858cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) registry_->TriggerOnLoaded(extension); 1859cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 1860cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 1861116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch registry_->TriggerOnInstalled(extension, true); 1862f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 1863cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) if (!is_from_sync && extension_sync_service_) 1864cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) extension_sync_service_->SyncExtensionChangeIfNeeded(*extension); 1865cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 1866cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 18672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const Extension* ExtensionService::GetPendingExtensionUpdate( 18682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& id) const { 1869eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return delayed_installs_.GetByID(id); 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::TrackTerminatedExtension(const Extension* extension) { 18735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // No need to check for duplicates; inserting a duplicate is a no-op. 18745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->AddTerminated(make_scoped_refptr(extension)); 18755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extensions_being_terminated_.erase(extension->id()); 18761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) UnloadExtension(extension->id(), UnloadedExtensionInfo::REASON_TERMINATE); 18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18790529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ExtensionService::TerminateExtension(const std::string& extension_id) { 18800529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch const Extension* extension = GetInstalledExtension(extension_id); 18810529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch TrackTerminatedExtension(extension); 18820529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch} 18830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch 18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::UntrackTerminatedExtension(const std::string& id) { 18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string lowercase_id = StringToLowerASCII(id); 18865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const Extension* extension = 18875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->terminated_extensions().GetByID(lowercase_id); 18885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->RemoveTerminated(lowercase_id); 1889a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) if (extension) { 1890a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) content::NotificationService::current()->Notify( 1891a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) chrome::NOTIFICATION_EXTENSION_REMOVED, 1892a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) content::Source<Profile>(profile_), 1893a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) content::Details<const Extension>(extension)); 1894a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const Extension* ExtensionService::GetInstalledExtension( 18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id) const { 18995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return registry_->GetExtensionById(id, ExtensionRegistry::EVERYTHING); 19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionService::OnExternalExtensionFileFound( 19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& id, 19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Version* version, 19052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& path, 19062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Manifest::Location location, 19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int creation_flags, 19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool mark_acknowledged) { 19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1910116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#if defined(ENABLE_EXTENSIONS) 19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(Extension::IdIsValid(id)); 19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension_prefs_->IsExternalExtensionUninstalled(id)) 19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Before even bothering to unpack, check and see if we already have this 19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // version. This is important because these extensions are going to get 19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // installed on every startup. 19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const Extension* existing = GetExtensionById(id, true); 19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (existing) { 19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The default apps will have the location set as INTERNAL. Since older 19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // default apps are installed as EXTERNAL, we override them. However, if the 19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // app is already installed as internal, then do the version check. 19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(grv) : Remove after Q1-2013. 19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_default_apps_migration = 19262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (location == Manifest::INTERNAL && 19272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Manifest::IsExternalLocation(existing->location())); 19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_default_apps_migration) { 19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(version); 19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (existing->version()->CompareTo(*version)) { 19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case -1: // existing version is older, we should upgrade 19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 0: // existing version is same, do nothing 19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case 1: // existing version is newer, uh-oh 19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Found external version of extension " << id 19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "that is older than current version. Current version " 19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "is: " << existing->VersionString() << ". New " 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "version is: " << version->GetString() 19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << ". Keeping current version."; 19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the extension is already pending, don't start an install. 19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pending_extension_manager()->AddFromExternalFile( 19504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) id, location, *version, creation_flags, mark_acknowledged)) { 19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // no client (silent install) 1955ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(this)); 19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer->set_install_source(location); 19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer->set_expected_id(id); 19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer->set_expected_version(*version); 19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer->set_install_cause(extension_misc::INSTALL_CAUSE_EXTERNAL_FILE); 19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer->set_creation_flags(creation_flags); 19612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_CHROMEOS) 19622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::InstallLimiter::Get(profile_)->Add(installer, path); 19632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) installer->InstallCrx(path); 19652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Depending on the source, a new external extension might not need a user 19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notification on installation. For such extensions, mark them acknowledged 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // now to suppress the notification. 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mark_acknowledged) 1971116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch external_install_manager_->AcknowledgeExternalExtension(id); 19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1974116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#else 1975116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return false; 1976116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#endif // defined(ENABLE_EXTENSIONS) 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::DidCreateRenderViewForBackgroundPage( 19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ExtensionHost* host) { 19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OrphanedDevTools::iterator iter = 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) orphaned_dev_tools_.find(host->extension_id()); 19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (iter == orphaned_dev_tools_.end()) 19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch iter->second->ConnectRenderViewHost(host->render_view_host()); 19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) orphaned_dev_tools_.erase(iter); 19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ExtensionService::Observe(int type, 19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationSource& source, 19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const content::NotificationDetails& details) { 19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chrome::NOTIFICATION_APP_TERMINATING: 19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Shutdown has started. Don't start any more extension installs. 19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (We cannot use ExtensionService::Shutdown() for this because it 19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // happens too late in browser teardown.) 19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser_terminating_ = true; 19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case chrome::NOTIFICATION_EXTENSION_PROCESS_TERMINATED: { 20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (profile_ != 20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<Profile>(source).ptr()->GetOriginalProfile()) { 20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) extensions::ExtensionHost* host = 20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<extensions::ExtensionHost>(details).ptr(); 20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // If the extension is already being terminated, there is nothing left to 20105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // do. 20115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!extensions_being_terminated_.insert(host->extension_id()).second) 20125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 20135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Mark the extension as terminated and Unload it. We want it to 20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be in a consistent state: either fully working or not loaded 20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // at all, but never half-crashed. We do it in a PostTask so 20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that other handlers of this notification will still have 20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // access to the Extension and ExtensionHost. 201990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask( 20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind( 20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &ExtensionService::TrackTerminatedExtension, 20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AsWeakPtr(), 20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host->extension())); 20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: { 20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RenderProcessHost* process = 20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<content::RenderProcessHost>(source).ptr(); 20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* host_profile = 20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile::FromBrowserContext(process->GetBrowserContext()); 20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!profile_->IsSameProfile(host_profile->GetOriginalProfile())) 20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extensions::ProcessMap* process_map = 20365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extensions::ProcessMap::Get(profile_); 20375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (process_map->Contains(process->GetID())) { 20380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // An extension process was terminated, this might have resulted in an 20390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // app or extension becoming idle. 20400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) std::set<std::string> extension_ids = 20415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) process_map->GetExtensionsInProcess(process->GetID()); 20420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) for (std::set<std::string>::const_iterator it = extension_ids.begin(); 20430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) it != extension_ids.end(); ++it) { 20440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (delayed_installs_.Contains(*it)) { 20450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 20460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) FROM_HERE, 20470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::Bind(&ExtensionService::MaybeFinishDelayedInstallation, 20480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) AsWeakPtr(), *it), 20490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) base::TimeDelta::FromSeconds(kUpdateIdleDelay)); 20500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 20510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 20520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 20530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 20545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) process_map->RemoveAllFromProcess(process->GetID()); 20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BrowserThread::PostTask( 2056f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) BrowserThread::IO, 2057f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) FROM_HERE, 2058f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) base::Bind(&extensions::InfoMap::UnregisterAllExtensionsInProcess, 20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) system_->info_map(), 20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) process->GetID())); 20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case chrome::NOTIFICATION_UPGRADE_RECOMMENDED: { 20642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Notify observers that chrome update is available. 20652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FOR_EACH_OBSERVER(extensions::UpdateObserver, update_observers_, 20662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OnChromeUpdateAvailable()); 20672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 20682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2069cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) case chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED: { 2070cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) OnProfileDestructionStarted(); 2071cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) break; 2072cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unexpected notification type."; 20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionService::OnExtensionInstallPrefChanged() { 2080c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch error_controller_->ShowErrorIfNeeded(); 20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckManagementPolicy(); 20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2084eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochbool ExtensionService::IsBeingReloaded( 2085eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const std::string& extension_id) const { 2086eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return ContainsKey(extensions_being_reloaded_, extension_id); 2087eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 2088eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2089eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ExtensionService::SetBeingReloaded(const std::string& extension_id, 2090a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch bool isBeingReloaded) { 2091a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch if (isBeingReloaded) 2092eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch extensions_being_reloaded_.insert(extension_id); 2093a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch else 2094eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch extensions_being_reloaded_.erase(extension_id); 2095eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 2096eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ExtensionService::ShouldEnableOnInstall(const Extension* extension) { 20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extensions installed by policy can't be disabled. So even if a previous 20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // installation disabled the extension, make sure it is now enabled. 2100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (system_->management_policy()->MustRemainEnabled(extension, NULL)) 21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (extension_prefs_->IsExtensionDisabled(extension->id())) 21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FeatureSwitch::prompt_for_external_extensions()->IsEnabled()) { 21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // External extensions are initially disabled. We prompt the user before 21082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // enabling them. Hosted apps are excepted because they are not dangerous 21092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (they need to be launched by the user anyway). 21102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (extension->GetType() != Manifest::TYPE_HOSTED_APP && 21112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Manifest::IsExternalLocation(extension->location()) && 21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !extension_prefs_->IsExternalExtensionAcknowledged(extension->id())) { 21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ExtensionService::ShouldDelayExtensionUpdate( 21212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& extension_id, 2122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) bool install_immediately) const { 21232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char kOnUpdateAvailableEvent[] = "runtime.onUpdateAvailable"; 21242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If delayed updates are globally disabled, or just for this extension, 21262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // don't delay. 2127f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!install_updates_when_idle_ || install_immediately) 21282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 21292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Extension* old = GetInstalledExtension(extension_id); 21312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If there is no old extension, this is not an update, so don't delay. 21322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!old) 21332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 21342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (extensions::BackgroundInfo::HasPersistentBackgroundPage(old)) { 21362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Delay installation if the extension listens for the onUpdateAvailable 21372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // event. 21382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return system_->event_router()->ExtensionHasEventListener( 21392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension_id, kOnUpdateAvailableEvent); 21402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 21412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Delay installation if the extension is not idle. 21425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return !extensions::util::IsExtensionIdle(extension_id, profile_); 21432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 21442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 21452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2146e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdochvoid ExtensionService::OnGarbageCollectIsolatedStorageStart() { 2147e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK(!installs_delayed_for_gc_); 2148e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch installs_delayed_for_gc_ = true; 21492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 21502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionService::OnGarbageCollectIsolatedStorageFinished() { 2152e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch DCHECK(installs_delayed_for_gc_); 2153e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch installs_delayed_for_gc_ = false; 2154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MaybeFinishDelayedInstallations(); 2155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 2156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 2157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid ExtensionService::MaybeFinishDelayedInstallations() { 2158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch std::vector<std::string> to_be_installed; 21592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (ExtensionSet::const_iterator it = delayed_installs_.begin(); 21602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != delayed_installs_.end(); 21612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++it) { 2162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch to_be_installed.push_back((*it)->id()); 21632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (std::vector<std::string>::const_iterator it = to_be_installed.begin(); 2165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch it != to_be_installed.end(); 21662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++it) { 2167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch MaybeFinishDelayedInstallation(*it); 21682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 21692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 21702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionService::OnBlacklistUpdated() { 21725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) blacklist_->GetBlacklistedIDs( 217323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) registry_->GenerateInstalledExtensionsSet()->GetIDs(), 217468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&ExtensionService::ManageBlacklist, AsWeakPtr())); 21752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 21762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionService::ManageBlacklist( 21785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const extensions::Blacklist::BlacklistStateMap& state_map) { 2179effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK_CURRENTLY_ON(BrowserThread::UI); 21802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::set<std::string> blocked; 21825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionIdSet greylist; 21835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionIdSet unchanged; 21845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (extensions::Blacklist::BlacklistStateMap::const_iterator it = 21855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) state_map.begin(); 21865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != state_map.end(); 21875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++it) { 21885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switch (it->second) { 21895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case extensions::NOT_BLACKLISTED: 21905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 21915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 21925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case extensions::BLACKLISTED_MALWARE: 21935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) blocked.insert(it->first); 21945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 21955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 21965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case extensions::BLACKLISTED_SECURITY_VULNERABILITY: 21975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case extensions::BLACKLISTED_CWS_POLICY_VIOLATION: 21985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case extensions::BLACKLISTED_POTENTIALLY_UNWANTED: 21995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) greylist.insert(it->first); 22005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 22015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 22025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) case extensions::BLACKLISTED_UNKNOWN: 22035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) unchanged.insert(it->first); 22045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 22055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 22065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 22075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 22085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UpdateBlockedExtensions(blocked, unchanged); 22095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UpdateGreylistedExtensions(greylist, unchanged, state_map); 22105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2211c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch error_controller_->ShowErrorIfNeeded(); 22125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 22135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 22145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 22155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void Partition(const ExtensionIdSet& before, 22165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ExtensionIdSet& after, 22175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ExtensionIdSet& unchanged, 22185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionIdSet* no_longer, 22195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionIdSet* not_yet) { 22205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *not_yet = base::STLSetDifference<ExtensionIdSet>(after, before); 22215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *no_longer = base::STLSetDifference<ExtensionIdSet>(before, after); 22225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *no_longer = base::STLSetDifference<ExtensionIdSet>(*no_longer, unchanged); 22235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 22245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 22255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 22265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionService::UpdateBlockedExtensions( 22275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ExtensionIdSet& blocked, 22285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ExtensionIdSet& unchanged) { 22295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionIdSet not_yet_blocked, no_longer_blocked; 22305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Partition(registry_->blacklisted_extensions().GetIDs(), 22315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) blocked, unchanged, 22325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &no_longer_blocked, ¬_yet_blocked); 22332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 22345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (ExtensionIdSet::iterator it = no_longer_blocked.begin(); 22355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != no_longer_blocked.end(); ++it) { 22362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<const Extension> extension = 22375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->blacklisted_extensions().GetByID(*it); 223868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!extension.get()) { 22395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOTREACHED() << "Extension " << *it << " no longer blocked, " 22405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << "but it was never blocked."; 22412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 224268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 22435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->RemoveBlacklisted(*it); 224468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) extension_prefs_->SetExtensionBlacklisted(extension->id(), false); 2245868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) AddExtension(extension.get()); 22462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.UnblacklistInstalled", 2247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) extension->location(), 2248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) Manifest::NUM_LOCATIONS); 22492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 22502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 22515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (ExtensionIdSet::iterator it = not_yet_blocked.begin(); 22525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != not_yet_blocked.end(); ++it) { 22532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<const Extension> extension = GetInstalledExtension(*it); 225468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!extension.get()) { 225568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) NOTREACHED() << "Extension " << *it << " needs to be " 225668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) << "blacklisted, but it's not installed."; 22572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 225868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 22595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->AddBlacklisted(extension); 22605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_prefs_->SetExtensionBlacklistState( 22615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension->id(), extensions::BLACKLISTED_MALWARE); 22621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) UnloadExtension(*it, UnloadedExtensionInfo::REASON_BLACKLIST); 22632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("ExtensionBlacklist.BlacklistInstalled", 22642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extension->location(), Manifest::NUM_LOCATIONS); 22652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 22665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 22672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 22685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(oleg): UMA logging 22695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionService::UpdateGreylistedExtensions( 22705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ExtensionIdSet& greylist, 22715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const ExtensionIdSet& unchanged, 22725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const extensions::Blacklist::BlacklistStateMap& state_map) { 22735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ExtensionIdSet not_yet_greylisted, no_longer_greylisted; 22745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Partition(greylist_.GetIDs(), 22755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) greylist, unchanged, 22765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &no_longer_greylisted, ¬_yet_greylisted); 22775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 22785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (ExtensionIdSet::iterator it = no_longer_greylisted.begin(); 22795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != no_longer_greylisted.end(); ++it) { 22805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<const Extension> extension = greylist_.GetByID(*it); 22815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!extension.get()) { 22825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOTREACHED() << "Extension " << *it << " no longer greylisted, " 22835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << "but it was not marked as greylisted."; 22845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 22855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 22865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 22875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) greylist_.Remove(*it); 22885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_prefs_->SetExtensionBlacklistState(extension->id(), 22895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extensions::NOT_BLACKLISTED); 22905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (extension_prefs_->GetDisableReasons(extension->id()) & 22915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extensions::Extension::DISABLE_GREYLIST) 22925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) EnableExtension(*it); 22935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 22945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 22955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (ExtensionIdSet::iterator it = not_yet_greylisted.begin(); 22965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != not_yet_greylisted.end(); ++it) { 22975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<const Extension> extension = GetInstalledExtension(*it); 22985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!extension.get()) { 22995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOTREACHED() << "Extension " << *it << " needs to be " 23005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) << "disabled, but it's not installed."; 23015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 23025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 23035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) greylist_.Insert(extension); 23045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) extension_prefs_->SetExtensionBlacklistState(extension->id(), 23055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) state_map.find(*it)->second); 23065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (registry_->enabled_extensions().Contains(extension->id())) 23075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DisableExtension(*it, extensions::Extension::DISABLE_GREYLIST); 23085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 23092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 23102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 23112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionService::AddUpdateObserver(extensions::UpdateObserver* observer) { 23122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) update_observers_.AddObserver(observer); 23132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 23142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 23152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ExtensionService::RemoveUpdateObserver( 23162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) extensions::UpdateObserver* observer) { 23172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) update_observers_.RemoveObserver(observer); 23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 23195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 23205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Used only by test code. 23215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ExtensionService::UnloadAllExtensionsInternal() { 23225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile_->GetExtensionSpecialStoragePolicy()->RevokeRightsForAllExtensions(); 23235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 23245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) registry_->ClearAll(); 23255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) system_->runtime_data()->ClearAll(); 23265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 23275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(erikkay) should there be a notification for this? We can't use 23285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // EXTENSION_UNLOADED since that implies that the extension has been disabled 23295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // or uninstalled. 23305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 2332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void ExtensionService::OnProfileDestructionStarted() { 2333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ExtensionIdSet ids_to_unload = registry_->enabled_extensions().GetIDs(); 2334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) for (ExtensionIdSet::iterator it = ids_to_unload.begin(); 2335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) it != ids_to_unload.end(); 2336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ++it) { 2337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) UnloadExtension(*it, UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN); 2338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) } 2339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 2340