diff options
author | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-13 18:00:25 +0000 |
---|---|---|
committer | sadrul@chromium.org <sadrul@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-13 18:00:25 +0000 |
commit | 7492275526897a62fe04400aa536dde5c51278d7 (patch) | |
tree | 187d8e83d349b975adf00c1f31d1c6e2630f4e7a /chrome | |
parent | 0fc357452454dbcf342314dfa828bdcb2dd560be (diff) | |
download | chromium_src-7492275526897a62fe04400aa536dde5c51278d7.zip chromium_src-7492275526897a62fe04400aa536dde5c51278d7.tar.gz chromium_src-7492275526897a62fe04400aa536dde5c51278d7.tar.bz2 |
apps: Add 'background_page' support for hosted apps.
A hosted app can have a 'background_page' if it has 'background' 'permission'.
The 'background_page' will launch immediately after the app is installed.
BUG=77718
TEST=AppBackgroundPageApiTest.ManifestBackgroundPage, and existing tests.
Review URL: http://codereview.chromium.org/6708100
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81438 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/background_contents_service.cc | 95 | ||||
-rw-r--r-- | chrome/browser/background_contents_service.h | 10 | ||||
-rw-r--r-- | chrome/browser/background_page_tracker.cc | 3 | ||||
-rw-r--r-- | chrome/browser/extensions/app_background_page_apitest.cc | 39 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_process_manager.cc | 5 | ||||
-rw-r--r-- | chrome/browser/renderer_host/browser_render_process_host.cc | 1 | ||||
-rw-r--r-- | chrome/browser/tab_contents/render_view_host_delegate_helper.cc | 5 | ||||
-rw-r--r-- | chrome/browser/task_manager/task_manager_resource_providers.cc | 3 | ||||
-rw-r--r-- | chrome/common/chrome_switches.cc | 3 | ||||
-rw-r--r-- | chrome/common/chrome_switches.h | 1 | ||||
-rw-r--r-- | chrome/common/extensions/extension.cc | 52 | ||||
-rw-r--r-- | chrome/common/extensions/extension_constants.cc | 8 | ||||
-rw-r--r-- | chrome/common/extensions/extension_constants.h | 2 | ||||
-rw-r--r-- | chrome/common/extensions/extension_file_util.cc | 6 | ||||
-rw-r--r-- | chrome/common/extensions/extension_manifests_unittest.cc | 6 |
15 files changed, 209 insertions, 30 deletions
diff --git a/chrome/browser/background_contents_service.cc b/chrome/browser/background_contents_service.cc index cacca3c..e5f2906 100644 --- a/chrome/browser/background_contents_service.cc +++ b/chrome/browser/background_contents_service.cc @@ -49,7 +49,7 @@ class CrashNotificationDelegate : public NotificationDelegate { public: CrashNotificationDelegate(Profile* profile, const Extension* extension) : profile_(profile), - is_app_(extension->is_app()), + is_hosted_app_(extension->is_hosted_app()), extension_id_(extension->id()) { } @@ -63,7 +63,7 @@ class CrashNotificationDelegate : public NotificationDelegate { void Close(bool by_user) {} void Click() { - if (is_app_) { + if (is_hosted_app_) { profile_->GetBackgroundContentsService()-> LoadBackgroundContentsForExtension(profile_, extension_id_); } else { @@ -81,7 +81,7 @@ class CrashNotificationDelegate : public NotificationDelegate { private: Profile* profile_; - bool is_app_; + bool is_hosted_app_; std::string extension_id_; DISALLOW_COPY_AND_ASSIGN(CrashNotificationDelegate); @@ -89,7 +89,7 @@ class CrashNotificationDelegate : public NotificationDelegate { void ShowBalloon(const Extension* extension, Profile* profile) { string16 message = l10n_util::GetStringFUTF16( - extension->is_app() ? IDS_BACKGROUND_CRASHED_APP_BALLOON_MESSAGE : + extension->is_hosted_app() ? IDS_BACKGROUND_CRASHED_APP_BALLOON_MESSAGE : IDS_BACKGROUND_CRASHED_EXTENSION_BALLOON_MESSAGE, UTF8ToUTF16(extension->name())); string16 content_url = DesktopNotificationService::CreateDataUrl( @@ -171,6 +171,11 @@ void BackgroundContentsService::StartObserving(Profile* profile) { registrar_.Add(this, NotificationType::BACKGROUND_CONTENTS_NAVIGATED, Source<Profile>(profile)); + // Listen for new extension installs so that we can load any associated + // background page. + registrar_.Add(this, NotificationType::EXTENSION_LOADED, + Source<Profile>(profile)); + // Track when the extensions crash so that the user can be notified // about it, and the crashed contents can be restarted. registrar_.Add(this, NotificationType::EXTENSION_PROCESS_TERMINATED, @@ -198,6 +203,7 @@ void BackgroundContentsService::Observe(NotificationType type, const NotificationDetails& details) { switch (type.value) { case NotificationType::EXTENSIONS_READY: + LoadBackgroundContentsFromManifests(Source<Profile>(source).ptr()); LoadBackgroundContentsFromPrefs(Source<Profile>(source).ptr()); break; case NotificationType::BACKGROUND_CONTENTS_DELETED: @@ -207,11 +213,46 @@ void BackgroundContentsService::Observe(NotificationType type, DCHECK(IsTracked(Details<BackgroundContents>(details).ptr())); UnregisterBackgroundContents(Details<BackgroundContents>(details).ptr()); break; - case NotificationType::BACKGROUND_CONTENTS_NAVIGATED: + case NotificationType::BACKGROUND_CONTENTS_NAVIGATED: { DCHECK(IsTracked(Details<BackgroundContents>(details).ptr())); + + // Do not register in the pref if the extension has a manifest-specified + // background page. + BackgroundContents* bgcontents = + Details<BackgroundContents>(details).ptr(); + Profile* profile = Source<Profile>(source).ptr(); + const string16& appid = GetParentApplicationId(bgcontents); + ExtensionService* extension_service = profile->GetExtensionService(); + // extension_service can be NULL when running tests. + if (extension_service) { + const Extension* extension = + extension_service->GetExtensionById(UTF16ToUTF8(appid), false); + if (extension && extension->background_url().is_valid()) + break; + } RegisterBackgroundContents(Details<BackgroundContents>(details).ptr()); break; - + } + case NotificationType::EXTENSION_LOADED: { + const Extension* extension = Details<const Extension>(details).ptr(); + Profile* profile = Source<Profile>(source).ptr(); + if (extension->is_hosted_app() && + extension->background_url().is_valid()) { + // If there is a background page specified in the manifest for a hosted + // app, then blow away registered urls in the pref. + ShutdownAssociatedBackgroundContents(ASCIIToUTF16(extension->id())); + + ExtensionService* service = profile->GetExtensionService(); + if (service && service->is_ready()) { + // Now load the manifest-specified background page. If service isn't + // ready, then the background page will be loaded from the + // EXTENSIONS_READY callback. + LoadBackgroundContents(profile, extension->background_url(), + ASCIIToUTF16("background"), UTF8ToUTF16(extension->id())); + } + } + break; + } case NotificationType::EXTENSION_PROCESS_TERMINATED: case NotificationType::BACKGROUND_CONTENTS_TERMINATED: { Profile* profile = Source<Profile>(source).ptr(); @@ -247,9 +288,17 @@ void BackgroundContentsService::Observe(NotificationType type, ASCIIToUTF16( Details<UnloadedExtensionInfo>(details)->extension->id())); break; - case UnloadedExtensionInfo::UPDATE: - // Leave BackgroundContents in place + case UnloadedExtensionInfo::UPDATE: { + // If there is a manifest specified background page, then shut it down + // here, since if the updated extension still has the background page, + // then it will be loaded from LOADED callback. Otherwise, leave + // BackgroundContents in place. + const Extension* extension = + Details<UnloadedExtensionInfo>(details)->extension; + if (extension->background_url().is_valid()) + ShutdownAssociatedBackgroundContents(ASCIIToUTF16(extension->id())); break; + } default: NOTREACHED(); ShutdownAssociatedBackgroundContents( @@ -312,6 +361,19 @@ void BackgroundContentsService::LoadBackgroundContentsFromPrefs( void BackgroundContentsService::LoadBackgroundContentsForExtension( Profile* profile, const std::string& extension_id) { + // First look if the manifest specifies a background page. + const Extension* extension = + profile->GetExtensionService()->GetExtensionById(extension_id, false); + DCHECK(!extension || extension->is_hosted_app()); + if (extension && extension->background_url().is_valid()) { + LoadBackgroundContents(profile, + extension->background_url(), + ASCIIToUTF16("background"), + UTF8ToUTF16(extension->id())); + return; + } + + // Now look in the prefs. if (!prefs_) return; const DictionaryValue* contents = @@ -342,6 +404,23 @@ void BackgroundContentsService::LoadBackgroundContentsFromDictionary( UTF8ToUTF16(extension_id)); } +void BackgroundContentsService::LoadBackgroundContentsFromManifests( + Profile* profile) { + const ExtensionList* extensions = + profile->GetExtensionService()->extensions(); + ExtensionList::const_iterator iter = extensions->begin(); + for (; iter != extensions->end(); ++iter) { + const Extension* extension = *iter; + if (extension->is_hosted_app() && + extension->background_url().is_valid()) { + LoadBackgroundContents(profile, + extension->background_url(), + ASCIIToUTF16("background"), + UTF8ToUTF16(extension->id())); + } + } +} + void BackgroundContentsService::LoadBackgroundContents( Profile* profile, const GURL& url, diff --git a/chrome/browser/background_contents_service.h b/chrome/browser/background_contents_service.h index 1b388c7..e6bf19b 100644 --- a/chrome/browser/background_contents_service.h +++ b/chrome/browser/background_contents_service.h @@ -78,8 +78,10 @@ class BackgroundContentsService : private NotificationObserver, const string16& frame_name, const string16& application_id); - // Load the registered BackgroundContents for the specified extension. This - // is typically used to reload a crashed background page. + // Load the manifest-specified background page for the specified hosted app. + // If the manifest doesn't specify one, then load the BackgroundContents + // registered in the pref. This is typically used to reload a crashed + // background page. void LoadBackgroundContentsForExtension(Profile* profile, const std::string& extension_id); @@ -114,6 +116,10 @@ class BackgroundContentsService : private NotificationObserver, const std::string& extension_id, const DictionaryValue* contents); + // Load the manifest-specified BackgroundContents for all apps for the + // profile. + void LoadBackgroundContentsFromManifests(Profile* profile); + // Creates a single BackgroundContents associated with the specified |appid|, // creates an associated RenderView with the name specified by |frame_name|, // and navigates to the passed |url|. diff --git a/chrome/browser/background_page_tracker.cc b/chrome/browser/background_page_tracker.cc index 5c52ea0..5a41c8d 100644 --- a/chrome/browser/background_page_tracker.cc +++ b/chrome/browser/background_page_tracker.cc @@ -160,7 +160,8 @@ void BackgroundPageTracker::Observe(NotificationType type, } case NotificationType::EXTENSION_LOADED: { const Extension* extension = Details<const Extension>(details).ptr(); - if (extension->background_url().is_valid()) + if (!extension->is_hosted_app() && + extension->background_url().is_valid()) OnBackgroundPageLoaded(extension->id()); break; } diff --git a/chrome/browser/extensions/app_background_page_apitest.cc b/chrome/browser/extensions/app_background_page_apitest.cc index f1f98bf..b13dc77 100644 --- a/chrome/browser/extensions/app_background_page_apitest.cc +++ b/chrome/browser/extensions/app_background_page_apitest.cc @@ -1,10 +1,15 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "base/string_util.h" +#include "chrome/browser/background_contents_service.h" #include "chrome/browser/extensions/extension_apitest.h" +#include "chrome/browser/extensions/extension_service.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/extensions/extension.h" #include "chrome/test/ui_test_utils.h" #include "net/base/mock_host_resolver.h" @@ -13,6 +18,7 @@ class AppBackgroundPageApiTest : public ExtensionApiTest { void SetUpCommandLine(CommandLine* command_line) { ExtensionApiTest::SetUpCommandLine(command_line); command_line->AppendSwitch(switches::kDisablePopupBlocking); + command_line->AppendSwitch(switches::kAllowHTTPBackgroundPage); } bool CreateApp(const std::string& app_manifest, @@ -90,3 +96,34 @@ IN_PROC_BROWSER_TEST_F(AppBackgroundPageApiTest, DISABLED_LacksPermission) { ASSERT_TRUE(RunExtensionTest("app_background_page/lacks_permission")) << message_; } + +IN_PROC_BROWSER_TEST_F(AppBackgroundPageApiTest, ManifestBackgroundPage) { + host_resolver()->AddRule("a.com", "127.0.0.1"); + ASSERT_TRUE(StartTestServer()); + + std::string app_manifest = StringPrintf( + "{" + " \"name\": \"App\"," + " \"version\": \"0.1\"," + " \"app\": {" + " \"urls\": [" + " \"http://a.com/\"" + " ]," + " \"launch\": {" + " \"web_url\": \"http://a.com:%d/\"" + " }" + " }," + " \"permissions\": [\"background\"]," + " \"background_page\": \"http://a.com:%d/test.html\"" + "}", + test_server()->host_port_pair().port(), + test_server()->host_port_pair().port()); + + FilePath app_dir; + ASSERT_TRUE(CreateApp(app_manifest, &app_dir)); + ASSERT_TRUE(LoadExtension(app_dir)); + + const Extension* extension = GetSingleLoadedExtension(); + ASSERT_TRUE(browser()->profile()->GetBackgroundContentsService()-> + GetAppBackgroundContents(ASCIIToUTF16(extension->id()))); +} diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc index b0dc81e..5eccb76 100644 --- a/chrome/browser/extensions/extension_process_manager.cc +++ b/chrome/browser/extensions/extension_process_manager.cc @@ -168,6 +168,11 @@ ExtensionHost* ExtensionProcessManager::CreateInfobar(const GURL& url, void ExtensionProcessManager::CreateBackgroundHost( const Extension* extension, const GURL& url) { + // Hosted apps are taken care of from BackgroundContentsService. Ignore them + // here. + if (extension->is_hosted_app()) + return; + // Don't create multiple background hosts for an extension. if (GetBackgroundHostForExtension(extension)) return; diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index 58097a2..8c2664e 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -681,6 +681,7 @@ void BrowserRenderProcessHost::PropagateBrowserCommandLineToRenderer( // Propagate the following switches to the renderer command line (along // with any associated values) if present in the browser command line. static const char* const kSwitchNames[] = { + switches::kAllowHTTPBackgroundPage, switches::kAllowScriptingGallery, switches::kAlwaysAuthorizePlugins, switches::kAppsGalleryURL, diff --git a/chrome/browser/tab_contents/render_view_host_delegate_helper.cc b/chrome/browser/tab_contents/render_view_host_delegate_helper.cc index 85f8ce2..c07acdd 100644 --- a/chrome/browser/tab_contents/render_view_host_delegate_helper.cc +++ b/chrome/browser/tab_contents/render_view_host_delegate_helper.cc @@ -58,6 +58,11 @@ RenderViewHostDelegateViewHelper::MaybeCreateBackgroundContents( if (!extension) return NULL; + // If the extension manifest specifies a background page, then don't allow one + // to be created here. + if (extension->background_url().is_valid()) + return NULL; + // Only allow a single background contents per app. if (!profile->GetBackgroundContentsService() || profile->GetBackgroundContentsService()->GetAppBackgroundContents( diff --git a/chrome/browser/task_manager/task_manager_resource_providers.cc b/chrome/browser/task_manager/task_manager_resource_providers.cc index c4dfbf8..19747c0 100644 --- a/chrome/browser/task_manager/task_manager_resource_providers.cc +++ b/chrome/browser/task_manager/task_manager_resource_providers.cc @@ -363,6 +363,9 @@ void TaskManagerTabContentsResourceProvider::Observe(NotificationType type, TabContentsWrapper* tab_contents = TabContentsWrapper::GetCurrentWrapperForContents( Source<TabContents>(source).ptr()); + // A background page does not have a TabContentsWrapper. + if (!tab_contents) + return; switch (type.value) { case NotificationType::TAB_CONTENTS_CONNECTED: Add(tab_contents); diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 82a4ab9..44aa7cd 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -21,6 +21,9 @@ const char kActivateOnLaunch[] = "activate-on-launch"; // directories. This switch re-enables file:// for testing. const char kAllowFileAccess[] = "allow-file-access"; +// Allow non-https URL for background_page for hosted apps. +const char kAllowHTTPBackgroundPage[] = "allow-http-background-page"; + // Don't block outdated plugins. const char kAllowOutdatedPlugins[] = "allow-outdated-plugins"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 582c41d..640e764 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -26,6 +26,7 @@ namespace switches { extern const char kActivateOnLaunch[]; extern const char kAllowFileAccess[]; extern const char kAllowOutdatedPlugins[]; +extern const char kAllowHTTPBackgroundPage[]; extern const char kAllowScriptingGallery[]; extern const char kAlwaysAuthorizePlugins[]; extern const char kAlwaysEnableDevTools[]; diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc index 3fc7be1..471dd11 100644 --- a/chrome/common/extensions/extension.cc +++ b/chrome/common/extensions/extension.cc @@ -1284,8 +1284,10 @@ bool Extension::EnsureNotHybridApp(const DictionaryValue* manifest, if (!IsBaseCrxKey(*key) && *key != keys::kApp && *key != keys::kPermissions && - *key != keys::kOptionsPage) { - *error = errors::kHostedAppsCannotIncludeExtensionFeatures; + *key != keys::kOptionsPage && + *key != keys::kBackground) { + *error = ExtensionErrorUtils::FormatErrorMessage( + errors::kHostedAppsCannotIncludeExtensionFeatures, *key); return false; } } @@ -1854,16 +1856,6 @@ bool Extension::InitFromValue(const DictionaryValue& source, int flags, } } - // Initialize background url (optional). - if (source.HasKey(keys::kBackground)) { - std::string background_str; - if (!source.GetString(keys::kBackground, &background_str)) { - *error = errors::kInvalidBackground; - return false; - } - background_url_ = GetResourceURL(background_str); - } - // Initialize toolstrips. This is deprecated for public use. // NOTE(erikkay) Although deprecated, we intend to preserve this parsing // code indefinitely. Please contact me or Joi for details as to why. @@ -2012,7 +2004,6 @@ bool Extension::InitFromValue(const DictionaryValue& source, int flags, return false; } options_url_ = options_url; - } else { GURL absolute(options_str); if (absolute.is_valid()) { @@ -2118,6 +2109,41 @@ bool Extension::InitFromValue(const DictionaryValue& source, int flags, } } + // Initialize background url (optional). + if (source.HasKey(keys::kBackground)) { + std::string background_str; + if (!source.GetString(keys::kBackground, &background_str)) { + *error = errors::kInvalidBackground; + return false; + } + + if (is_hosted_app()) { + // Make sure "background" permission is set. + if (api_permissions_.find(kBackgroundPermission) == + api_permissions_.end()) { + *error = errors::kBackgroundPermissionNeeded; + return false; + } + // Hosted apps require an absolute URL. + GURL bg_page(background_str); + if (!bg_page.is_valid()) { + *error = errors::kInvalidBackgroundInHostedApp; + return false; + } + + if (!(bg_page.SchemeIs("https") || + (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kAllowHTTPBackgroundPage) && + bg_page.SchemeIs("http")))) { + *error = errors::kInvalidBackgroundInHostedApp; + return false; + } + background_url_ = bg_page; + } else { + background_url_ = GetResourceURL(background_str); + } + } + if (source.HasKey(keys::kDefaultLocale)) { if (!source.GetString(keys::kDefaultLocale, &default_locale_) || !l10n_util::IsValidLocaleSyntax(default_locale_)) { diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc index 97243e5..27324ef 100644 --- a/chrome/common/extensions/extension_constants.cc +++ b/chrome/common/extensions/extension_constants.cc @@ -102,6 +102,9 @@ const char* kLaunchContainerWindow = "window"; namespace extension_manifest_errors { const char* kAppsNotEnabled = "Apps are not enabled."; +const char* kBackgroundPermissionNeeded = + "Hosted apps that use 'background_page' must have the 'background' " + "permission."; const char* kCannotAccessPage = "Cannot access contents of url \"*\". " "Extension manifest must request permission to access this host."; @@ -128,11 +131,14 @@ const char *kExperimentalFeature = "This feature requires 'experimental' permissions and" " --enable-experimental-extension-apis command line flag."; const char* kHostedAppsCannotIncludeExtensionFeatures = - "Hosted apps cannot use extension features."; + "Hosted apps cannot use the extension feature '*'."; const char* kInvalidAllFrames = "Invalid value for 'content_scripts[*].all_frames'."; const char* kInvalidBackground = "Invalid value for 'background_page'."; +const char* kInvalidBackgroundInHostedApp = + "Invalid value for 'background_page'. Hosted apps must specify an " + "absolute HTTPS URL for the background page."; const char* kInvalidBrowserAction = "Invalid value for 'browser_action'."; const char* kInvalidChromeURLOverrides = diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h index daa2156..f05c947 100644 --- a/chrome/common/extensions/extension_constants.h +++ b/chrome/common/extensions/extension_constants.h @@ -104,6 +104,7 @@ namespace extension_manifest_values { // Error messages returned from Extension::InitFromValue(). namespace extension_manifest_errors { extern const char* kAppsNotEnabled; + extern const char* kBackgroundPermissionNeeded; extern const char* kCannotAccessPage; extern const char* kCannotClaimAllHostsInExtent; extern const char* kCannotClaimAllURLsInExtent; @@ -118,6 +119,7 @@ namespace extension_manifest_errors { extern const char* kHostedAppsCannotIncludeExtensionFeatures; extern const char* kInvalidAllFrames; extern const char* kInvalidBackground; + extern const char* kInvalidBackgroundInHostedApp; extern const char* kInvalidBrowserAction; extern const char* kInvalidBrowseURL; extern const char* kInvalidBrowseURLs; diff --git a/chrome/common/extensions/extension_file_util.cc b/chrome/common/extensions/extension_file_util.cc index 1c4ec8c..be34cfb 100644 --- a/chrome/common/extensions/extension_file_util.cc +++ b/chrome/common/extensions/extension_file_util.cc @@ -245,8 +245,10 @@ bool ValidateExtension(Extension* extension, std::string* error) { } } - // Validate background page location. - if (!extension->background_url().is_empty()) { + // Validate background page location, except for hosted apps, which should use + // an external URL. Background page for hosted apps are verified when the + // extension is created (in Extension::InitFromValue) + if (!extension->background_url().is_empty() && !extension->is_hosted_app()) { FilePath page_path = ExtensionURLToRelativeFilePath( extension->background_url()); const FilePath path = extension->GetResource(page_path).GetFilePath(); diff --git a/chrome/common/extensions/extension_manifests_unittest.cc b/chrome/common/extensions/extension_manifests_unittest.cc index 5deef17..e49ec0a 100644 --- a/chrome/common/extensions/extension_manifests_unittest.cc +++ b/chrome/common/extensions/extension_manifests_unittest.cc @@ -405,9 +405,11 @@ TEST_F(ExtensionManifestTest, Sidebar) { TEST_F(ExtensionManifestTest, DisallowHybridApps) { LoadAndExpectError("disallow_hybrid_1.json", - errors::kHostedAppsCannotIncludeExtensionFeatures); + ExtensionErrorUtils::FormatErrorMessage( + errors::kHostedAppsCannotIncludeExtensionFeatures, + keys::kBrowserAction)); LoadAndExpectError("disallow_hybrid_2.json", - errors::kHostedAppsCannotIncludeExtensionFeatures); + errors::kBackgroundPermissionNeeded); } TEST_F(ExtensionManifestTest, OptionsPageInApps) { |