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/extension_action_manager.h"
15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/extensions/extension_error_reporter.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
17cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/browser/extensions/extension_util.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/common/extensions/api/managed_mode_private/managed_mode_handler.h"
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/extensions/extension_constants.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"
26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "extensions/browser/api/runtime/runtime_api.h"
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_prefs.h"
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_registry.h"
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extension_system.h"
30f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/browser/management_policy.h"
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
32c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "extensions/common/extension_l10n_util.h"
33cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "extensions/common/extension_set.h"
34a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "extensions/common/file_util.h"
353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest.h"
36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "extensions/common/manifest_constants.h"
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/manifest_handlers/background_info.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)using base::UserMetricsAction;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)namespace extensions {
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace errors = manifest_errors;
45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The following enumeration is used in histograms matching
49cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Extensions.ManifestReload*.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum ManifestReloadReason {
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NOT_NEEDED = 0,        // Reload not needed.
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  UNPACKED_DIR,          // Unpacked directory.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NEEDS_RELOCALIZATION,  // The locale has changed since we read this extension.
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  CORRUPT_PREFERENCES,   // The manifest in the preferences is corrupt.
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // New enum values must go above here.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NUM_MANIFEST_RELOAD_REASONS
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Used in histogram Extension.BackgroundPageType.
61868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)enum BackgroundPageType {
62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  NO_BACKGROUND_PAGE = 0,
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  BACKGROUND_PAGE_PERSISTENT,
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EVENT_PAGE,
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // New enum values must go above here.
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  NUM_BACKGROUND_PAGE_TYPES
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)};
69868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Used in histogram Extensions.ExternalItemState.
71c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdochenum ExternalItemState {
72c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch  DEPRECATED_EXTERNAL_ITEM_DISABLED = 0,
73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  DEPRECATED_EXTERNAL_ITEM_ENABLED,
74cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXTERNAL_ITEM_WEBSTORE_DISABLED,
75cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXTERNAL_ITEM_WEBSTORE_ENABLED,
76cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXTERNAL_ITEM_NONWEBSTORE_DISABLED,
77cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXTERNAL_ITEM_NONWEBSTORE_ENABLED,
78cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXTERNAL_ITEM_WEBSTORE_UNINSTALLED,
79cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXTERNAL_ITEM_NONWEBSTORE_UNINSTALLED,
80cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // New enum values must go above here.
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  EXTERNAL_ITEM_MAX_ITEMS
83c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch};
84c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool IsManifestCorrupt(const base::DictionaryValue* manifest) {
863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!manifest)
873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return false;
883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Because of bug #272524 sometimes manifests got mangled in the preferences
903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // file, one particularly bad case resulting in having both a background page
913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // and background scripts values. In those situations we want to reload the
923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // manifest from the extension to fix this.
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::Value* background_page;
945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const base::Value* background_scripts;
953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return manifest->Get(manifest_keys::kBackgroundPage, &background_page) &&
963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      manifest->Get(manifest_keys::kBackgroundScripts, &background_scripts);
973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ManifestReloadReason ShouldReloadExtensionManifest(const ExtensionInfo& info) {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Always reload manifests of unpacked extensions, because they can change
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on disk independent of the manifest in our prefs.
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (Manifest::IsUnpackedLocation(info.extension_location))
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return UNPACKED_DIR;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Reload the manifest if it needs to be relocalized.
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (extension_l10n_util::ShouldRelocalizeManifest(
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          info.extension_manifest.get()))
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NEEDS_RELOCALIZATION;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  // Reload if the copy of the manifest in the preferences is corrupt.
1113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (IsManifestCorrupt(info.extension_manifest.get()))
1123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return CORRUPT_PREFERENCES;
1133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NOT_NEEDED;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
117868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)BackgroundPageType GetBackgroundPageType(const Extension* extension) {
118868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!BackgroundInfo::HasBackgroundPage(extension))
119868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return NO_BACKGROUND_PAGE;
120868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (BackgroundInfo::HasPersistentBackgroundPage(extension))
121868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    return BACKGROUND_PAGE_PERSISTENT;
122868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return EVENT_PAGE;
123868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)}
124868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
125cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Records the creation flags of an extension grouped by
126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// Extension::InitFromValueFlags.
127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void RecordCreationFlags(const Extension* extension) {
128cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (int i = 0; i < Extension::kInitFromValueFlagBits; ++i) {
129cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    int flag = 1 << i;
130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (extension->creation_flags() & flag) {
131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      UMA_HISTOGRAM_ENUMERATION(
132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          "Extensions.LoadCreationFlags", i, Extension::kInitFromValueFlagBits);
133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
134cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
135cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
136cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InstalledLoader::InstalledLoader(ExtensionService* extension_service)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : extension_service_(extension_service),
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extension_registry_(ExtensionRegistry::Get(extension_service->profile())),
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      extension_prefs_(ExtensionPrefs::Get(extension_service->profile())) {}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InstalledLoader::~InstalledLoader() {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstalledLoader::Load(const ExtensionInfo& info, bool write_to_prefs) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<const Extension> extension(NULL);
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (info.extension_manifest) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension = Extension::Create(
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        info.extension_path,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        info.extension_location,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *info.extension_manifest,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetCreationFlags(&info),
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        &error);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error = errors::kManifestUnreadable;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Once installed, non-unpacked extensions cannot change their IDs (e.g., by
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // updating the 'key' field in their manifest).
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(jstritar): migrate preferences when unpacked extensions change IDs.
164868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (extension.get() && !Manifest::IsUnpackedLocation(extension->location()) &&
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info.extension_id != extension->id()) {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error = errors::kCannotChangeExtensionID;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    extension = NULL;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check policy on every load in case an extension was blacklisted while
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Chrome was not running.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const ManagementPolicy* policy = extensions::ExtensionSystem::Get(
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension_service_->profile())->management_policy();
174f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (extension.get()) {
175f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    Extension::DisableReason disable_reason = Extension::DISABLE_NONE;
1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool force_disabled = false;
177f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    if (!policy->UserMayLoad(extension.get(), NULL)) {
178f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // The error message from UserMayInstall() often contains the extension ID
179f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      // and is therefore not well suited to this UI.
180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      error = errors::kDisabledByPolicy;
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      extension = NULL;
182f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    } else if (!extension_prefs_->IsExtensionDisabled(extension->id()) &&
183f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)               policy->MustRemainDisabled(extension, &disable_reason, NULL)) {
184f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      extension_prefs_->SetExtensionState(extension->id(), Extension::DISABLED);
185f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      extension_prefs_->AddDisableReason(extension->id(), disable_reason);
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      force_disabled = true;
187f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    }
1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    UMA_HISTOGRAM_BOOLEAN("ExtensionInstalledLoader.ForceDisabled",
1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          force_disabled);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
192868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!extension.get()) {
193010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    ExtensionErrorReporter::GetInstance()->ReportLoadError(
194010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        info.extension_path,
195010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        error,
196010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        extension_service_->profile(),
197010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        false);  // Be quiet.
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (write_to_prefs)
202868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    extension_prefs_->UpdateManifest(extension.get());
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
204868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  extension_service_->AddExtension(extension.get());
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstalledLoader::LoadAllExtensions() {
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::TimeTicks start_time = base::TimeTicks::Now();
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
212cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Profile* profile = extension_service_->profile();
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ExtensionPrefs::ExtensionsInfo> extensions_info(
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extension_prefs_->GetInstalledExtensionsInfo());
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<int> reload_reason_counts(NUM_MANIFEST_RELOAD_REASONS, 0);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool should_write_prefs = false;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < extensions_info->size(); ++i) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ExtensionInfo* info = extensions_info->at(i).get();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Skip extensions that were loaded from the command-line because we don't
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // want those to persist across browser restart.
2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (info->extension_location == Manifest::COMMAND_LINE)
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      continue;
2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ManifestReloadReason reload_reason = ShouldReloadExtensionManifest(*info);
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++reload_reason_counts[reload_reason];
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (reload_reason != NOT_NEEDED) {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // Reloading an extension reads files from disk.  We do this on the
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // UI thread because reloads should be very rare, and the complexity
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // added by delaying the time when the extensions service knows about
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // all extensions is significant.  See crbug.com/37548 for details.
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // |allow_io| disables tests that file operations run on the file
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // thread.
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::ThreadRestrictions::ScopedAllowIO allow_io;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string error;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_refptr<const Extension> extension(
241a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch          file_util::LoadExtension(info->extension_path,
242a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                   info->extension_location,
243a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                   GetCreationFlags(info),
244a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch                                   &error));
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      if (!extension.get()) {
247010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        ExtensionErrorReporter::GetInstance()->ReportLoadError(
248010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            info->extension_path,
249010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            error,
250cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            profile,
251010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            false);  // Be quiet.
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extensions_info->at(i)->extension_manifest.reset(
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          static_cast<base::DictionaryValue*>(
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              extension->manifest()->value()->DeepCopy()));
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      should_write_prefs = true;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < extensions_info->size(); ++i) {
263cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (extensions_info->at(i)->extension_location != Manifest::COMMAND_LINE)
264cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      Load(*extensions_info->at(i), should_write_prefs);
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension_service_->OnLoadedInstalledExtensions();
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The histograms Extensions.ManifestReload* allow us to validate
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the assumption that reloading manifest is a rare event.
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.ManifestReloadNotNeeded",
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           reload_reason_counts[NOT_NEEDED]);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.ManifestReloadUnpackedDir",
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           reload_reason_counts[UNPACKED_DIR]);
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.ManifestReloadNeedsRelocalization",
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           reload_reason_counts[NEEDS_RELOCALIZATION]);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadAll",
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           extension_registry_->enabled_extensions().size());
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.Disabled",
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                           extension_registry_->disabled_extensions().size());
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_TIMES("Extensions.LoadAllTime",
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      base::TimeTicks::Now() - start_time);
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int app_user_count = 0;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int app_external_count = 0;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int hosted_app_count = 0;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int legacy_packaged_app_count = 0;
2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int platform_app_count = 0;
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int user_script_count = 0;
2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int content_pack_count = 0;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int extension_user_count = 0;
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int extension_external_count = 0;
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int theme_count = 0;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int page_action_count = 0;
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int browser_action_count = 0;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int disabled_for_permissions_count = 0;
299558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  int non_webstore_ntp_override_count = 0;
300cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int incognito_allowed_count = 0;
301cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int incognito_not_allowed_count = 0;
302cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int file_access_allowed_count = 0;
303cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  int file_access_not_allowed_count = 0;
304cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const ExtensionSet& extensions = extension_registry_->enabled_extensions();
306cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  ExtensionActionManager* extension_action_manager =
307cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ExtensionActionManager::Get(profile);
308cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (ExtensionSet::const_iterator iter = extensions.begin();
309cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       iter != extensions.end();
310cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       ++iter) {
311cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const Extension* extension = *iter;
312cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    Manifest::Location location = extension->location();
313cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    Manifest::Type type = extension->GetType();
314cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
315cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // For the first few metrics, include all extensions and apps (component,
316cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // unpacked, etc). It's good to know these locations, and it doesn't
317cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // muck up any of the stats. Later, though, we want to omit component and
318cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // unpacked, as they are less interesting.
319cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (extension->is_app())
320cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      UMA_HISTOGRAM_ENUMERATION(
321cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          "Extensions.AppLocation", location, Manifest::NUM_LOCATIONS);
322cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    else if (extension->is_extension())
323cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      UMA_HISTOGRAM_ENUMERATION(
324cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          "Extensions.ExtensionLocation", location, Manifest::NUM_LOCATIONS);
325cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
326cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!ManifestURL::UpdatesFromGallery(extension)) {
327cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      UMA_HISTOGRAM_ENUMERATION(
328cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          "Extensions.NonWebstoreLocation", location, Manifest::NUM_LOCATIONS);
329cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
330cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // Check for inconsistencies if the extension was supposedly installed
331cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      // from the webstore.
332cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      enum {
333cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        BAD_UPDATE_URL = 0,
334cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // This value was a mistake. Turns out sideloaded extensions can
335cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        // have the from_webstore bit if they update from the webstore.
336cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        DEPRECATED_IS_EXTERNAL = 1,
337cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      };
338cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (extension->from_webstore()) {
339cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        UMA_HISTOGRAM_ENUMERATION(
340cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            "Extensions.FromWebstoreInconsistency", BAD_UPDATE_URL, 2);
341cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
3423240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    }
343cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3443240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    if (Manifest::IsExternalLocation(location)) {
3453240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      // See loop below for DISABLED.
346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (ManifestURL::UpdatesFromGallery(extension)) {
347c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalItemState",
348c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch                                  EXTERNAL_ITEM_WEBSTORE_ENABLED,
349c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch                                  EXTERNAL_ITEM_MAX_ITEMS);
350c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      } else {
351c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalItemState",
352c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch                                  EXTERNAL_ITEM_NONWEBSTORE_ENABLED,
353c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch                                  EXTERNAL_ITEM_MAX_ITEMS);
354c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      }
3553240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    }
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
357cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // From now on, don't count component extensions, since they are only
358cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // extensions as an implementation detail. Continue to count unpacked
359cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // extensions for a few metrics.
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (location == Manifest::COMPONENT)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
362cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
363558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // Histogram for non-webstore extensions overriding new tab page should
364558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    // include unpacked extensions.
365cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (!extension->from_webstore() &&
366cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        URLOverrides::GetChromeURLOverrides(extension).count("newtab")) {
367cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ++non_webstore_ntp_override_count;
368558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch    }
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
370cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Don't count unpacked extensions anymore, either.
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (Manifest::IsUnpackedLocation(location))
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
374868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION("Extensions.ManifestVersion",
375cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              extension->manifest_version(),
376cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                              10);  // TODO(kalman): Why 10 manifest versions?
377868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
378cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // We might have wanted to count legacy packaged apps here, too, since they
379cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // are effectively extensions. Unfortunately, it's too late, as we don't
380cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // want to mess up the existing stats.
381868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    if (type == Manifest::TYPE_EXTENSION) {
382cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      UMA_HISTOGRAM_ENUMERATION("Extensions.BackgroundPageType",
383cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                GetBackgroundPageType(extension),
384cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                NUM_BACKGROUND_PAGE_TYPES);
385868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    }
386868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Using an enumeration shows us the total installed ratio across all users.
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Using the totals per user at each startup tells us the distribution of
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // usage for each user (e.g. 40% of users have at least one app installed).
390cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION(
391cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        "Extensions.LoadType", type, Manifest::NUM_LOAD_TYPES);
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (type) {
3932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case Manifest::TYPE_THEME:
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ++theme_count;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
3962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case Manifest::TYPE_USER_SCRIPT:
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ++user_script_count;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case Manifest::TYPE_HOSTED_APP:
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ++hosted_app_count;
4012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (Manifest::IsExternalLocation(location)) {
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ++app_external_count;
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ++app_user_count;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case Manifest::TYPE_LEGACY_PACKAGED_APP:
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ++legacy_packaged_app_count;
4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (Manifest::IsExternalLocation(location)) {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ++app_external_count;
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ++app_user_count;
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case Manifest::TYPE_PLATFORM_APP:
4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ++platform_app_count;
4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (Manifest::IsExternalLocation(location)) {
4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          ++app_external_count;
4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        } else {
4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          ++app_user_count;
4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        }
4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        break;
4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      case Manifest::TYPE_EXTENSION:
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        if (Manifest::IsExternalLocation(location)) {
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ++extension_external_count;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        } else {
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ++extension_user_count;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        break;
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
432cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
433cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (extension_action_manager->GetPageAction(*extension))
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++page_action_count;
435cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
436cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (extension_action_manager->GetBrowserAction(*extension))
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++browser_action_count;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
439cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (ManagedModeInfo::IsContentPack(extension))
4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ++content_pack_count;
4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
442cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    RecordCreationFlags(extension);
443cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
444cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    ExtensionService::RecordPermissionMessagesHistogram(
44546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        extension, "Extensions.Permissions_Load2");
446cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
447cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // For incognito and file access, skip anything that doesn't appear in
448cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // settings. Also, policy-installed (and unpacked of course, checked above)
449cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // extensions are boring.
450cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    if (extension->ShouldDisplayInExtensionSettings() &&
451cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        !Manifest::IsPolicyLocation(extension->location())) {
452cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (extension->can_be_incognito_enabled()) {
453cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (util::IsIncognitoEnabled(extension->id(), profile))
454cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          ++incognito_allowed_count;
455cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        else
456cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          ++incognito_not_allowed_count;
457cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
458cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      if (extension->wants_file_access()) {
459cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        if (util::AllowFileAccess(extension->id(), profile))
460cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          ++file_access_allowed_count;
461cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        else
462cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          ++file_access_not_allowed_count;
463cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      }
464cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const ExtensionSet& disabled_extensions =
4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      extension_registry_->disabled_extensions();
469cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
470cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  for (ExtensionSet::const_iterator ex = disabled_extensions.begin();
471cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)       ex != disabled_extensions.end();
4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)       ++ex) {
473a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    if (extension_prefs_->DidExtensionEscalatePermissions((*ex)->id())) {
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++disabled_for_permissions_count;
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4763240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    if (Manifest::IsExternalLocation((*ex)->location())) {
4773240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch      // See loop above for ENABLED.
478c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      if (ManifestURL::UpdatesFromGallery(*ex)) {
479c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalItemState",
480c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch                                  EXTERNAL_ITEM_WEBSTORE_DISABLED,
481c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch                                  EXTERNAL_ITEM_MAX_ITEMS);
482c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      } else {
483c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch        UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalItemState",
484c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch                                  EXTERNAL_ITEM_NONWEBSTORE_DISABLED,
485c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch                                  EXTERNAL_ITEM_MAX_ITEMS);
4863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      }
4873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    }
4883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
4893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<ExtensionPrefs::ExtensionsInfo> uninstalled_extensions_info(
4913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      extension_prefs_->GetUninstalledExtensionsInfo());
4923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  for (size_t i = 0; i < uninstalled_extensions_info->size(); ++i) {
4933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    ExtensionInfo* info = uninstalled_extensions_info->at(i).get();
4943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    if (Manifest::IsExternalLocation(info->extension_location)) {
4953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      std::string update_url;
4963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      if (info->extension_manifest->GetString("update_url", &update_url) &&
4973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          extension_urls::IsWebstoreUpdateUrl(GURL(update_url))) {
4983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalItemState",
4993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                  EXTERNAL_ITEM_WEBSTORE_UNINSTALLED,
5003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                  EXTERNAL_ITEM_MAX_ITEMS);
5013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      } else {
5023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)        UMA_HISTOGRAM_ENUMERATION("Extensions.ExternalItemState",
5033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                  EXTERNAL_ITEM_NONWEBSTORE_UNINSTALLED,
5043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                                  EXTERNAL_ITEM_MAX_ITEMS);
505c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      }
5063240926e260ce088908e02ac07a6cf7b0c0cbf44Ben Murdoch    }
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadApp",
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           app_user_count + app_external_count);
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadAppUser", app_user_count);
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadAppExternal", app_external_count);
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadHostedApp", hosted_app_count);
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPackagedApp",
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           legacy_packaged_app_count);
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPlatformApp", platform_app_count);
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExtension",
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           extension_user_count + extension_external_count);
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExtensionUser",
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           extension_user_count);
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadExtensionExternal",
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           extension_external_count);
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadUserScript", user_script_count);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadTheme", theme_count);
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadPageAction", page_action_count);
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadBrowserAction",
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           browser_action_count);
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.LoadContentPack", content_pack_count);
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UMA_HISTOGRAM_COUNTS_100("Extensions.DisabledForPermissions",
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                           disabled_for_permissions_count);
531558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  UMA_HISTOGRAM_COUNTS_100("Extensions.NonWebStoreNewTabPageOverrides",
532558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch                           non_webstore_ntp_override_count);
533cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (incognito_allowed_count + incognito_not_allowed_count > 0) {
534cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS_100("Extensions.IncognitoAllowed",
535cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             incognito_allowed_count);
536cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS_100("Extensions.IncognitoNotAllowed",
537cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             incognito_not_allowed_count);
538cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
539cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (file_access_allowed_count + file_access_not_allowed_count > 0) {
540cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS_100("Extensions.FileAccessAllowed",
541cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             file_access_allowed_count);
542cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    UMA_HISTOGRAM_COUNTS_100("Extensions.FileAccessNotAllowed",
543cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                             file_access_not_allowed_count);
544cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int InstalledLoader::GetCreationFlags(const ExtensionInfo* info) {
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int flags = extension_prefs_->GetCreationFlags(info->extension_id);
5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!Manifest::IsUnpackedLocation(info->extension_location))
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= Extension::REQUIRE_KEY;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (extension_prefs_->AllowFileAccess(info->extension_id))
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    flags |= Extension::ALLOW_FILE_ACCESS;
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return flags;
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
557