| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/extensions_service.h" | 5 #include "chrome/browser/extensions/extension_service.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 11 #include "base/file_util.h" | 11 #include "base/file_util.h" |
| 12 #include "base/metrics/histogram.h" | 12 #include "base/metrics/histogram.h" |
| 13 #include "base/stl_util-inl.h" | 13 #include "base/stl_util-inl.h" |
| 14 #include "base/string16.h" | 14 #include "base/string16.h" |
| 15 #include "base/string_number_conversions.h" | 15 #include "base/string_number_conversions.h" |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 PendingExtensionInfo::PendingExtensionInfo() | 163 PendingExtensionInfo::PendingExtensionInfo() |
| 164 : update_url(), | 164 : update_url(), |
| 165 expected_crx_type(PendingExtensionInfo::UNKNOWN), | 165 expected_crx_type(PendingExtensionInfo::UNKNOWN), |
| 166 is_from_sync(true), | 166 is_from_sync(true), |
| 167 install_silently(false), | 167 install_silently(false), |
| 168 enable_on_install(false), | 168 enable_on_install(false), |
| 169 enable_incognito_on_install(false), | 169 enable_incognito_on_install(false), |
| 170 install_source(Extension::INVALID) {} | 170 install_source(Extension::INVALID) {} |
| 171 | 171 |
| 172 | 172 |
| 173 ExtensionsService::ExtensionRuntimeData::ExtensionRuntimeData() | 173 ExtensionService::ExtensionRuntimeData::ExtensionRuntimeData() |
| 174 : background_page_ready(false), | 174 : background_page_ready(false), |
| 175 being_upgraded(false) { | 175 being_upgraded(false) { |
| 176 } | 176 } |
| 177 | 177 |
| 178 ExtensionsService::ExtensionRuntimeData::~ExtensionRuntimeData() { | 178 ExtensionService::ExtensionRuntimeData::~ExtensionRuntimeData() { |
| 179 } | 179 } |
| 180 | 180 |
| 181 // ExtensionsService. | 181 // ExtensionService. |
| 182 | 182 |
| 183 const char* ExtensionsService::kInstallDirectoryName = "Extensions"; | 183 const char* ExtensionService::kInstallDirectoryName = "Extensions"; |
| 184 const char* ExtensionsService::kCurrentVersionFileName = "Current Version"; | 184 const char* ExtensionService::kCurrentVersionFileName = "Current Version"; |
| 185 | 185 |
| 186 // Implements IO for the ExtensionsService. | 186 // Implements IO for the ExtensionService. |
| 187 | 187 |
| 188 class ExtensionsServiceBackend | 188 class ExtensionServiceBackend |
| 189 : public base::RefCountedThreadSafe<ExtensionsServiceBackend>, | 189 : public base::RefCountedThreadSafe<ExtensionServiceBackend>, |
| 190 public ExternalExtensionProvider::Visitor { | 190 public ExternalExtensionProvider::Visitor { |
| 191 public: | 191 public: |
| 192 // |install_directory| is a path where to look for extensions to load. | 192 // |install_directory| is a path where to look for extensions to load. |
| 193 ExtensionsServiceBackend(PrefService* prefs, | 193 ExtensionServiceBackend(PrefService* prefs, |
| 194 const FilePath& install_directory); | 194 const FilePath& install_directory); |
| 195 | 195 |
| 196 // Loads a single extension from |path| where |path| is the top directory of | 196 // Loads a single extension from |path| where |path| is the top directory of |
| 197 // a specific extension where its manifest file lives. | 197 // a specific extension where its manifest file lives. |
| 198 // Errors are reported through ExtensionErrorReporter. On success, | 198 // Errors are reported through ExtensionErrorReporter. On success, |
| 199 // OnExtensionLoaded() is called. | 199 // OnExtensionLoaded() is called. |
| 200 // TODO(erikkay): It might be useful to be able to load a packed extension | 200 // TODO(erikkay): It might be useful to be able to load a packed extension |
| 201 // (presumably into memory) without installing it. | 201 // (presumably into memory) without installing it. |
| 202 void LoadSingleExtension(const FilePath &path, | 202 void LoadSingleExtension(const FilePath &path, |
| 203 scoped_refptr<ExtensionsService> frontend); | 203 scoped_refptr<ExtensionService> frontend); |
| 204 | 204 |
| 205 // Check externally updated extensions for updates and install if necessary. | 205 // Check externally updated extensions for updates and install if necessary. |
| 206 // Errors are reported through ExtensionErrorReporter. Succcess is not | 206 // Errors are reported through ExtensionErrorReporter. Succcess is not |
| 207 // reported. | 207 // reported. |
| 208 void CheckForExternalUpdates(scoped_refptr<ExtensionsService> frontend); | 208 void CheckForExternalUpdates(scoped_refptr<ExtensionService> frontend); |
| 209 | 209 |
| 210 // For the extension in |version_path| with |id|, check to see if it's an | 210 // For the extension in |version_path| with |id|, check to see if it's an |
| 211 // externally managed extension. If so, tell the frontend to uninstall it. | 211 // externally managed extension. If so, tell the frontend to uninstall it. |
| 212 void CheckExternalUninstall(scoped_refptr<ExtensionsService> frontend, | 212 void CheckExternalUninstall(scoped_refptr<ExtensionService> frontend, |
| 213 const std::string& id); | 213 const std::string& id); |
| 214 | 214 |
| 215 // Clear all ExternalExtensionProviders. | 215 // Clear all ExternalExtensionProviders. |
| 216 void ClearProvidersForTesting(); | 216 void ClearProvidersForTesting(); |
| 217 | 217 |
| 218 // Adds an ExternalExtensionProvider for the service to use during testing. | 218 // Adds an ExternalExtensionProvider for the service to use during testing. |
| 219 // Takes ownership of |test_provider|. | 219 // Takes ownership of |test_provider|. |
| 220 void AddProviderForTesting(ExternalExtensionProvider* test_provider); | 220 void AddProviderForTesting(ExternalExtensionProvider* test_provider); |
| 221 | 221 |
| 222 // ExternalExtensionProvider::Visitor implementation. | 222 // ExternalExtensionProvider::Visitor implementation. |
| 223 virtual void OnExternalExtensionFileFound(const std::string& id, | 223 virtual void OnExternalExtensionFileFound(const std::string& id, |
| 224 const Version* version, | 224 const Version* version, |
| 225 const FilePath& path, | 225 const FilePath& path, |
| 226 Extension::Location location); | 226 Extension::Location location); |
| 227 | 227 |
| 228 virtual void OnExternalExtensionUpdateUrlFound(const std::string& id, | 228 virtual void OnExternalExtensionUpdateUrlFound(const std::string& id, |
| 229 const GURL& update_url, | 229 const GURL& update_url, |
| 230 Extension::Location location); | 230 Extension::Location location); |
| 231 | 231 |
| 232 virtual void UpdateExternalPolicyExtensionProvider( | 232 virtual void UpdateExternalPolicyExtensionProvider( |
| 233 scoped_refptr<RefCountedList> forcelist); | 233 scoped_refptr<RefCountedList> forcelist); |
| 234 | 234 |
| 235 private: | 235 private: |
| 236 friend class base::RefCountedThreadSafe<ExtensionsServiceBackend>; | 236 friend class base::RefCountedThreadSafe<ExtensionServiceBackend>; |
| 237 | 237 |
| 238 virtual ~ExtensionsServiceBackend(); | 238 virtual ~ExtensionServiceBackend(); |
| 239 | 239 |
| 240 // Finish installing the extension in |crx_path| after it has been unpacked to | 240 // Finish installing the extension in |crx_path| after it has been unpacked to |
| 241 // |unpacked_path|. If |expected_id| is not empty, it's verified against the | 241 // |unpacked_path|. If |expected_id| is not empty, it's verified against the |
| 242 // extension's manifest before installation. If |silent| is true, there will | 242 // extension's manifest before installation. If |silent| is true, there will |
| 243 // be no install confirmation dialog. |from_gallery| indicates whether the | 243 // be no install confirmation dialog. |from_gallery| indicates whether the |
| 244 // crx was installed from our gallery, which results in different UI. | 244 // crx was installed from our gallery, which results in different UI. |
| 245 // | 245 // |
| 246 // Note: We take ownership of |extension|. | 246 // Note: We take ownership of |extension|. |
| 247 void OnExtensionUnpacked(const FilePath& crx_path, | 247 void OnExtensionUnpacked(const FilePath& crx_path, |
| 248 const FilePath& unpacked_path, | 248 const FilePath& unpacked_path, |
| 249 const Extension* extension, | 249 const Extension* extension, |
| 250 const std::string expected_id); | 250 const std::string expected_id); |
| 251 | 251 |
| 252 // Notify the frontend that there was an error loading an extension. | 252 // Notify the frontend that there was an error loading an extension. |
| 253 void ReportExtensionLoadError(const FilePath& extension_path, | 253 void ReportExtensionLoadError(const FilePath& extension_path, |
| 254 const std::string& error); | 254 const std::string& error); |
| 255 | 255 |
| 256 // This is a naked pointer which is set by each entry point. | 256 // This is a naked pointer which is set by each entry point. |
| 257 // The entry point is responsible for ensuring lifetime. | 257 // The entry point is responsible for ensuring lifetime. |
| 258 ExtensionsService* frontend_; | 258 ExtensionService* frontend_; |
| 259 | 259 |
| 260 // The top-level extensions directory being installed to. | 260 // The top-level extensions directory being installed to. |
| 261 FilePath install_directory_; | 261 FilePath install_directory_; |
| 262 | 262 |
| 263 // Whether errors result in noisy alerts. | 263 // Whether errors result in noisy alerts. |
| 264 bool alert_on_error_; | 264 bool alert_on_error_; |
| 265 | 265 |
| 266 // A collection of external extension providers. Each provider reads | 266 // A collection of external extension providers. Each provider reads |
| 267 // a source of external extension information. Examples include the | 267 // a source of external extension information. Examples include the |
| 268 // windows registry and external_extensions.json. | 268 // windows registry and external_extensions.json. |
| 269 typedef std::vector<linked_ptr<ExternalExtensionProvider> > | 269 typedef std::vector<linked_ptr<ExternalExtensionProvider> > |
| 270 ProviderCollection; | 270 ProviderCollection; |
| 271 ProviderCollection external_extension_providers_; | 271 ProviderCollection external_extension_providers_; |
| 272 linked_ptr<ExternalPolicyExtensionProvider> | 272 linked_ptr<ExternalPolicyExtensionProvider> |
| 273 external_policy_extension_provider_; | 273 external_policy_extension_provider_; |
| 274 | 274 |
| 275 // Set to true by OnExternalExtensionUpdateUrlFound() when an external | 275 // Set to true by OnExternalExtensionUpdateUrlFound() when an external |
| 276 // extension URL is found. Used in CheckForExternalUpdates() to see | 276 // extension URL is found. Used in CheckForExternalUpdates() to see |
| 277 // if an update check is needed to install pending extensions. | 277 // if an update check is needed to install pending extensions. |
| 278 bool external_extension_added_; | 278 bool external_extension_added_; |
| 279 | 279 |
| 280 DISALLOW_COPY_AND_ASSIGN(ExtensionsServiceBackend); | 280 DISALLOW_COPY_AND_ASSIGN(ExtensionServiceBackend); |
| 281 }; | 281 }; |
| 282 | 282 |
| 283 ExtensionsServiceBackend::ExtensionsServiceBackend( | 283 ExtensionServiceBackend::ExtensionServiceBackend( |
| 284 PrefService* prefs, | 284 PrefService* prefs, |
| 285 const FilePath& install_directory) | 285 const FilePath& install_directory) |
| 286 : frontend_(NULL), | 286 : frontend_(NULL), |
| 287 install_directory_(install_directory), | 287 install_directory_(install_directory), |
| 288 alert_on_error_(false), | 288 alert_on_error_(false), |
| 289 external_extension_added_(false) { | 289 external_extension_added_(false) { |
| 290 // TODO(aa): This ends up doing blocking IO on the UI thread because it reads | 290 // TODO(aa): This ends up doing blocking IO on the UI thread because it reads |
| 291 // pref data in the ctor and that is called on the UI thread. Would be better | 291 // pref data in the ctor and that is called on the UI thread. Would be better |
| 292 // to re-read data each time we list external extensions, anyway. | 292 // to re-read data each time we list external extensions, anyway. |
| 293 external_extension_providers_.push_back( | 293 external_extension_providers_.push_back( |
| 294 linked_ptr<ExternalExtensionProvider>( | 294 linked_ptr<ExternalExtensionProvider>( |
| 295 new ExternalPrefExtensionProvider())); | 295 new ExternalPrefExtensionProvider())); |
| 296 #if defined(OS_WIN) | 296 #if defined(OS_WIN) |
| 297 external_extension_providers_.push_back( | 297 external_extension_providers_.push_back( |
| 298 linked_ptr<ExternalExtensionProvider>( | 298 linked_ptr<ExternalExtensionProvider>( |
| 299 new ExternalRegistryExtensionProvider())); | 299 new ExternalRegistryExtensionProvider())); |
| 300 #endif | 300 #endif |
| 301 // The policy-controlled extension provider is also stored in a member | 301 // The policy-controlled extension provider is also stored in a member |
| 302 // variable so that UpdateExternalPolicyExtensionProvider can access it and | 302 // variable so that UpdateExternalPolicyExtensionProvider can access it and |
| 303 // update its extension list later. | 303 // update its extension list later. |
| 304 external_policy_extension_provider_.reset( | 304 external_policy_extension_provider_.reset( |
| 305 new ExternalPolicyExtensionProvider()); | 305 new ExternalPolicyExtensionProvider()); |
| 306 external_policy_extension_provider_->SetPreferences( | 306 external_policy_extension_provider_->SetPreferences( |
| 307 prefs->GetList(prefs::kExtensionInstallForceList)); | 307 prefs->GetList(prefs::kExtensionInstallForceList)); |
| 308 external_extension_providers_.push_back(external_policy_extension_provider_); | 308 external_extension_providers_.push_back(external_policy_extension_provider_); |
| 309 } | 309 } |
| 310 | 310 |
| 311 ExtensionsServiceBackend::~ExtensionsServiceBackend() { | 311 ExtensionServiceBackend::~ExtensionServiceBackend() { |
| 312 } | 312 } |
| 313 | 313 |
| 314 void ExtensionsServiceBackend::LoadSingleExtension( | 314 void ExtensionServiceBackend::LoadSingleExtension( |
| 315 const FilePath& path_in, scoped_refptr<ExtensionsService> frontend) { | 315 const FilePath& path_in, scoped_refptr<ExtensionService> frontend) { |
| 316 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 316 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 317 | 317 |
| 318 frontend_ = frontend; | 318 frontend_ = frontend; |
| 319 | 319 |
| 320 // Explicit UI loads are always noisy. | 320 // Explicit UI loads are always noisy. |
| 321 alert_on_error_ = true; | 321 alert_on_error_ = true; |
| 322 | 322 |
| 323 FilePath extension_path = path_in; | 323 FilePath extension_path = path_in; |
| 324 file_util::AbsolutePath(&extension_path); | 324 file_util::AbsolutePath(&extension_path); |
| 325 | 325 |
| 326 std::string error; | 326 std::string error; |
| 327 scoped_refptr<const Extension> extension(extension_file_util::LoadExtension( | 327 scoped_refptr<const Extension> extension(extension_file_util::LoadExtension( |
| 328 extension_path, | 328 extension_path, |
| 329 Extension::LOAD, | 329 Extension::LOAD, |
| 330 false, // Don't require id | 330 false, // Don't require id |
| 331 &error)); | 331 &error)); |
| 332 | 332 |
| 333 if (!extension) { | 333 if (!extension) { |
| 334 ReportExtensionLoadError(extension_path, error); | 334 ReportExtensionLoadError(extension_path, error); |
| 335 return; | 335 return; |
| 336 } | 336 } |
| 337 | 337 |
| 338 // Report this as an installed extension so that it gets remembered in the | 338 // Report this as an installed extension so that it gets remembered in the |
| 339 // prefs. | 339 // prefs. |
| 340 BrowserThread::PostTask( | 340 BrowserThread::PostTask( |
| 341 BrowserThread::UI, FROM_HERE, | 341 BrowserThread::UI, FROM_HERE, |
| 342 NewRunnableMethod(frontend_, | 342 NewRunnableMethod(frontend_, |
| 343 &ExtensionsService::OnExtensionInstalled, | 343 &ExtensionService::OnExtensionInstalled, |
| 344 extension)); | 344 extension)); |
| 345 } | 345 } |
| 346 | 346 |
| 347 void ExtensionsServiceBackend::ReportExtensionLoadError( | 347 void ExtensionServiceBackend::ReportExtensionLoadError( |
| 348 const FilePath& extension_path, const std::string &error) { | 348 const FilePath& extension_path, const std::string &error) { |
| 349 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 349 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 350 BrowserThread::PostTask( | 350 BrowserThread::PostTask( |
| 351 BrowserThread::UI, FROM_HERE, | 351 BrowserThread::UI, FROM_HERE, |
| 352 NewRunnableMethod( | 352 NewRunnableMethod( |
| 353 frontend_, | 353 frontend_, |
| 354 &ExtensionsService::ReportExtensionLoadError, extension_path, | 354 &ExtensionService::ReportExtensionLoadError, extension_path, |
| 355 error, NotificationType::EXTENSION_INSTALL_ERROR, alert_on_error_)); | 355 error, NotificationType::EXTENSION_INSTALL_ERROR, alert_on_error_)); |
| 356 } | 356 } |
| 357 | 357 |
| 358 // Some extensions will autoupdate themselves externally from Chrome. These | 358 // Some extensions will autoupdate themselves externally from Chrome. These |
| 359 // are typically part of some larger client application package. To support | 359 // are typically part of some larger client application package. To support |
| 360 // these, the extension will register its location in the the preferences file | 360 // these, the extension will register its location in the the preferences file |
| 361 // (and also, on Windows, in the registry) and this code will periodically | 361 // (and also, on Windows, in the registry) and this code will periodically |
| 362 // check that location for a .crx file, which it will then install locally if | 362 // check that location for a .crx file, which it will then install locally if |
| 363 // a new version is available. | 363 // a new version is available. |
| 364 void ExtensionsServiceBackend::CheckForExternalUpdates( | 364 void ExtensionServiceBackend::CheckForExternalUpdates( |
| 365 scoped_refptr<ExtensionsService> frontend) { | 365 scoped_refptr<ExtensionService> frontend) { |
| 366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 366 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 367 | 367 |
| 368 // Note that this installation is intentionally silent (since it didn't | 368 // Note that this installation is intentionally silent (since it didn't |
| 369 // go through the front-end). Extensions that are registered in this | 369 // go through the front-end). Extensions that are registered in this |
| 370 // way are effectively considered 'pre-bundled', and so implicitly | 370 // way are effectively considered 'pre-bundled', and so implicitly |
| 371 // trusted. In general, if something has HKLM or filesystem access, | 371 // trusted. In general, if something has HKLM or filesystem access, |
| 372 // they could install an extension manually themselves anyway. | 372 // they could install an extension manually themselves anyway. |
| 373 alert_on_error_ = false; | 373 alert_on_error_ = false; |
| 374 frontend_ = frontend; | 374 frontend_ = frontend; |
| 375 external_extension_added_ = false; | 375 external_extension_added_ = false; |
| 376 | 376 |
| 377 // Ask each external extension provider to give us a call back for each | 377 // Ask each external extension provider to give us a call back for each |
| 378 // extension they know about. See OnExternalExtension(File|UpdateUrl)Found. | 378 // extension they know about. See OnExternalExtension(File|UpdateUrl)Found. |
| 379 ProviderCollection::const_iterator i; | 379 ProviderCollection::const_iterator i; |
| 380 for (i = external_extension_providers_.begin(); | 380 for (i = external_extension_providers_.begin(); |
| 381 i != external_extension_providers_.end(); ++i) { | 381 i != external_extension_providers_.end(); ++i) { |
| 382 ExternalExtensionProvider* provider = i->get(); | 382 ExternalExtensionProvider* provider = i->get(); |
| 383 provider->VisitRegisteredExtension(this); | 383 provider->VisitRegisteredExtension(this); |
| 384 } | 384 } |
| 385 | 385 |
| 386 if (external_extension_added_ && frontend->updater()) { | 386 if (external_extension_added_ && frontend->updater()) { |
| 387 BrowserThread::PostTask( | 387 BrowserThread::PostTask( |
| 388 BrowserThread::UI, FROM_HERE, | 388 BrowserThread::UI, FROM_HERE, |
| 389 NewRunnableMethod( | 389 NewRunnableMethod( |
| 390 frontend->updater(), &ExtensionUpdater::CheckNow)); | 390 frontend->updater(), &ExtensionUpdater::CheckNow)); |
| 391 } | 391 } |
| 392 } | 392 } |
| 393 | 393 |
| 394 void ExtensionsServiceBackend::CheckExternalUninstall( | 394 void ExtensionServiceBackend::CheckExternalUninstall( |
| 395 scoped_refptr<ExtensionsService> frontend, const std::string& id) { | 395 scoped_refptr<ExtensionService> frontend, const std::string& id) { |
| 396 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 396 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 397 | 397 |
| 398 // Check if the providers know about this extension. | 398 // Check if the providers know about this extension. |
| 399 ProviderCollection::const_iterator i; | 399 ProviderCollection::const_iterator i; |
| 400 for (i = external_extension_providers_.begin(); | 400 for (i = external_extension_providers_.begin(); |
| 401 i != external_extension_providers_.end(); ++i) { | 401 i != external_extension_providers_.end(); ++i) { |
| 402 if (i->get()->HasExtension(id)) | 402 if (i->get()->HasExtension(id)) |
| 403 return; // Yup, known extension, don't uninstall. | 403 return; // Yup, known extension, don't uninstall. |
| 404 } | 404 } |
| 405 | 405 |
| 406 // This is an external extension that we don't have registered. Uninstall. | 406 // This is an external extension that we don't have registered. Uninstall. |
| 407 BrowserThread::PostTask( | 407 BrowserThread::PostTask( |
| 408 BrowserThread::UI, FROM_HERE, | 408 BrowserThread::UI, FROM_HERE, |
| 409 NewRunnableMethod( | 409 NewRunnableMethod( |
| 410 frontend.get(), &ExtensionsService::UninstallExtension, id, true)); | 410 frontend.get(), &ExtensionService::UninstallExtension, id, true)); |
| 411 } | 411 } |
| 412 | 412 |
| 413 void ExtensionsServiceBackend::UpdateExternalPolicyExtensionProvider( | 413 void ExtensionServiceBackend::UpdateExternalPolicyExtensionProvider( |
| 414 scoped_refptr<RefCountedList> forcelist) { | 414 scoped_refptr<RefCountedList> forcelist) { |
| 415 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 415 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 416 external_policy_extension_provider_->SetPreferences(forcelist->Get()); | 416 external_policy_extension_provider_->SetPreferences(forcelist->Get()); |
| 417 } | 417 } |
| 418 | 418 |
| 419 void ExtensionsServiceBackend::ClearProvidersForTesting() { | 419 void ExtensionServiceBackend::ClearProvidersForTesting() { |
| 420 external_extension_providers_.clear(); | 420 external_extension_providers_.clear(); |
| 421 } | 421 } |
| 422 | 422 |
| 423 void ExtensionsServiceBackend::AddProviderForTesting( | 423 void ExtensionServiceBackend::AddProviderForTesting( |
| 424 ExternalExtensionProvider* test_provider) { | 424 ExternalExtensionProvider* test_provider) { |
| 425 DCHECK(test_provider); | 425 DCHECK(test_provider); |
| 426 external_extension_providers_.push_back( | 426 external_extension_providers_.push_back( |
| 427 linked_ptr<ExternalExtensionProvider>(test_provider)); | 427 linked_ptr<ExternalExtensionProvider>(test_provider)); |
| 428 } | 428 } |
| 429 | 429 |
| 430 void ExtensionsServiceBackend::OnExternalExtensionFileFound( | 430 void ExtensionServiceBackend::OnExternalExtensionFileFound( |
| 431 const std::string& id, const Version* version, const FilePath& path, | 431 const std::string& id, const Version* version, const FilePath& path, |
| 432 Extension::Location location) { | 432 Extension::Location location) { |
| 433 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 433 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 434 | 434 |
| 435 DCHECK(version); | 435 DCHECK(version); |
| 436 BrowserThread::PostTask( | 436 BrowserThread::PostTask( |
| 437 BrowserThread::UI, FROM_HERE, | 437 BrowserThread::UI, FROM_HERE, |
| 438 NewRunnableMethod( | 438 NewRunnableMethod( |
| 439 frontend_, &ExtensionsService::OnExternalExtensionFileFound, id, | 439 frontend_, &ExtensionService::OnExternalExtensionFileFound, id, |
| 440 version->GetString(), path, location)); | 440 version->GetString(), path, location)); |
| 441 } | 441 } |
| 442 | 442 |
| 443 void ExtensionsServiceBackend::OnExternalExtensionUpdateUrlFound( | 443 void ExtensionServiceBackend::OnExternalExtensionUpdateUrlFound( |
| 444 const std::string& id, | 444 const std::string& id, |
| 445 const GURL& update_url, | 445 const GURL& update_url, |
| 446 Extension::Location location) { | 446 Extension::Location location) { |
| 447 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 447 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 448 | 448 |
| 449 if (frontend_->GetExtensionById(id, true)) { | 449 if (frontend_->GetExtensionById(id, true)) { |
| 450 // Already installed. Do not change the update URL that the extension set. | 450 // Already installed. Do not change the update URL that the extension set. |
| 451 return; | 451 return; |
| 452 } | 452 } |
| 453 | 453 |
| 454 BrowserThread::PostTask( | 454 BrowserThread::PostTask( |
| 455 BrowserThread::UI, FROM_HERE, | 455 BrowserThread::UI, FROM_HERE, |
| 456 NewRunnableMethod( | 456 NewRunnableMethod( |
| 457 frontend_, | 457 frontend_, |
| 458 &ExtensionsService::AddPendingExtensionFromExternalUpdateUrl, | 458 &ExtensionService::AddPendingExtensionFromExternalUpdateUrl, |
| 459 id, update_url, location)); | 459 id, update_url, location)); |
| 460 external_extension_added_ |= true; | 460 external_extension_added_ |= true; |
| 461 } | 461 } |
| 462 | 462 |
| 463 bool ExtensionsService::IsDownloadFromGallery(const GURL& download_url, | 463 bool ExtensionService::IsDownloadFromGallery(const GURL& download_url, |
| 464 const GURL& referrer_url) { | 464 const GURL& referrer_url) { |
| 465 // Special-case the themes mini-gallery. | 465 // Special-case the themes mini-gallery. |
| 466 // TODO(erikkay) When that gallery goes away, remove this code. | 466 // TODO(erikkay) When that gallery goes away, remove this code. |
| 467 if (IsDownloadFromMiniGallery(download_url) && | 467 if (IsDownloadFromMiniGallery(download_url) && |
| 468 StartsWithASCII(referrer_url.spec(), | 468 StartsWithASCII(referrer_url.spec(), |
| 469 extension_urls::kMiniGalleryBrowsePrefix, false)) { | 469 extension_urls::kMiniGalleryBrowsePrefix, false)) { |
| 470 return true; | 470 return true; |
| 471 } | 471 } |
| 472 | 472 |
| 473 const Extension* download_extension = GetExtensionByWebExtent(download_url); | 473 const Extension* download_extension = GetExtensionByWebExtent(download_url); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 502 GURL(download_url)); | 502 GURL(download_url)); |
| 503 | 503 |
| 504 // Otherwise, the TLD must match the TLD of the command-line url. | 504 // Otherwise, the TLD must match the TLD of the command-line url. |
| 505 download_valid = (download_tld == store_tld); | 505 download_valid = (download_tld == store_tld); |
| 506 } | 506 } |
| 507 } | 507 } |
| 508 | 508 |
| 509 return (referrer_valid && download_valid); | 509 return (referrer_valid && download_valid); |
| 510 } | 510 } |
| 511 | 511 |
| 512 bool ExtensionsService::IsDownloadFromMiniGallery(const GURL& download_url) { | 512 bool ExtensionService::IsDownloadFromMiniGallery(const GURL& download_url) { |
| 513 return StartsWithASCII(download_url.spec(), | 513 return StartsWithASCII(download_url.spec(), |
| 514 extension_urls::kMiniGalleryDownloadPrefix, | 514 extension_urls::kMiniGalleryDownloadPrefix, |
| 515 false); // case_sensitive | 515 false); // case_sensitive |
| 516 } | 516 } |
| 517 | 517 |
| 518 bool ExtensionsService::IsInstalledApp(const GURL& url) { | 518 bool ExtensionService::IsInstalledApp(const GURL& url) { |
| 519 // Check for hosted app. | 519 // Check for hosted app. |
| 520 if (GetExtensionByWebExtent(url) != NULL) | 520 if (GetExtensionByWebExtent(url) != NULL) |
| 521 return true; | 521 return true; |
| 522 | 522 |
| 523 // Check for packaged app. | 523 // Check for packaged app. |
| 524 const Extension* extension = GetExtensionByURL(url); | 524 const Extension* extension = GetExtensionByURL(url); |
| 525 return extension != NULL && extension->is_app(); | 525 return extension != NULL && extension->is_app(); |
| 526 } | 526 } |
| 527 | 527 |
| 528 // static | 528 // static |
| 529 bool ExtensionsService::UninstallExtensionHelper( | 529 bool ExtensionService::UninstallExtensionHelper( |
| 530 ExtensionsService* extensions_service, | 530 ExtensionService* extensions_service, |
| 531 const std::string& extension_id) { | 531 const std::string& extension_id) { |
| 532 DCHECK(extensions_service); | 532 DCHECK(extensions_service); |
| 533 | 533 |
| 534 // We can't call UninstallExtension with an invalid extension ID, so check it | 534 // We can't call UninstallExtension with an invalid extension ID, so check it |
| 535 // first. | 535 // first. |
| 536 if (extensions_service->GetExtensionById(extension_id, true)) { | 536 if (extensions_service->GetExtensionById(extension_id, true)) { |
| 537 extensions_service->UninstallExtension(extension_id, false); | 537 extensions_service->UninstallExtension(extension_id, false); |
| 538 } else { | 538 } else { |
| 539 LOG(WARNING) << "Attempted uninstallation of non-existent extension with " | 539 LOG(WARNING) << "Attempted uninstallation of non-existent extension with " |
| 540 << "id: " << extension_id; | 540 << "id: " << extension_id; |
| 541 return false; | 541 return false; |
| 542 } | 542 } |
| 543 | 543 |
| 544 return true; | 544 return true; |
| 545 } | 545 } |
| 546 | 546 |
| 547 ExtensionsService::ExtensionsService(Profile* profile, | 547 ExtensionService::ExtensionService(Profile* profile, |
| 548 const CommandLine* command_line, | 548 const CommandLine* command_line, |
| 549 const FilePath& install_directory, | 549 const FilePath& install_directory, |
| 550 ExtensionPrefs* extension_prefs, | 550 ExtensionPrefs* extension_prefs, |
| 551 bool autoupdate_enabled) | 551 bool autoupdate_enabled) |
| 552 : profile_(profile), | 552 : profile_(profile), |
| 553 extension_prefs_(extension_prefs), | 553 extension_prefs_(extension_prefs), |
| 554 install_directory_(install_directory), | 554 install_directory_(install_directory), |
| 555 extensions_enabled_(true), | 555 extensions_enabled_(true), |
| 556 show_extensions_prompts_(true), | 556 show_extensions_prompts_(true), |
| 557 ready_(false), | 557 ready_(false), |
| (...skipping 22 matching lines...) Expand all Loading... |
| 580 if (command_line->HasSwitch(switches::kExtensionsUpdateFrequency)) { | 580 if (command_line->HasSwitch(switches::kExtensionsUpdateFrequency)) { |
| 581 base::StringToInt(command_line->GetSwitchValueASCII( | 581 base::StringToInt(command_line->GetSwitchValueASCII( |
| 582 switches::kExtensionsUpdateFrequency), | 582 switches::kExtensionsUpdateFrequency), |
| 583 &update_frequency); | 583 &update_frequency); |
| 584 } | 584 } |
| 585 updater_ = new ExtensionUpdater(this, | 585 updater_ = new ExtensionUpdater(this, |
| 586 profile->GetPrefs(), | 586 profile->GetPrefs(), |
| 587 update_frequency); | 587 update_frequency); |
| 588 } | 588 } |
| 589 | 589 |
| 590 backend_ = new ExtensionsServiceBackend(profile->GetPrefs(), | 590 backend_ = new ExtensionServiceBackend(profile->GetPrefs(), |
| 591 install_directory_); | 591 install_directory_); |
| 592 | 592 |
| 593 // Use monochrome icons for Omnibox icons. | 593 // Use monochrome icons for Omnibox icons. |
| 594 omnibox_popup_icon_manager_.set_monochrome(true); | 594 omnibox_popup_icon_manager_.set_monochrome(true); |
| 595 omnibox_icon_manager_.set_monochrome(true); | 595 omnibox_icon_manager_.set_monochrome(true); |
| 596 omnibox_icon_manager_.set_padding(gfx::Insets(0, kOmniboxIconPaddingLeft, | 596 omnibox_icon_manager_.set_padding(gfx::Insets(0, kOmniboxIconPaddingLeft, |
| 597 0, kOmniboxIconPaddingRight)); | 597 0, kOmniboxIconPaddingRight)); |
| 598 } | 598 } |
| 599 | 599 |
| 600 const ExtensionList* ExtensionsService::extensions() const { | 600 const ExtensionList* ExtensionService::extensions() const { |
| 601 return &extensions_; | 601 return &extensions_; |
| 602 } | 602 } |
| 603 | 603 |
| 604 const ExtensionList* ExtensionsService::disabled_extensions() const { | 604 const ExtensionList* ExtensionService::disabled_extensions() const { |
| 605 return &disabled_extensions_; | 605 return &disabled_extensions_; |
| 606 } | 606 } |
| 607 | 607 |
| 608 const PendingExtensionMap& ExtensionsService::pending_extensions() const { | 608 const PendingExtensionMap& ExtensionService::pending_extensions() const { |
| 609 return pending_extensions_; | 609 return pending_extensions_; |
| 610 } | 610 } |
| 611 | 611 |
| 612 bool ExtensionsService::HasInstalledExtensions() { | 612 bool ExtensionService::HasInstalledExtensions() { |
| 613 return !(extensions_.empty() && disabled_extensions_.empty()); | 613 return !(extensions_.empty() && disabled_extensions_.empty()); |
| 614 } | 614 } |
| 615 | 615 |
| 616 ExtensionsService::~ExtensionsService() { | 616 ExtensionService::~ExtensionService() { |
| 617 DCHECK(!profile_); // Profile should have told us it's going away. | 617 DCHECK(!profile_); // Profile should have told us it's going away. |
| 618 UnloadAllExtensions(); | 618 UnloadAllExtensions(); |
| 619 if (updater_.get()) { | 619 if (updater_.get()) { |
| 620 updater_->Stop(); | 620 updater_->Stop(); |
| 621 } | 621 } |
| 622 } | 622 } |
| 623 | 623 |
| 624 void ExtensionsService::InitEventRouters() { | 624 void ExtensionService::InitEventRouters() { |
| 625 if (event_routers_initialized_) | 625 if (event_routers_initialized_) |
| 626 return; | 626 return; |
| 627 | 627 |
| 628 ExtensionHistoryEventRouter::GetInstance()->ObserveProfile(profile_); | 628 ExtensionHistoryEventRouter::GetInstance()->ObserveProfile(profile_); |
| 629 ExtensionAccessibilityEventRouter::GetInstance()->ObserveProfile(profile_); | 629 ExtensionAccessibilityEventRouter::GetInstance()->ObserveProfile(profile_); |
| 630 ExtensionBrowserEventRouter::GetInstance()->Init(profile_); | 630 ExtensionBrowserEventRouter::GetInstance()->Init(profile_); |
| 631 ExtensionBookmarkEventRouter::GetInstance()->Observe( | 631 ExtensionBookmarkEventRouter::GetInstance()->Observe( |
| 632 profile_->GetBookmarkModel()); | 632 profile_->GetBookmarkModel()); |
| 633 ExtensionCookiesEventRouter::GetInstance()->Init(); | 633 ExtensionCookiesEventRouter::GetInstance()->Init(); |
| 634 ExtensionManagementEventRouter::GetInstance()->Init(); | 634 ExtensionManagementEventRouter::GetInstance()->Init(); |
| 635 ExtensionProcessesEventRouter::GetInstance()->ObserveProfile(profile_); | 635 ExtensionProcessesEventRouter::GetInstance()->ObserveProfile(profile_); |
| 636 ExtensionWebNavigationEventRouter::GetInstance()->Init(); | 636 ExtensionWebNavigationEventRouter::GetInstance()->Init(); |
| 637 event_routers_initialized_ = true; | 637 event_routers_initialized_ = true; |
| 638 } | 638 } |
| 639 | 639 |
| 640 const Extension* ExtensionsService::GetExtensionById(const std::string& id, | 640 const Extension* ExtensionService::GetExtensionById(const std::string& id, |
| 641 bool include_disabled) { | 641 bool include_disabled) { |
| 642 return GetExtensionByIdInternal(id, true, include_disabled); | 642 return GetExtensionByIdInternal(id, true, include_disabled); |
| 643 } | 643 } |
| 644 | 644 |
| 645 void ExtensionsService::Init() { | 645 void ExtensionService::Init() { |
| 646 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 646 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 647 | 647 |
| 648 DCHECK(!ready_); // Can't redo init. | 648 DCHECK(!ready_); // Can't redo init. |
| 649 DCHECK_EQ(extensions_.size(), 0u); | 649 DCHECK_EQ(extensions_.size(), 0u); |
| 650 | 650 |
| 651 // Hack: we need to ensure the ResourceDispatcherHost is ready before we load | 651 // Hack: we need to ensure the ResourceDispatcherHost is ready before we load |
| 652 // the first extension, because its members listen for loaded notifications. | 652 // the first extension, because its members listen for loaded notifications. |
| 653 g_browser_process->resource_dispatcher_host(); | 653 g_browser_process->resource_dispatcher_host(); |
| 654 | 654 |
| 655 LoadAllExtensions(); | 655 LoadAllExtensions(); |
| 656 | 656 |
| 657 // TODO(erikkay) this should probably be deferred to a future point | 657 // TODO(erikkay) this should probably be deferred to a future point |
| 658 // rather than running immediately at startup. | 658 // rather than running immediately at startup. |
| 659 CheckForExternalUpdates(); | 659 CheckForExternalUpdates(); |
| 660 | 660 |
| 661 // TODO(erikkay) this should probably be deferred as well. | 661 // TODO(erikkay) this should probably be deferred as well. |
| 662 GarbageCollectExtensions(); | 662 GarbageCollectExtensions(); |
| 663 } | 663 } |
| 664 | 664 |
| 665 void ExtensionsService::InstallExtension(const FilePath& extension_path) { | 665 void ExtensionService::InstallExtension(const FilePath& extension_path) { |
| 666 scoped_refptr<CrxInstaller> installer( | 666 scoped_refptr<CrxInstaller> installer( |
| 667 new CrxInstaller(this, // frontend | 667 new CrxInstaller(this, // frontend |
| 668 NULL)); // no client (silent install) | 668 NULL)); // no client (silent install) |
| 669 installer->InstallCrx(extension_path); | 669 installer->InstallCrx(extension_path); |
| 670 } | 670 } |
| 671 | 671 |
| 672 namespace { | 672 namespace { |
| 673 // TODO(akalin): Put this somewhere where both crx_installer.cc and | 673 // TODO(akalin): Put this somewhere where both crx_installer.cc and |
| 674 // this file can use it. | 674 // this file can use it. |
| 675 void DeleteFileHelper(const FilePath& path, bool recursive) { | 675 void DeleteFileHelper(const FilePath& path, bool recursive) { |
| 676 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 676 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 677 file_util::Delete(path, recursive); | 677 file_util::Delete(path, recursive); |
| 678 } | 678 } |
| 679 } // namespace | 679 } // namespace |
| 680 | 680 |
| 681 void ExtensionsService::UpdateExtension(const std::string& id, | 681 void ExtensionService::UpdateExtension(const std::string& id, |
| 682 const FilePath& extension_path, | 682 const FilePath& extension_path, |
| 683 const GURL& download_url) { | 683 const GURL& download_url) { |
| 684 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 684 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 685 | 685 |
| 686 PendingExtensionMap::const_iterator it = pending_extensions_.find(id); | 686 PendingExtensionMap::const_iterator it = pending_extensions_.find(id); |
| 687 bool is_pending_extension = (it != pending_extensions_.end()); | 687 bool is_pending_extension = (it != pending_extensions_.end()); |
| 688 | 688 |
| 689 const Extension* extension = GetExtensionByIdInternal(id, true, true); | 689 const Extension* extension = GetExtensionByIdInternal(id, true, true); |
| 690 if (!is_pending_extension && !extension) { | 690 if (!is_pending_extension && !extension) { |
| 691 LOG(WARNING) << "Will not update extension " << id | 691 LOG(WARNING) << "Will not update extension " << id |
| (...skipping 18 matching lines...) Expand all Loading... |
| 710 installer->set_expected_id(id); | 710 installer->set_expected_id(id); |
| 711 if (is_pending_extension) | 711 if (is_pending_extension) |
| 712 installer->set_install_source(it->second.install_source); | 712 installer->set_install_source(it->second.install_source); |
| 713 else if (extension) | 713 else if (extension) |
| 714 installer->set_install_source(extension->location()); | 714 installer->set_install_source(extension->location()); |
| 715 installer->set_delete_source(true); | 715 installer->set_delete_source(true); |
| 716 installer->set_original_url(download_url); | 716 installer->set_original_url(download_url); |
| 717 installer->InstallCrx(extension_path); | 717 installer->InstallCrx(extension_path); |
| 718 } | 718 } |
| 719 | 719 |
| 720 void ExtensionsService::AddPendingExtensionFromSync( | 720 void ExtensionService::AddPendingExtensionFromSync( |
| 721 const std::string& id, const GURL& update_url, | 721 const std::string& id, const GURL& update_url, |
| 722 PendingExtensionInfo::ExpectedCrxType expected_crx_type, | 722 PendingExtensionInfo::ExpectedCrxType expected_crx_type, |
| 723 bool install_silently, bool enable_on_install, | 723 bool install_silently, bool enable_on_install, |
| 724 bool enable_incognito_on_install) { | 724 bool enable_incognito_on_install) { |
| 725 if (GetExtensionByIdInternal(id, true, true)) { | 725 if (GetExtensionByIdInternal(id, true, true)) { |
| 726 LOG(DFATAL) << "Trying to add pending extension " << id | 726 LOG(DFATAL) << "Trying to add pending extension " << id |
| 727 << " which already exists"; | 727 << " which already exists"; |
| 728 return; | 728 return; |
| 729 } | 729 } |
| 730 | 730 |
| 731 AddPendingExtensionInternal(id, update_url, expected_crx_type, true, | 731 AddPendingExtensionInternal(id, update_url, expected_crx_type, true, |
| 732 install_silently, enable_on_install, | 732 install_silently, enable_on_install, |
| 733 enable_incognito_on_install, | 733 enable_incognito_on_install, |
| 734 Extension::INTERNAL); | 734 Extension::INTERNAL); |
| 735 } | 735 } |
| 736 | 736 |
| 737 void ExtensionsService::AddPendingExtensionFromExternalUpdateUrl( | 737 void ExtensionService::AddPendingExtensionFromExternalUpdateUrl( |
| 738 const std::string& id, const GURL& update_url, | 738 const std::string& id, const GURL& update_url, |
| 739 Extension::Location location) { | 739 Extension::Location location) { |
| 740 // Add the extension to this list of extensions to update. | 740 // Add the extension to this list of extensions to update. |
| 741 const PendingExtensionInfo::ExpectedCrxType kExpectedCrxType = | 741 const PendingExtensionInfo::ExpectedCrxType kExpectedCrxType = |
| 742 PendingExtensionInfo::UNKNOWN; | 742 PendingExtensionInfo::UNKNOWN; |
| 743 const bool kIsFromSync = false; | 743 const bool kIsFromSync = false; |
| 744 const bool kInstallSilently = true; | 744 const bool kInstallSilently = true; |
| 745 const bool kEnableOnInstall = true; | 745 const bool kEnableOnInstall = true; |
| 746 const bool kEnableIncognitoOnInstall = false; | 746 const bool kEnableIncognitoOnInstall = false; |
| 747 if (extension_prefs_->IsExtensionKilled(id)) | 747 if (extension_prefs_->IsExtensionKilled(id)) |
| 748 return; | 748 return; |
| 749 | 749 |
| 750 if (GetExtensionByIdInternal(id, true, true)) { | 750 if (GetExtensionByIdInternal(id, true, true)) { |
| 751 LOG(DFATAL) << "Trying to add extension " << id | 751 LOG(DFATAL) << "Trying to add extension " << id |
| 752 << " by external update, but it is already installed."; | 752 << " by external update, but it is already installed."; |
| 753 return; | 753 return; |
| 754 } | 754 } |
| 755 | 755 |
| 756 AddPendingExtensionInternal(id, update_url, kExpectedCrxType, kIsFromSync, | 756 AddPendingExtensionInternal(id, update_url, kExpectedCrxType, kIsFromSync, |
| 757 kInstallSilently, kEnableOnInstall, | 757 kInstallSilently, kEnableOnInstall, |
| 758 kEnableIncognitoOnInstall, | 758 kEnableIncognitoOnInstall, |
| 759 location); | 759 location); |
| 760 } | 760 } |
| 761 | 761 |
| 762 void ExtensionsService::AddPendingExtensionFromDefaultAppList( | 762 void ExtensionService::AddPendingExtensionFromDefaultAppList( |
| 763 const std::string& id) { | 763 const std::string& id) { |
| 764 // Add the extension to this list of extensions to update. | 764 // Add the extension to this list of extensions to update. |
| 765 const PendingExtensionInfo::ExpectedCrxType kExpectedCrxType = | 765 const PendingExtensionInfo::ExpectedCrxType kExpectedCrxType = |
| 766 PendingExtensionInfo::APP; | 766 PendingExtensionInfo::APP; |
| 767 const bool kIsFromSync = false; | 767 const bool kIsFromSync = false; |
| 768 const bool kInstallSilently = true; | 768 const bool kInstallSilently = true; |
| 769 const bool kEnableOnInstall = true; | 769 const bool kEnableOnInstall = true; |
| 770 const bool kEnableIncognitoOnInstall = true; | 770 const bool kEnableIncognitoOnInstall = true; |
| 771 | 771 |
| 772 // This can legitimately happen if the user manually installed one of the | 772 // This can legitimately happen if the user manually installed one of the |
| 773 // default apps before this code ran. | 773 // default apps before this code ran. |
| 774 if (GetExtensionByIdInternal(id, true, true)) | 774 if (GetExtensionByIdInternal(id, true, true)) |
| 775 return; | 775 return; |
| 776 | 776 |
| 777 AddPendingExtensionInternal(id, GURL(), kExpectedCrxType, kIsFromSync, | 777 AddPendingExtensionInternal(id, GURL(), kExpectedCrxType, kIsFromSync, |
| 778 kInstallSilently, kEnableOnInstall, | 778 kInstallSilently, kEnableOnInstall, |
| 779 kEnableIncognitoOnInstall, | 779 kEnableIncognitoOnInstall, |
| 780 Extension::INTERNAL); | 780 Extension::INTERNAL); |
| 781 } | 781 } |
| 782 | 782 |
| 783 void ExtensionsService::AddPendingExtensionInternal( | 783 void ExtensionService::AddPendingExtensionInternal( |
| 784 const std::string& id, const GURL& update_url, | 784 const std::string& id, const GURL& update_url, |
| 785 PendingExtensionInfo::ExpectedCrxType expected_crx_type, | 785 PendingExtensionInfo::ExpectedCrxType expected_crx_type, |
| 786 bool is_from_sync, bool install_silently, | 786 bool is_from_sync, bool install_silently, |
| 787 bool enable_on_install, bool enable_incognito_on_install, | 787 bool enable_on_install, bool enable_incognito_on_install, |
| 788 Extension::Location install_source) { | 788 Extension::Location install_source) { |
| 789 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 789 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 790 | 790 |
| 791 // If a non-sync update is pending, a sync request should not | 791 // If a non-sync update is pending, a sync request should not |
| 792 // overwrite it. This is important for external extensions. | 792 // overwrite it. This is important for external extensions. |
| 793 // If an external extension download is pending, and the user has | 793 // If an external extension download is pending, and the user has |
| (...skipping 11 matching lines...) Expand all Loading... |
| 805 if (!it->second.is_from_sync && is_from_sync) | 805 if (!it->second.is_from_sync && is_from_sync) |
| 806 return; | 806 return; |
| 807 } | 807 } |
| 808 | 808 |
| 809 pending_extensions_[id] = | 809 pending_extensions_[id] = |
| 810 PendingExtensionInfo(update_url, expected_crx_type, is_from_sync, | 810 PendingExtensionInfo(update_url, expected_crx_type, is_from_sync, |
| 811 install_silently, enable_on_install, | 811 install_silently, enable_on_install, |
| 812 enable_incognito_on_install, install_source); | 812 enable_incognito_on_install, install_source); |
| 813 } | 813 } |
| 814 | 814 |
| 815 void ExtensionsService::ReloadExtension(const std::string& extension_id) { | 815 void ExtensionService::ReloadExtension(const std::string& extension_id) { |
| 816 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 816 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 817 FilePath path; | 817 FilePath path; |
| 818 const Extension* current_extension = GetExtensionById(extension_id, false); | 818 const Extension* current_extension = GetExtensionById(extension_id, false); |
| 819 | 819 |
| 820 // Disable the extension if it's loaded. It might not be loaded if it crashed. | 820 // Disable the extension if it's loaded. It might not be loaded if it crashed. |
| 821 if (current_extension) { | 821 if (current_extension) { |
| 822 // If the extension has an inspector open for its background page, detach | 822 // If the extension has an inspector open for its background page, detach |
| 823 // the inspector and hang onto a cookie for it, so that we can reattach | 823 // the inspector and hang onto a cookie for it, so that we can reattach |
| 824 // later. | 824 // later. |
| 825 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager(); | 825 ExtensionProcessManager* manager = profile_->GetExtensionProcessManager(); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 848 installed_extension->extension_manifest.get()) { | 848 installed_extension->extension_manifest.get()) { |
| 849 LoadInstalledExtension(*installed_extension, false); | 849 LoadInstalledExtension(*installed_extension, false); |
| 850 } else { | 850 } else { |
| 851 // We should always be able to remember the extension's path. If it's not in | 851 // We should always be able to remember the extension's path. If it's not in |
| 852 // the map, someone failed to update |unloaded_extension_paths_|. | 852 // the map, someone failed to update |unloaded_extension_paths_|. |
| 853 CHECK(!path.empty()); | 853 CHECK(!path.empty()); |
| 854 LoadExtension(path); | 854 LoadExtension(path); |
| 855 } | 855 } |
| 856 } | 856 } |
| 857 | 857 |
| 858 void ExtensionsService::UninstallExtension(const std::string& extension_id, | 858 void ExtensionService::UninstallExtension(const std::string& extension_id, |
| 859 bool external_uninstall) { | 859 bool external_uninstall) { |
| 860 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 860 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 861 | 861 |
| 862 const Extension* extension = | 862 const Extension* extension = |
| 863 GetExtensionByIdInternal(extension_id, true, true); | 863 GetExtensionByIdInternal(extension_id, true, true); |
| 864 | 864 |
| 865 // Callers should not send us nonexistent extensions. | 865 // Callers should not send us nonexistent extensions. |
| 866 CHECK(extension); | 866 CHECK(extension); |
| 867 | 867 |
| 868 // Get hold of information we need after unloading, since the extension | 868 // Get hold of information we need after unloading, since the extension |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 900 | 900 |
| 901 ClearExtensionData(extension_url); | 901 ClearExtensionData(extension_url); |
| 902 | 902 |
| 903 // Notify interested parties that we've uninstalled this extension. | 903 // Notify interested parties that we've uninstalled this extension. |
| 904 NotificationService::current()->Notify( | 904 NotificationService::current()->Notify( |
| 905 NotificationType::EXTENSION_UNINSTALLED, | 905 NotificationType::EXTENSION_UNINSTALLED, |
| 906 Source<Profile>(profile_), | 906 Source<Profile>(profile_), |
| 907 Details<UninstalledExtensionInfo>(&uninstalled_extension_info)); | 907 Details<UninstalledExtensionInfo>(&uninstalled_extension_info)); |
| 908 } | 908 } |
| 909 | 909 |
| 910 void ExtensionsService::ClearExtensionData(const GURL& extension_url) { | 910 void ExtensionService::ClearExtensionData(const GURL& extension_url) { |
| 911 scoped_refptr<ExtensionDataDeleter> deleter( | 911 scoped_refptr<ExtensionDataDeleter> deleter( |
| 912 new ExtensionDataDeleter(profile_, extension_url)); | 912 new ExtensionDataDeleter(profile_, extension_url)); |
| 913 deleter->StartDeleting(); | 913 deleter->StartDeleting(); |
| 914 } | 914 } |
| 915 | 915 |
| 916 void ExtensionsService::EnableExtension(const std::string& extension_id) { | 916 void ExtensionService::EnableExtension(const std::string& extension_id) { |
| 917 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 917 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 918 | 918 |
| 919 const Extension* extension = | 919 const Extension* extension = |
| 920 GetExtensionByIdInternal(extension_id, false, true); | 920 GetExtensionByIdInternal(extension_id, false, true); |
| 921 if (!extension) | 921 if (!extension) |
| 922 return; | 922 return; |
| 923 | 923 |
| 924 extension_prefs_->SetExtensionState(extension, Extension::ENABLED); | 924 extension_prefs_->SetExtensionState(extension, Extension::ENABLED); |
| 925 | 925 |
| 926 // Move it over to the enabled list. | 926 // Move it over to the enabled list. |
| 927 extensions_.push_back(make_scoped_refptr(extension)); | 927 extensions_.push_back(make_scoped_refptr(extension)); |
| 928 ExtensionList::iterator iter = std::find(disabled_extensions_.begin(), | 928 ExtensionList::iterator iter = std::find(disabled_extensions_.begin(), |
| 929 disabled_extensions_.end(), | 929 disabled_extensions_.end(), |
| 930 extension); | 930 extension); |
| 931 disabled_extensions_.erase(iter); | 931 disabled_extensions_.erase(iter); |
| 932 | 932 |
| 933 // Make sure any browser action contained within it is not hidden. | 933 // Make sure any browser action contained within it is not hidden. |
| 934 extension_prefs_->SetBrowserActionVisibility(extension, true); | 934 extension_prefs_->SetBrowserActionVisibility(extension, true); |
| 935 | 935 |
| 936 ExtensionDOMUI::RegisterChromeURLOverrides(profile_, | 936 ExtensionDOMUI::RegisterChromeURLOverrides(profile_, |
| 937 extension->GetChromeURLOverrides()); | 937 extension->GetChromeURLOverrides()); |
| 938 | 938 |
| 939 NotifyExtensionLoaded(extension); | 939 NotifyExtensionLoaded(extension); |
| 940 UpdateActiveExtensionsInCrashReporter(); | 940 UpdateActiveExtensionsInCrashReporter(); |
| 941 } | 941 } |
| 942 | 942 |
| 943 void ExtensionsService::DisableExtension(const std::string& extension_id) { | 943 void ExtensionService::DisableExtension(const std::string& extension_id) { |
| 944 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 944 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 945 | 945 |
| 946 const Extension* extension = | 946 const Extension* extension = |
| 947 GetExtensionByIdInternal(extension_id, true, false); | 947 GetExtensionByIdInternal(extension_id, true, false); |
| 948 // The extension may have been disabled already. | 948 // The extension may have been disabled already. |
| 949 if (!extension) | 949 if (!extension) |
| 950 return; | 950 return; |
| 951 | 951 |
| 952 extension_prefs_->SetExtensionState(extension, Extension::DISABLED); | 952 extension_prefs_->SetExtensionState(extension, Extension::DISABLED); |
| 953 | 953 |
| 954 // Move it over to the disabled list. | 954 // Move it over to the disabled list. |
| 955 disabled_extensions_.push_back(make_scoped_refptr(extension)); | 955 disabled_extensions_.push_back(make_scoped_refptr(extension)); |
| 956 ExtensionList::iterator iter = std::find(extensions_.begin(), | 956 ExtensionList::iterator iter = std::find(extensions_.begin(), |
| 957 extensions_.end(), | 957 extensions_.end(), |
| 958 extension); | 958 extension); |
| 959 extensions_.erase(iter); | 959 extensions_.erase(iter); |
| 960 | 960 |
| 961 ExtensionDOMUI::UnregisterChromeURLOverrides(profile_, | 961 ExtensionDOMUI::UnregisterChromeURLOverrides(profile_, |
| 962 extension->GetChromeURLOverrides()); | 962 extension->GetChromeURLOverrides()); |
| 963 | 963 |
| 964 NotifyExtensionUnloaded(extension); | 964 NotifyExtensionUnloaded(extension); |
| 965 UpdateActiveExtensionsInCrashReporter(); | 965 UpdateActiveExtensionsInCrashReporter(); |
| 966 } | 966 } |
| 967 | 967 |
| 968 void ExtensionsService::GrantPermissions(const Extension* extension) { | 968 void ExtensionService::GrantPermissions(const Extension* extension) { |
| 969 CHECK(extension); | 969 CHECK(extension); |
| 970 | 970 |
| 971 // We only maintain the granted permissions prefs for INTERNAL extensions. | 971 // We only maintain the granted permissions prefs for INTERNAL extensions. |
| 972 CHECK(extension->location() == Extension::INTERNAL); | 972 CHECK(extension->location() == Extension::INTERNAL); |
| 973 | 973 |
| 974 ExtensionExtent effective_hosts = extension->GetEffectiveHostPermissions(); | 974 ExtensionExtent effective_hosts = extension->GetEffectiveHostPermissions(); |
| 975 extension_prefs_->AddGrantedPermissions(extension->id(), | 975 extension_prefs_->AddGrantedPermissions(extension->id(), |
| 976 extension->HasFullPermissions(), | 976 extension->HasFullPermissions(), |
| 977 extension->api_permissions(), | 977 extension->api_permissions(), |
| 978 effective_hosts); | 978 effective_hosts); |
| 979 } | 979 } |
| 980 | 980 |
| 981 void ExtensionsService::GrantPermissionsAndEnableExtension( | 981 void ExtensionService::GrantPermissionsAndEnableExtension( |
| 982 const Extension* extension) { | 982 const Extension* extension) { |
| 983 CHECK(extension); | 983 CHECK(extension); |
| 984 GrantPermissions(extension); | 984 GrantPermissions(extension); |
| 985 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); | 985 extension_prefs_->SetDidExtensionEscalatePermissions(extension, false); |
| 986 EnableExtension(extension->id()); | 986 EnableExtension(extension->id()); |
| 987 } | 987 } |
| 988 | 988 |
| 989 void ExtensionsService::LoadExtension(const FilePath& extension_path) { | 989 void ExtensionService::LoadExtension(const FilePath& extension_path) { |
| 990 BrowserThread::PostTask( | 990 BrowserThread::PostTask( |
| 991 BrowserThread::FILE, FROM_HERE, | 991 BrowserThread::FILE, FROM_HERE, |
| 992 NewRunnableMethod( | 992 NewRunnableMethod( |
| 993 backend_.get(), | 993 backend_.get(), |
| 994 &ExtensionsServiceBackend::LoadSingleExtension, | 994 &ExtensionServiceBackend::LoadSingleExtension, |
| 995 extension_path, scoped_refptr<ExtensionsService>(this))); | 995 extension_path, scoped_refptr<ExtensionService>(this))); |
| 996 } | 996 } |
| 997 | 997 |
| 998 void ExtensionsService::LoadComponentExtensions() { | 998 void ExtensionService::LoadComponentExtensions() { |
| 999 for (RegisteredComponentExtensions::iterator it = | 999 for (RegisteredComponentExtensions::iterator it = |
| 1000 component_extension_manifests_.begin(); | 1000 component_extension_manifests_.begin(); |
| 1001 it != component_extension_manifests_.end(); ++it) { | 1001 it != component_extension_manifests_.end(); ++it) { |
| 1002 JSONStringValueSerializer serializer(it->manifest); | 1002 JSONStringValueSerializer serializer(it->manifest); |
| 1003 scoped_ptr<Value> manifest(serializer.Deserialize(NULL, NULL)); | 1003 scoped_ptr<Value> manifest(serializer.Deserialize(NULL, NULL)); |
| 1004 if (!manifest.get()) { | 1004 if (!manifest.get()) { |
| 1005 DLOG(ERROR) << "Failed to parse manifest for extension"; | 1005 DLOG(ERROR) << "Failed to parse manifest for extension"; |
| 1006 continue; | 1006 continue; |
| 1007 } | 1007 } |
| 1008 | 1008 |
| 1009 std::string error; | 1009 std::string error; |
| 1010 scoped_refptr<const Extension> extension(Extension::Create( | 1010 scoped_refptr<const Extension> extension(Extension::Create( |
| 1011 it->root_directory, | 1011 it->root_directory, |
| 1012 Extension::COMPONENT, | 1012 Extension::COMPONENT, |
| 1013 *static_cast<DictionaryValue*>(manifest.get()), | 1013 *static_cast<DictionaryValue*>(manifest.get()), |
| 1014 true, // require key | 1014 true, // require key |
| 1015 &error)); | 1015 &error)); |
| 1016 if (!extension.get()) { | 1016 if (!extension.get()) { |
| 1017 NOTREACHED() << error; | 1017 NOTREACHED() << error; |
| 1018 return; | 1018 return; |
| 1019 } | 1019 } |
| 1020 | 1020 |
| 1021 OnExtensionLoaded(extension); | 1021 OnExtensionLoaded(extension); |
| 1022 } | 1022 } |
| 1023 } | 1023 } |
| 1024 | 1024 |
| 1025 void ExtensionsService::LoadAllExtensions() { | 1025 void ExtensionService::LoadAllExtensions() { |
| 1026 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1026 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1027 | 1027 |
| 1028 base::TimeTicks start_time = base::TimeTicks::Now(); | 1028 base::TimeTicks start_time = base::TimeTicks::Now(); |
| 1029 | 1029 |
| 1030 // Load any component extensions. | 1030 // Load any component extensions. |
| 1031 LoadComponentExtensions(); | 1031 LoadComponentExtensions(); |
| 1032 | 1032 |
| 1033 // Load the previously installed extensions. | 1033 // Load the previously installed extensions. |
| 1034 scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info( | 1034 scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info( |
| 1035 extension_prefs_->GetInstalledExtensionsInfo()); | 1035 extension_prefs_->GetInstalledExtensionsInfo()); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1156 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPackagedApp", packaged_app_count); | 1156 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPackagedApp", packaged_app_count); |
| 1157 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExtension", extension_count); | 1157 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExtension", extension_count); |
| 1158 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadUserScript", user_script_count); | 1158 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadUserScript", user_script_count); |
| 1159 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadTheme", theme_count); | 1159 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadTheme", theme_count); |
| 1160 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExternal", external_count); | 1160 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExternal", external_count); |
| 1161 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPageAction", page_action_count); | 1161 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPageAction", page_action_count); |
| 1162 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadBrowserAction", | 1162 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadBrowserAction", |
| 1163 browser_action_count); | 1163 browser_action_count); |
| 1164 } | 1164 } |
| 1165 | 1165 |
| 1166 void ExtensionsService::LoadInstalledExtension(const ExtensionInfo& info, | 1166 void ExtensionService::LoadInstalledExtension(const ExtensionInfo& info, |
| 1167 bool write_to_prefs) { | 1167 bool write_to_prefs) { |
| 1168 std::string error; | 1168 std::string error; |
| 1169 scoped_refptr<const Extension> extension(NULL); | 1169 scoped_refptr<const Extension> extension(NULL); |
| 1170 if (!extension_prefs_->IsExtensionAllowedByPolicy(info.extension_id)) { | 1170 if (!extension_prefs_->IsExtensionAllowedByPolicy(info.extension_id)) { |
| 1171 error = errors::kDisabledByPolicy; | 1171 error = errors::kDisabledByPolicy; |
| 1172 } else if (info.extension_manifest.get()) { | 1172 } else if (info.extension_manifest.get()) { |
| 1173 bool require_key = info.extension_location != Extension::LOAD; | 1173 bool require_key = info.extension_location != Extension::LOAD; |
| 1174 extension = Extension::Create( | 1174 extension = Extension::Create( |
| 1175 info.extension_path, info.extension_location, *info.extension_manifest, | 1175 info.extension_path, info.extension_location, *info.extension_manifest, |
| 1176 require_key, &error); | 1176 require_key, &error); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1189 if (write_to_prefs) | 1189 if (write_to_prefs) |
| 1190 extension_prefs_->UpdateManifest(extension); | 1190 extension_prefs_->UpdateManifest(extension); |
| 1191 | 1191 |
| 1192 OnExtensionLoaded(extension); | 1192 OnExtensionLoaded(extension); |
| 1193 | 1193 |
| 1194 if (Extension::IsExternalLocation(info.extension_location)) { | 1194 if (Extension::IsExternalLocation(info.extension_location)) { |
| 1195 BrowserThread::PostTask( | 1195 BrowserThread::PostTask( |
| 1196 BrowserThread::FILE, FROM_HERE, | 1196 BrowserThread::FILE, FROM_HERE, |
| 1197 NewRunnableMethod( | 1197 NewRunnableMethod( |
| 1198 backend_.get(), | 1198 backend_.get(), |
| 1199 &ExtensionsServiceBackend::CheckExternalUninstall, | 1199 &ExtensionServiceBackend::CheckExternalUninstall, |
| 1200 scoped_refptr<ExtensionsService>(this), | 1200 scoped_refptr<ExtensionService>(this), |
| 1201 info.extension_id)); | 1201 info.extension_id)); |
| 1202 } | 1202 } |
| 1203 } | 1203 } |
| 1204 | 1204 |
| 1205 void ExtensionsService::NotifyExtensionLoaded(const Extension* extension) { | 1205 void ExtensionService::NotifyExtensionLoaded(const Extension* extension) { |
| 1206 // The ChromeURLRequestContexts need to be first to know that the extension | 1206 // The ChromeURLRequestContexts need to be first to know that the extension |
| 1207 // was loaded, otherwise a race can arise where a renderer that is created | 1207 // was loaded, otherwise a race can arise where a renderer that is created |
| 1208 // for the extension may try to load an extension URL with an extension id | 1208 // for the extension may try to load an extension URL with an extension id |
| 1209 // that the request context doesn't yet know about. The profile is responsible | 1209 // that the request context doesn't yet know about. The profile is responsible |
| 1210 // for ensuring its URLRequestContexts appropriately discover the loaded | 1210 // for ensuring its URLRequestContexts appropriately discover the loaded |
| 1211 // extension. | 1211 // extension. |
| 1212 if (profile_) { | 1212 if (profile_) { |
| 1213 profile_->RegisterExtensionWithRequestContexts(extension); | 1213 profile_->RegisterExtensionWithRequestContexts(extension); |
| 1214 | 1214 |
| 1215 // Check if this permission requires unlimited storage quota | 1215 // Check if this permission requires unlimited storage quota |
| 1216 if (extension->HasApiPermission(Extension::kUnlimitedStoragePermission)) | 1216 if (extension->HasApiPermission(Extension::kUnlimitedStoragePermission)) |
| 1217 GrantUnlimitedStorage(extension); | 1217 GrantUnlimitedStorage(extension); |
| 1218 | 1218 |
| 1219 // If the extension is an app, protect its local storage from | 1219 // If the extension is an app, protect its local storage from |
| 1220 // "Clear browsing data." | 1220 // "Clear browsing data." |
| 1221 if (extension->is_app()) | 1221 if (extension->is_app()) |
| 1222 GrantProtectedStorage(extension); | 1222 GrantProtectedStorage(extension); |
| 1223 } | 1223 } |
| 1224 | 1224 |
| 1225 NotificationService::current()->Notify( | 1225 NotificationService::current()->Notify( |
| 1226 NotificationType::EXTENSION_LOADED, | 1226 NotificationType::EXTENSION_LOADED, |
| 1227 Source<Profile>(profile_), | 1227 Source<Profile>(profile_), |
| 1228 Details<const Extension>(extension)); | 1228 Details<const Extension>(extension)); |
| 1229 } | 1229 } |
| 1230 | 1230 |
| 1231 void ExtensionsService::NotifyExtensionUnloaded(const Extension* extension) { | 1231 void ExtensionService::NotifyExtensionUnloaded(const Extension* extension) { |
| 1232 NotificationService::current()->Notify( | 1232 NotificationService::current()->Notify( |
| 1233 NotificationType::EXTENSION_UNLOADED, | 1233 NotificationType::EXTENSION_UNLOADED, |
| 1234 Source<Profile>(profile_), | 1234 Source<Profile>(profile_), |
| 1235 Details<const Extension>(extension)); | 1235 Details<const Extension>(extension)); |
| 1236 | 1236 |
| 1237 if (profile_) { | 1237 if (profile_) { |
| 1238 profile_->UnregisterExtensionWithRequestContexts(extension); | 1238 profile_->UnregisterExtensionWithRequestContexts(extension); |
| 1239 | 1239 |
| 1240 // Check if this permission required unlimited storage quota, reset its | 1240 // Check if this permission required unlimited storage quota, reset its |
| 1241 // in-memory quota. | 1241 // in-memory quota. |
| 1242 if (extension->HasApiPermission(Extension::kUnlimitedStoragePermission)) | 1242 if (extension->HasApiPermission(Extension::kUnlimitedStoragePermission)) |
| 1243 RevokeUnlimitedStorage(extension); | 1243 RevokeUnlimitedStorage(extension); |
| 1244 | 1244 |
| 1245 // If this is an app, then stop protecting its storage so it can be deleted. | 1245 // If this is an app, then stop protecting its storage so it can be deleted. |
| 1246 if (extension->is_app()) | 1246 if (extension->is_app()) |
| 1247 RevokeProtectedStorage(extension); | 1247 RevokeProtectedStorage(extension); |
| 1248 } | 1248 } |
| 1249 } | 1249 } |
| 1250 | 1250 |
| 1251 void ExtensionsService::GrantProtectedStorage(const Extension* extension) { | 1251 void ExtensionService::GrantProtectedStorage(const Extension* extension) { |
| 1252 DCHECK(extension->is_app()) << "Only Apps are allowed protected storage."; | 1252 DCHECK(extension->is_app()) << "Only Apps are allowed protected storage."; |
| 1253 std::vector<GURL> origins; | 1253 std::vector<GURL> origins; |
| 1254 GetExplicitOriginsInExtent(extension, &origins); | 1254 GetExplicitOriginsInExtent(extension, &origins); |
| 1255 for (size_t i = 0; i < origins.size(); ++i) | 1255 for (size_t i = 0; i < origins.size(); ++i) |
| 1256 ++protected_storage_map_[origins[i]]; | 1256 ++protected_storage_map_[origins[i]]; |
| 1257 } | 1257 } |
| 1258 | 1258 |
| 1259 void ExtensionsService::RevokeProtectedStorage(const Extension* extension) { | 1259 void ExtensionService::RevokeProtectedStorage(const Extension* extension) { |
| 1260 DCHECK(extension->is_app()) << "Attempting to revoke protected storage from " | 1260 DCHECK(extension->is_app()) << "Attempting to revoke protected storage from " |
| 1261 << " a non-app extension."; | 1261 << " a non-app extension."; |
| 1262 std::vector<GURL> origins; | 1262 std::vector<GURL> origins; |
| 1263 GetExplicitOriginsInExtent(extension, &origins); | 1263 GetExplicitOriginsInExtent(extension, &origins); |
| 1264 for (size_t i = 0; i < origins.size(); ++i) { | 1264 for (size_t i = 0; i < origins.size(); ++i) { |
| 1265 const GURL& origin = origins[i]; | 1265 const GURL& origin = origins[i]; |
| 1266 DCHECK(protected_storage_map_[origin] > 0); | 1266 DCHECK(protected_storage_map_[origin] > 0); |
| 1267 if (--protected_storage_map_[origin] <= 0) | 1267 if (--protected_storage_map_[origin] <= 0) |
| 1268 protected_storage_map_.erase(origin); | 1268 protected_storage_map_.erase(origin); |
| 1269 } | 1269 } |
| 1270 } | 1270 } |
| 1271 | 1271 |
| 1272 void ExtensionsService::GrantUnlimitedStorage(const Extension* extension) { | 1272 void ExtensionService::GrantUnlimitedStorage(const Extension* extension) { |
| 1273 DCHECK(extension->HasApiPermission(Extension::kUnlimitedStoragePermission)); | 1273 DCHECK(extension->HasApiPermission(Extension::kUnlimitedStoragePermission)); |
| 1274 std::vector<GURL> origins; | 1274 std::vector<GURL> origins; |
| 1275 GetExplicitOriginsInExtent(extension, &origins); | 1275 GetExplicitOriginsInExtent(extension, &origins); |
| 1276 origins.push_back(extension->url()); | 1276 origins.push_back(extension->url()); |
| 1277 | 1277 |
| 1278 for (size_t i = 0; i < origins.size(); ++i) { | 1278 for (size_t i = 0; i < origins.size(); ++i) { |
| 1279 const GURL& origin = origins[i]; | 1279 const GURL& origin = origins[i]; |
| 1280 if (++unlimited_storage_map_[origin] == 1) { | 1280 if (++unlimited_storage_map_[origin] == 1) { |
| 1281 string16 origin_identifier = | 1281 string16 origin_identifier = |
| 1282 webkit_database::DatabaseUtil::GetOriginIdentifier(origin); | 1282 webkit_database::DatabaseUtil::GetOriginIdentifier(origin); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1297 BrowserThread::PostTask( | 1297 BrowserThread::PostTask( |
| 1298 BrowserThread::IO, FROM_HERE, | 1298 BrowserThread::IO, FROM_HERE, |
| 1299 NewRunnableMethod( | 1299 NewRunnableMethod( |
| 1300 profile_->GetFileSystemContext(), | 1300 profile_->GetFileSystemContext(), |
| 1301 &fileapi::SandboxedFileSystemContext::SetOriginQuotaUnlimited, | 1301 &fileapi::SandboxedFileSystemContext::SetOriginQuotaUnlimited, |
| 1302 origin)); | 1302 origin)); |
| 1303 } | 1303 } |
| 1304 } | 1304 } |
| 1305 } | 1305 } |
| 1306 | 1306 |
| 1307 void ExtensionsService::RevokeUnlimitedStorage(const Extension* extension) { | 1307 void ExtensionService::RevokeUnlimitedStorage(const Extension* extension) { |
| 1308 DCHECK(extension->HasApiPermission(Extension::kUnlimitedStoragePermission)); | 1308 DCHECK(extension->HasApiPermission(Extension::kUnlimitedStoragePermission)); |
| 1309 std::vector<GURL> origins; | 1309 std::vector<GURL> origins; |
| 1310 GetExplicitOriginsInExtent(extension, &origins); | 1310 GetExplicitOriginsInExtent(extension, &origins); |
| 1311 origins.push_back(extension->url()); | 1311 origins.push_back(extension->url()); |
| 1312 | 1312 |
| 1313 for (size_t i = 0; i < origins.size(); ++i) { | 1313 for (size_t i = 0; i < origins.size(); ++i) { |
| 1314 const GURL& origin = origins[i]; | 1314 const GURL& origin = origins[i]; |
| 1315 DCHECK(unlimited_storage_map_[origin] > 0); | 1315 DCHECK(unlimited_storage_map_[origin] > 0); |
| 1316 if (--unlimited_storage_map_[origin] == 0) { | 1316 if (--unlimited_storage_map_[origin] == 0) { |
| 1317 unlimited_storage_map_.erase(origin); | 1317 unlimited_storage_map_.erase(origin); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1332 BrowserThread::PostTask( | 1332 BrowserThread::PostTask( |
| 1333 BrowserThread::IO, FROM_HERE, | 1333 BrowserThread::IO, FROM_HERE, |
| 1334 NewRunnableMethod( | 1334 NewRunnableMethod( |
| 1335 profile_->GetFileSystemContext(), | 1335 profile_->GetFileSystemContext(), |
| 1336 &fileapi::SandboxedFileSystemContext::ResetOriginQuotaUnlimited, | 1336 &fileapi::SandboxedFileSystemContext::ResetOriginQuotaUnlimited, |
| 1337 origin)); | 1337 origin)); |
| 1338 } | 1338 } |
| 1339 } | 1339 } |
| 1340 } | 1340 } |
| 1341 | 1341 |
| 1342 void ExtensionsService::UpdateExtensionBlacklist( | 1342 void ExtensionService::UpdateExtensionBlacklist( |
| 1343 const std::vector<std::string>& blacklist) { | 1343 const std::vector<std::string>& blacklist) { |
| 1344 // Use this set to indicate if an extension in the blacklist has been used. | 1344 // Use this set to indicate if an extension in the blacklist has been used. |
| 1345 std::set<std::string> blacklist_set; | 1345 std::set<std::string> blacklist_set; |
| 1346 for (unsigned int i = 0; i < blacklist.size(); ++i) { | 1346 for (unsigned int i = 0; i < blacklist.size(); ++i) { |
| 1347 if (Extension::IdIsValid(blacklist[i])) { | 1347 if (Extension::IdIsValid(blacklist[i])) { |
| 1348 blacklist_set.insert(blacklist[i]); | 1348 blacklist_set.insert(blacklist[i]); |
| 1349 } | 1349 } |
| 1350 } | 1350 } |
| 1351 extension_prefs_->UpdateBlacklist(blacklist_set); | 1351 extension_prefs_->UpdateBlacklist(blacklist_set); |
| 1352 std::vector<std::string> to_be_removed; | 1352 std::vector<std::string> to_be_removed; |
| 1353 // Loop current extensions, unload installed extensions. | 1353 // Loop current extensions, unload installed extensions. |
| 1354 for (ExtensionList::const_iterator iter = extensions_.begin(); | 1354 for (ExtensionList::const_iterator iter = extensions_.begin(); |
| 1355 iter != extensions_.end(); ++iter) { | 1355 iter != extensions_.end(); ++iter) { |
| 1356 const Extension* extension = (*iter); | 1356 const Extension* extension = (*iter); |
| 1357 if (blacklist_set.find(extension->id()) != blacklist_set.end()) { | 1357 if (blacklist_set.find(extension->id()) != blacklist_set.end()) { |
| 1358 to_be_removed.push_back(extension->id()); | 1358 to_be_removed.push_back(extension->id()); |
| 1359 } | 1359 } |
| 1360 } | 1360 } |
| 1361 | 1361 |
| 1362 // UnloadExtension will change the extensions_ list. So, we should | 1362 // UnloadExtension will change the extensions_ list. So, we should |
| 1363 // call it outside the iterator loop. | 1363 // call it outside the iterator loop. |
| 1364 for (unsigned int i = 0; i < to_be_removed.size(); ++i) { | 1364 for (unsigned int i = 0; i < to_be_removed.size(); ++i) { |
| 1365 UnloadExtension(to_be_removed[i]); | 1365 UnloadExtension(to_be_removed[i]); |
| 1366 } | 1366 } |
| 1367 } | 1367 } |
| 1368 | 1368 |
| 1369 void ExtensionsService::DestroyingProfile() { | 1369 void ExtensionService::DestroyingProfile() { |
| 1370 pref_change_registrar_.RemoveAll(); | 1370 pref_change_registrar_.RemoveAll(); |
| 1371 profile_ = NULL; | 1371 profile_ = NULL; |
| 1372 toolbar_model_.DestroyingProfile(); | 1372 toolbar_model_.DestroyingProfile(); |
| 1373 } | 1373 } |
| 1374 | 1374 |
| 1375 ExtensionPrefs* ExtensionsService::extension_prefs() { | 1375 ExtensionPrefs* ExtensionService::extension_prefs() { |
| 1376 return extension_prefs_; | 1376 return extension_prefs_; |
| 1377 } | 1377 } |
| 1378 | 1378 |
| 1379 void ExtensionsService::CheckAdminBlacklist() { | 1379 void ExtensionService::CheckAdminBlacklist() { |
| 1380 std::vector<std::string> to_be_removed; | 1380 std::vector<std::string> to_be_removed; |
| 1381 // Loop through extensions list, unload installed extensions. | 1381 // Loop through extensions list, unload installed extensions. |
| 1382 for (ExtensionList::const_iterator iter = extensions_.begin(); | 1382 for (ExtensionList::const_iterator iter = extensions_.begin(); |
| 1383 iter != extensions_.end(); ++iter) { | 1383 iter != extensions_.end(); ++iter) { |
| 1384 const Extension* extension = (*iter); | 1384 const Extension* extension = (*iter); |
| 1385 if (!extension_prefs_->IsExtensionAllowedByPolicy(extension->id())) | 1385 if (!extension_prefs_->IsExtensionAllowedByPolicy(extension->id())) |
| 1386 to_be_removed.push_back(extension->id()); | 1386 to_be_removed.push_back(extension->id()); |
| 1387 } | 1387 } |
| 1388 | 1388 |
| 1389 // UnloadExtension will change the extensions_ list. So, we should | 1389 // UnloadExtension will change the extensions_ list. So, we should |
| 1390 // call it outside the iterator loop. | 1390 // call it outside the iterator loop. |
| 1391 for (unsigned int i = 0; i < to_be_removed.size(); ++i) | 1391 for (unsigned int i = 0; i < to_be_removed.size(); ++i) |
| 1392 UnloadExtension(to_be_removed[i]); | 1392 UnloadExtension(to_be_removed[i]); |
| 1393 } | 1393 } |
| 1394 | 1394 |
| 1395 bool ExtensionsService::IsIncognitoEnabled(const Extension* extension) { | 1395 bool ExtensionService::IsIncognitoEnabled(const Extension* extension) { |
| 1396 // If this is a component extension we always allow it to work in incognito | 1396 // If this is a component extension we always allow it to work in incognito |
| 1397 // mode. | 1397 // mode. |
| 1398 if (extension->location() == Extension::COMPONENT) | 1398 if (extension->location() == Extension::COMPONENT) |
| 1399 return true; | 1399 return true; |
| 1400 | 1400 |
| 1401 // Check the prefs. | 1401 // Check the prefs. |
| 1402 return extension_prefs_->IsIncognitoEnabled(extension->id()); | 1402 return extension_prefs_->IsIncognitoEnabled(extension->id()); |
| 1403 } | 1403 } |
| 1404 | 1404 |
| 1405 void ExtensionsService::SetIsIncognitoEnabled(const Extension* extension, | 1405 void ExtensionService::SetIsIncognitoEnabled(const Extension* extension, |
| 1406 bool enabled) { | 1406 bool enabled) { |
| 1407 extension_prefs_->SetIsIncognitoEnabled(extension->id(), enabled); | 1407 extension_prefs_->SetIsIncognitoEnabled(extension->id(), enabled); |
| 1408 | 1408 |
| 1409 // Broadcast unloaded and loaded events to update browser state. Only bother | 1409 // Broadcast unloaded and loaded events to update browser state. Only bother |
| 1410 // if the extension is actually enabled, since there is no UI otherwise. | 1410 // if the extension is actually enabled, since there is no UI otherwise. |
| 1411 bool is_enabled = std::find(extensions_.begin(), extensions_.end(), | 1411 bool is_enabled = std::find(extensions_.begin(), extensions_.end(), |
| 1412 extension) != extensions_.end(); | 1412 extension) != extensions_.end(); |
| 1413 if (is_enabled) { | 1413 if (is_enabled) { |
| 1414 NotifyExtensionUnloaded(extension); | 1414 NotifyExtensionUnloaded(extension); |
| 1415 NotifyExtensionLoaded(extension); | 1415 NotifyExtensionLoaded(extension); |
| 1416 } | 1416 } |
| 1417 } | 1417 } |
| 1418 | 1418 |
| 1419 bool ExtensionsService::CanCrossIncognito(const Extension* extension) { | 1419 bool ExtensionService::CanCrossIncognito(const Extension* extension) { |
| 1420 // We allow the extension to see events and data from another profile iff it | 1420 // We allow the extension to see events and data from another profile iff it |
| 1421 // uses "spanning" behavior and it has incognito access. "split" mode | 1421 // uses "spanning" behavior and it has incognito access. "split" mode |
| 1422 // extensions only see events for a matching profile. | 1422 // extensions only see events for a matching profile. |
| 1423 return IsIncognitoEnabled(extension) && !extension->incognito_split_mode(); | 1423 return IsIncognitoEnabled(extension) && !extension->incognito_split_mode(); |
| 1424 } | 1424 } |
| 1425 | 1425 |
| 1426 bool ExtensionsService::AllowFileAccess(const Extension* extension) { | 1426 bool ExtensionService::AllowFileAccess(const Extension* extension) { |
| 1427 return (CommandLine::ForCurrentProcess()->HasSwitch( | 1427 return (CommandLine::ForCurrentProcess()->HasSwitch( |
| 1428 switches::kDisableExtensionsFileAccessCheck) || | 1428 switches::kDisableExtensionsFileAccessCheck) || |
| 1429 extension_prefs_->AllowFileAccess(extension->id())); | 1429 extension_prefs_->AllowFileAccess(extension->id())); |
| 1430 } | 1430 } |
| 1431 | 1431 |
| 1432 void ExtensionsService::SetAllowFileAccess(const Extension* extension, | 1432 void ExtensionService::SetAllowFileAccess(const Extension* extension, |
| 1433 bool allow) { | 1433 bool allow) { |
| 1434 extension_prefs_->SetAllowFileAccess(extension->id(), allow); | 1434 extension_prefs_->SetAllowFileAccess(extension->id(), allow); |
| 1435 NotificationService::current()->Notify( | 1435 NotificationService::current()->Notify( |
| 1436 NotificationType::EXTENSION_USER_SCRIPTS_UPDATED, | 1436 NotificationType::EXTENSION_USER_SCRIPTS_UPDATED, |
| 1437 Source<Profile>(profile_), | 1437 Source<Profile>(profile_), |
| 1438 Details<const Extension>(extension)); | 1438 Details<const Extension>(extension)); |
| 1439 } | 1439 } |
| 1440 | 1440 |
| 1441 bool ExtensionsService::GetBrowserActionVisibility(const Extension* extension) { | 1441 bool ExtensionService::GetBrowserActionVisibility(const Extension* extension) { |
| 1442 return extension_prefs_->GetBrowserActionVisibility(extension); | 1442 return extension_prefs_->GetBrowserActionVisibility(extension); |
| 1443 } | 1443 } |
| 1444 | 1444 |
| 1445 void ExtensionsService::SetBrowserActionVisibility(const Extension* extension, | 1445 void ExtensionService::SetBrowserActionVisibility(const Extension* extension, |
| 1446 bool visible) { | 1446 bool visible) { |
| 1447 extension_prefs_->SetBrowserActionVisibility(extension, visible); | 1447 extension_prefs_->SetBrowserActionVisibility(extension, visible); |
| 1448 } | 1448 } |
| 1449 | 1449 |
| 1450 void ExtensionsService::CheckForExternalUpdates() { | 1450 void ExtensionService::CheckForExternalUpdates() { |
| 1451 BrowserThread::PostTask( | 1451 BrowserThread::PostTask( |
| 1452 BrowserThread::FILE, FROM_HERE, | 1452 BrowserThread::FILE, FROM_HERE, |
| 1453 NewRunnableMethod( | 1453 NewRunnableMethod( |
| 1454 backend_.get(), &ExtensionsServiceBackend::CheckForExternalUpdates, | 1454 backend_.get(), &ExtensionServiceBackend::CheckForExternalUpdates, |
| 1455 scoped_refptr<ExtensionsService>(this))); | 1455 scoped_refptr<ExtensionService>(this))); |
| 1456 } | 1456 } |
| 1457 | 1457 |
| 1458 void ExtensionsService::UpdateExternalPolicyExtensionProvider() { | 1458 void ExtensionService::UpdateExternalPolicyExtensionProvider() { |
| 1459 const ListValue* list_pref = | 1459 const ListValue* list_pref = |
| 1460 profile_->GetPrefs()->GetList(prefs::kExtensionInstallForceList); | 1460 profile_->GetPrefs()->GetList(prefs::kExtensionInstallForceList); |
| 1461 ListValue* list_copy = NULL; | 1461 ListValue* list_copy = NULL; |
| 1462 if (list_pref) | 1462 if (list_pref) |
| 1463 list_copy = static_cast<ListValue*>(list_pref->DeepCopy()); | 1463 list_copy = static_cast<ListValue*>(list_pref->DeepCopy()); |
| 1464 BrowserThread::PostTask( | 1464 BrowserThread::PostTask( |
| 1465 BrowserThread::FILE, FROM_HERE, | 1465 BrowserThread::FILE, FROM_HERE, |
| 1466 NewRunnableMethod( | 1466 NewRunnableMethod( |
| 1467 backend_.get(), | 1467 backend_.get(), |
| 1468 &ExtensionsServiceBackend::UpdateExternalPolicyExtensionProvider, | 1468 &ExtensionServiceBackend::UpdateExternalPolicyExtensionProvider, |
| 1469 scoped_refptr<RefCountedList>( | 1469 scoped_refptr<RefCountedList>( |
| 1470 new RefCountedList(list_copy)))); | 1470 new RefCountedList(list_copy)))); |
| 1471 } | 1471 } |
| 1472 | 1472 |
| 1473 void ExtensionsService::UnloadExtension(const std::string& extension_id) { | 1473 void ExtensionService::UnloadExtension(const std::string& extension_id) { |
| 1474 // Make sure the extension gets deleted after we return from this function. | 1474 // Make sure the extension gets deleted after we return from this function. |
| 1475 scoped_refptr<const Extension> extension( | 1475 scoped_refptr<const Extension> extension( |
| 1476 GetExtensionByIdInternal(extension_id, true, true)); | 1476 GetExtensionByIdInternal(extension_id, true, true)); |
| 1477 | 1477 |
| 1478 // This method can be called via PostTask, so the extension may have been | 1478 // This method can be called via PostTask, so the extension may have been |
| 1479 // unloaded by the time this runs. | 1479 // unloaded by the time this runs. |
| 1480 if (!extension) | 1480 if (!extension) |
| 1481 return; | 1481 return; |
| 1482 | 1482 |
| 1483 // Keep information about the extension so that we can reload it later | 1483 // Keep information about the extension so that we can reload it later |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1507 | 1507 |
| 1508 iter = std::find(extensions_.begin(), extensions_.end(), extension.get()); | 1508 iter = std::find(extensions_.begin(), extensions_.end(), extension.get()); |
| 1509 | 1509 |
| 1510 // Remove the extension from our list. | 1510 // Remove the extension from our list. |
| 1511 extensions_.erase(iter); | 1511 extensions_.erase(iter); |
| 1512 | 1512 |
| 1513 NotifyExtensionUnloaded(extension.get()); | 1513 NotifyExtensionUnloaded(extension.get()); |
| 1514 UpdateActiveExtensionsInCrashReporter(); | 1514 UpdateActiveExtensionsInCrashReporter(); |
| 1515 } | 1515 } |
| 1516 | 1516 |
| 1517 void ExtensionsService::UnloadAllExtensions() { | 1517 void ExtensionService::UnloadAllExtensions() { |
| 1518 extensions_.clear(); | 1518 extensions_.clear(); |
| 1519 disabled_extensions_.clear(); | 1519 disabled_extensions_.clear(); |
| 1520 extension_runtime_data_.clear(); | 1520 extension_runtime_data_.clear(); |
| 1521 | 1521 |
| 1522 // TODO(erikkay) should there be a notification for this? We can't use | 1522 // TODO(erikkay) should there be a notification for this? We can't use |
| 1523 // EXTENSION_UNLOADED since that implies that the extension has been disabled | 1523 // EXTENSION_UNLOADED since that implies that the extension has been disabled |
| 1524 // or uninstalled, and UnloadAll is just part of shutdown. | 1524 // or uninstalled, and UnloadAll is just part of shutdown. |
| 1525 } | 1525 } |
| 1526 | 1526 |
| 1527 void ExtensionsService::ReloadExtensions() { | 1527 void ExtensionService::ReloadExtensions() { |
| 1528 UnloadAllExtensions(); | 1528 UnloadAllExtensions(); |
| 1529 LoadAllExtensions(); | 1529 LoadAllExtensions(); |
| 1530 } | 1530 } |
| 1531 | 1531 |
| 1532 void ExtensionsService::GarbageCollectExtensions() { | 1532 void ExtensionService::GarbageCollectExtensions() { |
| 1533 if (extension_prefs_->pref_service()->ReadOnly()) | 1533 if (extension_prefs_->pref_service()->ReadOnly()) |
| 1534 return; | 1534 return; |
| 1535 | 1535 |
| 1536 scoped_ptr<ExtensionPrefs::ExtensionsInfo> info( | 1536 scoped_ptr<ExtensionPrefs::ExtensionsInfo> info( |
| 1537 extension_prefs_->GetInstalledExtensionsInfo()); | 1537 extension_prefs_->GetInstalledExtensionsInfo()); |
| 1538 | 1538 |
| 1539 std::map<std::string, FilePath> extension_paths; | 1539 std::map<std::string, FilePath> extension_paths; |
| 1540 for (size_t i = 0; i < info->size(); ++i) | 1540 for (size_t i = 0; i < info->size(); ++i) |
| 1541 extension_paths[info->at(i)->extension_id] = info->at(i)->extension_path; | 1541 extension_paths[info->at(i)->extension_id] = info->at(i)->extension_path; |
| 1542 | 1542 |
| 1543 BrowserThread::PostTask( | 1543 BrowserThread::PostTask( |
| 1544 BrowserThread::FILE, FROM_HERE, | 1544 BrowserThread::FILE, FROM_HERE, |
| 1545 NewRunnableFunction( | 1545 NewRunnableFunction( |
| 1546 &extension_file_util::GarbageCollectExtensions, install_directory_, | 1546 &extension_file_util::GarbageCollectExtensions, install_directory_, |
| 1547 extension_paths)); | 1547 extension_paths)); |
| 1548 | 1548 |
| 1549 // Also garbage-collect themes. We check |profile_| to be | 1549 // Also garbage-collect themes. We check |profile_| to be |
| 1550 // defensive; in the future, we may call GarbageCollectExtensions() | 1550 // defensive; in the future, we may call GarbageCollectExtensions() |
| 1551 // from somewhere other than Init() (e.g., in a timer). | 1551 // from somewhere other than Init() (e.g., in a timer). |
| 1552 if (profile_) { | 1552 if (profile_) { |
| 1553 profile_->GetThemeProvider()->RemoveUnusedThemes(); | 1553 profile_->GetThemeProvider()->RemoveUnusedThemes(); |
| 1554 } | 1554 } |
| 1555 } | 1555 } |
| 1556 | 1556 |
| 1557 void ExtensionsService::OnLoadedInstalledExtensions() { | 1557 void ExtensionService::OnLoadedInstalledExtensions() { |
| 1558 if (updater_.get()) { | 1558 if (updater_.get()) { |
| 1559 updater_->Start(); | 1559 updater_->Start(); |
| 1560 } | 1560 } |
| 1561 | 1561 |
| 1562 ready_ = true; | 1562 ready_ = true; |
| 1563 NotificationService::current()->Notify( | 1563 NotificationService::current()->Notify( |
| 1564 NotificationType::EXTENSIONS_READY, | 1564 NotificationType::EXTENSIONS_READY, |
| 1565 Source<Profile>(profile_), | 1565 Source<Profile>(profile_), |
| 1566 NotificationService::NoDetails()); | 1566 NotificationService::NoDetails()); |
| 1567 } | 1567 } |
| 1568 | 1568 |
| 1569 void ExtensionsService::OnExtensionLoaded(const Extension* extension) { | 1569 void ExtensionService::OnExtensionLoaded(const Extension* extension) { |
| 1570 // Ensure extension is deleted unless we transfer ownership. | 1570 // Ensure extension is deleted unless we transfer ownership. |
| 1571 scoped_refptr<const Extension> scoped_extension(extension); | 1571 scoped_refptr<const Extension> scoped_extension(extension); |
| 1572 | 1572 |
| 1573 // The extension is now loaded, remove its data from unloaded extension map. | 1573 // The extension is now loaded, remove its data from unloaded extension map. |
| 1574 unloaded_extension_paths_.erase(extension->id()); | 1574 unloaded_extension_paths_.erase(extension->id()); |
| 1575 | 1575 |
| 1576 // If the extension was disabled for a reload, then enable it. | 1576 // If the extension was disabled for a reload, then enable it. |
| 1577 if (disabled_extension_paths_.erase(extension->id()) > 0) | 1577 if (disabled_extension_paths_.erase(extension->id()) > 0) |
| 1578 EnableExtension(extension->id()); | 1578 EnableExtension(extension->id()); |
| 1579 | 1579 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1619 profile_->GetTemplateURLModel()->RegisterExtensionKeyword(extension); | 1619 profile_->GetTemplateURLModel()->RegisterExtensionKeyword(extension); |
| 1620 | 1620 |
| 1621 // Load the icon for omnibox-enabled extensions so it will be ready to display | 1621 // Load the icon for omnibox-enabled extensions so it will be ready to display |
| 1622 // in the URL bar. | 1622 // in the URL bar. |
| 1623 if (!extension->omnibox_keyword().empty()) { | 1623 if (!extension->omnibox_keyword().empty()) { |
| 1624 omnibox_popup_icon_manager_.LoadIcon(extension); | 1624 omnibox_popup_icon_manager_.LoadIcon(extension); |
| 1625 omnibox_icon_manager_.LoadIcon(extension); | 1625 omnibox_icon_manager_.LoadIcon(extension); |
| 1626 } | 1626 } |
| 1627 } | 1627 } |
| 1628 | 1628 |
| 1629 void ExtensionsService::DisableIfPrivilegeIncrease(const Extension* extension) { | 1629 void ExtensionService::DisableIfPrivilegeIncrease(const Extension* extension) { |
| 1630 // We keep track of all permissions the user has granted each extension. | 1630 // We keep track of all permissions the user has granted each extension. |
| 1631 // This allows extensions to gracefully support backwards compatibility | 1631 // This allows extensions to gracefully support backwards compatibility |
| 1632 // by including unknown permissions in their manifests. When the user | 1632 // by including unknown permissions in their manifests. When the user |
| 1633 // installs the extension, only the recognized permissions are recorded. | 1633 // installs the extension, only the recognized permissions are recorded. |
| 1634 // When the unknown permissions become recognized (e.g., through browser | 1634 // When the unknown permissions become recognized (e.g., through browser |
| 1635 // upgrade), we can prompt the user to accept these new permissions. | 1635 // upgrade), we can prompt the user to accept these new permissions. |
| 1636 // Extensions can also silently upgrade to less permissions, and then | 1636 // Extensions can also silently upgrade to less permissions, and then |
| 1637 // silently upgrade to a version that adds these permissions back. | 1637 // silently upgrade to a version that adds these permissions back. |
| 1638 // | 1638 // |
| 1639 // For example, pretend that Chrome 10 includes a permission "omnibox" | 1639 // For example, pretend that Chrome 10 includes a permission "omnibox" |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1701 } | 1701 } |
| 1702 | 1702 |
| 1703 // Extension has changed permissions significantly. Disable it. A | 1703 // Extension has changed permissions significantly. Disable it. A |
| 1704 // notification should be sent by the caller. | 1704 // notification should be sent by the caller. |
| 1705 if (is_privilege_increase) { | 1705 if (is_privilege_increase) { |
| 1706 extension_prefs_->SetExtensionState(extension, Extension::DISABLED); | 1706 extension_prefs_->SetExtensionState(extension, Extension::DISABLED); |
| 1707 extension_prefs_->SetDidExtensionEscalatePermissions(extension, true); | 1707 extension_prefs_->SetDidExtensionEscalatePermissions(extension, true); |
| 1708 } | 1708 } |
| 1709 } | 1709 } |
| 1710 | 1710 |
| 1711 void ExtensionsService::UpdateActiveExtensionsInCrashReporter() { | 1711 void ExtensionService::UpdateActiveExtensionsInCrashReporter() { |
| 1712 std::set<std::string> extension_ids; | 1712 std::set<std::string> extension_ids; |
| 1713 for (size_t i = 0; i < extensions_.size(); ++i) { | 1713 for (size_t i = 0; i < extensions_.size(); ++i) { |
| 1714 if (!extensions_[i]->is_theme() && | 1714 if (!extensions_[i]->is_theme() && |
| 1715 extensions_[i]->location() != Extension::COMPONENT) | 1715 extensions_[i]->location() != Extension::COMPONENT) |
| 1716 extension_ids.insert(extensions_[i]->id()); | 1716 extension_ids.insert(extensions_[i]->id()); |
| 1717 } | 1717 } |
| 1718 | 1718 |
| 1719 child_process_logging::SetActiveExtensions(extension_ids); | 1719 child_process_logging::SetActiveExtensions(extension_ids); |
| 1720 } | 1720 } |
| 1721 | 1721 |
| 1722 void ExtensionsService::OnExtensionInstalled(const Extension* extension) { | 1722 void ExtensionService::OnExtensionInstalled(const Extension* extension) { |
| 1723 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1723 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1724 | 1724 |
| 1725 // Ensure extension is deleted unless we transfer ownership. | 1725 // Ensure extension is deleted unless we transfer ownership. |
| 1726 scoped_refptr<const Extension> scoped_extension(extension); | 1726 scoped_refptr<const Extension> scoped_extension(extension); |
| 1727 Extension::State initial_state = Extension::DISABLED; | 1727 Extension::State initial_state = Extension::DISABLED; |
| 1728 bool initial_enable_incognito = false; | 1728 bool initial_enable_incognito = false; |
| 1729 PendingExtensionMap::iterator it = | 1729 PendingExtensionMap::iterator it = |
| 1730 pending_extensions_.find(extension->id()); | 1730 pending_extensions_.find(extension->id()); |
| 1731 if (it != pending_extensions_.end()) { | 1731 if (it != pending_extensions_.end()) { |
| 1732 PendingExtensionInfo pending_extension_info = it->second; | 1732 PendingExtensionInfo pending_extension_info = it->second; |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1857 if (extension->is_app()) { | 1857 if (extension->is_app()) { |
| 1858 ExtensionIdSet installed_ids = GetAppIds(); | 1858 ExtensionIdSet installed_ids = GetAppIds(); |
| 1859 installed_ids.insert(extension->id()); | 1859 installed_ids.insert(extension->id()); |
| 1860 default_apps_.DidInstallApp(installed_ids); | 1860 default_apps_.DidInstallApp(installed_ids); |
| 1861 } | 1861 } |
| 1862 | 1862 |
| 1863 // Transfer ownership of |extension| to OnExtensionLoaded. | 1863 // Transfer ownership of |extension| to OnExtensionLoaded. |
| 1864 OnExtensionLoaded(scoped_extension); | 1864 OnExtensionLoaded(scoped_extension); |
| 1865 } | 1865 } |
| 1866 | 1866 |
| 1867 const Extension* ExtensionsService::GetExtensionByIdInternal( | 1867 const Extension* ExtensionService::GetExtensionByIdInternal( |
| 1868 const std::string& id, bool include_enabled, bool include_disabled) { | 1868 const std::string& id, bool include_enabled, bool include_disabled) { |
| 1869 std::string lowercase_id = StringToLowerASCII(id); | 1869 std::string lowercase_id = StringToLowerASCII(id); |
| 1870 if (include_enabled) { | 1870 if (include_enabled) { |
| 1871 for (ExtensionList::const_iterator iter = extensions_.begin(); | 1871 for (ExtensionList::const_iterator iter = extensions_.begin(); |
| 1872 iter != extensions_.end(); ++iter) { | 1872 iter != extensions_.end(); ++iter) { |
| 1873 if ((*iter)->id() == lowercase_id) | 1873 if ((*iter)->id() == lowercase_id) |
| 1874 return *iter; | 1874 return *iter; |
| 1875 } | 1875 } |
| 1876 } | 1876 } |
| 1877 if (include_disabled) { | 1877 if (include_disabled) { |
| 1878 for (ExtensionList::const_iterator iter = disabled_extensions_.begin(); | 1878 for (ExtensionList::const_iterator iter = disabled_extensions_.begin(); |
| 1879 iter != disabled_extensions_.end(); ++iter) { | 1879 iter != disabled_extensions_.end(); ++iter) { |
| 1880 if ((*iter)->id() == lowercase_id) | 1880 if ((*iter)->id() == lowercase_id) |
| 1881 return *iter; | 1881 return *iter; |
| 1882 } | 1882 } |
| 1883 } | 1883 } |
| 1884 return NULL; | 1884 return NULL; |
| 1885 } | 1885 } |
| 1886 | 1886 |
| 1887 const Extension* ExtensionsService::GetWebStoreApp() { | 1887 const Extension* ExtensionService::GetWebStoreApp() { |
| 1888 return GetExtensionById(extension_misc::kWebStoreAppId, false); | 1888 return GetExtensionById(extension_misc::kWebStoreAppId, false); |
| 1889 } | 1889 } |
| 1890 | 1890 |
| 1891 const Extension* ExtensionsService::GetExtensionByURL(const GURL& url) { | 1891 const Extension* ExtensionService::GetExtensionByURL(const GURL& url) { |
| 1892 return url.scheme() != chrome::kExtensionScheme ? NULL : | 1892 return url.scheme() != chrome::kExtensionScheme ? NULL : |
| 1893 GetExtensionById(url.host(), false); | 1893 GetExtensionById(url.host(), false); |
| 1894 } | 1894 } |
| 1895 | 1895 |
| 1896 const Extension* ExtensionsService::GetExtensionByWebExtent(const GURL& url) { | 1896 const Extension* ExtensionService::GetExtensionByWebExtent(const GURL& url) { |
| 1897 for (size_t i = 0; i < extensions_.size(); ++i) { | 1897 for (size_t i = 0; i < extensions_.size(); ++i) { |
| 1898 if (extensions_[i]->web_extent().ContainsURL(url)) | 1898 if (extensions_[i]->web_extent().ContainsURL(url)) |
| 1899 return extensions_[i]; | 1899 return extensions_[i]; |
| 1900 } | 1900 } |
| 1901 return NULL; | 1901 return NULL; |
| 1902 } | 1902 } |
| 1903 | 1903 |
| 1904 bool ExtensionsService::ExtensionBindingsAllowed(const GURL& url) { | 1904 bool ExtensionService::ExtensionBindingsAllowed(const GURL& url) { |
| 1905 // Allow bindings for all packaged extension. | 1905 // Allow bindings for all packaged extension. |
| 1906 if (GetExtensionByURL(url)) | 1906 if (GetExtensionByURL(url)) |
| 1907 return true; | 1907 return true; |
| 1908 | 1908 |
| 1909 // Allow bindings for all component, hosted apps. | 1909 // Allow bindings for all component, hosted apps. |
| 1910 const Extension* extension = GetExtensionByWebExtent(url); | 1910 const Extension* extension = GetExtensionByWebExtent(url); |
| 1911 return (extension && extension->location() == Extension::COMPONENT); | 1911 return (extension && extension->location() == Extension::COMPONENT); |
| 1912 } | 1912 } |
| 1913 | 1913 |
| 1914 const Extension* ExtensionsService::GetExtensionByOverlappingWebExtent( | 1914 const Extension* ExtensionService::GetExtensionByOverlappingWebExtent( |
| 1915 const ExtensionExtent& extent) { | 1915 const ExtensionExtent& extent) { |
| 1916 for (size_t i = 0; i < extensions_.size(); ++i) { | 1916 for (size_t i = 0; i < extensions_.size(); ++i) { |
| 1917 if (extensions_[i]->web_extent().OverlapsWith(extent)) | 1917 if (extensions_[i]->web_extent().OverlapsWith(extent)) |
| 1918 return extensions_[i]; | 1918 return extensions_[i]; |
| 1919 } | 1919 } |
| 1920 | 1920 |
| 1921 return NULL; | 1921 return NULL; |
| 1922 } | 1922 } |
| 1923 | 1923 |
| 1924 const SkBitmap& ExtensionsService::GetOmniboxIcon( | 1924 const SkBitmap& ExtensionService::GetOmniboxIcon( |
| 1925 const std::string& extension_id) { | 1925 const std::string& extension_id) { |
| 1926 return omnibox_icon_manager_.GetIcon(extension_id); | 1926 return omnibox_icon_manager_.GetIcon(extension_id); |
| 1927 } | 1927 } |
| 1928 | 1928 |
| 1929 const SkBitmap& ExtensionsService::GetOmniboxPopupIcon( | 1929 const SkBitmap& ExtensionService::GetOmniboxPopupIcon( |
| 1930 const std::string& extension_id) { | 1930 const std::string& extension_id) { |
| 1931 return omnibox_popup_icon_manager_.GetIcon(extension_id); | 1931 return omnibox_popup_icon_manager_.GetIcon(extension_id); |
| 1932 } | 1932 } |
| 1933 | 1933 |
| 1934 void ExtensionsService::ClearProvidersForTesting() { | 1934 void ExtensionService::ClearProvidersForTesting() { |
| 1935 BrowserThread::PostTask( | 1935 BrowserThread::PostTask( |
| 1936 BrowserThread::FILE, FROM_HERE, | 1936 BrowserThread::FILE, FROM_HERE, |
| 1937 NewRunnableMethod( | 1937 NewRunnableMethod( |
| 1938 backend_.get(), &ExtensionsServiceBackend::ClearProvidersForTesting)); | 1938 backend_.get(), &ExtensionServiceBackend::ClearProvidersForTesting)); |
| 1939 } | 1939 } |
| 1940 | 1940 |
| 1941 void ExtensionsService::AddProviderForTesting( | 1941 void ExtensionService::AddProviderForTesting( |
| 1942 ExternalExtensionProvider* test_provider) { | 1942 ExternalExtensionProvider* test_provider) { |
| 1943 BrowserThread::PostTask( | 1943 BrowserThread::PostTask( |
| 1944 BrowserThread::FILE, FROM_HERE, | 1944 BrowserThread::FILE, FROM_HERE, |
| 1945 NewRunnableMethod( | 1945 NewRunnableMethod( |
| 1946 backend_.get(), &ExtensionsServiceBackend::AddProviderForTesting, | 1946 backend_.get(), &ExtensionServiceBackend::AddProviderForTesting, |
| 1947 test_provider)); | 1947 test_provider)); |
| 1948 } | 1948 } |
| 1949 | 1949 |
| 1950 void ExtensionsService::OnExternalExtensionFileFound( | 1950 void ExtensionService::OnExternalExtensionFileFound( |
| 1951 const std::string& id, | 1951 const std::string& id, |
| 1952 const std::string& version, | 1952 const std::string& version, |
| 1953 const FilePath& path, | 1953 const FilePath& path, |
| 1954 Extension::Location location) { | 1954 Extension::Location location) { |
| 1955 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1955 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1956 if (extension_prefs_->IsExtensionKilled(id)) | 1956 if (extension_prefs_->IsExtensionKilled(id)) |
| 1957 return; | 1957 return; |
| 1958 | 1958 |
| 1959 // Before even bothering to unpack, check and see if we already have this | 1959 // Before even bothering to unpack, check and see if we already have this |
| 1960 // version. This is important because these extensions are going to get | 1960 // version. This is important because these extensions are going to get |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1993 location); | 1993 location); |
| 1994 | 1994 |
| 1995 scoped_refptr<CrxInstaller> installer( | 1995 scoped_refptr<CrxInstaller> installer( |
| 1996 new CrxInstaller(this, // frontend | 1996 new CrxInstaller(this, // frontend |
| 1997 NULL)); // no client (silent install) | 1997 NULL)); // no client (silent install) |
| 1998 installer->set_install_source(location); | 1998 installer->set_install_source(location); |
| 1999 installer->set_expected_id(id); | 1999 installer->set_expected_id(id); |
| 2000 installer->InstallCrx(path); | 2000 installer->InstallCrx(path); |
| 2001 } | 2001 } |
| 2002 | 2002 |
| 2003 void ExtensionsService::ReportExtensionLoadError( | 2003 void ExtensionService::ReportExtensionLoadError( |
| 2004 const FilePath& extension_path, | 2004 const FilePath& extension_path, |
| 2005 const std::string &error, | 2005 const std::string &error, |
| 2006 NotificationType type, | 2006 NotificationType type, |
| 2007 bool be_noisy) { | 2007 bool be_noisy) { |
| 2008 NotificationService* service = NotificationService::current(); | 2008 NotificationService* service = NotificationService::current(); |
| 2009 service->Notify(type, | 2009 service->Notify(type, |
| 2010 Source<Profile>(profile_), | 2010 Source<Profile>(profile_), |
| 2011 Details<const std::string>(&error)); | 2011 Details<const std::string>(&error)); |
| 2012 | 2012 |
| 2013 // TODO(port): note that this isn't guaranteed to work properly on Linux. | 2013 // TODO(port): note that this isn't guaranteed to work properly on Linux. |
| 2014 std::string path_str = WideToUTF8(extension_path.ToWStringHack()); | 2014 std::string path_str = WideToUTF8(extension_path.ToWStringHack()); |
| 2015 std::string message = base::StringPrintf( | 2015 std::string message = base::StringPrintf( |
| 2016 "Could not load extension from '%s'. %s", | 2016 "Could not load extension from '%s'. %s", |
| 2017 path_str.c_str(), error.c_str()); | 2017 path_str.c_str(), error.c_str()); |
| 2018 ExtensionErrorReporter::GetInstance()->ReportError(message, be_noisy); | 2018 ExtensionErrorReporter::GetInstance()->ReportError(message, be_noisy); |
| 2019 } | 2019 } |
| 2020 | 2020 |
| 2021 void ExtensionsService::DidCreateRenderViewForBackgroundPage( | 2021 void ExtensionService::DidCreateRenderViewForBackgroundPage( |
| 2022 ExtensionHost* host) { | 2022 ExtensionHost* host) { |
| 2023 OrphanedDevTools::iterator iter = | 2023 OrphanedDevTools::iterator iter = |
| 2024 orphaned_dev_tools_.find(host->extension()->id()); | 2024 orphaned_dev_tools_.find(host->extension()->id()); |
| 2025 if (iter == orphaned_dev_tools_.end()) | 2025 if (iter == orphaned_dev_tools_.end()) |
| 2026 return; | 2026 return; |
| 2027 | 2027 |
| 2028 DevToolsManager::GetInstance()->AttachClientHost( | 2028 DevToolsManager::GetInstance()->AttachClientHost( |
| 2029 iter->second, host->render_view_host()); | 2029 iter->second, host->render_view_host()); |
| 2030 orphaned_dev_tools_.erase(iter); | 2030 orphaned_dev_tools_.erase(iter); |
| 2031 } | 2031 } |
| 2032 | 2032 |
| 2033 void ExtensionsService::Observe(NotificationType type, | 2033 void ExtensionService::Observe(NotificationType type, |
| 2034 const NotificationSource& source, | 2034 const NotificationSource& source, |
| 2035 const NotificationDetails& details) { | 2035 const NotificationDetails& details) { |
| 2036 switch (type.value) { | 2036 switch (type.value) { |
| 2037 case NotificationType::EXTENSION_PROCESS_TERMINATED: { | 2037 case NotificationType::EXTENSION_PROCESS_TERMINATED: { |
| 2038 if (profile_ != Source<Profile>(source).ptr()->GetOriginalProfile()) | 2038 if (profile_ != Source<Profile>(source).ptr()->GetOriginalProfile()) |
| 2039 break; | 2039 break; |
| 2040 | 2040 |
| 2041 ExtensionHost* host = Details<ExtensionHost>(details).ptr(); | 2041 ExtensionHost* host = Details<ExtensionHost>(details).ptr(); |
| 2042 | 2042 |
| 2043 // Unload the entire extension. We want it to be in a consistent state: | 2043 // Unload the entire extension. We want it to be in a consistent state: |
| 2044 // either fully working or not loaded at all, but never half-crashed. | 2044 // either fully working or not loaded at all, but never half-crashed. |
| 2045 // We do it in a PostTask so that other handlers of this notification will | 2045 // We do it in a PostTask so that other handlers of this notification will |
| 2046 // still have access to the Extension and ExtensionHost. | 2046 // still have access to the Extension and ExtensionHost. |
| 2047 MessageLoop::current()->PostTask(FROM_HERE, | 2047 MessageLoop::current()->PostTask(FROM_HERE, |
| 2048 NewRunnableMethod(this, &ExtensionsService::UnloadExtension, | 2048 NewRunnableMethod(this, &ExtensionService::UnloadExtension, |
| 2049 host->extension()->id())); | 2049 host->extension()->id())); |
| 2050 break; | 2050 break; |
| 2051 } | 2051 } |
| 2052 | 2052 |
| 2053 case NotificationType::PREF_CHANGED: { | 2053 case NotificationType::PREF_CHANGED: { |
| 2054 std::string* pref_name = Details<std::string>(details).ptr(); | 2054 std::string* pref_name = Details<std::string>(details).ptr(); |
| 2055 if (*pref_name == prefs::kExtensionInstallAllowList || | 2055 if (*pref_name == prefs::kExtensionInstallAllowList || |
| 2056 *pref_name == prefs::kExtensionInstallDenyList) { | 2056 *pref_name == prefs::kExtensionInstallDenyList) { |
| 2057 CheckAdminBlacklist(); | 2057 CheckAdminBlacklist(); |
| 2058 } else if (*pref_name == prefs::kExtensionInstallForceList) { | 2058 } else if (*pref_name == prefs::kExtensionInstallForceList) { |
| 2059 UpdateExternalPolicyExtensionProvider(); | 2059 UpdateExternalPolicyExtensionProvider(); |
| 2060 CheckForExternalUpdates(); | 2060 CheckForExternalUpdates(); |
| 2061 // TODO(gfeher): Also check for external extensions that can be | 2061 // TODO(gfeher): Also check for external extensions that can be |
| 2062 // uninstalled because they were removed from the pref. | 2062 // uninstalled because they were removed from the pref. |
| 2063 // (crbug.com/63667) | 2063 // (crbug.com/63667) |
| 2064 } else { | 2064 } else { |
| 2065 NOTREACHED() << "Unexpected preference name."; | 2065 NOTREACHED() << "Unexpected preference name."; |
| 2066 } | 2066 } |
| 2067 break; | 2067 break; |
| 2068 } | 2068 } |
| 2069 | 2069 |
| 2070 default: | 2070 default: |
| 2071 NOTREACHED() << "Unexpected notification type."; | 2071 NOTREACHED() << "Unexpected notification type."; |
| 2072 } | 2072 } |
| 2073 } | 2073 } |
| 2074 | 2074 |
| 2075 bool ExtensionsService::HasApps() const { | 2075 bool ExtensionService::HasApps() const { |
| 2076 return !GetAppIds().empty(); | 2076 return !GetAppIds().empty(); |
| 2077 } | 2077 } |
| 2078 | 2078 |
| 2079 ExtensionIdSet ExtensionsService::GetAppIds() const { | 2079 ExtensionIdSet ExtensionService::GetAppIds() const { |
| 2080 ExtensionIdSet result; | 2080 ExtensionIdSet result; |
| 2081 for (ExtensionList::const_iterator it = extensions_.begin(); | 2081 for (ExtensionList::const_iterator it = extensions_.begin(); |
| 2082 it != extensions_.end(); ++it) { | 2082 it != extensions_.end(); ++it) { |
| 2083 if ((*it)->is_app() && (*it)->location() != Extension::COMPONENT) | 2083 if ((*it)->is_app() && (*it)->location() != Extension::COMPONENT) |
| 2084 result.insert((*it)->id()); | 2084 result.insert((*it)->id()); |
| 2085 } | 2085 } |
| 2086 | 2086 |
| 2087 return result; | 2087 return result; |
| 2088 } | 2088 } |
| 2089 | 2089 |
| 2090 bool ExtensionsService::IsBackgroundPageReady(const Extension* extension) { | 2090 bool ExtensionService::IsBackgroundPageReady(const Extension* extension) { |
| 2091 return (extension->background_url().is_empty() || | 2091 return (extension->background_url().is_empty() || |
| 2092 extension_runtime_data_[extension->id()].background_page_ready); | 2092 extension_runtime_data_[extension->id()].background_page_ready); |
| 2093 } | 2093 } |
| 2094 | 2094 |
| 2095 void ExtensionsService::SetBackgroundPageReady(const Extension* extension) { | 2095 void ExtensionService::SetBackgroundPageReady(const Extension* extension) { |
| 2096 DCHECK(!extension->background_url().is_empty()); | 2096 DCHECK(!extension->background_url().is_empty()); |
| 2097 extension_runtime_data_[extension->id()].background_page_ready = true; | 2097 extension_runtime_data_[extension->id()].background_page_ready = true; |
| 2098 NotificationService::current()->Notify( | 2098 NotificationService::current()->Notify( |
| 2099 NotificationType::EXTENSION_BACKGROUND_PAGE_READY, | 2099 NotificationType::EXTENSION_BACKGROUND_PAGE_READY, |
| 2100 Source<const Extension>(extension), | 2100 Source<const Extension>(extension), |
| 2101 NotificationService::NoDetails()); | 2101 NotificationService::NoDetails()); |
| 2102 } | 2102 } |
| 2103 | 2103 |
| 2104 bool ExtensionsService::IsBeingUpgraded(const Extension* extension) { | 2104 bool ExtensionService::IsBeingUpgraded(const Extension* extension) { |
| 2105 return extension_runtime_data_[extension->id()].being_upgraded; | 2105 return extension_runtime_data_[extension->id()].being_upgraded; |
| 2106 } | 2106 } |
| 2107 | 2107 |
| 2108 void ExtensionsService::SetBeingUpgraded(const Extension* extension, | 2108 void ExtensionService::SetBeingUpgraded(const Extension* extension, |
| 2109 bool value) { | 2109 bool value) { |
| 2110 extension_runtime_data_[extension->id()].being_upgraded = value; | 2110 extension_runtime_data_[extension->id()].being_upgraded = value; |
| 2111 } | 2111 } |
| 2112 | 2112 |
| 2113 PropertyBag* ExtensionsService::GetPropertyBag(const Extension* extension) { | 2113 PropertyBag* ExtensionService::GetPropertyBag(const Extension* extension) { |
| 2114 return &extension_runtime_data_[extension->id()].property_bag; | 2114 return &extension_runtime_data_[extension->id()].property_bag; |
| 2115 } | 2115 } |
| OLD | NEW |