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/component_loader.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include <string>
87dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/file_util.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_string_value_serializer.h"
12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/metrics/field_trial.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/extension_service.h"
156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "chrome/browser/search/hotword_service_factory.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_switches.h"
180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "chrome/common/chrome_version_info.h"
19cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "chrome/common/extensions/extension_constants.h"
2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/generated_resources.h"
2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/crx_file/id_util.h"
226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "content/public/browser/browser_context.h"
23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/public/browser/plugin_service.h"
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "extensions/common/extension.h"
26a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch#include "extensions/common/file_util.h"
273551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "extensions/common/manifest_constants.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/browser_resources.h"
297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "ui/base/l10n/l10n_util.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_CHROMEOS)
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "grit/keyboard_resources.h"
340529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#include "ui/file_manager/grit/file_manager_resources.h"
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "ui/keyboard/keyboard_util.h"
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/defaults.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chromeos/chromeos_switches.h"
455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/site_instance.h"
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/storage_partition.h"
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "extensions/browser/extensions_browser_client.h"
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h"
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_APP_LIST)
5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/grit/chromium_strings.h"
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)using content::BrowserThread;
56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace extensions {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static bool enable_background_extensions_during_testing = false;
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)std::string GenerateId(const base::DictionaryValue* manifest,
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       const base::FilePath& path) {
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string raw_key;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string id_input;
673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  CHECK(manifest->GetString(manifest_keys::kPublicKey, &raw_key));
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(Extension::ParsePEMKeyBytes(raw_key, &id_input));
6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  std::string id = crx_file::id_util::GenerateId(id_input);
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return id;
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#if defined(OS_CHROMEOS)
74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)scoped_ptr<base::DictionaryValue>
75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)LoadManifestOnFileThread(
76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const base::FilePath& chromevox_path, const char* manifest_filename) {
77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK_CURRENTLY_ON(content::BrowserThread::FILE);
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::string error;
79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> manifest(
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      file_util::LoadManifest(chromevox_path, manifest_filename, &error));
81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CHECK(manifest) << error;
82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  return manifest.Pass();
83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#endif  // defined(OS_CHROMEOS)
85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ComponentLoader::ComponentExtensionInfo::ComponentExtensionInfo(
893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const base::DictionaryValue* manifest, const base::FilePath& directory)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : manifest(manifest),
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      root_directory(directory) {
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!root_directory.IsAbsolute()) {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK(PathService::Get(chrome::DIR_RESOURCES, &root_directory));
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    root_directory = root_directory.Append(directory);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extension_id = GenerateId(manifest, root_directory);
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ComponentLoader::ComponentLoader(ExtensionServiceInterface* extension_service,
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 PrefService* profile_prefs,
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 PrefService* local_state,
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                 content::BrowserContext* browser_context)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : profile_prefs_(profile_prefs),
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      local_state_(local_state),
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      browser_context_(browser_context),
106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      extension_service_(extension_service),
107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      weak_factory_(this) {}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ComponentLoader::~ComponentLoader() {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ClearAllRegistered();
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ComponentLoader::LoadAll() {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (RegisteredComponentExtensions::iterator it =
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          component_extensions_.begin();
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      it != component_extensions_.end(); ++it) {
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Load(*it);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)base::DictionaryValue* ComponentLoader::ParseManifest(
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& manifest_contents) const {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JSONStringValueSerializer serializer(manifest_contents);
1243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<base::Value> manifest(serializer.Deserialize(NULL, NULL));
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!manifest.get() || !manifest->IsType(base::Value::TYPE_DICTIONARY)) {
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Failed to parse extension manifest.";
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Transfer ownership to the caller.
1313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return static_cast<base::DictionaryValue*>(manifest.release());
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ComponentLoader::ClearAllRegistered() {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (RegisteredComponentExtensions::iterator it =
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          component_extensions_.begin();
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      it != component_extensions_.end(); ++it) {
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      delete it->manifest;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  component_extensions_.clear();
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)std::string ComponentLoader::GetExtensionID(
1453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    int manifest_resource_id,
1463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const base::FilePath& root_directory) {
1473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string manifest_contents = ResourceBundle::GetSharedInstance().
1483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      GetRawDataResource(manifest_resource_id).as_string();
1493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::DictionaryValue* manifest = ParseManifest(manifest_contents);
1503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!manifest)
1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return std::string();
1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  ComponentExtensionInfo info(manifest, root_directory);
1543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return info.extension_id;
1553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
1563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ComponentLoader::Add(int manifest_resource_id,
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 const base::FilePath& root_directory) {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string manifest_contents =
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ResourceBundle::GetSharedInstance().GetRawDataResource(
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          manifest_resource_id).as_string();
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Add(manifest_contents, root_directory);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string ComponentLoader::Add(const std::string& manifest_contents,
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 const base::FilePath& root_directory) {
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The Value is kept for the lifetime of the ComponentLoader. This is
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // required in case LoadAll() is called again.
1693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::DictionaryValue* manifest = ParseManifest(manifest_contents);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (manifest)
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Add(manifest, root_directory);
172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return std::string();
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)std::string ComponentLoader::Add(const base::DictionaryValue* parsed_manifest,
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 const base::FilePath& root_directory) {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ComponentExtensionInfo info(parsed_manifest, root_directory);
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  component_extensions_.push_back(info);
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (extension_service_->is_ready())
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Load(info);
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return info.extension_id;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string ComponentLoader::AddOrReplace(const base::FilePath& path) {
185c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  base::FilePath absolute_path = base::MakeAbsoluteFilePath(path);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
1873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> manifest(
188a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch      file_util::LoadManifest(absolute_path, &error));
189c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!manifest) {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Could not load extension from '" <<
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  absolute_path.value() << "'. " << error;
19290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return std::string();
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Remove(GenerateId(manifest.get(), absolute_path));
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return Add(manifest.release(), absolute_path);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ComponentLoader::Reload(const std::string& extension_id) {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (RegisteredComponentExtensions::iterator it =
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         component_extensions_.begin(); it != component_extensions_.end();
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)         ++it) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (it->extension_id == extension_id) {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Load(*it);
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ComponentLoader::Load(const ComponentExtensionInfo& info) {
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(abarth): We should REQUIRE_MODERN_MANIFEST_VERSION once we've updated
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //               our component extensions to the new manifest version.
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int flags = Extension::REQUIRE_KEY;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string error;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<const Extension> extension(Extension::Create(
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      info.root_directory,
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Manifest::COMPONENT,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *info.manifest,
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      flags,
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &error));
223868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (!extension.get()) {
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << error;
2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK_EQ(info.extension_id, extension->id()) << extension->name();
229868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  extension_service_->AddComponentExtension(extension.get());
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ComponentLoader::Remove(const base::FilePath& root_directory) {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Find the ComponentExtensionInfo for the extension.
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisteredComponentExtensions::iterator it = component_extensions_.begin();
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (; it != component_extensions_.end(); ++it) {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (it->root_directory == root_directory) {
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Remove(GenerateId(it->manifest, root_directory));
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ComponentLoader::Remove(const std::string& id) {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisteredComponentExtensions::iterator it = component_extensions_.begin();
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (; it != component_extensions_.end(); ++it) {
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (it->extension_id == id) {
2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      UnloadComponent(&(*it));
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      it = component_extensions_.erase(it);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ComponentLoader::Exists(const std::string& id) const {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RegisteredComponentExtensions::const_iterator it =
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      component_extensions_.begin();
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (; it != component_extensions_.end(); ++it)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (it->extension_id == id)
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ComponentLoader::AddFileManagerExtension() {
2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_CHROMEOS)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NDEBUG
2667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const CommandLine* command_line = CommandLine::ForCurrentProcess();
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (command_line->HasSwitch(switches::kFileManagerExtensionPath)) {
2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::FilePath filemgr_extension_path(
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        command_line->GetSwitchValuePath(switches::kFileManagerExtensionPath));
270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    AddWithNameAndDescription(IDR_FILEMANAGER_MANIFEST,
271116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                              filemgr_extension_path,
272116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                              IDS_FILEMANAGER_APP_NAME,
273116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                              IDS_FILEMANAGER_APP_DESCRIPTION);
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // NDEBUG
277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AddWithNameAndDescription(IDR_FILEMANAGER_MANIFEST,
278116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            base::FilePath(FILE_PATH_LITERAL("file_manager")),
279116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            IDS_FILEMANAGER_APP_NAME,
280116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            IDS_FILEMANAGER_APP_DESCRIPTION);
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif  // defined(OS_CHROMEOS)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
284effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid ComponentLoader::AddVideoPlayerExtension() {
2850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#if defined(OS_CHROMEOS)
2860529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  Add(IDR_VIDEO_PLAYER_MANIFEST,
287effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      base::FilePath(FILE_PATH_LITERAL("video_player")));
2880529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch#endif  // defined(OS_CHROMEOS)
2890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch}
2900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
2910529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochvoid ComponentLoader::AddGalleryExtension() {
292cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(OS_CHROMEOS)
293cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  Add(IDR_GALLERY_MANIFEST, base::FilePath(FILE_PATH_LITERAL("gallery")));
294cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
295effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
296effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
2971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void ComponentLoader::AddHangoutServicesExtension() {
2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD) || defined(ENABLE_HANGOUT_SERVICES_EXTENSION)
2991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  Add(IDR_HANGOUT_SERVICES_MANIFEST,
3001e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL("hangout_services")));
3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ComponentLoader::AddHotwordAudioVerificationApp() {
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  CommandLine* command_line = CommandLine::ForCurrentProcess();
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (command_line->HasSwitch(switches::kEnableExperimentalHotwording)) {
3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    Add(IDR_HOTWORD_AUDIO_VERIFICATION_MANIFEST,
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::FilePath(FILE_PATH_LITERAL("hotword_audio_verification")));
3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ComponentLoader::AddHotwordHelperExtension() {
313a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (HotwordServiceFactory::IsHotwordAllowed(browser_context_)) {
3146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    CommandLine* command_line = CommandLine::ForCurrentProcess();
3156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (command_line->HasSwitch(switches::kEnableExperimentalHotwording)) {
3166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      Add(IDR_HOTWORD_MANIFEST,
3176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          base::FilePath(FILE_PATH_LITERAL("hotword")));
3186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    } else {
3196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      Add(IDR_HOTWORD_HELPER_MANIFEST,
3206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          base::FilePath(FILE_PATH_LITERAL("hotword_helper")));
3216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
3231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
3241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ComponentLoader::AddImageLoaderExtension() {
3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(IMAGE_LOADER_EXTENSION)
3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Add(IDR_IMAGE_LOADER_MANIFEST,
3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL("image_loader")));
3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // defined(IMAGE_LOADER_EXTENSION)
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)void ComponentLoader::AddNetworkSpeechSynthesisExtension() {
3330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  Add(IDR_NETWORK_SPEECH_SYNTHESIS_MANIFEST,
3340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL("network_speech_synthesis")));
3350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
3360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_CHROMEOS)
338f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ComponentLoader::AddChromeVoxExtension(
339f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const base::Closure& done_cb) {
340f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
341f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::FilePath resources_path;
342f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  PathService::Get(chrome::DIR_RESOURCES, &resources_path);
3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
344f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::FilePath chromevox_path =
345f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      resources_path.Append(extension_misc::kChromeVoxExtensionPath);
346cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
3475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const CommandLine* command_line = CommandLine::ForCurrentProcess();
3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool is_chromevox_next =
3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      command_line->HasSwitch(chromeos::switches::kEnableChromeVoxNext);
3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  bool is_guest = command_line->HasSwitch(chromeos::switches::kGuestSession);
3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const char* manifest_filename;
3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (is_chromevox_next) {
3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    manifest_filename =
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        is_guest ? extension_misc::kChromeVoxNextGuestManifestFilename
3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 : extension_misc::kChromeVoxNextManifestFilename;
3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } else {
3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    manifest_filename =
3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        is_guest ? extension_misc::kChromeVoxGuestManifestFilename
3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 : extension_misc::kChromeVoxManifestFilename;
3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
361f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  BrowserThread::PostTaskAndReplyWithResult(
362f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      BrowserThread::FILE,
363f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      FROM_HERE,
364f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(&LoadManifestOnFileThread, chromevox_path, manifest_filename),
365f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      base::Bind(&ComponentLoader::AddChromeVoxExtensionWithManifest,
366f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                 weak_factory_.GetWeakPtr(),
367f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                 chromevox_path,
368f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                 done_cb));
369f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)}
370f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
371f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ComponentLoader::AddChromeVoxExtensionWithManifest(
372f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const base::FilePath& chromevox_path,
373f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    const base::Closure& done_cb,
374f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    scoped_ptr<base::DictionaryValue> manifest) {
375f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
376f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::string extension_id = Add(manifest.release(), chromevox_path);
377f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  CHECK_EQ(extension_misc::kChromeVoxExtensionId, extension_id);
378f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!done_cb.is_null())
379f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    done_cb.Run();
3805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
3825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string ComponentLoader::AddChromeOsSpeechSynthesisExtension() {
3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const CommandLine* command_line = CommandLine::ForCurrentProcess();
3845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int idr = command_line->HasSwitch(chromeos::switches::kGuestSession) ?
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      IDR_SPEECH_SYNTHESIS_GUEST_MANIFEST : IDR_SPEECH_SYNTHESIS_MANIFEST;
3865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  std::string id = Add(idr,
3875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::FilePath(extension_misc::kSpeechSynthesisExtensionPath));
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EnableFileSystemInGuestMode(id);
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return id;
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
3915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
393116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid ComponentLoader::AddWithNameAndDescription(
394116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int manifest_resource_id,
395116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const base::FilePath& root_directory,
396116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int name_string_id,
397116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int description_string_id) {
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string manifest_contents =
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ResourceBundle::GetSharedInstance().GetRawDataResource(
4007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          manifest_resource_id).as_string();
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The Value is kept for the lifetime of the ComponentLoader. This is
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // required in case LoadAll() is called again.
4043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::DictionaryValue* manifest = ParseManifest(manifest_contents);
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (manifest) {
407116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    manifest->SetString(manifest_keys::kName,
408116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        l10n_util::GetStringUTF8(name_string_id));
409116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    manifest->SetString(manifest_keys::kDescription,
410116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                        l10n_util::GetStringUTF8(description_string_id));
4117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    Add(manifest, root_directory);
4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
4147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ComponentLoader::AddChromeApp() {
4167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#if defined(ENABLE_APP_LIST)
417116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AddWithNameAndDescription(IDR_CHROME_APP_MANIFEST,
418116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            base::FilePath(FILE_PATH_LITERAL("chrome_app")),
419116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            IDS_SHORT_PRODUCT_NAME,
420116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            IDS_CHROME_SHORTCUT_DESCRIPTION);
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void ComponentLoader::AddKeyboardApp() {
4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_CHROMEOS)
4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  Add(IDR_KEYBOARD_MANIFEST, base::FilePath(FILE_PATH_LITERAL("keyboard")));
427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif
428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
429c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ComponentLoader::AddWebStoreApp() {
431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AddWithNameAndDescription(IDR_WEBSTORE_MANIFEST,
432116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            base::FilePath(FILE_PATH_LITERAL("web_store")),
433116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            IDS_WEBSTORE_NAME_STORE,
434116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            IDS_WEBSTORE_APP_DESCRIPTION);
4357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
4367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static
4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ComponentLoader::EnableBackgroundExtensionsForTesting() {
4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enable_background_extensions_during_testing = true;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ComponentLoader::AddDefaultComponentExtensions(
4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool skip_session_components) {
4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Do not add component extensions that have background pages here -- add them
4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // to AddDefaultComponentExtensionsWithBackgroundPages.
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Add(IDR_MOBILE_MANIFEST,
4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL("/usr/share/chromeos-assets/mobile")));
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
450c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD)
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (browser_defaults::enable_help_app) {
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Add(IDR_HELP_MANIFEST, base::FilePath(FILE_PATH_LITERAL(
4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                               "/usr/share/chromeos-assets/helpapp")));
4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Skip all other extensions that require user session presence.
4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!skip_session_components) {
4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const CommandLine* command_line = CommandLine::ForCurrentProcess();
460c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!command_line->HasSwitch(chromeos::switches::kGuestSession))
46123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      Add(IDR_BOOKMARKS_MANIFEST,
46223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)          base::FilePath(FILE_PATH_LITERAL("bookmark_manager")));
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Add(IDR_CROSH_BUILTIN_MANIFEST, base::FilePath(FILE_PATH_LITERAL(
4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        "/usr/share/chromeos-assets/crosh_builtin")));
4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else  // !defined(OS_CHROMEOS)
4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!skip_session_components);
46923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  Add(IDR_BOOKMARKS_MANIFEST,
47023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL("bookmark_manager")));
4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Cloud Print component app. Not required on Chrome OS.
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Add(IDR_CLOUDPRINT_MANIFEST,
4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::FilePath(FILE_PATH_LITERAL("cloud_print")));
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!skip_session_components) {
4777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    AddWebStoreApp();
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddChromeApp();
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
481c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  AddKeyboardApp();
482c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AddDefaultComponentExtensionsWithBackgroundPages(skip_session_components);
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ComponentLoader::AddDefaultComponentExtensionsForKioskMode(
4875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool skip_session_components) {
4885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // No component extension for kiosk app launch splash screen.
4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (skip_session_components)
4905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return;
4915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Component extensions needed for kiosk apps.
4935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddFileManagerExtension();
4945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Add virtual keyboard.
4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  AddKeyboardApp();
4975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ComponentLoader::AddDefaultComponentExtensionsWithBackgroundPages(
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool skip_session_components) {
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const CommandLine* command_line = CommandLine::ForCurrentProcess();
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Component extensions with background pages are not enabled during tests
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // because they generate a lot of background behavior that can interfere.
5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!enable_background_extensions_during_testing &&
506a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      (command_line->HasSwitch(switches::kTestType) ||
5074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          command_line->HasSwitch(
5084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)              switches::kDisableComponentExtensionsWithBackgroundPages))) {
5092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if defined(OS_CHROMEOS) && defined(GOOGLE_CHROME_BUILD)
513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Since this is a v2 app it has a background page.
5141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  AddWithNameAndDescription(IDR_GENIUS_APP_MANIFEST,
5151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            base::FilePath(FILE_PATH_LITERAL(
5161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                "/usr/share/chromeos-assets/genius_app")),
5171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            IDS_GENIUS_APP_NAME,
5181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                            IDS_GENIUS_APP_DESCRIPTION);
519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!skip_session_components) {
522effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    AddVideoPlayerExtension();
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddFileManagerExtension();
5240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    AddGalleryExtension();
525effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
5261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    AddHangoutServicesExtension();
5271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    AddHotwordAudioVerificationApp();
5285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    AddHotwordHelperExtension();
5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    AddImageLoaderExtension();
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_SETTINGS_APP)
5322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Add(IDR_SETTINGS_APP_MANIFEST,
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::FilePath(FILE_PATH_LITERAL("settings_app")));
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // If (!enable_background_extensions_during_testing || this isn't a test)
5388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  //   install_feedback = false;
5398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  bool install_feedback = enable_background_extensions_during_testing;
5403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD)
5418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  install_feedback = true;
5423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#endif  // defined(GOOGLE_CHROME_BUILD)
5438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (install_feedback)
5448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    Add(IDR_FEEDBACK_MANIFEST, base::FilePath(FILE_PATH_LITERAL("feedback")));
5453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_CHROMEOS)
5471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!skip_session_components) {
548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD)
549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (!command_line->HasSwitch(
550116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            chromeos::switches::kDisableOfficeEditingComponentApp)) {
5515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      std::string id = Add(IDR_QUICKOFFICE_MANIFEST, base::FilePath(
552a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          FILE_PATH_LITERAL("/usr/share/chromeos-assets/quickoffice")));
5535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EnableFileSystemInGuestMode(id);
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#endif  // defined(GOOGLE_CHROME_BUILD)
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
557cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    Add(IDR_ECHO_MANIFEST,
558cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        base::FilePath(FILE_PATH_LITERAL("/usr/share/chromeos-assets/echo")));
5592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    if (!command_line->HasSwitch(chromeos::switches::kGuestSession)) {
5611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      Add(IDR_WALLPAPERMANAGER_MANIFEST,
5621e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)          base::FilePath(FILE_PATH_LITERAL("chromeos/wallpaper_manager")));
5631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    }
5641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
565cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    Add(IDR_FIRST_RUN_DIALOG_MANIFEST,
566cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        base::FilePath(FILE_PATH_LITERAL("chromeos/first_run/app")));
567a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Add(IDR_NETWORK_CONFIGURATION_MANIFEST,
5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::FilePath(FILE_PATH_LITERAL("chromeos/network_configuration")));
570ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch
571ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch    Add(IDR_CONNECTIVITY_DIAGNOSTICS_MANIFEST,
572ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch        base::FilePath(extension_misc::kConnectivityDiagnosticsPath));
573a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    Add(IDR_CONNECTIVITY_DIAGNOSTICS_LAUNCHER_MANIFEST,
574a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        base::FilePath(extension_misc::kConnectivityDiagnosticsLauncherPath));
5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Load ChromeVox extension now if spoken feedback is enabled.
578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  if (chromeos::AccessibilityManager::Get() &&
579868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      chromeos::AccessibilityManager::Get()->IsSpokenFeedbackEnabled()) {
580f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    AddChromeVoxExtension(base::Closure());
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // defined(OS_CHROMEOS)
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(ENABLE_GOOGLE_NOW)
5853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const char kEnablePrefix[] = "Enable";
5863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const char kFieldTrialName[] = "GoogleNow";
5873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string enable_prefix(kEnablePrefix);
5883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::string field_trial_result =
5893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      base::FieldTrialList::FindFullName(kFieldTrialName);
5900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
591e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  bool enabled_via_field_trial =
592e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      field_trial_result.compare(0, enable_prefix.length(), enable_prefix) == 0;
5930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
594e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  // Enable the feature on trybots and trunk builds.
595e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  bool enabled_via_trunk_build =
596e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      chrome::VersionInfo::GetChannel() == chrome::VersionInfo::CHANNEL_UNKNOWN;
5970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
598e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  bool enabled = enabled_via_field_trial || enabled_via_trunk_build;
5990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
600e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  if (!skip_session_components && enabled) {
6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Add(IDR_GOOGLE_NOW_MANIFEST,
6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        base::FilePath(FILE_PATH_LITERAL("google_now")));
6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
6060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD)
607f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#if !defined(OS_CHROMEOS)  // http://crbug.com/314799
6080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  AddNetworkSpeechSynthesisExtension();
609f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif
610e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch
6110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#endif  // defined(GOOGLE_CHROME_BUILD)
612a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
613a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(ENABLE_PLUGINS)
614a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::FilePath pdf_path;
615a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  content::PluginService* plugin_service =
616a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      content::PluginService::GetInstance();
617a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kOutOfProcessPdf) &&
618a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_path) &&
619a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      plugin_service->GetRegisteredPpapiPluginInfo(pdf_path)) {
620a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    Add(IDR_PDF_MANIFEST, base::FilePath(FILE_PATH_LITERAL("pdf")));
621a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
622a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif
6235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
6245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  Add(IDR_CRYPTOTOKEN_MANIFEST,
6255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      base::FilePath(FILE_PATH_LITERAL("cryptotoken")));
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ComponentLoader::UnloadComponent(ComponentExtensionInfo* component) {
6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  delete component->manifest;
6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (extension_service_->is_ready()) {
6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    extension_service_->
63258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        RemoveComponentExtension(component->extension_id);
6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void ComponentLoader::EnableFileSystemInGuestMode(const std::string& id) {
6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(OS_CHROMEOS)
6385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const CommandLine* command_line = CommandLine::ForCurrentProcess();
6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (command_line->HasSwitch(chromeos::switches::kGuestSession)) {
6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // TODO(dpolukhin): Hack to enable HTML5 temporary file system for
6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // the extension. Some component extensions don't work without temporary
6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // file system access. Make sure temporary file system is enabled in the off
6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // the record browser context (as that is the one used in guest session).
6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    content::BrowserContext* off_the_record_context =
6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        ExtensionsBrowserClient::Get()->GetOffTheRecordContext(
6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            browser_context_);
6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    GURL site = content::SiteInstance::GetSiteForURL(
6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        off_the_record_context, Extension::GetBaseURLFromExtensionId(id));
64903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::FileSystemContext* file_system_context =
6505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        content::BrowserContext::GetStoragePartitionForSite(
6515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)            off_the_record_context, site)->GetFileSystemContext();
6525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    file_system_context->EnableTemporaryFileSystemInIncognito();
6535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
6545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
6555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
6565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace extensions
658