Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / extensions / installed_loader.cc
blob55b3b78795b3464bc2fd11530a2dfabaa2fcbb01
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/installed_loader.h"
7 #include "base/files/file_path.h"
8 #include "base/metrics/histogram.h"
9 #include "base/metrics/sparse_histogram.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/threading/thread_restrictions.h"
13 #include "base/trace_event/trace_event.h"
14 #include "base/values.h"
15 #include "chrome/browser/browser_process.h"
16 #include "chrome/browser/extensions/extension_action_manager.h"
17 #include "chrome/browser/extensions/extension_error_reporter.h"
18 #include "chrome/browser/extensions/extension_service.h"
19 #include "chrome/browser/extensions/extension_util.h"
20 #include "chrome/browser/profiles/profile_manager.h"
21 #include "chrome/common/chrome_switches.h"
22 #include "chrome/common/extensions/api/supervised_user_private/supervised_user_handler.h"
23 #include "chrome/common/extensions/chrome_manifest_url_handlers.h"
24 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/notification_service.h"
26 #include "content/public/browser/user_metrics.h"
27 #include "extensions/browser/event_router.h"
28 #include "extensions/browser/extension_prefs.h"
29 #include "extensions/browser/extension_registry.h"
30 #include "extensions/browser/extension_system.h"
31 #include "extensions/browser/management_policy.h"
32 #include "extensions/common/extension.h"
33 #include "extensions/common/extension_l10n_util.h"
34 #include "extensions/common/extension_set.h"
35 #include "extensions/common/extension_urls.h"
36 #include "extensions/common/file_util.h"
37 #include "extensions/common/manifest.h"
38 #include "extensions/common/manifest_constants.h"
39 #include "extensions/common/manifest_handlers/background_info.h"
40 #include "extensions/common/manifest_url_handlers.h"
42 using base::UserMetricsAction;
43 using content::BrowserThread;
45 namespace extensions {
47 namespace errors = manifest_errors;
49 namespace {
51 // The following enumeration is used in histograms matching
52 // Extensions.ManifestReload*.
53 enum ManifestReloadReason {
54 NOT_NEEDED = 0, // Reload not needed.
55 UNPACKED_DIR, // Unpacked directory.
56 NEEDS_RELOCALIZATION, // The locale has changed since we read this extension.
57 CORRUPT_PREFERENCES, // The manifest in the preferences is corrupt.
59 // New enum values must go above here.
60 NUM_MANIFEST_RELOAD_REASONS
63 // Used in histogram Extension.BackgroundPageType.
64 enum BackgroundPageType {
65 NO_BACKGROUND_PAGE = 0,
66 BACKGROUND_PAGE_PERSISTENT,
67 EVENT_PAGE,
69 // New enum values must go above here.
70 NUM_BACKGROUND_PAGE_TYPES
73 // Used in histogram Extensions.ExternalItemState.
74 enum ExternalItemState {
75 DEPRECATED_EXTERNAL_ITEM_DISABLED = 0,
76 DEPRECATED_EXTERNAL_ITEM_ENABLED,
77 EXTERNAL_ITEM_WEBSTORE_DISABLED,
78 EXTERNAL_ITEM_WEBSTORE_ENABLED,
79 EXTERNAL_ITEM_NONWEBSTORE_DISABLED,
80 EXTERNAL_ITEM_NONWEBSTORE_ENABLED,
81 EXTERNAL_ITEM_WEBSTORE_UNINSTALLED,
82 EXTERNAL_ITEM_NONWEBSTORE_UNINSTALLED,
84 // New enum values must go above here.
85 EXTERNAL_ITEM_MAX_ITEMS
88 bool IsManifestCorrupt(const base::DictionaryValue* manifest) {
89 if (!manifest)
90 return false;
92 // Because of bug #272524 sometimes manifests got mangled in the preferences
93 // file, one particularly bad case resulting in having both a background page
94 // and background scripts values. In those situations we want to reload the
95 // manifest from the extension to fix this.
96 const base::Value* background_page;
97 const base::Value* background_scripts;
98 return manifest->Get(manifest_keys::kBackgroundPage, &background_page) &&
99 manifest->Get(manifest_keys::kBackgroundScripts, &background_scripts);
102 ManifestReloadReason ShouldReloadExtensionManifest(const ExtensionInfo& info) {
103 // Always reload manifests of unpacked extensions, because they can change
104 // on disk independent of the manifest in our prefs.
105 if (Manifest::IsUnpackedLocation(info.extension_location))
106 return UNPACKED_DIR;
108 // Reload the manifest if it needs to be relocalized.
109 if (extension_l10n_util::ShouldRelocalizeManifest(
110 info.extension_manifest.get()))
111 return NEEDS_RELOCALIZATION;
113 // Reload if the copy of the manifest in the preferences is corrupt.
114 if (IsManifestCorrupt(info.extension_manifest.get()))
115 return CORRUPT_PREFERENCES;
117 return NOT_NEEDED;
120 BackgroundPageType GetBackgroundPageType(const Extension* extension) {
121 if (!BackgroundInfo::HasBackgroundPage(extension))
122 return NO_BACKGROUND_PAGE;
123 if (BackgroundInfo::HasPersistentBackgroundPage(extension))
124 return BACKGROUND_PAGE_PERSISTENT;
125 return EVENT_PAGE;
128 // Records the creation flags of an extension grouped by
129 // Extension::InitFromValueFlags.
130 void RecordCreationFlags(const Extension* extension) {
131 for (int i = 0; i < Extension::kInitFromValueFlagBits; ++i) {
132 int flag = 1 << i;
133 if (extension->creation_flags() & flag) {
134 UMA_HISTOGRAM_ENUMERATION(
135 "Extensions.LoadCreationFlags", i, Extension::kInitFromValueFlagBits);
140 // Helper to record a single disable reason histogram value (see
141 // RecordDisableReasons below).
142 void RecordDisbleReasonHistogram(int reason) {
143 UMA_HISTOGRAM_SPARSE_SLOWLY("Extensions.DisableReason", reason);
146 // Records the disable reasons for a single extension grouped by
147 // Extension::DisableReason.
148 void RecordDisableReasons(int reasons) {
149 // |reasons| is a bitmask with values from Extension::DisabledReason
150 // which are increasing powers of 2.
151 if (reasons == Extension::DISABLE_NONE) {
152 RecordDisbleReasonHistogram(Extension::DISABLE_NONE);
153 return;
155 for (int reason = 1; reason < Extension::DISABLE_REASON_LAST; reason <<= 1) {
156 if (reasons & reason)
157 RecordDisbleReasonHistogram(reason);
161 } // namespace
163 InstalledLoader::InstalledLoader(ExtensionService* extension_service)
164 : extension_service_(extension_service),
165 extension_registry_(ExtensionRegistry::Get(extension_service->profile())),
166 extension_prefs_(ExtensionPrefs::Get(extension_service->profile())) {}
168 InstalledLoader::~InstalledLoader() {
171 void InstalledLoader::Load(const ExtensionInfo& info, bool write_to_prefs) {
172 std::string error;
173 scoped_refptr<const Extension> extension(NULL);
174 if (info.extension_manifest) {
175 extension = Extension::Create(
176 info.extension_path,
177 info.extension_location,
178 *info.extension_manifest,
179 GetCreationFlags(&info),
180 &error);
181 } else {
182 error = errors::kManifestUnreadable;
185 // Once installed, non-unpacked extensions cannot change their IDs (e.g., by
186 // updating the 'key' field in their manifest).
187 // TODO(jstritar): migrate preferences when unpacked extensions change IDs.
188 if (extension.get() && !Manifest::IsUnpackedLocation(extension->location()) &&
189 info.extension_id != extension->id()) {
190 error = errors::kCannotChangeExtensionID;
191 extension = NULL;
194 // Check policy on every load in case an extension was blacklisted while
195 // Chrome was not running.
196 const ManagementPolicy* policy = extensions::ExtensionSystem::Get(
197 extension_service_->profile())->management_policy();
198 if (extension.get()) {
199 Extension::DisableReason disable_reason = Extension::DISABLE_NONE;
200 bool force_disabled = false;
201 if (!policy->UserMayLoad(extension.get(), NULL)) {
202 // The error message from UserMayInstall() often contains the extension ID
203 // and is therefore not well suited to this UI.
204 error = errors::kDisabledByPolicy;
205 extension = NULL;
206 } else if (!extension_prefs_->IsExtensionDisabled(extension->id()) &&
207 policy->MustRemainDisabled(
208 extension.get(), &disable_reason, NULL)) {
209 extension_prefs_->SetExtensionState(extension->id(), Extension::DISABLED);
210 extension_prefs_->AddDisableReason(extension->id(), disable_reason);
211 force_disabled = true;
213 UMA_HISTOGRAM_BOOLEAN("ExtensionInstalledLoader.ForceDisabled",
214 force_disabled);
217 if (!extension.get()) {
218 ExtensionErrorReporter::GetInstance()->ReportLoadError(
219 info.extension_path,
220 error,
221 extension_service_->profile(),
222 false); // Be quiet.
223 return;
226 if (write_to_prefs)
227 extension_prefs_->UpdateManifest(extension.get());
229 extension_service_->AddExtension(extension.get());
232 void InstalledLoader::LoadAllExtensions() {
233 DCHECK_CURRENTLY_ON(BrowserThread::UI);
234 TRACE_EVENT0("browser,startup", "InstalledLoader::LoadAllExtensions");
235 SCOPED_UMA_HISTOGRAM_TIMER("Extensions.LoadAllTime2");
236 base::TimeTicks start_time = base::TimeTicks::Now();
238 Profile* profile = extension_service_->profile();
239 scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info(
240 extension_prefs_->GetInstalledExtensionsInfo());
242 std::vector<int> reload_reason_counts(NUM_MANIFEST_RELOAD_REASONS, 0);
243 bool should_write_prefs = false;
245 for (size_t i = 0; i < extensions_info->size(); ++i) {
246 ExtensionInfo* info = extensions_info->at(i).get();
248 // Skip extensions that were loaded from the command-line because we don't
249 // want those to persist across browser restart.
250 if (info->extension_location == Manifest::COMMAND_LINE)
251 continue;
253 ManifestReloadReason reload_reason = ShouldReloadExtensionManifest(*info);
254 ++reload_reason_counts[reload_reason];
256 if (reload_reason != NOT_NEEDED) {
257 // Reloading an extension reads files from disk. We do this on the
258 // UI thread because reloads should be very rare, and the complexity
259 // added by delaying the time when the extensions service knows about
260 // all extensions is significant. See crbug.com/37548 for details.
261 // |allow_io| disables tests that file operations run on the file
262 // thread.
263 base::ThreadRestrictions::ScopedAllowIO allow_io;
265 std::string error;
266 scoped_refptr<const Extension> extension(
267 file_util::LoadExtension(info->extension_path,
268 info->extension_location,
269 GetCreationFlags(info),
270 &error));
272 if (!extension.get()) {
273 ExtensionErrorReporter::GetInstance()->ReportLoadError(
274 info->extension_path,
275 error,
276 profile,
277 false); // Be quiet.
278 continue;
281 extensions_info->at(i)->extension_manifest.reset(
282 static_cast<base::DictionaryValue*>(
283 extension->manifest()->value()->DeepCopy()));
284 should_write_prefs = true;
288 for (size_t i = 0; i < extensions_info->size(); ++i) {
289 if (extensions_info->at(i)->extension_location != Manifest::COMMAND_LINE)
290 Load(*extensions_info->at(i), should_write_prefs);
293 extension_service_->OnLoadedInstalledExtensions();
295 // The histograms Extensions.ManifestReload* allow us to validate
296 // the assumption that reloading manifest is a rare event.
297 UMA_HISTOGRAM_COUNTS_100("Extensions.ManifestReloadNotNeeded",
298 reload_reason_counts[NOT_NEEDED]);
299 UMA_HISTOGRAM_COUNTS_100("Extensions.ManifestReloadUnpackedDir",
300 reload_reason_counts[UNPACKED_DIR]);
301 UMA_HISTOGRAM_COUNTS_100("Extensions.ManifestReloadNeedsRelocalization",
302 reload_reason_counts[NEEDS_RELOCALIZATION]);
304 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadAll",
305 extension_registry_->enabled_extensions().size());
306 UMA_HISTOGRAM_COUNTS_100("Extensions.Disabled",
307 extension_registry_->disabled_extensions().size());
309 // TODO(rkaplow): Obsolete this when verified similar to LoadAllTime2.
310 UMA_HISTOGRAM_TIMES("Extensions.LoadAllTime",
311 base::TimeTicks::Now() - start_time);
312 RecordExtensionsMetrics();
315 void InstalledLoader::RecordExtensionsMetrics() {
316 Profile* profile = extension_service_->profile();
318 int app_user_count = 0;
319 int app_external_count = 0;
320 int hosted_app_count = 0;
321 int legacy_packaged_app_count = 0;
322 int platform_app_count = 0;
323 int user_script_count = 0;
324 int content_pack_count = 0;
325 int extension_user_count = 0;
326 int extension_external_count = 0;
327 int theme_count = 0;
328 int page_action_count = 0;
329 int browser_action_count = 0;
330 int disabled_for_permissions_count = 0;
331 int non_webstore_ntp_override_count = 0;
332 int incognito_allowed_count = 0;
333 int incognito_not_allowed_count = 0;
334 int file_access_allowed_count = 0;
335 int file_access_not_allowed_count = 0;
336 int eventless_event_pages_count = 0;
338 const ExtensionSet& extensions = extension_registry_->enabled_extensions();
339 ExtensionActionManager* extension_action_manager =
340 ExtensionActionManager::Get(profile);
341 for (ExtensionSet::const_iterator iter = extensions.begin();
342 iter != extensions.end();
343 ++iter) {
344 const Extension* extension = iter->get();
345 Manifest::Location location = extension->location();
346 Manifest::Type type = extension->GetType();
348 // For the first few metrics, include all extensions and apps (component,
349 // unpacked, etc). It's good to know these locations, and it doesn't
350 // muck up any of the stats. Later, though, we want to omit component and
351 // unpacked, as they are less interesting.
352 if (extension->is_app())
353 UMA_HISTOGRAM_ENUMERATION(
354 "Extensions.AppLocation", location, Manifest::NUM_LOCATIONS);
355 else if (extension->is_extension())
356 UMA_HISTOGRAM_ENUMERATION(
357 "Extensions.ExtensionLocation", location, Manifest::NUM_LOCATIONS);
359 if (!ManifestURL::UpdatesFromGallery(extension)) {
360 UMA_HISTOGRAM_ENUMERATION(
361 "Extensions.NonWebstoreLocation", location, Manifest::NUM_LOCATIONS);
363 // Check for inconsistencies if the extension was supposedly installed
364 // from the webstore.
365 enum {
366 BAD_UPDATE_URL = 0,
367 // This value was a mistake. Turns out sideloaded extensions can
368 // have the from_webstore bit if they update from the webstore.
369 DEPRECATED_IS_EXTERNAL = 1,
371 if (extension->from_webstore()) {
372 UMA_HISTOGRAM_ENUMERATION(
373 "Extensions.FromWebstoreInconsistency", BAD_UPDATE_URL, 2);
377 if (Manifest::IsExternalLocation(location)) {
378 // See loop below for DISABLED.
379 if (ManifestURL::UpdatesFromGallery(extension)) {
380 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalItemState",
381 EXTERNAL_ITEM_WEBSTORE_ENABLED,
382 EXTERNAL_ITEM_MAX_ITEMS);
383 } else {
384 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalItemState",
385 EXTERNAL_ITEM_NONWEBSTORE_ENABLED,
386 EXTERNAL_ITEM_MAX_ITEMS);
390 // From now on, don't count component extensions, since they are only
391 // extensions as an implementation detail. Continue to count unpacked
392 // extensions for a few metrics.
393 if (location == Manifest::COMPONENT)
394 continue;
396 // Histogram for non-webstore extensions overriding new tab page should
397 // include unpacked extensions.
398 if (!extension->from_webstore() &&
399 URLOverrides::GetChromeURLOverrides(extension).count("newtab")) {
400 ++non_webstore_ntp_override_count;
403 // Don't count unpacked extensions anymore, either.
404 if (Manifest::IsUnpackedLocation(location))
405 continue;
407 UMA_HISTOGRAM_ENUMERATION("Extensions.ManifestVersion",
408 extension->manifest_version(),
409 10); // TODO(kalman): Why 10 manifest versions?
411 // We might have wanted to count legacy packaged apps here, too, since they
412 // are effectively extensions. Unfortunately, it's too late, as we don't
413 // want to mess up the existing stats.
414 if (type == Manifest::TYPE_EXTENSION) {
415 UMA_HISTOGRAM_ENUMERATION("Extensions.BackgroundPageType",
416 GetBackgroundPageType(extension),
417 NUM_BACKGROUND_PAGE_TYPES);
419 if (GetBackgroundPageType(extension) == EVENT_PAGE) {
420 // Count extension event pages with no registered events. Either the
421 // event page is badly designed, or there may be a bug where the event
422 // page failed to start after an update (crbug.com/469361).
423 if (EventRouter::Get(extension_service_->profile())->
424 GetRegisteredEvents(extension->id()).size() == 0) {
425 ++eventless_event_pages_count;
426 VLOG(1) << "Event page without registered event listeners: "
427 << extension->id() << " " << extension->name();
432 // Using an enumeration shows us the total installed ratio across all users.
433 // Using the totals per user at each startup tells us the distribution of
434 // usage for each user (e.g. 40% of users have at least one app installed).
435 UMA_HISTOGRAM_ENUMERATION(
436 "Extensions.LoadType", type, Manifest::NUM_LOAD_TYPES);
437 switch (type) {
438 case Manifest::TYPE_THEME:
439 ++theme_count;
440 break;
441 case Manifest::TYPE_USER_SCRIPT:
442 ++user_script_count;
443 break;
444 case Manifest::TYPE_HOSTED_APP:
445 ++hosted_app_count;
446 if (Manifest::IsExternalLocation(location)) {
447 ++app_external_count;
448 } else {
449 ++app_user_count;
451 break;
452 case Manifest::TYPE_LEGACY_PACKAGED_APP:
453 ++legacy_packaged_app_count;
454 if (Manifest::IsExternalLocation(location)) {
455 ++app_external_count;
456 } else {
457 ++app_user_count;
459 break;
460 case Manifest::TYPE_PLATFORM_APP:
461 ++platform_app_count;
462 if (Manifest::IsExternalLocation(location)) {
463 ++app_external_count;
464 } else {
465 ++app_user_count;
467 break;
468 case Manifest::TYPE_EXTENSION:
469 default:
470 if (Manifest::IsExternalLocation(location)) {
471 ++extension_external_count;
472 } else {
473 ++extension_user_count;
475 break;
478 if (extension_action_manager->GetPageAction(*extension))
479 ++page_action_count;
481 if (extension_action_manager->GetBrowserAction(*extension))
482 ++browser_action_count;
484 if (SupervisedUserInfo::IsContentPack(extension))
485 ++content_pack_count;
487 RecordCreationFlags(extension);
489 ExtensionService::RecordPermissionMessagesHistogram(
490 extension, "Extensions.Permissions_Load2");
492 // For incognito and file access, skip anything that doesn't appear in
493 // settings. Also, policy-installed (and unpacked of course, checked above)
494 // extensions are boring.
495 if (extension->ShouldDisplayInExtensionSettings() &&
496 !Manifest::IsPolicyLocation(extension->location())) {
497 if (extension->can_be_incognito_enabled()) {
498 if (util::IsIncognitoEnabled(extension->id(), profile))
499 ++incognito_allowed_count;
500 else
501 ++incognito_not_allowed_count;
503 if (extension->wants_file_access()) {
504 if (util::AllowFileAccess(extension->id(), profile))
505 ++file_access_allowed_count;
506 else
507 ++file_access_not_allowed_count;
512 const ExtensionSet& disabled_extensions =
513 extension_registry_->disabled_extensions();
515 for (ExtensionSet::const_iterator ex = disabled_extensions.begin();
516 ex != disabled_extensions.end();
517 ++ex) {
518 if (extension_prefs_->DidExtensionEscalatePermissions((*ex)->id())) {
519 ++disabled_for_permissions_count;
521 RecordDisableReasons(extension_prefs_->GetDisableReasons((*ex)->id()));
522 if (Manifest::IsExternalLocation((*ex)->location())) {
523 // See loop above for ENABLED.
524 if (ManifestURL::UpdatesFromGallery(ex->get())) {
525 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalItemState",
526 EXTERNAL_ITEM_WEBSTORE_DISABLED,
527 EXTERNAL_ITEM_MAX_ITEMS);
528 } else {
529 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalItemState",
530 EXTERNAL_ITEM_NONWEBSTORE_DISABLED,
531 EXTERNAL_ITEM_MAX_ITEMS);
536 scoped_ptr<ExtensionPrefs::ExtensionsInfo> uninstalled_extensions_info(
537 extension_prefs_->GetUninstalledExtensionsInfo());
538 for (size_t i = 0; i < uninstalled_extensions_info->size(); ++i) {
539 ExtensionInfo* info = uninstalled_extensions_info->at(i).get();
540 if (Manifest::IsExternalLocation(info->extension_location)) {
541 std::string update_url;
542 if (info->extension_manifest->GetString("update_url", &update_url) &&
543 extension_urls::IsWebstoreUpdateUrl(GURL(update_url))) {
544 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalItemState",
545 EXTERNAL_ITEM_WEBSTORE_UNINSTALLED,
546 EXTERNAL_ITEM_MAX_ITEMS);
547 } else {
548 UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalItemState",
549 EXTERNAL_ITEM_NONWEBSTORE_UNINSTALLED,
550 EXTERNAL_ITEM_MAX_ITEMS);
555 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadApp",
556 app_user_count + app_external_count);
557 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadAppUser", app_user_count);
558 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadAppExternal", app_external_count);
559 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadHostedApp", hosted_app_count);
560 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPackagedApp",
561 legacy_packaged_app_count);
562 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPlatformApp", platform_app_count);
563 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExtension",
564 extension_user_count + extension_external_count);
565 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExtensionUser",
566 extension_user_count);
567 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExtensionExternal",
568 extension_external_count);
569 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadUserScript", user_script_count);
570 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadTheme", theme_count);
571 // Histogram name different for legacy reasons.
572 UMA_HISTOGRAM_COUNTS_100("PageActionController.ExtensionsWithPageActions",
573 page_action_count);
574 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadBrowserAction",
575 browser_action_count);
576 UMA_HISTOGRAM_COUNTS_100("Extensions.LoadContentPack", content_pack_count);
577 UMA_HISTOGRAM_COUNTS_100("Extensions.DisabledForPermissions",
578 disabled_for_permissions_count);
579 UMA_HISTOGRAM_COUNTS_100("Extensions.NonWebStoreNewTabPageOverrides",
580 non_webstore_ntp_override_count);
581 if (incognito_allowed_count + incognito_not_allowed_count > 0) {
582 UMA_HISTOGRAM_COUNTS_100("Extensions.IncognitoAllowed",
583 incognito_allowed_count);
584 UMA_HISTOGRAM_COUNTS_100("Extensions.IncognitoNotAllowed",
585 incognito_not_allowed_count);
587 if (file_access_allowed_count + file_access_not_allowed_count > 0) {
588 UMA_HISTOGRAM_COUNTS_100("Extensions.FileAccessAllowed",
589 file_access_allowed_count);
590 UMA_HISTOGRAM_COUNTS_100("Extensions.FileAccessNotAllowed",
591 file_access_not_allowed_count);
593 UMA_HISTOGRAM_COUNTS_100("Extensions.CorruptExtensionTotalDisables",
594 extension_prefs_->GetCorruptedDisableCount());
595 UMA_HISTOGRAM_COUNTS_100("Extensions.EventlessEventPages",
596 eventless_event_pages_count);
599 int InstalledLoader::GetCreationFlags(const ExtensionInfo* info) {
600 int flags = extension_prefs_->GetCreationFlags(info->extension_id);
601 if (!Manifest::IsUnpackedLocation(info->extension_location))
602 flags |= Extension::REQUIRE_KEY;
603 if (extension_prefs_->AllowFileAccess(info->extension_id))
604 flags |= Extension::ALLOW_FILE_ACCESS;
605 return flags;
608 } // namespace extensions