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