OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 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/installed_loader.h" | 5 #include "chrome/browser/extensions/installed_loader.h" |
6 | 6 |
7 #include "base/files/file_path.h" | 7 #include "base/files/file_path.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
11 #include "base/threading/thread_restrictions.h" | 11 #include "base/threading/thread_restrictions.h" |
12 #include "base/values.h" | 12 #include "base/values.h" |
13 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
14 #include "chrome/browser/extensions/extension_action_manager.h" | 14 #include "chrome/browser/extensions/extension_action_manager.h" |
15 #include "chrome/browser/extensions/extension_error_reporter.h" | 15 #include "chrome/browser/extensions/extension_error_reporter.h" |
16 #include "chrome/browser/extensions/extension_service.h" | 16 #include "chrome/browser/extensions/extension_service.h" |
17 #include "chrome/browser/extensions/extension_util.h" | |
17 #include "chrome/browser/profiles/profile_manager.h" | 18 #include "chrome/browser/profiles/profile_manager.h" |
18 #include "chrome/common/chrome_switches.h" | 19 #include "chrome/common/chrome_switches.h" |
19 #include "chrome/common/extensions/api/managed_mode_private/managed_mode_handler .h" | 20 #include "chrome/common/extensions/api/managed_mode_private/managed_mode_handler .h" |
20 #include "chrome/common/extensions/manifest_url_handler.h" | 21 #include "chrome/common/extensions/manifest_url_handler.h" |
21 #include "chrome/common/pref_names.h" | 22 #include "chrome/common/pref_names.h" |
22 #include "content/public/browser/notification_service.h" | 23 #include "content/public/browser/notification_service.h" |
23 #include "content/public/browser/user_metrics.h" | 24 #include "content/public/browser/user_metrics.h" |
24 #include "extensions/browser/api/runtime/runtime_api.h" | 25 #include "extensions/browser/api/runtime/runtime_api.h" |
25 #include "extensions/browser/extension_prefs.h" | 26 #include "extensions/browser/extension_prefs.h" |
26 #include "extensions/browser/extension_registry.h" | 27 #include "extensions/browser/extension_registry.h" |
27 #include "extensions/browser/extension_system.h" | 28 #include "extensions/browser/extension_system.h" |
28 #include "extensions/browser/management_policy.h" | 29 #include "extensions/browser/management_policy.h" |
29 #include "extensions/common/extension.h" | 30 #include "extensions/common/extension.h" |
30 #include "extensions/common/extension_l10n_util.h" | 31 #include "extensions/common/extension_l10n_util.h" |
32 #include "extensions/common/extension_set.h" | |
31 #include "extensions/common/file_util.h" | 33 #include "extensions/common/file_util.h" |
32 #include "extensions/common/manifest.h" | 34 #include "extensions/common/manifest.h" |
33 #include "extensions/common/manifest_constants.h" | 35 #include "extensions/common/manifest_constants.h" |
34 #include "extensions/common/manifest_handlers/background_info.h" | 36 #include "extensions/common/manifest_handlers/background_info.h" |
35 | 37 |
36 using base::UserMetricsAction; | 38 using base::UserMetricsAction; |
37 using content::BrowserThread; | 39 using content::BrowserThread; |
38 | 40 |
39 namespace extensions { | 41 namespace extensions { |
40 | 42 |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
184 extension_prefs_->UpdateManifest(extension.get()); | 186 extension_prefs_->UpdateManifest(extension.get()); |
185 | 187 |
186 extension_service_->AddExtension(extension.get()); | 188 extension_service_->AddExtension(extension.get()); |
187 } | 189 } |
188 | 190 |
189 void InstalledLoader::LoadAllExtensions() { | 191 void InstalledLoader::LoadAllExtensions() { |
190 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 192 CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
191 | 193 |
192 base::TimeTicks start_time = base::TimeTicks::Now(); | 194 base::TimeTicks start_time = base::TimeTicks::Now(); |
193 | 195 |
196 Profile* profile = extension_service_->profile(); | |
194 scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info( | 197 scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info( |
195 extension_prefs_->GetInstalledExtensionsInfo()); | 198 extension_prefs_->GetInstalledExtensionsInfo()); |
196 | 199 |
197 std::vector<int> reload_reason_counts(NUM_MANIFEST_RELOAD_REASONS, 0); | 200 std::vector<int> reload_reason_counts(NUM_MANIFEST_RELOAD_REASONS, 0); |
198 bool should_write_prefs = false; | 201 bool should_write_prefs = false; |
199 | 202 |
200 for (size_t i = 0; i < extensions_info->size(); ++i) { | 203 for (size_t i = 0; i < extensions_info->size(); ++i) { |
201 ExtensionInfo* info = extensions_info->at(i).get(); | 204 ExtensionInfo* info = extensions_info->at(i).get(); |
202 | 205 |
203 // Skip extensions that were loaded from the command-line because we don't | 206 // Skip extensions that were loaded from the command-line because we don't |
(...skipping 19 matching lines...) Expand all Loading... | |
223 scoped_refptr<const Extension> extension( | 226 scoped_refptr<const Extension> extension( |
224 file_util::LoadExtension(info->extension_path, | 227 file_util::LoadExtension(info->extension_path, |
225 info->extension_location, | 228 info->extension_location, |
226 GetCreationFlags(info), | 229 GetCreationFlags(info), |
227 &error)); | 230 &error)); |
228 | 231 |
229 if (!extension.get()) { | 232 if (!extension.get()) { |
230 ExtensionErrorReporter::GetInstance()->ReportLoadError( | 233 ExtensionErrorReporter::GetInstance()->ReportLoadError( |
231 info->extension_path, | 234 info->extension_path, |
232 error, | 235 error, |
233 extension_service_->profile(), | 236 profile, |
234 false); // Be quiet. | 237 false); // Be quiet. |
235 continue; | 238 continue; |
236 } | 239 } |
237 | 240 |
238 extensions_info->at(i)->extension_manifest.reset( | 241 extensions_info->at(i)->extension_manifest.reset( |
239 static_cast<base::DictionaryValue*>( | 242 static_cast<base::DictionaryValue*>( |
240 extension->manifest()->value()->DeepCopy())); | 243 extension->manifest()->value()->DeepCopy())); |
241 should_write_prefs = true; | 244 should_write_prefs = true; |
242 } | 245 } |
243 } | 246 } |
244 | 247 |
245 for (size_t i = 0; i < extensions_info->size(); ++i) { | 248 for (size_t i = 0; i < extensions_info->size(); ++i) { |
246 if (extensions_info->at(i)->extension_location == Manifest::COMMAND_LINE) | 249 if (extensions_info->at(i)->extension_location != Manifest::COMMAND_LINE) |
247 continue; | 250 Load(*extensions_info->at(i), should_write_prefs); |
248 Load(*extensions_info->at(i), should_write_prefs); | |
249 } | 251 } |
250 | 252 |
251 extension_service_->OnLoadedInstalledExtensions(); | 253 extension_service_->OnLoadedInstalledExtensions(); |
252 | 254 |
253 // The histograms Extensions.ManifestReload* allow us to validate | 255 // The histograms Extensions.ManifestReload* allow us to validate |
254 // the assumption that reloading manifest is a rare event. | 256 // the assumption that reloading manifest is a rare event. |
255 UMA_HISTOGRAM_COUNTS_100("Extensions.ManifestReloadNotNeeded", | 257 UMA_HISTOGRAM_COUNTS_100("Extensions.ManifestReloadNotNeeded", |
256 reload_reason_counts[NOT_NEEDED]); | 258 reload_reason_counts[NOT_NEEDED]); |
257 UMA_HISTOGRAM_COUNTS_100("Extensions.ManifestReloadUnpackedDir", | 259 UMA_HISTOGRAM_COUNTS_100("Extensions.ManifestReloadUnpackedDir", |
258 reload_reason_counts[UNPACKED_DIR]); | 260 reload_reason_counts[UNPACKED_DIR]); |
(...skipping 16 matching lines...) Expand all Loading... | |
275 int user_script_count = 0; | 277 int user_script_count = 0; |
276 int content_pack_count = 0; | 278 int content_pack_count = 0; |
277 int extension_user_count = 0; | 279 int extension_user_count = 0; |
278 int extension_external_count = 0; | 280 int extension_external_count = 0; |
279 int theme_count = 0; | 281 int theme_count = 0; |
280 int page_action_count = 0; | 282 int page_action_count = 0; |
281 int browser_action_count = 0; | 283 int browser_action_count = 0; |
282 int disabled_for_permissions_count = 0; | 284 int disabled_for_permissions_count = 0; |
283 int item_user_count = 0; | 285 int item_user_count = 0; |
284 int non_webstore_ntp_override_count = 0; | 286 int non_webstore_ntp_override_count = 0; |
287 int incognito = 0; | |
288 int not_incognito = 0; | |
289 int file_access = 0; | |
290 int not_file_access = 0; | |
291 | |
285 const ExtensionSet& extensions = extension_registry_->enabled_extensions(); | 292 const ExtensionSet& extensions = extension_registry_->enabled_extensions(); |
286 ExtensionSet::const_iterator ex; | 293 |
287 for (ex = extensions.begin(); ex != extensions.end(); ++ex) { | 294 for (ExtensionSet::const_iterator ex = extensions.begin(); |
295 ex != extensions.end(); | |
296 ++ex) { | |
288 Manifest::Location location = (*ex)->location(); | 297 Manifest::Location location = (*ex)->location(); |
289 Manifest::Type type = (*ex)->GetType(); | 298 Manifest::Type type = (*ex)->GetType(); |
290 if ((*ex)->is_app()) { | 299 if ((*ex)->is_app()) { |
Devlin
2014/05/09 23:29:12
nit: I liked your const Extension* e = *iter to sa
| |
291 UMA_HISTOGRAM_ENUMERATION("Extensions.AppLocation", | 300 UMA_HISTOGRAM_ENUMERATION("Extensions.AppLocation", |
292 location, 100); | 301 location, 100); |
293 } else if (type == Manifest::TYPE_EXTENSION) { | 302 } else if (type == Manifest::TYPE_EXTENSION) { |
294 UMA_HISTOGRAM_ENUMERATION("Extensions.ExtensionLocation", | 303 UMA_HISTOGRAM_ENUMERATION("Extensions.ExtensionLocation", |
295 location, 100); | 304 location, 100); |
296 } | 305 } |
297 if (!ManifestURL::UpdatesFromGallery(*ex)) { | 306 if (!ManifestURL::UpdatesFromGallery(*ex)) { |
298 UMA_HISTOGRAM_ENUMERATION("Extensions.NonWebstoreLocation", | 307 UMA_HISTOGRAM_ENUMERATION("Extensions.NonWebstoreLocation", |
299 location, 100); | 308 location, 100); |
300 } | 309 } |
(...skipping 24 matching lines...) Expand all Loading... | |
325 } | 334 } |
326 } | 335 } |
327 | 336 |
328 // Don't count component extensions, since they are only extensions as an | 337 // Don't count component extensions, since they are only extensions as an |
329 // implementation detail. | 338 // implementation detail. |
330 if (location == Manifest::COMPONENT) | 339 if (location == Manifest::COMPONENT) |
331 continue; | 340 continue; |
332 // Histogram for non-webstore extensions overriding new tab page should | 341 // Histogram for non-webstore extensions overriding new tab page should |
333 // include unpacked extensions. | 342 // include unpacked extensions. |
334 if (!(*ex)->from_webstore()) { | 343 if (!(*ex)->from_webstore()) { |
335 const extensions::URLOverrides::URLOverrideMap& override_map = | 344 const extensions::URLOverrides::URLOverrideMap& override_map = |
Devlin
2014/05/09 23:29:12
don't need extensions:: prefix.
| |
336 extensions::URLOverrides::GetChromeURLOverrides(ex->get()); | 345 extensions::URLOverrides::GetChromeURLOverrides(ex->get()); |
337 if (override_map.find("newtab") != override_map.end()) { | 346 if (override_map.find("newtab") != override_map.end()) { |
338 ++non_webstore_ntp_override_count; | 347 ++non_webstore_ntp_override_count; |
339 } | 348 } |
340 } | 349 } |
341 | 350 |
342 // Don't count unpacked extensions, since they're a developer-specific | 351 // Don't count unpacked extensions, since they're a developer-specific |
343 // feature. | 352 // feature. |
344 if (Manifest::IsUnpackedLocation(location)) | 353 if (Manifest::IsUnpackedLocation(location)) |
345 continue; | 354 continue; |
(...skipping 30 matching lines...) Expand all Loading... | |
376 case Manifest::TYPE_LEGACY_PACKAGED_APP: | 385 case Manifest::TYPE_LEGACY_PACKAGED_APP: |
377 ++legacy_packaged_app_count; | 386 ++legacy_packaged_app_count; |
378 if (Manifest::IsExternalLocation(location)) { | 387 if (Manifest::IsExternalLocation(location)) { |
379 ++app_external_count; | 388 ++app_external_count; |
380 } else { | 389 } else { |
381 ++app_user_count; | 390 ++app_user_count; |
382 } | 391 } |
383 break; | 392 break; |
384 case Manifest::TYPE_PLATFORM_APP: | 393 case Manifest::TYPE_PLATFORM_APP: |
385 ++platform_app_count; | 394 ++platform_app_count; |
386 if (Manifest::IsExternalLocation(location)) { | 395 if (Manifest::IsExternalLocation(location)) { |
Devlin
2014/05/09 23:29:12
gah.
bool is_external_location = Manifest::IsExter
| |
387 ++app_external_count; | 396 ++app_external_count; |
388 } else { | 397 } else { |
389 ++app_user_count; | 398 ++app_user_count; |
390 } | 399 } |
391 break; | 400 break; |
392 case Manifest::TYPE_EXTENSION: | 401 case Manifest::TYPE_EXTENSION: |
393 default: | 402 default: |
394 if (Manifest::IsExternalLocation(location)) { | 403 if (Manifest::IsExternalLocation(location)) { |
395 ++extension_external_count; | 404 ++extension_external_count; |
396 } else { | 405 } else { |
397 ++extension_user_count; | 406 ++extension_user_count; |
398 } | 407 } |
399 break; | 408 break; |
400 } | 409 } |
401 if (!Manifest::IsExternalLocation((*ex)->location())) | 410 if (!Manifest::IsExternalLocation((*ex)->location())) |
Devlin
2014/05/09 23:29:12
location, not ex->location.
| |
402 ++item_user_count; | 411 ++item_user_count; |
403 ExtensionActionManager* extension_action_manager = | 412 ExtensionActionManager* extension_action_manager = |
Devlin
2014/05/09 23:29:12
move this outside the for-loop, so we don't have t
| |
404 ExtensionActionManager::Get(extension_service_->profile()); | 413 ExtensionActionManager::Get(extension_service_->profile()); |
405 if (extension_action_manager->GetPageAction(*ex->get())) | 414 if (extension_action_manager->GetPageAction(*ex->get())) |
406 ++page_action_count; | 415 ++page_action_count; |
407 if (extension_action_manager->GetBrowserAction(*ex->get())) | 416 if (extension_action_manager->GetBrowserAction(*ex->get())) |
408 ++browser_action_count; | 417 ++browser_action_count; |
409 | 418 |
410 if (extensions::ManagedModeInfo::IsContentPack(ex->get())) | 419 if (extensions::ManagedModeInfo::IsContentPack(ex->get())) |
411 ++content_pack_count; | 420 ++content_pack_count; |
412 | 421 |
413 extension_service_->RecordPermissionMessagesHistogram( | 422 extension_service_->RecordPermissionMessagesHistogram( |
414 ex->get(), "Extensions.Permissions_Load"); | 423 ex->get(), "Extensions.Permissions_Load"); |
424 | |
425 // For incognito and file access, skip unpacked extensions because they get | |
426 // file access up-front, and the data isn't useful. Skip anything that | |
427 // doesn't appear in settings. | |
428 if ((*ex)->location() != Manifest::UNPACKED && | |
Devlin
2014/05/09 23:29:12
location, not ex->location.
Also, we already skipp
| |
429 (*ex)->ShouldDisplayInExtensionSettings()) { | |
430 if ((*ex)->can_be_incognito_enabled()) { | |
431 if (util::IsIncognitoEnabled((*ex)->id(), profile)) | |
432 ++incognito; | |
433 else | |
434 ++not_incognito; | |
435 } | |
436 if ((*ex)->wants_file_access()) { | |
437 if (util::AllowFileAccess((*ex)->id(), profile)) | |
438 ++file_access; | |
439 else | |
440 ++not_file_access; | |
441 } | |
442 } | |
415 } | 443 } |
416 | 444 |
417 const ExtensionSet& disabled_extensions = | 445 const ExtensionSet& disabled_extensions = |
418 extension_registry_->disabled_extensions(); | 446 extension_registry_->disabled_extensions(); |
419 for (ex = disabled_extensions.begin(); ex != disabled_extensions.end(); | 447 |
448 for (ExtensionSet::const_iterator ex = disabled_extensions.begin(); | |
449 ex != disabled_extensions.end(); | |
420 ++ex) { | 450 ++ex) { |
421 if (extension_prefs_->DidExtensionEscalatePermissions((*ex)->id())) { | 451 if (extension_prefs_->DidExtensionEscalatePermissions((*ex)->id())) { |
422 ++disabled_for_permissions_count; | 452 ++disabled_for_permissions_count; |
423 } | 453 } |
424 if (Manifest::IsExternalLocation((*ex)->location())) { | 454 if (Manifest::IsExternalLocation((*ex)->location())) { |
425 // See loop above for ENABLED. | 455 // See loop above for ENABLED. |
426 if (ManifestURL::UpdatesFromGallery(*ex)) { | 456 if (ManifestURL::UpdatesFromGallery(*ex)) { |
427 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalItemState", | 457 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalItemState", |
428 EXTERNAL_ITEM_WEBSTORE_DISABLED, | 458 EXTERNAL_ITEM_WEBSTORE_DISABLED, |
429 EXTERNAL_ITEM_MAX_ITEMS); | 459 EXTERNAL_ITEM_MAX_ITEMS); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
472 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadUserScript", user_script_count); | 502 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadUserScript", user_script_count); |
473 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadTheme", theme_count); | 503 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadTheme", theme_count); |
474 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPageAction", page_action_count); | 504 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPageAction", page_action_count); |
475 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadBrowserAction", | 505 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadBrowserAction", |
476 browser_action_count); | 506 browser_action_count); |
477 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadContentPack", content_pack_count); | 507 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadContentPack", content_pack_count); |
478 UMA_HISTOGRAM_COUNTS_100("Extensions.DisabledForPermissions", | 508 UMA_HISTOGRAM_COUNTS_100("Extensions.DisabledForPermissions", |
479 disabled_for_permissions_count); | 509 disabled_for_permissions_count); |
480 UMA_HISTOGRAM_COUNTS_100("Extensions.NonWebStoreNewTabPageOverrides", | 510 UMA_HISTOGRAM_COUNTS_100("Extensions.NonWebStoreNewTabPageOverrides", |
481 non_webstore_ntp_override_count); | 511 non_webstore_ntp_override_count); |
512 UMA_HISTOGRAM_COUNTS_100("Extensions.IncognitoAllowed", incognito); | |
513 UMA_HISTOGRAM_COUNTS_100("Extensions.IncognitoNotAllowed", not_incognito); | |
514 UMA_HISTOGRAM_COUNTS_100("Extensions.FileAccessAllowed", file_access); | |
515 UMA_HISTOGRAM_COUNTS_100("Extensions.FileAccessNotAllowed", not_file_access); | |
482 } | 516 } |
483 | 517 |
484 int InstalledLoader::GetCreationFlags(const ExtensionInfo* info) { | 518 int InstalledLoader::GetCreationFlags(const ExtensionInfo* info) { |
485 int flags = extension_prefs_->GetCreationFlags(info->extension_id); | 519 int flags = extension_prefs_->GetCreationFlags(info->extension_id); |
486 if (!Manifest::IsUnpackedLocation(info->extension_location)) | 520 if (!Manifest::IsUnpackedLocation(info->extension_location)) |
487 flags |= Extension::REQUIRE_KEY; | 521 flags |= Extension::REQUIRE_KEY; |
488 if (extension_prefs_->AllowFileAccess(info->extension_id)) | 522 if (extension_prefs_->AllowFileAccess(info->extension_id)) |
489 flags |= Extension::ALLOW_FILE_ACCESS; | 523 flags |= Extension::ALLOW_FILE_ACCESS; |
490 return flags; | 524 return flags; |
491 } | 525 } |
492 | 526 |
493 } // namespace extensions | 527 } // namespace extensions |
OLD | NEW |