NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / chrome / browser / extensions / component_loader.cc
blob7929617591bd4771800e6e54c24ea7bb8e045b62
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/profiles/profile.h"
19 #include "chrome/browser/search/hotword_service_factory.h"
20 #include "chrome/common/chrome_paths.h"
21 #include "chrome/common/chrome_switches.h"
22 #include "chrome/common/chrome_version_info.h"
23 #include "chrome/common/extensions/extension_file_util.h"
24 #include "chrome/common/pref_names.h"
25 #include "content/public/browser/notification_details.h"
26 #include "content/public/browser/notification_source.h"
27 #include "content/public/browser/plugin_service.h"
28 #include "extensions/common/extension.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/keyboard/keyboard_util.h"
39 #endif
41 #if defined(GOOGLE_CHROME_BUILD)
42 #include "chrome/browser/defaults.h"
43 #endif
45 #if defined(OS_CHROMEOS)
46 #include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
47 #include "chrome/browser/chromeos/login/user_manager.h"
48 #include "chromeos/chromeos_switches.h"
49 #include "content/public/browser/site_instance.h"
50 #include "content/public/browser/storage_partition.h"
51 #include "extensions/browser/extensions_browser_client.h"
52 #include "webkit/browser/fileapi/file_system_context.h"
53 #endif
55 #if defined(ENABLE_APP_LIST)
56 #include "grit/chromium_strings.h"
57 #endif
59 namespace extensions {
61 namespace {
63 static bool enable_background_extensions_during_testing = false;
65 std::string LookupWebstoreName() {
66 const char kWebStoreNameFieldTrialName[] = "WebStoreName";
67 const char kStoreControl[] = "StoreControl";
68 const char kWebStore[] = "WebStore";
69 const char kGetApps[] = "GetApps";
70 const char kAddApps[] = "AddApps";
71 const char kMoreApps[] = "MoreApps";
73 typedef std::map<std::string, int> NameMap;
74 CR_DEFINE_STATIC_LOCAL(NameMap, names, ());
75 if (names.empty()) {
76 names.insert(std::make_pair(kStoreControl, IDS_WEBSTORE_NAME_STORE));
77 names.insert(std::make_pair(kWebStore, IDS_WEBSTORE_NAME_WEBSTORE));
78 names.insert(std::make_pair(kGetApps, IDS_WEBSTORE_NAME_GET_APPS));
79 names.insert(std::make_pair(kAddApps, IDS_WEBSTORE_NAME_ADD_APPS));
80 names.insert(std::make_pair(kMoreApps, IDS_WEBSTORE_NAME_MORE_APPS));
82 std::string field_trial_name =
83 base::FieldTrialList::FindFullName(kWebStoreNameFieldTrialName);
84 NameMap::iterator it = names.find(field_trial_name);
85 int string_id = it == names.end() ? names[kStoreControl] : it->second;
86 return l10n_util::GetStringUTF8(string_id);
89 std::string GenerateId(const base::DictionaryValue* manifest,
90 const base::FilePath& path) {
91 std::string raw_key;
92 std::string id_input;
93 CHECK(manifest->GetString(manifest_keys::kPublicKey, &raw_key));
94 CHECK(Extension::ParsePEMKeyBytes(raw_key, &id_input));
95 std::string id = id_util::GenerateId(id_input);
96 return id;
99 } // namespace
101 ComponentLoader::ComponentExtensionInfo::ComponentExtensionInfo(
102 const base::DictionaryValue* manifest, const base::FilePath& directory)
103 : manifest(manifest),
104 root_directory(directory) {
105 if (!root_directory.IsAbsolute()) {
106 CHECK(PathService::Get(chrome::DIR_RESOURCES, &root_directory));
107 root_directory = root_directory.Append(directory);
109 extension_id = GenerateId(manifest, root_directory);
112 ComponentLoader::ComponentLoader(ExtensionServiceInterface* extension_service,
113 PrefService* profile_prefs,
114 PrefService* local_state,
115 content::BrowserContext* browser_context)
116 : profile_prefs_(profile_prefs),
117 local_state_(local_state),
118 browser_context_(browser_context),
119 extension_service_(extension_service) {}
121 ComponentLoader::~ComponentLoader() {
122 ClearAllRegistered();
125 void ComponentLoader::LoadAll() {
126 for (RegisteredComponentExtensions::iterator it =
127 component_extensions_.begin();
128 it != component_extensions_.end(); ++it) {
129 Load(*it);
133 base::DictionaryValue* ComponentLoader::ParseManifest(
134 const std::string& manifest_contents) const {
135 JSONStringValueSerializer serializer(manifest_contents);
136 scoped_ptr<base::Value> manifest(serializer.Deserialize(NULL, NULL));
138 if (!manifest.get() || !manifest->IsType(base::Value::TYPE_DICTIONARY)) {
139 LOG(ERROR) << "Failed to parse extension manifest.";
140 return NULL;
142 // Transfer ownership to the caller.
143 return static_cast<base::DictionaryValue*>(manifest.release());
146 void ComponentLoader::ClearAllRegistered() {
147 for (RegisteredComponentExtensions::iterator it =
148 component_extensions_.begin();
149 it != component_extensions_.end(); ++it) {
150 delete it->manifest;
153 component_extensions_.clear();
156 std::string ComponentLoader::GetExtensionID(
157 int manifest_resource_id,
158 const base::FilePath& root_directory) {
159 std::string manifest_contents = ResourceBundle::GetSharedInstance().
160 GetRawDataResource(manifest_resource_id).as_string();
161 base::DictionaryValue* manifest = ParseManifest(manifest_contents);
162 if (!manifest)
163 return std::string();
165 ComponentExtensionInfo info(manifest, root_directory);
166 return info.extension_id;
169 std::string ComponentLoader::Add(int manifest_resource_id,
170 const base::FilePath& root_directory) {
171 std::string manifest_contents =
172 ResourceBundle::GetSharedInstance().GetRawDataResource(
173 manifest_resource_id).as_string();
174 return Add(manifest_contents, root_directory);
177 std::string ComponentLoader::Add(const std::string& manifest_contents,
178 const base::FilePath& root_directory) {
179 // The Value is kept for the lifetime of the ComponentLoader. This is
180 // required in case LoadAll() is called again.
181 base::DictionaryValue* manifest = ParseManifest(manifest_contents);
182 if (manifest)
183 return Add(manifest, root_directory);
184 return std::string();
187 std::string ComponentLoader::Add(const base::DictionaryValue* parsed_manifest,
188 const base::FilePath& root_directory) {
189 ComponentExtensionInfo info(parsed_manifest, root_directory);
190 component_extensions_.push_back(info);
191 if (extension_service_->is_ready())
192 Load(info);
193 return info.extension_id;
196 std::string ComponentLoader::AddOrReplace(const base::FilePath& path) {
197 base::FilePath absolute_path = base::MakeAbsoluteFilePath(path);
198 std::string error;
199 scoped_ptr<base::DictionaryValue> manifest(
200 extension_file_util::LoadManifest(absolute_path, &error));
201 if (!manifest) {
202 LOG(ERROR) << "Could not load extension from '" <<
203 absolute_path.value() << "'. " << error;
204 return std::string();
206 Remove(GenerateId(manifest.get(), absolute_path));
208 return Add(manifest.release(), absolute_path);
211 void ComponentLoader::Reload(const std::string& extension_id) {
212 for (RegisteredComponentExtensions::iterator it =
213 component_extensions_.begin(); it != component_extensions_.end();
214 ++it) {
215 if (it->extension_id == extension_id) {
216 Load(*it);
217 break;
222 void ComponentLoader::Load(const ComponentExtensionInfo& info) {
223 // TODO(abarth): We should REQUIRE_MODERN_MANIFEST_VERSION once we've updated
224 // our component extensions to the new manifest version.
225 int flags = Extension::REQUIRE_KEY;
227 std::string error;
229 scoped_refptr<const Extension> extension(Extension::Create(
230 info.root_directory,
231 Manifest::COMPONENT,
232 *info.manifest,
233 flags,
234 &error));
235 if (!extension.get()) {
236 LOG(ERROR) << error;
237 return;
240 CHECK_EQ(info.extension_id, extension->id()) << extension->name();
241 extension_service_->AddComponentExtension(extension.get());
244 void ComponentLoader::Remove(const base::FilePath& root_directory) {
245 // Find the ComponentExtensionInfo for the extension.
246 RegisteredComponentExtensions::iterator it = component_extensions_.begin();
247 for (; it != component_extensions_.end(); ++it) {
248 if (it->root_directory == root_directory) {
249 Remove(GenerateId(it->manifest, root_directory));
250 break;
255 void ComponentLoader::Remove(const std::string& id) {
256 RegisteredComponentExtensions::iterator it = component_extensions_.begin();
257 for (; it != component_extensions_.end(); ++it) {
258 if (it->extension_id == id) {
259 UnloadComponent(&(*it));
260 it = component_extensions_.erase(it);
261 break;
266 bool ComponentLoader::Exists(const std::string& id) const {
267 RegisteredComponentExtensions::const_iterator it =
268 component_extensions_.begin();
269 for (; it != component_extensions_.end(); ++it)
270 if (it->extension_id == id)
271 return true;
272 return false;
275 void ComponentLoader::AddFileManagerExtension() {
276 #if defined(OS_CHROMEOS)
277 #ifndef NDEBUG
278 const CommandLine* command_line = CommandLine::ForCurrentProcess();
279 if (command_line->HasSwitch(switches::kFileManagerExtensionPath)) {
280 base::FilePath filemgr_extension_path(
281 command_line->GetSwitchValuePath(switches::kFileManagerExtensionPath));
282 Add(IDR_FILEMANAGER_MANIFEST, filemgr_extension_path);
283 return;
285 #endif // NDEBUG
286 Add(IDR_FILEMANAGER_MANIFEST,
287 base::FilePath(FILE_PATH_LITERAL("file_manager")));
288 #endif // defined(OS_CHROMEOS)
291 void ComponentLoader::AddHangoutServicesExtension() {
292 #if defined(GOOGLE_CHROME_BUILD) || defined(ENABLE_HANGOUT_SERVICES_EXTENSION)
293 Add(IDR_HANGOUT_SERVICES_MANIFEST,
294 base::FilePath(FILE_PATH_LITERAL("hangout_services")));
295 #endif
298 void ComponentLoader::AddHotwordHelperExtension() {
299 Profile* profile = static_cast<Profile*>(browser_context_);
300 if (HotwordServiceFactory::IsHotwordAllowed(profile)) {
301 Add(IDR_HOTWORD_HELPER_MANIFEST,
302 base::FilePath(FILE_PATH_LITERAL("hotword_helper")));
306 void ComponentLoader::AddImageLoaderExtension() {
307 #if defined(IMAGE_LOADER_EXTENSION)
308 #ifndef NDEBUG
309 const CommandLine* command_line = CommandLine::ForCurrentProcess();
310 if (command_line->HasSwitch(switches::kImageLoaderExtensionPath)) {
311 base::FilePath image_loader_extension_path(
312 command_line->GetSwitchValuePath(switches::kImageLoaderExtensionPath));
313 Add(IDR_IMAGE_LOADER_MANIFEST, image_loader_extension_path);
314 return;
316 #endif // NDEBUG
317 Add(IDR_IMAGE_LOADER_MANIFEST,
318 base::FilePath(FILE_PATH_LITERAL("image_loader")));
319 #endif // defined(IMAGE_LOADER_EXTENSION)
322 void ComponentLoader::AddBookmarksExtensions() {
323 Add(IDR_BOOKMARKS_MANIFEST,
324 base::FilePath(FILE_PATH_LITERAL("bookmark_manager")));
325 #if defined(ENABLE_ENHANCED_BOOKMARKS)
326 Add(IDR_ENHANCED_BOOKMARKS_MANIFEST,
327 base::FilePath(FILE_PATH_LITERAL("enhanced_bookmark_manager")));
328 #endif
331 void ComponentLoader::AddNetworkSpeechSynthesisExtension() {
332 Add(IDR_NETWORK_SPEECH_SYNTHESIS_MANIFEST,
333 base::FilePath(FILE_PATH_LITERAL("network_speech_synthesis")));
336 #if defined(OS_CHROMEOS)
337 std::string ComponentLoader::AddChromeVoxExtension() {
338 const CommandLine* command_line = CommandLine::ForCurrentProcess();
339 int idr = command_line->HasSwitch(chromeos::switches::kGuestSession) ?
340 IDR_CHROMEVOX_GUEST_MANIFEST : IDR_CHROMEVOX_MANIFEST;
341 return Add(idr, base::FilePath(extension_misc::kChromeVoxExtensionPath));
344 std::string ComponentLoader::AddChromeOsSpeechSynthesisExtension() {
345 const CommandLine* command_line = CommandLine::ForCurrentProcess();
346 int idr = command_line->HasSwitch(chromeos::switches::kGuestSession) ?
347 IDR_SPEECH_SYNTHESIS_GUEST_MANIFEST : IDR_SPEECH_SYNTHESIS_MANIFEST;
348 std::string id = Add(idr,
349 base::FilePath(extension_misc::kSpeechSynthesisExtensionPath));
350 EnableFileSystemInGuestMode(id);
351 return id;
353 #endif
355 void ComponentLoader::AddWithName(int manifest_resource_id,
356 const base::FilePath& root_directory,
357 const std::string& name) {
358 std::string manifest_contents =
359 ResourceBundle::GetSharedInstance().GetRawDataResource(
360 manifest_resource_id).as_string();
362 // The Value is kept for the lifetime of the ComponentLoader. This is
363 // required in case LoadAll() is called again.
364 base::DictionaryValue* manifest = ParseManifest(manifest_contents);
366 if (manifest) {
367 // Update manifest to use a proper name.
368 manifest->SetString(manifest_keys::kName, name);
369 Add(manifest, root_directory);
373 void ComponentLoader::AddChromeApp() {
374 #if defined(ENABLE_APP_LIST)
375 AddWithName(IDR_CHROME_APP_MANIFEST,
376 base::FilePath(FILE_PATH_LITERAL("chrome_app")),
377 l10n_util::GetStringUTF8(IDS_SHORT_PRODUCT_NAME));
378 #endif
381 void ComponentLoader::AddKeyboardApp() {
382 #if defined(OS_CHROMEOS)
383 Add(IDR_KEYBOARD_MANIFEST, base::FilePath(FILE_PATH_LITERAL("keyboard")));
384 #endif
387 void ComponentLoader::AddWebStoreApp() {
388 AddWithName(IDR_WEBSTORE_MANIFEST,
389 base::FilePath(FILE_PATH_LITERAL("web_store")),
390 LookupWebstoreName());
393 // static
394 void ComponentLoader::EnableBackgroundExtensionsForTesting() {
395 enable_background_extensions_during_testing = true;
398 void ComponentLoader::AddDefaultComponentExtensions(
399 bool skip_session_components) {
400 // Do not add component extensions that have background pages here -- add them
401 // to AddDefaultComponentExtensionsWithBackgroundPages.
402 #if defined(OS_CHROMEOS)
403 Add(IDR_MOBILE_MANIFEST,
404 base::FilePath(FILE_PATH_LITERAL("/usr/share/chromeos-assets/mobile")));
406 #if defined(GOOGLE_CHROME_BUILD)
407 if (browser_defaults::enable_help_app) {
408 Add(IDR_HELP_MANIFEST, base::FilePath(FILE_PATH_LITERAL(
409 "/usr/share/chromeos-assets/helpapp")));
411 #endif
413 // Skip all other extensions that require user session presence.
414 if (!skip_session_components) {
415 const CommandLine* command_line = CommandLine::ForCurrentProcess();
416 if (!command_line->HasSwitch(chromeos::switches::kGuestSession))
417 AddBookmarksExtensions();
419 Add(IDR_CROSH_BUILTIN_MANIFEST, base::FilePath(FILE_PATH_LITERAL(
420 "/usr/share/chromeos-assets/crosh_builtin")));
422 #else // !defined(OS_CHROMEOS)
423 DCHECK(!skip_session_components);
424 AddBookmarksExtensions();
425 // Cloud Print component app. Not required on Chrome OS.
426 Add(IDR_CLOUDPRINT_MANIFEST,
427 base::FilePath(FILE_PATH_LITERAL("cloud_print")));
428 #endif
430 if (!skip_session_components) {
431 AddWebStoreApp();
432 AddChromeApp();
435 AddKeyboardApp();
437 AddDefaultComponentExtensionsWithBackgroundPages(skip_session_components);
440 void ComponentLoader::AddDefaultComponentExtensionsForKioskMode(
441 bool skip_session_components) {
442 // No component extension for kiosk app launch splash screen.
443 if (skip_session_components)
444 return;
446 // Component extensions needed for kiosk apps.
447 AddFileManagerExtension();
449 // Add virtual keyboard.
450 AddKeyboardApp();
453 void ComponentLoader::AddDefaultComponentExtensionsWithBackgroundPages(
454 bool skip_session_components) {
455 const CommandLine* command_line = CommandLine::ForCurrentProcess();
457 // Component extensions with background pages are not enabled during tests
458 // because they generate a lot of background behavior that can interfere.
459 if (!enable_background_extensions_during_testing &&
460 (command_line->HasSwitch(switches::kTestType) ||
461 command_line->HasSwitch(
462 switches::kDisableComponentExtensionsWithBackgroundPages))) {
463 return;
466 #if defined(OS_CHROMEOS) && defined(GOOGLE_CHROME_BUILD)
467 // Since this is a v2 app it has a background page.
468 if (!command_line->HasSwitch(chromeos::switches::kDisableGeniusApp)) {
469 AddWithName(IDR_GENIUS_APP_MANIFEST,
470 base::FilePath(FILE_PATH_LITERAL(
471 "/usr/share/chromeos-assets/genius_app")),
472 l10n_util::GetStringUTF8(IDS_GENIUS_APP_NAME));
474 #endif
476 if (!skip_session_components) {
477 AddFileManagerExtension();
478 AddHangoutServicesExtension();
479 AddHotwordHelperExtension();
480 AddImageLoaderExtension();
482 #if defined(ENABLE_SETTINGS_APP)
483 Add(IDR_SETTINGS_APP_MANIFEST,
484 base::FilePath(FILE_PATH_LITERAL("settings_app")));
485 #endif
488 // If (!enable_background_extensions_during_testing || this isn't a test)
489 // install_feedback = false;
490 bool install_feedback = enable_background_extensions_during_testing;
491 #if defined(GOOGLE_CHROME_BUILD)
492 install_feedback = true;
493 #endif // defined(GOOGLE_CHROME_BUILD)
494 if (install_feedback)
495 Add(IDR_FEEDBACK_MANIFEST, base::FilePath(FILE_PATH_LITERAL("feedback")));
497 #if defined(OS_CHROMEOS)
498 if (!skip_session_components) {
499 #if defined(GOOGLE_CHROME_BUILD)
500 if (!command_line->HasSwitch(
501 chromeos::switches::kDisableQuickofficeComponentApp)) {
502 std::string id = Add(IDR_QUICKOFFICE_MANIFEST, base::FilePath(
503 FILE_PATH_LITERAL("/usr/share/chromeos-assets/quick_office")));
504 EnableFileSystemInGuestMode(id);
506 #endif // defined(GOOGLE_CHROME_BUILD)
508 base::FilePath echo_extension_path(FILE_PATH_LITERAL(
509 "/usr/share/chromeos-assets/echo"));
510 if (command_line->HasSwitch(chromeos::switches::kEchoExtensionPath)) {
511 echo_extension_path = command_line->GetSwitchValuePath(
512 chromeos::switches::kEchoExtensionPath);
514 Add(IDR_ECHO_MANIFEST, echo_extension_path);
516 if (!command_line->HasSwitch(chromeos::switches::kGuestSession)) {
517 Add(IDR_WALLPAPERMANAGER_MANIFEST,
518 base::FilePath(FILE_PATH_LITERAL("chromeos/wallpaper_manager")));
521 if (!command_line->HasSwitch(chromeos::switches::kDisableFirstRunUI)) {
522 Add(IDR_FIRST_RUN_DIALOG_MANIFEST,
523 base::FilePath(FILE_PATH_LITERAL("chromeos/first_run/app")));
526 Add(IDR_NETWORK_CONFIGURATION_MANIFEST,
527 base::FilePath(FILE_PATH_LITERAL("chromeos/network_configuration")));
529 Add(IDR_CONNECTIVITY_DIAGNOSTICS_MANIFEST,
530 base::FilePath(extension_misc::kConnectivityDiagnosticsPath));
531 Add(IDR_CONNECTIVITY_DIAGNOSTICS_LAUNCHER_MANIFEST,
532 base::FilePath(extension_misc::kConnectivityDiagnosticsLauncherPath));
535 // Load ChromeVox extension now if spoken feedback is enabled.
536 if (chromeos::AccessibilityManager::Get() &&
537 chromeos::AccessibilityManager::Get()->IsSpokenFeedbackEnabled()) {
538 AddChromeVoxExtension();
540 #endif // defined(OS_CHROMEOS)
542 #if defined(ENABLE_GOOGLE_NOW)
543 const char kEnablePrefix[] = "Enable";
544 const char kFieldTrialName[] = "GoogleNow";
545 std::string enable_prefix(kEnablePrefix);
546 std::string field_trial_result =
547 base::FieldTrialList::FindFullName(kFieldTrialName);
549 bool enabled_via_field_trial = field_trial_result.compare(
551 enable_prefix.length(),
552 enable_prefix) == 0;
554 // Enable the feature on trybots.
555 bool enabled_via_trunk_build = chrome::VersionInfo::GetChannel() ==
556 chrome::VersionInfo::CHANNEL_UNKNOWN;
558 bool enabled_via_flag =
559 chrome::VersionInfo::GetChannel() !=
560 chrome::VersionInfo::CHANNEL_STABLE &&
561 CommandLine::ForCurrentProcess()->HasSwitch(
562 switches::kEnableGoogleNowIntegration);
564 bool enabled =
565 enabled_via_field_trial || enabled_via_trunk_build || enabled_via_flag;
567 bool disabled_via_flag =
568 CommandLine::ForCurrentProcess()->HasSwitch(
569 switches::kDisableGoogleNowIntegration);
571 if (!skip_session_components && enabled && !disabled_via_flag) {
572 Add(IDR_GOOGLE_NOW_MANIFEST,
573 base::FilePath(FILE_PATH_LITERAL("google_now")));
575 #endif
577 #if defined(GOOGLE_CHROME_BUILD)
578 #if !defined(OS_CHROMEOS) // http://crbug.com/314799
579 AddNetworkSpeechSynthesisExtension();
580 #endif
581 #endif // defined(GOOGLE_CHROME_BUILD)
583 #if defined(ENABLE_PLUGINS)
584 base::FilePath pdf_path;
585 content::PluginService* plugin_service =
586 content::PluginService::GetInstance();
587 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kOutOfProcessPdf) &&
588 PathService::Get(chrome::FILE_PDF_PLUGIN, &pdf_path) &&
589 plugin_service->GetRegisteredPpapiPluginInfo(pdf_path)) {
590 Add(IDR_PDF_MANIFEST, base::FilePath(FILE_PATH_LITERAL("pdf")));
592 #endif
595 void ComponentLoader::UnloadComponent(ComponentExtensionInfo* component) {
596 delete component->manifest;
597 if (extension_service_->is_ready()) {
598 extension_service_->
599 RemoveComponentExtension(component->extension_id);
603 void ComponentLoader::EnableFileSystemInGuestMode(const std::string& id) {
604 #if defined(OS_CHROMEOS)
605 const CommandLine* command_line = CommandLine::ForCurrentProcess();
606 if (command_line->HasSwitch(chromeos::switches::kGuestSession)) {
607 // TODO(dpolukhin): Hack to enable HTML5 temporary file system for
608 // the extension. Some component extensions don't work without temporary
609 // file system access. Make sure temporary file system is enabled in the off
610 // the record browser context (as that is the one used in guest session).
611 content::BrowserContext* off_the_record_context =
612 ExtensionsBrowserClient::Get()->GetOffTheRecordContext(
613 browser_context_);
614 GURL site = content::SiteInstance::GetSiteForURL(
615 off_the_record_context, Extension::GetBaseURLFromExtensionId(id));
616 fileapi::FileSystemContext* file_system_context =
617 content::BrowserContext::GetStoragePartitionForSite(
618 off_the_record_context, site)->GetFileSystemContext();
619 file_system_context->EnableTemporaryFileSystemInIncognito();
621 #endif
624 } // namespace extensions