Temporarily re-enabling SizeAfterPrefChange test with traces (this time for Linux...
[chromium-blink-merge.git] / chrome / browser / extensions / component_loader.cc
blobcca90da20b2b4b9396d2297946ece53920ca7471
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/component_loader.h"
7 #include <map>
8 #include <string>
10 #include "base/command_line.h"
11 #include "base/file_util.h"
12 #include "base/json/json_string_value_serializer.h"
13 #include "base/metrics/field_trial.h"
14 #include "base/path_service.h"
15 #include "base/prefs/pref_change_registrar.h"
16 #include "chrome/browser/chrome_notification_types.h"
17 #include "chrome/browser/extensions/extension_service.h"
18 #include "chrome/browser/search/hotword_service_factory.h"
19 #include "chrome/common/chrome_paths.h"
20 #include "chrome/common/chrome_switches.h"
21 #include "chrome/common/chrome_version_info.h"
22 #include "chrome/common/extensions/extension_constants.h"
23 #include "chrome/common/pref_names.h"
24 #include "content/public/browser/notification_details.h"
25 #include "content/public/browser/notification_source.h"
26 #include "content/public/browser/plugin_service.h"
27 #include "extensions/common/extension.h"
28 #include "extensions/common/file_util.h"
29 #include "extensions/common/id_util.h"
30 #include "extensions/common/manifest_constants.h"
31 #include "grit/browser_resources.h"
32 #include "grit/generated_resources.h"
33 #include "ui/base/l10n/l10n_util.h"
34 #include "ui/base/resource/resource_bundle.h"
36 #if defined(OS_CHROMEOS)
37 #include "grit/keyboard_resources.h"
38 #include "ui/file_manager/grit/file_manager_resources.h"
39 #include "ui/keyboard/keyboard_util.h"
40 #endif
42 #if defined(GOOGLE_CHROME_BUILD)
43 #include "chrome/browser/defaults.h"
44 #endif
46 #if defined(OS_CHROMEOS)
47 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
48 #include "chrome/browser/chromeos/login/users/user_manager.h"
49 #include "chromeos/chromeos_switches.h"
50 #include "content/public/browser/site_instance.h"
51 #include "content/public/browser/storage_partition.h"
52 #include "extensions/browser/extensions_browser_client.h"
53 #include "webkit/browser/fileapi/file_system_context.h"
54 #endif
56 #if defined(ENABLE_APP_LIST)
57 #include "grit/chromium_strings.h"
58 #endif
60 namespace extensions {
62 namespace {
64 static bool enable_background_extensions_during_testing = false;
66 std::string LookupWebstoreName() {
67 const char kWebStoreNameFieldTrialName[] = "WebStoreName";
68 const char kStoreControl[] = "StoreControl";
69 const char kWebStore[] = "WebStore";
70 const char kGetApps[] = "GetApps";
71 const char kAddApps[] = "AddApps";
72 const char kMoreApps[] = "MoreApps";
74 typedef std::map<std::string, int> NameMap;
75 CR_DEFINE_STATIC_LOCAL(NameMap, names, ());
76 if (names.empty()) {
77 names.insert(std::make_pair(kStoreControl, IDS_WEBSTORE_NAME_STORE));
78 names.insert(std::make_pair(kWebStore, IDS_WEBSTORE_NAME_WEBSTORE));
79 names.insert(std::make_pair(kGetApps, IDS_WEBSTORE_NAME_GET_APPS));
80 names.insert(std::make_pair(kAddApps, IDS_WEBSTORE_NAME_ADD_APPS));
81 names.insert(std::make_pair(kMoreApps, IDS_WEBSTORE_NAME_MORE_APPS));
83 std::string field_trial_name =
84 base::FieldTrialList::FindFullName(kWebStoreNameFieldTrialName);
85 NameMap::iterator it = names.find(field_trial_name);
86 int string_id = it == names.end() ? names[kStoreControl] : it->second;
87 return l10n_util::GetStringUTF8(string_id);
90 std::string GenerateId(const base::DictionaryValue* manifest,
91 const base::FilePath& path) {
92 std::string raw_key;
93 std::string id_input;
94 CHECK(manifest->GetString(manifest_keys::kPublicKey, &raw_key));
95 CHECK(Extension::ParsePEMKeyBytes(raw_key, &id_input));
96 std::string id = id_util::GenerateId(id_input);
97 return id;
100 } // namespace
102 ComponentLoader::ComponentExtensionInfo::ComponentExtensionInfo(
103 const base::DictionaryValue* manifest, const base::FilePath& directory)
104 : manifest(manifest),
105 root_directory(directory) {
106 if (!root_directory.IsAbsolute()) {
107 CHECK(PathService::Get(chrome::DIR_RESOURCES, &root_directory));
108 root_directory = root_directory.Append(directory);
110 extension_id = GenerateId(manifest, root_directory);
113 ComponentLoader::ComponentLoader(ExtensionServiceInterface* extension_service,
114 PrefService* profile_prefs,
115 PrefService* local_state,
116 content::BrowserContext* browser_context)
117 : profile_prefs_(profile_prefs),
118 local_state_(local_state),
119 browser_context_(browser_context),
120 extension_service_(extension_service) {}
122 ComponentLoader::~ComponentLoader() {
123 ClearAllRegistered();
126 void ComponentLoader::LoadAll() {
127 for (RegisteredComponentExtensions::iterator it =
128 component_extensions_.begin();
129 it != component_extensions_.end(); ++it) {
130 Load(*it);
134 base::DictionaryValue* ComponentLoader::ParseManifest(
135 const std::string& manifest_contents) const {
136 JSONStringValueSerializer serializer(manifest_contents);
137 scoped_ptr<base::Value> manifest(serializer.Deserialize(NULL, NULL));
139 if (!manifest.get() || !manifest->IsType(base::Value::TYPE_DICTIONARY)) {
140 LOG(ERROR) << "Failed to parse extension manifest.";
141 return NULL;
143 // Transfer ownership to the caller.
144 return static_cast<base::DictionaryValue*>(manifest.release());
147 void ComponentLoader::ClearAllRegistered() {
148 for (RegisteredComponentExtensions::iterator it =
149 component_extensions_.begin();
150 it != component_extensions_.end(); ++it) {
151 delete it->manifest;
154 component_extensions_.clear();
157 std::string ComponentLoader::GetExtensionID(
158 int manifest_resource_id,
159 const base::FilePath& root_directory) {
160 std::string manifest_contents = ResourceBundle::GetSharedInstance().
161 GetRawDataResource(manifest_resource_id).as_string();
162 base::DictionaryValue* manifest = ParseManifest(manifest_contents);
163 if (!manifest)
164 return std::string();
166 ComponentExtensionInfo info(manifest, root_directory);
167 return info.extension_id;
170 std::string ComponentLoader::Add(int manifest_resource_id,
171 const base::FilePath& root_directory) {
172 std::string manifest_contents =
173 ResourceBundle::GetSharedInstance().GetRawDataResource(
174 manifest_resource_id).as_string();
175 return Add(manifest_contents, root_directory);
178 std::string ComponentLoader::Add(const std::string& manifest_contents,
179 const base::FilePath& root_directory) {
180 // The Value is kept for the lifetime of the ComponentLoader. This is
181 // required in case LoadAll() is called again.
182 base::DictionaryValue* manifest = ParseManifest(manifest_contents);
183 if (manifest)
184 return Add(manifest, root_directory);
185 return std::string();
188 std::string ComponentLoader::Add(const base::DictionaryValue* parsed_manifest,
189 const base::FilePath& root_directory) {
190 ComponentExtensionInfo info(parsed_manifest, root_directory);
191 component_extensions_.push_back(info);
192 if (extension_service_->is_ready())
193 Load(info);
194 return info.extension_id;
197 std::string ComponentLoader::AddOrReplace(const base::FilePath& path) {
198 base::FilePath absolute_path = base::MakeAbsoluteFilePath(path);
199 std::string error;
200 scoped_ptr<base::DictionaryValue> manifest(
201 file_util::LoadManifest(absolute_path, &error));
202 if (!manifest) {
203 LOG(ERROR) << "Could not load extension from '" <<
204 absolute_path.value() << "'. " << error;
205 return std::string();
207 Remove(GenerateId(manifest.get(), absolute_path));
209 return Add(manifest.release(), absolute_path);
212 void ComponentLoader::Reload(const std::string& extension_id) {
213 for (RegisteredComponentExtensions::iterator it =
214 component_extensions_.begin(); it != component_extensions_.end();
215 ++it) {
216 if (it->extension_id == extension_id) {
217 Load(*it);
218 break;
223 void ComponentLoader::Load(const ComponentExtensionInfo& info) {
224 // TODO(abarth): We should REQUIRE_MODERN_MANIFEST_VERSION once we've updated
225 // our component extensions to the new manifest version.
226 int flags = Extension::REQUIRE_KEY;
228 std::string error;
230 scoped_refptr<const Extension> extension(Extension::Create(
231 info.root_directory,
232 Manifest::COMPONENT,
233 *info.manifest,
234 flags,
235 &error));
236 if (!extension.get()) {
237 LOG(ERROR) << error;
238 return;
241 CHECK_EQ(info.extension_id, extension->id()) << extension->name();
242 extension_service_->AddComponentExtension(extension.get());
245 void ComponentLoader::Remove(const base::FilePath& root_directory) {
246 // Find the ComponentExtensionInfo for the extension.
247 RegisteredComponentExtensions::iterator it = component_extensions_.begin();
248 for (; it != component_extensions_.end(); ++it) {
249 if (it->root_directory == root_directory) {
250 Remove(GenerateId(it->manifest, root_directory));
251 break;
256 void ComponentLoader::Remove(const std::string& id) {
257 RegisteredComponentExtensions::iterator it = component_extensions_.begin();
258 for (; it != component_extensions_.end(); ++it) {
259 if (it->extension_id == id) {
260 UnloadComponent(&(*it));
261 it = component_extensions_.erase(it);
262 break;
267 bool ComponentLoader::Exists(const std::string& id) const {
268 RegisteredComponentExtensions::const_iterator it =
269 component_extensions_.begin();
270 for (; it != component_extensions_.end(); ++it)
271 if (it->extension_id == id)
272 return true;
273 return false;
276 void ComponentLoader::AddFileManagerExtension() {
277 #if defined(OS_CHROMEOS)
278 #ifndef NDEBUG
279 const CommandLine* command_line = CommandLine::ForCurrentProcess();
280 if (command_line->HasSwitch(switches::kFileManagerExtensionPath)) {
281 base::FilePath filemgr_extension_path(
282 command_line->GetSwitchValuePath(switches::kFileManagerExtensionPath));
283 Add(IDR_FILEMANAGER_MANIFEST, filemgr_extension_path);
284 return;
286 #endif // NDEBUG
287 Add(IDR_FILEMANAGER_MANIFEST,
288 base::FilePath(FILE_PATH_LITERAL("file_manager")));
289 #endif // defined(OS_CHROMEOS)
292 void ComponentLoader::AddVideoPlayerExtension() {
293 #if defined(OS_CHROMEOS)
294 Add(IDR_VIDEO_PLAYER_MANIFEST,
295 base::FilePath(FILE_PATH_LITERAL("video_player")));
296 #endif // defined(OS_CHROMEOS)
299 void ComponentLoader::AddGalleryExtension() {
300 #if defined(OS_CHROMEOS)
301 Add(IDR_GALLERY_MANIFEST, base::FilePath(FILE_PATH_LITERAL("gallery")));
302 #endif
305 void ComponentLoader::AddHangoutServicesExtension() {
306 #if defined(GOOGLE_CHROME_BUILD) || defined(ENABLE_HANGOUT_SERVICES_EXTENSION)
307 Add(IDR_HANGOUT_SERVICES_MANIFEST,
308 base::FilePath(FILE_PATH_LITERAL("hangout_services")));
309 #endif
312 void ComponentLoader::AddHotwordHelperExtension() {
313 if (HotwordServiceFactory::IsHotwordAllowed(browser_context_)) {
314 Add(IDR_HOTWORD_HELPER_MANIFEST,
315 base::FilePath(FILE_PATH_LITERAL("hotword_helper")));
319 void ComponentLoader::AddImageLoaderExtension() {
320 #if defined(IMAGE_LOADER_EXTENSION)
321 Add(IDR_IMAGE_LOADER_MANIFEST,
322 base::FilePath(FILE_PATH_LITERAL("image_loader")));
323 #endif // defined(IMAGE_LOADER_EXTENSION)
326 void ComponentLoader::AddNetworkSpeechSynthesisExtension() {
327 Add(IDR_NETWORK_SPEECH_SYNTHESIS_MANIFEST,
328 base::FilePath(FILE_PATH_LITERAL("network_speech_synthesis")));
331 #if defined(OS_CHROMEOS)
332 std::string ComponentLoader::AddChromeVoxExtension() {
333 base::FilePath chromevox_path;
334 PathService::Get(chrome::DIR_RESOURCES, &chromevox_path);
335 chromevox_path =
336 chromevox_path.Append(extension_misc::kChromeVoxExtensionPath);
338 const CommandLine* command_line = CommandLine::ForCurrentProcess();
339 const char* manifest_filename =
340 command_line->HasSwitch(chromeos::switches::kGuestSession) ?
341 extension_misc::kChromeVoxGuestManifestFilename :
342 extension_misc::kChromeVoxManifestFilename;
344 std::string error;
345 scoped_ptr<base::DictionaryValue> manifest(
346 file_util::LoadManifest(chromevox_path, manifest_filename, &error));
347 CHECK(manifest) << error;
349 return Add(manifest.release(), chromevox_path);
352 std::string ComponentLoader::AddChromeOsSpeechSynthesisExtension() {
353 const CommandLine* command_line = CommandLine::ForCurrentProcess();
354 int idr = command_line->HasSwitch(chromeos::switches::kGuestSession) ?
355 IDR_SPEECH_SYNTHESIS_GUEST_MANIFEST : IDR_SPEECH_SYNTHESIS_MANIFEST;
356 std::string id = Add(idr,
357 base::FilePath(extension_misc::kSpeechSynthesisExtensionPath));
358 EnableFileSystemInGuestMode(id);
359 return id;
361 #endif
363 void ComponentLoader::AddWithName(int manifest_resource_id,
364 const base::FilePath& root_directory,
365 const std::string& name) {
366 std::string manifest_contents =
367 ResourceBundle::GetSharedInstance().GetRawDataResource(
368 manifest_resource_id).as_string();
370 // The Value is kept for the lifetime of the ComponentLoader. This is
371 // required in case LoadAll() is called again.
372 base::DictionaryValue* manifest = ParseManifest(manifest_contents);
374 if (manifest) {
375 // Update manifest to use a proper name.
376 manifest->SetString(manifest_keys::kName, name);
377 Add(manifest, root_directory);
381 void ComponentLoader::AddChromeApp() {
382 #if defined(ENABLE_APP_LIST)
383 AddWithName(IDR_CHROME_APP_MANIFEST,
384 base::FilePath(FILE_PATH_LITERAL("chrome_app")),
385 l10n_util::GetStringUTF8(IDS_SHORT_PRODUCT_NAME));
386 #endif
389 void ComponentLoader::AddKeyboardApp() {
390 #if defined(OS_CHROMEOS)
391 Add(IDR_KEYBOARD_MANIFEST, base::FilePath(FILE_PATH_LITERAL("keyboard")));
392 #endif
395 void ComponentLoader::AddWebStoreApp() {
396 AddWithName(IDR_WEBSTORE_MANIFEST,
397 base::FilePath(FILE_PATH_LITERAL("web_store")),
398 LookupWebstoreName());
401 // static
402 void ComponentLoader::EnableBackgroundExtensionsForTesting() {
403 enable_background_extensions_during_testing = true;
406 void ComponentLoader::AddDefaultComponentExtensions(
407 bool skip_session_components) {
408 // Do not add component extensions that have background pages here -- add them
409 // to AddDefaultComponentExtensionsWithBackgroundPages.
410 #if defined(OS_CHROMEOS)
411 Add(IDR_MOBILE_MANIFEST,
412 base::FilePath(FILE_PATH_LITERAL("/usr/share/chromeos-assets/mobile")));
414 #if defined(GOOGLE_CHROME_BUILD)
415 if (browser_defaults::enable_help_app) {
416 Add(IDR_HELP_MANIFEST, base::FilePath(FILE_PATH_LITERAL(
417 "/usr/share/chromeos-assets/helpapp")));
419 #endif
421 // Skip all other extensions that require user session presence.
422 if (!skip_session_components) {
423 const CommandLine* command_line = CommandLine::ForCurrentProcess();
424 if (!command_line->HasSwitch(chromeos::switches::kGuestSession))
425 Add(IDR_BOOKMARKS_MANIFEST,
426 base::FilePath(FILE_PATH_LITERAL("bookmark_manager")));
428 Add(IDR_CROSH_BUILTIN_MANIFEST, base::FilePath(FILE_PATH_LITERAL(
429 "/usr/share/chromeos-assets/crosh_builtin")));
431 #else // !defined(OS_CHROMEOS)
432 DCHECK(!skip_session_components);
433 Add(IDR_BOOKMARKS_MANIFEST,
434 base::FilePath(FILE_PATH_LITERAL("bookmark_manager")));
435 // Cloud Print component app. Not required on Chrome OS.
436 Add(IDR_CLOUDPRINT_MANIFEST,
437 base::FilePath(FILE_PATH_LITERAL("cloud_print")));
438 #endif
440 if (!skip_session_components) {
441 AddWebStoreApp();
442 AddChromeApp();
445 AddKeyboardApp();
447 AddDefaultComponentExtensionsWithBackgroundPages(skip_session_components);
450 void ComponentLoader::AddDefaultComponentExtensionsForKioskMode(
451 bool skip_session_components) {
452 // No component extension for kiosk app launch splash screen.
453 if (skip_session_components)
454 return;
456 // Component extensions needed for kiosk apps.
457 AddVideoPlayerExtension();
458 AddFileManagerExtension();
459 AddGalleryExtension();
461 // Add virtual keyboard.
462 AddKeyboardApp();
465 void ComponentLoader::AddDefaultComponentExtensionsWithBackgroundPages(
466 bool skip_session_components) {
467 const CommandLine* command_line = CommandLine::ForCurrentProcess();
469 // Component extensions with background pages are not enabled during tests
470 // because they generate a lot of background behavior that can interfere.
471 if (!enable_background_extensions_during_testing &&
472 (command_line->HasSwitch(switches::kTestType) ||
473 command_line->HasSwitch(
474 switches::kDisableComponentExtensionsWithBackgroundPages))) {
475 return;
478 #if defined(OS_CHROMEOS) && defined(GOOGLE_CHROME_BUILD)
479 // Since this is a v2 app it has a background page.
480 if (!command_line->HasSwitch(chromeos::switches::kDisableGeniusApp)) {
481 AddWithName(IDR_GENIUS_APP_MANIFEST,
482 base::FilePath(FILE_PATH_LITERAL(
483 "/usr/share/chromeos-assets/genius_app")),
484 l10n_util::GetStringUTF8(IDS_GENIUS_APP_NAME));
486 #endif
488 if (!skip_session_components) {
489 AddVideoPlayerExtension();
490 AddFileManagerExtension();
491 AddGalleryExtension();
493 AddHangoutServicesExtension();
494 AddHotwordHelperExtension();
495 AddImageLoaderExtension();
497 #if defined(ENABLE_SETTINGS_APP)
498 Add(IDR_SETTINGS_APP_MANIFEST,
499 base::FilePath(FILE_PATH_LITERAL("settings_app")));
500 #endif
503 // If (!enable_background_extensions_during_testing || this isn't a test)
504 // install_feedback = false;
505 bool install_feedback = enable_background_extensions_during_testing;
506 #if defined(GOOGLE_CHROME_BUILD)
507 install_feedback = true;
508 #endif // defined(GOOGLE_CHROME_BUILD)
509 if (install_feedback)
510 Add(IDR_FEEDBACK_MANIFEST, base::FilePath(FILE_PATH_LITERAL("feedback")));
512 #if defined(OS_CHROMEOS)
513 if (!skip_session_components) {
514 #if defined(GOOGLE_CHROME_BUILD)
515 if (!command_line->HasSwitch(
516 chromeos::switches::kDisableQuickofficeComponentApp)) {
517 std::string id = Add(IDR_QUICKOFFICE_MANIFEST, base::FilePath(
518 FILE_PATH_LITERAL("/usr/share/chromeos-assets/quickoffice")));
519 EnableFileSystemInGuestMode(id);
521 #endif // defined(GOOGLE_CHROME_BUILD)
523 Add(IDR_ECHO_MANIFEST,
524 base::FilePath(FILE_PATH_LITERAL("/usr/share/chromeos-assets/echo")));
526 if (!command_line->HasSwitch(chromeos::switches::kGuestSession)) {
527 Add(IDR_WALLPAPERMANAGER_MANIFEST,
528 base::FilePath(FILE_PATH_LITERAL("chromeos/wallpaper_manager")));
531 Add(IDR_FIRST_RUN_DIALOG_MANIFEST,
532 base::FilePath(FILE_PATH_LITERAL("chromeos/first_run/app")));
534 Add(IDR_NETWORK_CONFIGURATION_MANIFEST,
535 base::FilePath(FILE_PATH_LITERAL("chromeos/network_configuration")));
537 Add(IDR_CONNECTIVITY_DIAGNOSTICS_MANIFEST,
538 base::FilePath(extension_misc::kConnectivityDiagnosticsPath));
539 Add(IDR_CONNECTIVITY_DIAGNOSTICS_LAUNCHER_MANIFEST,
540 base::FilePath(extension_misc::kConnectivityDiagnosticsLauncherPath));
543 // Load ChromeVox extension now if spoken feedback is enabled.
544 if (chromeos::AccessibilityManager::Get() &&
545 chromeos::AccessibilityManager::Get()->IsSpokenFeedbackEnabled()) {
546 AddChromeVoxExtension();
548 #endif // defined(OS_CHROMEOS)
550 #if defined(ENABLE_GOOGLE_NOW)
551 const char kEnablePrefix[] = "Enable";
552 const char kFieldTrialName[] = "GoogleNow";
553 std::string enable_prefix(kEnablePrefix);
554 std::string field_trial_result =
555 base::FieldTrialList::FindFullName(kFieldTrialName);
557 bool enabled_via_field_trial =
558 field_trial_result.compare(0, enable_prefix.length(), enable_prefix) == 0;
560 // Enable the feature on trybots and trunk builds.
561 bool enabled_via_trunk_build =
562 chrome::VersionInfo::GetChannel() == chrome::VersionInfo::CHANNEL_UNKNOWN;
564 bool enabled = enabled_via_field_trial || enabled_via_trunk_build;
566 if (!skip_session_components && enabled) {
567 Add(IDR_GOOGLE_NOW_MANIFEST,
568 base::FilePath(FILE_PATH_LITERAL("google_now")));
570 #endif
572 #if defined(GOOGLE_CHROME_BUILD)
573 #if !defined(OS_CHROMEOS) // http://crbug.com/314799
574 AddNetworkSpeechSynthesisExtension();
575 #endif
577 if (!skip_session_components &&
578 command_line->HasSwitch(switches::kEnableEasyUnlock)) {
579 if (command_line->HasSwitch(switches::kEasyUnlockAppPath)) {
580 base::FilePath easy_unlock_path(
581 command_line->GetSwitchValuePath(switches::kEasyUnlockAppPath));
582 Add(IDR_EASY_UNLOCK_MANIFEST, easy_unlock_path);
583 } else {
584 #if defined(OS_CHROMEOS)
585 Add(IDR_EASY_UNLOCK_MANIFEST,
586 base::FilePath(
587 FILE_PATH_LITERAL("/usr/share/chromeos-assets/easy_unlock")));
588 #endif
591 #endif // defined(GOOGLE_CHROME_BUILD)
593 #if defined(ENABLE_PLUGINS)
594 base::FilePath pdf_path;
595 content::PluginService* plugin_service =
596 content::PluginService::GetInstance();
597 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kOutOfProcessPdf) &&
598 PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_path) &&
599 plugin_service->GetRegisteredPpapiPluginInfo(pdf_path)) {
600 Add(IDR_PDF_MANIFEST, base::FilePath(FILE_PATH_LITERAL("pdf")));
602 #endif
604 Add(IDR_CRYPTOTOKEN_MANIFEST,
605 base::FilePath(FILE_PATH_LITERAL("cryptotoken")));
608 void ComponentLoader::UnloadComponent(ComponentExtensionInfo* component) {
609 delete component->manifest;
610 if (extension_service_->is_ready()) {
611 extension_service_->
612 RemoveComponentExtension(component->extension_id);
616 void ComponentLoader::EnableFileSystemInGuestMode(const std::string& id) {
617 #if defined(OS_CHROMEOS)
618 const CommandLine* command_line = CommandLine::ForCurrentProcess();
619 if (command_line->HasSwitch(chromeos::switches::kGuestSession)) {
620 // TODO(dpolukhin): Hack to enable HTML5 temporary file system for
621 // the extension. Some component extensions don't work without temporary
622 // file system access. Make sure temporary file system is enabled in the off
623 // the record browser context (as that is the one used in guest session).
624 content::BrowserContext* off_the_record_context =
625 ExtensionsBrowserClient::Get()->GetOffTheRecordContext(
626 browser_context_);
627 GURL site = content::SiteInstance::GetSiteForURL(
628 off_the_record_context, Extension::GetBaseURLFromExtensionId(id));
629 fileapi::FileSystemContext* file_system_context =
630 content::BrowserContext::GetStoragePartitionForSite(
631 off_the_record_context, site)->GetFileSystemContext();
632 file_system_context->EnableTemporaryFileSystemInIncognito();
634 #endif
637 } // namespace extensions