installed_loader.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/installed_loader.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/api/runtime/runtime_api.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_action_manager.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/extensions/api/managed_mode_private/managed_mode_handler.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_file_util.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_l10n_util.h"
22558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "chrome/common/extensions/manifest_url_handler.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h"
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_prefs.h"
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_registry.h"
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
29f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/management_policy.h"
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest.h"
32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "extensions/common/manifest_constants.h"
33f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/background_info.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UserMetricsAction;
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
38868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace extensions {
39868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace errors = manifest_errors;
41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The following enumeration is used in histograms matching
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Extensions.ManifestReload* .  Values may be added, as long as existing
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// values are not changed.
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum ManifestReloadReason {
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOT_NEEDED = 0,  // Reload not needed.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UNPACKED_DIR,  // Unpacked directory.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NEEDS_RELOCALIZATION,  // The locale has changed since we read this extension.
513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CORRUPT_PREFERENCES,  // The manifest in the preferences is corrupt.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NUM_MANIFEST_RELOAD_REASONS
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Used in histogram Extension.BackgroundPageType. Values may be added, as
56868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// long as existing values are not changed.
57868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)enum BackgroundPageType {
58868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NO_BACKGROUND_PAGE = 0,
59868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  BACKGROUND_PAGE_PERSISTENT = 1,
60868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  EVENT_PAGE = 2,
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
63c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch// Used in histogram Extensions.ExternalItemState. Values may be added, as
64c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch// long as existing values are not changed.
65c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdochenum ExternalItemState {
66c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DEPRECATED_EXTERNAL_ITEM_DISABLED = 0,
67c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DEPRECATED_EXTERNAL_ITEM_ENABLED = 1,
68c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  EXTERNAL_ITEM_WEBSTORE_DISABLED = 2,
69c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  EXTERNAL_ITEM_WEBSTORE_ENABLED = 3,
70c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  EXTERNAL_ITEM_NONWEBSTORE_DISABLED = 4,
71c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  EXTERNAL_ITEM_NONWEBSTORE_ENABLED = 5,
723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXTERNAL_ITEM_WEBSTORE_UNINSTALLED = 6,
733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXTERNAL_ITEM_NONWEBSTORE_UNINSTALLED = 7,
743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  EXTERNAL_ITEM_MAX_ITEMS = 8
75c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch};
76c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool IsManifestCorrupt(const base::DictionaryValue* manifest) {
783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!manifest)
793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Because of bug #272524 sometimes manifests got mangled in the preferences
823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // file, one particularly bad case resulting in having both a background page
833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // and background scripts values. In those situations we want to reload the
843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // manifest from the extension to fix this.
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::Value* background_page;
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::Value* background_scripts;
873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return manifest->Get(manifest_keys::kBackgroundPage, &background_page) &&
883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      manifest->Get(manifest_keys::kBackgroundScripts, &background_scripts);
893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ManifestReloadReason ShouldReloadExtensionManifest(const ExtensionInfo& info) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Always reload manifests of unpacked extensions, because they can change
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on disk independent of the manifest in our prefs.
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (Manifest::IsUnpackedLocation(info.extension_location))
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return UNPACKED_DIR;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reload the manifest if it needs to be relocalized.
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (extension_l10n_util::ShouldRelocalizeManifest(
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          info.extension_manifest.get()))
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NEEDS_RELOCALIZATION;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Reload if the copy of the manifest in the preferences is corrupt.
1033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsManifestCorrupt(info.extension_manifest.get()))
1043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return CORRUPT_PREFERENCES;
1053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NOT_NEEDED;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)BackgroundPageType GetBackgroundPageType(const Extension* extension) {
110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!BackgroundInfo::HasBackgroundPage(extension))
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return NO_BACKGROUND_PAGE;
112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (BackgroundInfo::HasPersistentBackgroundPage(extension))
113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return BACKGROUND_PAGE_PERSISTENT;
114868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return EVENT_PAGE;
115868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
116868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InstalledLoader::InstalledLoader(ExtensionService* extension_service)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : extension_service_(extension_service),
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extension_registry_(ExtensionRegistry::Get(extension_service->profile())),
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extension_prefs_(extension_service->extension_prefs()) {}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InstalledLoader::~InstalledLoader() {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstalledLoader::Load(const ExtensionInfo& info, bool write_to_prefs) {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<const Extension> extension(NULL);
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (info.extension_manifest) {
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension = Extension::Create(
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        info.extension_path,
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        info.extension_location,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *info.extension_manifest,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetCreationFlags(&info),
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &error);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error = errors::kManifestUnreadable;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Once installed, non-unpacked extensions cannot change their IDs (e.g., by
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // updating the 'key' field in their manifest).
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(jstritar): migrate preferences when unpacked extensions change IDs.
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (extension.get() && !Manifest::IsUnpackedLocation(extension->location()) &&
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info.extension_id != extension->id()) {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error = errors::kCannotChangeExtensionID;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension = NULL;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::RecordAction(UserMetricsAction("Extensions.IDChangedError"));
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check policy on every load in case an extension was blacklisted while
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Chrome was not running.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ManagementPolicy* policy = extensions::ExtensionSystem::Get(
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension_service_->profile())->management_policy();
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (extension.get()) {
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Extension::DisableReason disable_reason = Extension::DISABLE_NONE;
1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool force_disabled = false;
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!policy->UserMayLoad(extension.get(), NULL)) {
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // The error message from UserMayInstall() often contains the extension ID
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // and is therefore not well suited to this UI.
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      error = errors::kDisabledByPolicy;
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      extension = NULL;
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    } else if (!extension_prefs_->IsExtensionDisabled(extension->id()) &&
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)               policy->MustRemainDisabled(extension, &disable_reason, NULL)) {
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      extension_prefs_->SetExtensionState(extension->id(), Extension::DISABLED);
166f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      extension_prefs_->AddDisableReason(extension->id(), disable_reason);
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      force_disabled = true;
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UMA_HISTOGRAM_BOOLEAN("ExtensionInstalledLoader.ForceDisabled",
1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          force_disabled);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
173868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!extension.get()) {
174868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    extension_service_->ReportExtensionLoadError(
175868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        info.extension_path, error, false);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (write_to_prefs)
180868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    extension_prefs_->UpdateManifest(extension.get());
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
182868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  extension_service_->AddExtension(extension.get());
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstalledLoader::LoadAllExtensions() {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeTicks start_time = base::TimeTicks::Now();
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info(
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension_prefs_->GetInstalledExtensionsInfo());
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<int> reload_reason_counts(NUM_MANIFEST_RELOAD_REASONS, 0);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool should_write_prefs = false;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < extensions_info->size(); ++i) {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionInfo* info = extensions_info->at(i).get();
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Skip extensions that were loaded from the command-line because we don't
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // want those to persist across browser restart.
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (info->extension_location == Manifest::COMMAND_LINE)
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ManifestReloadReason reload_reason = ShouldReloadExtensionManifest(*info);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++reload_reason_counts[reload_reason];
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Extensions.ManifestReloadEnumValue",
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              reload_reason, 100);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (reload_reason != NOT_NEEDED) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Reloading an extension reads files from disk.  We do this on the
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // UI thread because reloads should be very rare, and the complexity
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // added by delaying the time when the extensions service knows about
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // all extensions is significant.  See crbug.com/37548 for details.
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // |allow_io| disables tests that file operations run on the file
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // thread.
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::ThreadRestrictions::ScopedAllowIO allow_io;
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string error;
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_refptr<const Extension> extension(
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          extension_file_util::LoadExtension(
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              info->extension_path,
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              info->extension_location,
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              GetCreationFlags(info),
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              &error));
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
226868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (!extension.get()) {
227868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        extension_service_->ReportExtensionLoadError(
228868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)            info->extension_path, error, false);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extensions_info->at(i)->extension_manifest.reset(
2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          static_cast<base::DictionaryValue*>(
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              extension->manifest()->value()->DeepCopy()));
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      should_write_prefs = true;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < extensions_info->size(); ++i) {
2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (extensions_info->at(i)->extension_location == Manifest::COMMAND_LINE)
2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Load(*extensions_info->at(i), should_write_prefs);
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension_service_->OnLoadedInstalledExtensions();
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The histograms Extensions.ManifestReload* allow us to validate
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the assumption that reloading manifest is a rare event.
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.ManifestReloadNotNeeded",
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           reload_reason_counts[NOT_NEEDED]);
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.ManifestReloadUnpackedDir",
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           reload_reason_counts[UNPACKED_DIR]);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.ManifestReloadNeedsRelocalization",
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           reload_reason_counts[NEEDS_RELOCALIZATION]);
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadAll",
2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           extension_registry_->enabled_extensions().size());
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.Disabled",
2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           extension_registry_->disabled_extensions().size());
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_TIMES("Extensions.LoadAllTime",
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      base::TimeTicks::Now() - start_time);
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int app_user_count = 0;
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int app_external_count = 0;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int hosted_app_count = 0;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int legacy_packaged_app_count = 0;
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int platform_app_count = 0;
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int user_script_count = 0;
2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int content_pack_count = 0;
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int extension_user_count = 0;
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int extension_external_count = 0;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int theme_count = 0;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int page_action_count = 0;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int browser_action_count = 0;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int disabled_for_permissions_count = 0;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int item_user_count = 0;
278558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  int non_webstore_ntp_override_count = 0;
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const ExtensionSet& extensions = extension_registry_->enabled_extensions();
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionSet::const_iterator ex;
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (ex = extensions.begin(); ex != extensions.end(); ++ex) {
2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Manifest::Location location = (*ex)->location();
2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Manifest::Type type = (*ex)->GetType();
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*ex)->is_app()) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UMA_HISTOGRAM_ENUMERATION("Extensions.AppLocation",
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                location, 100);
2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (type == Manifest::TYPE_EXTENSION) {
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UMA_HISTOGRAM_ENUMERATION("Extensions.ExtensionLocation",
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                location, 100);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2913240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    if (!ManifestURL::UpdatesFromGallery(*ex)) {
2923240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      UMA_HISTOGRAM_ENUMERATION("Extensions.NonWebstoreLocation",
2933240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                location, 100);
2943240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    }
2953240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    if (Manifest::IsExternalLocation(location)) {
2963240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      // See loop below for DISABLED.
297c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      if (ManifestURL::UpdatesFromGallery(*ex)) {
298c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalItemState",
299c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch                                  EXTERNAL_ITEM_WEBSTORE_ENABLED,
300c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch                                  EXTERNAL_ITEM_MAX_ITEMS);
301c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      } else {
302c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalItemState",
303c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch                                  EXTERNAL_ITEM_NONWEBSTORE_ENABLED,
304c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch                                  EXTERNAL_ITEM_MAX_ITEMS);
305c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      }
3063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    }
3073240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    if ((*ex)->from_webstore()) {
3083240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      // Check for inconsistencies if the extension was supposedly installed
3093240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      // from the webstore.
3103240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      enum {
3113240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        BAD_UPDATE_URL = 0,
312c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        // This value was a mistake. Turns out sideloaded extensions can
313c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        // have the from_webstore bit if they update from the webstore.
314c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        DEPRECATED_IS_EXTERNAL = 1,
3153240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      };
3163240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      if (!ManifestURL::UpdatesFromGallery(*ex)) {
3173240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch        UMA_HISTOGRAM_ENUMERATION("Extensions.FromWebstoreInconsistency",
3183240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch                                  BAD_UPDATE_URL, 2);
3193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      }
3203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    }
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Don't count component extensions, since they are only extensions as an
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // implementation detail.
3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (location == Manifest::COMPONENT)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
326558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // Histogram for non-webstore extensions overriding new tab page should
327558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // include unpacked extensions.
328558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    if (!(*ex)->from_webstore()) {
329558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      const extensions::URLOverrides::URLOverrideMap& override_map =
330558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch          extensions::URLOverrides::GetChromeURLOverrides(ex->get());
331558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      if (override_map.find("newtab") != override_map.end()) {
332558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch        ++non_webstore_ntp_override_count;
333558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      }
334558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    }
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Don't count unpacked extensions, since they're a developer-specific
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // feature.
3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (Manifest::IsUnpackedLocation(location))
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
341868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Extensions.ManifestVersion",
342868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)                              (*ex)->manifest_version(), 10);
343868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
344868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (type == Manifest::TYPE_EXTENSION) {
3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      BackgroundPageType background_page_type =
3467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          GetBackgroundPageType(ex->get());
3477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      UMA_HISTOGRAM_ENUMERATION(
3487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          "Extensions.BackgroundPageType", background_page_type, 10);
349868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
350868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Using an enumeration shows us the total installed ratio across all users.
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Using the totals per user at each startup tells us the distribution of
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // usage for each user (e.g. 40% of users have at least one app installed).
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Extensions.LoadType", type, 100);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (type) {
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case Manifest::TYPE_THEME:
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ++theme_count;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case Manifest::TYPE_USER_SCRIPT:
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ++user_script_count;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
3622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case Manifest::TYPE_HOSTED_APP:
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ++hosted_app_count;
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (Manifest::IsExternalLocation(location)) {
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ++app_external_count;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ++app_user_count;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case Manifest::TYPE_LEGACY_PACKAGED_APP:
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ++legacy_packaged_app_count;
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (Manifest::IsExternalLocation(location)) {
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ++app_external_count;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ++app_user_count;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case Manifest::TYPE_PLATFORM_APP:
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ++platform_app_count;
3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (Manifest::IsExternalLocation(location)) {
3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          ++app_external_count;
3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        } else {
3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          ++app_user_count;
3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case Manifest::TYPE_EXTENSION:
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (Manifest::IsExternalLocation(location)) {
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ++extension_external_count;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ++extension_user_count;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (!Manifest::IsExternalLocation((*ex)->location()))
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++item_user_count;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionActionManager* extension_action_manager =
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ExtensionActionManager::Get(extension_service_->profile());
3997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (extension_action_manager->GetPageAction(*ex->get()))
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++page_action_count;
4017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (extension_action_manager->GetBrowserAction(*ex->get()))
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++browser_action_count;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (extensions::ManagedModeInfo::IsContentPack(ex->get()))
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ++content_pack_count;
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension_service_->RecordPermissionMessagesHistogram(
4087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        ex->get(), "Extensions.Permissions_Load");
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const ExtensionSet& disabled_extensions =
4125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extension_registry_->disabled_extensions();
4135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  for (ex = disabled_extensions.begin(); ex != disabled_extensions.end();
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       ++ex) {
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (extension_service_->extension_prefs()->
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DidExtensionEscalatePermissions((*ex)->id())) {
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++disabled_for_permissions_count;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4193240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    if (Manifest::IsExternalLocation((*ex)->location())) {
4203240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      // See loop above for ENABLED.
421c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      if (ManifestURL::UpdatesFromGallery(*ex)) {
422c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalItemState",
423c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch                                  EXTERNAL_ITEM_WEBSTORE_DISABLED,
424c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch                                  EXTERNAL_ITEM_MAX_ITEMS);
425c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      } else {
426c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalItemState",
427c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch                                  EXTERNAL_ITEM_NONWEBSTORE_DISABLED,
428c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch                                  EXTERNAL_ITEM_MAX_ITEMS);
4293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      }
4303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
4313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
4323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<ExtensionPrefs::ExtensionsInfo> uninstalled_extensions_info(
4343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      extension_prefs_->GetUninstalledExtensionsInfo());
4353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  for (size_t i = 0; i < uninstalled_extensions_info->size(); ++i) {
4363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ExtensionInfo* info = uninstalled_extensions_info->at(i).get();
4373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (Manifest::IsExternalLocation(info->extension_location)) {
4383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      std::string update_url;
4393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      if (info->extension_manifest->GetString("update_url", &update_url) &&
4403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          extension_urls::IsWebstoreUpdateUrl(GURL(update_url))) {
4413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalItemState",
4423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                  EXTERNAL_ITEM_WEBSTORE_UNINSTALLED,
4433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                  EXTERNAL_ITEM_MAX_ITEMS);
4443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      } else {
4453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalItemState",
4463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                  EXTERNAL_ITEM_NONWEBSTORE_UNINSTALLED,
4473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                  EXTERNAL_ITEM_MAX_ITEMS);
448c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      }
4493240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    }
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadAllUser", item_user_count);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadApp",
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           app_user_count + app_external_count);
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadAppUser", app_user_count);
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadAppExternal", app_external_count);
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadHostedApp", hosted_app_count);
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPackagedApp",
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           legacy_packaged_app_count);
4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPlatformApp", platform_app_count);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExtension",
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           extension_user_count + extension_external_count);
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExtensionUser",
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           extension_user_count);
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExtensionExternal",
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           extension_external_count);
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadUserScript", user_script_count);
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadTheme", theme_count);
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPageAction", page_action_count);
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadBrowserAction",
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           browser_action_count);
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadContentPack", content_pack_count);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.DisabledForPermissions",
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           disabled_for_permissions_count);
475558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  UMA_HISTOGRAM_COUNTS_100("Extensions.NonWebStoreNewTabPageOverrides",
476558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                           non_webstore_ntp_override_count);
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int InstalledLoader::GetCreationFlags(const ExtensionInfo* info) {
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int flags = extension_prefs_->GetCreationFlags(info->extension_id);
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!Manifest::IsUnpackedLocation(info->extension_location))
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= Extension::REQUIRE_KEY;
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (extension_prefs_->AllowFileAccess(info->extension_id))
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= Extension::ALLOW_FILE_ACCESS;
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return flags;
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
489