| OLD | NEW | 
| (Empty) |  | 
 |    1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
 |    2 // Use of this source code is governed by a BSD-style license that can be | 
 |    3 // found in the LICENSE file. | 
 |    4  | 
 |    5 #include "chrome/browser/extensions/extension_system.h" | 
 |    6  | 
 |    7 #include "base/bind.h" | 
 |    8 #include "base/command_line.h" | 
 |    9 #include "base/file_path.h" | 
 |   10 #include "base/string_tokenizer.h" | 
 |   11 #include "chrome/browser/browser_process.h" | 
 |   12 #include "chrome/browser/extensions/component_loader.h" | 
 |   13 #include "chrome/browser/content_settings/cookie_settings.h" | 
 |   14 #include "chrome/browser/extensions/extension_devtools_manager.h" | 
 |   15 #include "chrome/browser/extensions/extension_error_reporter.h" | 
 |   16 #include "chrome/browser/extensions/extension_event_router.h" | 
 |   17 #include "chrome/browser/extensions/extension_info_map.h" | 
 |   18 #include "chrome/browser/extensions/extension_message_service.h" | 
 |   19 #include "chrome/browser/extensions/extension_navigation_observer.h" | 
 |   20 #include "chrome/browser/extensions/extension_pref_store.h" | 
 |   21 #include "chrome/browser/extensions/extension_pref_value_map.h" | 
 |   22 #include "chrome/browser/extensions/extension_process_manager.h" | 
 |   23 #include "chrome/browser/extensions/extension_service.h" | 
 |   24 #include "chrome/browser/extensions/extension_system_factory.h" | 
 |   25 #include "chrome/browser/extensions/lazy_background_task_queue.h" | 
 |   26 #include "chrome/browser/extensions/unpacked_installer.h" | 
 |   27 #include "chrome/browser/extensions/user_script_master.h" | 
 |   28 #include "chrome/browser/profiles/profile.h" | 
 |   29 #include "chrome/browser/profiles/profile_manager.h" | 
 |   30 #include "chrome/browser/ui/webui/chrome_url_data_manager.h" | 
 |   31 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" | 
 |   32 #include "chrome/common/chrome_switches.h" | 
 |   33 #include "chrome/common/extensions/extension.h" | 
 |   34 #include "chrome/common/pref_names.h" | 
 |   35 #include "content/public/browser/browser_thread.h" | 
 |   36  | 
 |   37 using content::BrowserThread; | 
 |   38  | 
 |   39 // | 
 |   40 // ExtensionSystem | 
 |   41 // | 
 |   42  | 
 |   43 ExtensionSystem::ExtensionSystem() { | 
 |   44 } | 
 |   45  | 
 |   46 ExtensionSystem::~ExtensionSystem() { | 
 |   47 } | 
 |   48  | 
 |   49 // | 
 |   50 // ExtensionSystemImpl::Shared | 
 |   51 // | 
 |   52  | 
 |   53 ExtensionSystemImpl::Shared::Shared(Profile* profile) | 
 |   54     : profile_(profile) { | 
 |   55 } | 
 |   56  | 
 |   57 ExtensionSystemImpl::Shared::~Shared() { | 
 |   58 } | 
 |   59  | 
 |   60 void ExtensionSystemImpl::Shared::InitPrefs() { | 
 |   61   bool extensions_disabled = | 
 |   62       profile_->GetPrefs()->GetBoolean(prefs::kDisableExtensions) || | 
 |   63       CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableExtensions); | 
 |   64   extension_prefs_.reset(new ExtensionPrefs( | 
 |   65       profile_->GetPrefs(), | 
 |   66       profile_->GetPath().AppendASCII(ExtensionService::kInstallDirectoryName), | 
 |   67       profile_->GetExtensionPrefValueMap())); | 
 |   68   extension_prefs_->Init(extensions_disabled); | 
 |   69 } | 
 |   70  | 
 |   71 void ExtensionSystemImpl::Shared::InitInfoMap() { | 
 |   72   // The ExtensionInfoMap needs to be created before the | 
 |   73   // ExtensionProcessManager. | 
 |   74   extension_info_map_ = new ExtensionInfoMap(); | 
 |   75 } | 
 |   76  | 
 |   77 void ExtensionSystemImpl::Shared::Init(bool extensions_enabled) { | 
 |   78   const CommandLine* command_line = CommandLine::ForCurrentProcess(); | 
 |   79  | 
 |   80   lazy_background_task_queue_.reset(new LazyBackgroundTaskQueue(profile_)); | 
 |   81   extension_event_router_.reset(new ExtensionEventRouter(profile_)); | 
 |   82   extension_message_service_.reset(new ExtensionMessageService( | 
 |   83       lazy_background_task_queue_.get())); | 
 |   84   extension_navigation_observer_.reset( | 
 |   85       new ExtensionNavigationObserver(profile_)); | 
 |   86  | 
 |   87   ExtensionErrorReporter::Init(true);  // allow noisy errors. | 
 |   88  | 
 |   89   user_script_master_ = new UserScriptMaster(profile_); | 
 |   90  | 
 |   91   bool autoupdate_enabled = true; | 
 |   92 #if defined(OS_CHROMEOS) | 
 |   93   if (!extensions_enabled) | 
 |   94     autoupdate_enabled = false; | 
 |   95   else | 
 |   96     autoupdate_enabled = !command_line->HasSwitch(switches::kGuestSession); | 
 |   97 #endif | 
 |   98   extension_service_.reset(new ExtensionService( | 
 |   99       profile_, | 
 |  100       CommandLine::ForCurrentProcess(), | 
 |  101       profile_->GetPath().AppendASCII(ExtensionService::kInstallDirectoryName), | 
 |  102       extension_prefs_.get(), | 
 |  103       autoupdate_enabled, | 
 |  104       extensions_enabled)); | 
 |  105  | 
 |  106   extension_service_->component_loader()->AddDefaultComponentExtensions(); | 
 |  107   if (command_line->HasSwitch(switches::kLoadComponentExtension)) { | 
 |  108     CommandLine::StringType path_list = command_line->GetSwitchValueNative( | 
 |  109         switches::kLoadComponentExtension); | 
 |  110     StringTokenizerT<CommandLine::StringType, | 
 |  111         CommandLine::StringType::const_iterator> t(path_list, | 
 |  112                                                    FILE_PATH_LITERAL(",")); | 
 |  113     while (t.GetNext()) { | 
 |  114       // Load the component extension manifest synchronously. | 
 |  115       // Blocking the UI thread is acceptable here since | 
 |  116       // this flag designated for developers. | 
 |  117       base::ThreadRestrictions::ScopedAllowIO allow_io; | 
 |  118       extension_service_->component_loader()->AddOrReplace( | 
 |  119           FilePath(t.token())); | 
 |  120     } | 
 |  121   } | 
 |  122   extension_service_->Init(); | 
 |  123  | 
 |  124   if (extensions_enabled) { | 
 |  125     // Load any extensions specified with --load-extension. | 
 |  126     // TODO(yoz): Seems like this should move into ExtensionService::Init. | 
 |  127     // But maybe it's no longer important. | 
 |  128     if (command_line->HasSwitch(switches::kLoadExtension)) { | 
 |  129       CommandLine::StringType path_list = command_line->GetSwitchValueNative( | 
 |  130           switches::kLoadExtension); | 
 |  131       StringTokenizerT<CommandLine::StringType, | 
 |  132           CommandLine::StringType::const_iterator> t(path_list, | 
 |  133                                                      FILE_PATH_LITERAL(",")); | 
 |  134       scoped_refptr<extensions::UnpackedInstaller> installer = | 
 |  135           extensions::UnpackedInstaller::Create(extension_service_.get()); | 
 |  136       while (t.GetNext()) { | 
 |  137         installer->LoadFromCommandLine(FilePath(t.token())); | 
 |  138       } | 
 |  139     } | 
 |  140   } | 
 |  141  | 
 |  142   // Make the chrome://extension-icon/ resource available. | 
 |  143   profile_->GetChromeURLDataManager()->AddDataSource( | 
 |  144       new ExtensionIconSource(profile_)); | 
 |  145  | 
 |  146   // Initialize extension event routers. Note that on Chrome OS, this will | 
 |  147   // not succeed if the user has not logged in yet, in which case the | 
 |  148   // event routers are initialized in LoginUtilsImpl::CompleteLogin instead. | 
 |  149   // The InitEventRouters call used to be in BrowserMain, because when bookmark | 
 |  150   // import happened on first run, the bookmark bar was not being correctly | 
 |  151   // initialized (see issue 40144). Now that bookmarks aren't imported and | 
 |  152   // the event routers need to be initialized for every profile individually, | 
 |  153   // initialize them with the extension service. | 
 |  154   // If this profile is being created as part of the import process, never | 
 |  155   // initialize the event routers. If import is going to run in a separate | 
 |  156   // process (the profile itself is on the main process), wait for import to | 
 |  157   // finish before initializing the routers. | 
 |  158   if (!command_line->HasSwitch(switches::kImport) && | 
 |  159       !command_line->HasSwitch(switches::kImportFromFile)) { | 
 |  160     if (g_browser_process->profile_manager()->will_import()) { | 
 |  161       extension_service_->InitEventRoutersAfterImport(); | 
 |  162     } else { | 
 |  163       extension_service_->InitEventRouters(); | 
 |  164     } | 
 |  165   } | 
 |  166 } | 
 |  167  | 
 |  168 ExtensionService* ExtensionSystemImpl::Shared::extension_service() { | 
 |  169   return extension_service_.get(); | 
 |  170 } | 
 |  171  | 
 |  172 UserScriptMaster* ExtensionSystemImpl::Shared::user_script_master() { | 
 |  173   return user_script_master_.get(); | 
 |  174 } | 
 |  175  | 
 |  176 ExtensionInfoMap* ExtensionSystemImpl::Shared::info_map() { | 
 |  177   return extension_info_map_.get(); | 
 |  178 } | 
 |  179  | 
 |  180 LazyBackgroundTaskQueue* | 
 |  181 ExtensionSystemImpl::Shared::lazy_background_task_queue() { | 
 |  182   return lazy_background_task_queue_.get(); | 
 |  183 } | 
 |  184  | 
 |  185 ExtensionMessageService* ExtensionSystemImpl::Shared::message_service() { | 
 |  186   return extension_message_service_.get(); | 
 |  187 } | 
 |  188  | 
 |  189 ExtensionEventRouter* ExtensionSystemImpl::Shared::event_router() { | 
 |  190   return extension_event_router_.get(); | 
 |  191 } | 
 |  192  | 
 |  193 // | 
 |  194 // ExtensionSystemImpl | 
 |  195 // | 
 |  196  | 
 |  197 ExtensionSystemImpl::ExtensionSystemImpl(Profile* profile) | 
 |  198     : profile_(profile), | 
 |  199       extension_devtools_manager_(NULL) { | 
 |  200   shared_ = ExtensionSystemSharedFactory::GetForProfile(profile); | 
 |  201  | 
 |  202   if (profile->IsOffTheRecord()) { | 
 |  203     extension_process_manager_.reset(ExtensionProcessManager::Create(profile)); | 
 |  204   } else { | 
 |  205     shared_->InitPrefs(); | 
 |  206   } | 
 |  207 } | 
 |  208  | 
 |  209 ExtensionSystemImpl::~ExtensionSystemImpl() { | 
 |  210 } | 
 |  211  | 
 |  212 void ExtensionSystemImpl::Shutdown() { | 
 |  213   extension_process_manager_.reset(); | 
 |  214 } | 
 |  215  | 
 |  216 void ExtensionSystemImpl::Init(bool extensions_enabled) { | 
 |  217   DCHECK(!profile_->IsOffTheRecord()); | 
 |  218   if (user_script_master() || extension_service()) | 
 |  219     return;  // Already initialized. | 
 |  220  | 
 |  221   const CommandLine* command_line = CommandLine::ForCurrentProcess(); | 
 |  222   if (command_line->HasSwitch( | 
 |  223       switches::kEnableExtensionTimelineApi)) { | 
 |  224     extension_devtools_manager_ = new ExtensionDevToolsManager(profile_); | 
 |  225   } | 
 |  226  | 
 |  227   shared_->InitInfoMap(); | 
 |  228  | 
 |  229   extension_process_manager_.reset(ExtensionProcessManager::Create(profile_)); | 
 |  230  | 
 |  231   shared_->Init(extensions_enabled); | 
 |  232 } | 
 |  233  | 
 |  234 ExtensionService* ExtensionSystemImpl::extension_service() { | 
 |  235   return shared_->extension_service(); | 
 |  236 } | 
 |  237  | 
 |  238 UserScriptMaster* ExtensionSystemImpl::user_script_master() { | 
 |  239   return shared_->user_script_master(); | 
 |  240 } | 
 |  241  | 
 |  242 ExtensionDevToolsManager* ExtensionSystemImpl::devtools_manager() { | 
 |  243   // TODO(mpcomplete): in incognito, figure out whether we should | 
 |  244   // return the original profile's version. | 
 |  245   return extension_devtools_manager_.get(); | 
 |  246 } | 
 |  247  | 
 |  248 ExtensionProcessManager* ExtensionSystemImpl::process_manager() { | 
 |  249   return extension_process_manager_.get(); | 
 |  250 } | 
 |  251  | 
 |  252 ExtensionInfoMap* ExtensionSystemImpl::info_map() { | 
 |  253   return shared_->info_map(); | 
 |  254 } | 
 |  255  | 
 |  256 LazyBackgroundTaskQueue* ExtensionSystemImpl::lazy_background_task_queue() { | 
 |  257   return shared_->lazy_background_task_queue(); | 
 |  258 } | 
 |  259  | 
 |  260 ExtensionMessageService* ExtensionSystemImpl::message_service() { | 
 |  261   return shared_->message_service(); | 
 |  262 } | 
 |  263  | 
 |  264 ExtensionEventRouter* ExtensionSystemImpl::event_router() { | 
 |  265   return shared_->event_router(); | 
 |  266 } | 
 |  267  | 
 |  268 void ExtensionSystemImpl::RegisterExtensionWithRequestContexts( | 
 |  269     const Extension* extension) { | 
 |  270   base::Time install_time; | 
 |  271   if (extension->location() != Extension::COMPONENT) { | 
 |  272     install_time = extension_service()->extension_prefs()-> | 
 |  273         GetInstallTime(extension->id()); | 
 |  274   } | 
 |  275   bool incognito_enabled = | 
 |  276       extension_service()->IsIncognitoEnabled(extension->id()); | 
 |  277   BrowserThread::PostTask( | 
 |  278       BrowserThread::IO, FROM_HERE, | 
 |  279       base::Bind(&ExtensionInfoMap::AddExtension, info_map(), | 
 |  280                  make_scoped_refptr(extension), install_time, | 
 |  281                  incognito_enabled)); | 
 |  282 } | 
 |  283  | 
 |  284 void ExtensionSystemImpl::UnregisterExtensionWithRequestContexts( | 
 |  285     const std::string& extension_id, | 
 |  286     const extension_misc::UnloadedExtensionReason reason) { | 
 |  287   BrowserThread::PostTask( | 
 |  288       BrowserThread::IO, FROM_HERE, | 
 |  289       base::Bind(&ExtensionInfoMap::RemoveExtension, info_map(), | 
 |  290                  extension_id, reason)); | 
 |  291 } | 
| OLD | NEW |