diff options
Diffstat (limited to 'chrome')
49 files changed, 244 insertions, 830 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index 378d86e..61de33c 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -381,9 +381,9 @@ bool Browser::OpenApplication(Profile* profile, const std::string& app_id) { return false; // TODO(erikkay): Support refocus. - Extension::LaunchContainer launch_container = - extension_app->launch_container(); - switch (launch_container) { + Extension::AppLaunchType launch_type = + extension_app->app_launch_type(); + switch (launch_type) { case Extension::LAUNCH_WINDOW: case Extension::LAUNCH_PANEL: Browser::OpenApplicationWindow(profile, extension_app); @@ -421,9 +421,8 @@ void Browser::OpenApplicationWindow(Profile* profile, const GURL& url, // Set UPDATE_SHORTCUT as the pending web app action. This action is picked // up in LoadingStateChanged to schedule a GetApplicationInfo. And when // the web app info is available, TabContents notifies Browser via - // OnDidGetApplicationInfo, which calls - // web_app::UpdateShortcutForTabContents when it sees UPDATE_SHORTCUT as - // pending web app action. + // OnDidGetApplicationInfo, which calls web_app::UpdateShortcutForTabContents + // when it sees UPDATE_SHORTCUT as pending web app action. browser->pending_web_app_action_ = UPDATE_SHORTCUT; } } @@ -431,13 +430,13 @@ void Browser::OpenApplicationWindow(Profile* profile, const GURL& url, // static void Browser::OpenApplicationWindow(Profile* profile, Extension* extension) { OpenApplicationWindow(profile, - extension->GetFullLaunchURL(), - (extension->launch_container() == Extension::LAUNCH_PANEL)); + extension->app_launch_url(), + (extension->app_launch_type() == Extension::LAUNCH_PANEL)); } // static bool Browser::OpenApplicationTab(Profile* profile, Extension* extension) { - DCHECK_EQ(extension->launch_container(), Extension::LAUNCH_TAB); + DCHECK_EQ(extension->app_launch_type(), Extension::LAUNCH_TAB); Browser* browser = BrowserList::GetLastActiveWithProfile(profile); if (!browser || browser->type() != Browser::TYPE_NORMAL) @@ -445,7 +444,7 @@ bool Browser::OpenApplicationTab(Profile* profile, Extension* extension) { // TODO(erikkay): This doesn't seem like the right transition in all cases. PageTransition::Type transition = PageTransition::START_PAGE; - GURL url = extension->GetFullLaunchURL(); + GURL url = extension->app_launch_url(); TabContents* tab_contents = browser->CreateTabContentsForURL(url, GURL(), profile, transition, false, NULL); diff --git a/chrome/browser/download/download_manager.cc b/chrome/browser/download/download_manager.cc index 0075352..cc47bea 100644 --- a/chrome/browser/download/download_manager.cc +++ b/chrome/browser/download/download_manager.cc @@ -1457,7 +1457,7 @@ void DownloadManager::OpenChromeExtension(const FilePath& full_path, } else { installer->set_allow_privilege_increase(true); installer->set_original_url(download_url); - installer->set_force_web_origin_to_download_url(true); + installer->set_force_app_origin_to_download_url(true); installer->InstallCrx(full_path); } } else { diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc index 93ec0bb..02bc700 100644 --- a/chrome/browser/extensions/crx_installer.cc +++ b/chrome/browser/extensions/crx_installer.cc @@ -39,7 +39,7 @@ CrxInstaller::CrxInstaller(const FilePath& install_directory, install_source_(Extension::INTERNAL), delete_source_(false), allow_privilege_increase_(false), - force_web_origin_to_download_url_(false), + force_app_origin_to_download_url_(false), create_app_shortcut_(false), frontend_(frontend), client_(client) { @@ -72,8 +72,8 @@ void CrxInstaller::InstallCrx(const FilePath& source_file) { g_browser_process->resource_dispatcher_host(), this)); - if (force_web_origin_to_download_url_ && original_url_.is_valid()) { - unpacker->set_web_origin(original_url_.GetOrigin()); + if (force_app_origin_to_download_url_ && original_url_.is_valid()) { + unpacker->set_app_origin_override(original_url_.GetOrigin()); } ChromeThread::PostTask( @@ -142,7 +142,7 @@ void CrxInstaller::OnUnpackSuccess(const FilePath& temp_dir, return; } - if (client_.get() || extension_->GetFullLaunchURL().is_valid()) { + if (client_.get() || extension_->IsApp()) { Extension::DecodeIcon(extension_.get(), Extension::EXTENSION_ICON_LARGE, &install_icon_); } @@ -177,7 +177,7 @@ void CrxInstaller::ConfirmInstall() { void CrxInstaller::InstallUIProceed(bool create_app_shortcut) { if (create_app_shortcut) { - DCHECK(extension_->GetFullLaunchURL().is_valid()); + DCHECK(extension_->IsApp()); create_app_shortcut_ = true; } @@ -233,7 +233,7 @@ void CrxInstaller::CompleteInstall() { IDR_EXTENSION_DEFAULT_ICON); ShellIntegration::ShortcutInfo shortcut_info; - shortcut_info.url = extension_->GetFullLaunchURL(); + shortcut_info.url = extension_->app_launch_url(); shortcut_info.extension_id = UTF8ToUTF16(extension_->id()); shortcut_info.title = UTF8ToUTF16(extension_->name()); shortcut_info.description = UTF8ToUTF16(extension_->description()); diff --git a/chrome/browser/extensions/crx_installer.h b/chrome/browser/extensions/crx_installer.h index bb109c2..9e4990e 100644 --- a/chrome/browser/extensions/crx_installer.h +++ b/chrome/browser/extensions/crx_installer.h @@ -83,11 +83,11 @@ class CrxInstaller allow_privilege_increase_ = val; } - bool force_web_origin_to_download_url() const { - return force_web_origin_to_download_url_; + bool force_app_origin_to_download_url() const { + return force_app_origin_to_download_url_; } - void set_force_web_origin_to_download_url(bool val) { - force_web_origin_to_download_url_ = val; + void set_force_app_origin_to_download_url(bool val) { + force_app_origin_to_download_url_ = val; } private: @@ -153,9 +153,9 @@ class CrxInstaller // either. Defaults to false. bool allow_privilege_increase_; - // If true and the installed extension uses web content, the web origin will + // If true and the installed extension is an app, the origin of that app will // be forced to the origin of |original_url_|. Defaults to false. - bool force_web_origin_to_download_url_; + bool force_app_origin_to_download_url_; // Whether to create an app shortcut after successful installation. This is // set based on the user's selection in the UI and can only ever be true for diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc index 3d72258..62432b5 100644 --- a/chrome/browser/extensions/extensions_service.cc +++ b/chrome/browser/extensions/extensions_service.cc @@ -216,7 +216,7 @@ void ExtensionsService::UpdateExtension(const std::string& id, NULL)); // no client (silent install) installer->set_expected_id(id); installer->set_delete_source(true); - installer->set_force_web_origin_to_download_url(true); + installer->set_force_app_origin_to_download_url(true); installer->set_original_url(download_url); installer->InstallCrx(extension_path); } @@ -511,7 +511,7 @@ void ExtensionsService::NotifyExtensionLoaded(Extension* extension) { new ChromeURLRequestContext::ExtensionInfo( extension->path(), extension->default_locale(), - std::vector<URLPattern>(), + extension->app_extent(), extension->api_permissions()))); } @@ -706,6 +706,15 @@ void ExtensionsService::OnExtensionLoaded(Extension* extension, // The extension is now loaded, remove its data from unloaded extension map. unloaded_extension_paths_.erase(extension->id()); + if (extension->IsApp() && + !CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableExtensionApps)) { + ReportExtensionLoadError(extension->path(), errors::kAppsDisabled, + NotificationType::EXTENSION_INSTALL_ERROR, + true); // be noisy + return; + } + // TODO(aa): Need to re-evaluate this branch. Does this still make sense now // that extensions are enabled by default? if (extensions_enabled() || diff --git a/chrome/browser/extensions/sandboxed_extension_unpacker.cc b/chrome/browser/extensions/sandboxed_extension_unpacker.cc index 427b864..1cbd932 100644 --- a/chrome/browser/extensions/sandboxed_extension_unpacker.cc +++ b/chrome/browser/extensions/sandboxed_extension_unpacker.cc @@ -255,18 +255,16 @@ DictionaryValue* SandboxedExtensionUnpacker::RewriteManifestFile( static_cast<DictionaryValue*>(manifest.DeepCopy())); final_manifest->SetString(extension_manifest_keys::kPublicKey, public_key_); - // Override the origin if appropriate. - bool web_content_enabled = false; - if (final_manifest->GetBoolean(extension_manifest_keys::kWebContentEnabled, - &web_content_enabled) && - web_content_enabled && - web_origin_.is_valid()) { - if (final_manifest->HasKey(extension_manifest_keys::kWebOrigin)) { - ReportFailure("Unexpected 'web_content.origin' key in manifest."); + // Override the app origin if appropriate. + DictionaryValue* app = NULL; + if (final_manifest->GetDictionary(extension_manifest_keys::kApp, &app) && + !app_origin_override_.is_empty()) { + if (app->HasKey(extension_manifest_keys::kAppOrigin)) { + ReportFailure("Unexpected 'origin' key in manifest."); return NULL; } - final_manifest->SetString(extension_manifest_keys::kWebOrigin, - web_origin_.spec()); + app->SetString(extension_manifest_keys::kAppOrigin, + app_origin_override_.spec()); } std::string manifest_json; diff --git a/chrome/browser/extensions/sandboxed_extension_unpacker.h b/chrome/browser/extensions/sandboxed_extension_unpacker.h index a3b190c..25d77b6 100644 --- a/chrome/browser/extensions/sandboxed_extension_unpacker.h +++ b/chrome/browser/extensions/sandboxed_extension_unpacker.h @@ -96,9 +96,9 @@ class SandboxedExtensionUnpacker : public UtilityProcessHost::Client { ResourceDispatcherHost* rdh, SandboxedExtensionUnpackerClient* cilent); - const GURL& web_origin() const { return web_origin_; } - void set_web_origin(const GURL& val) { - web_origin_ = val; + const GURL& app_origin_override() const { return app_origin_override_; } + void set_app_origin_override(const GURL& val) { + app_origin_override_ = val; } // Start unpacking the extension. The client is called with the results. @@ -169,10 +169,10 @@ class SandboxedExtensionUnpacker : public UtilityProcessHost::Client { // The public key that was extracted from the CRX header. std::string public_key_; - // If the unpacked extension uses web content, its origin will be set to this - // value. This is used when an app is self-hosted. The only valid origin is - // the origin it is served from. - GURL web_origin_; + // If the unpacked extension is an app, its origin will be forced to this + // value. This is used when an app is self-hosted. The only valid origin + // is the origin it is served from. + GURL app_origin_override_; }; #endif // CHROME_BROWSER_EXTENSIONS_SANDBOXED_EXTENSION_UNPACKER_H_ diff --git a/chrome/browser/net/chrome_url_request_context.cc b/chrome/browser/net/chrome_url_request_context.cc index f19bd08..81b9fb5 100644 --- a/chrome/browser/net/chrome_url_request_context.cc +++ b/chrome/browser/net/chrome_url_request_context.cc @@ -854,7 +854,7 @@ ChromeURLRequestContextFactory::ChromeURLRequestContextFactory(Profile* profile) new ChromeURLRequestContext::ExtensionInfo( (*iter)->path(), (*iter)->default_locale(), - std::vector<URLPattern>(), + (*iter)->app_extent(), (*iter)->api_permissions())); } } diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index 384cdd1..a869687 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -478,7 +478,7 @@ RenderProcessHost* TabContents::GetRenderProcessHost() const { } void TabContents::SetAppExtension(Extension* extension) { - DCHECK(!extension || extension->GetFullLaunchURL().is_valid()); + DCHECK(!extension || extension->IsApp()); app_extension_ = extension; NotificationService::current()->Notify( @@ -1284,7 +1284,7 @@ TabContents* TabContents::CloneAndMakePhantom() { NavigationEntry* entry = controller().GetActiveEntry(); if (app_extension_) - tab_nav.set_url(app_extension_->GetFullLaunchURL()); + tab_nav.set_url(app_extension_->app_launch_url()); else if (entry) tab_nav.SetFromNavigationEntry(*entry); diff --git a/chrome/browser/tabs/pinned_tab_codec.cc b/chrome/browser/tabs/pinned_tab_codec.cc index df096fc..51b8fd2 100644 --- a/chrome/browser/tabs/pinned_tab_codec.cc +++ b/chrome/browser/tabs/pinned_tab_codec.cc @@ -50,7 +50,7 @@ static void EncodePinnedTab(TabStripModel* model, // . the user is effectively restarting the app, so that returning them to // the app's launch page seems closest to what they expect. // . we do the same when restoring a phantom tab. - value->SetString(kURL, extension->GetFullLaunchURL().spec()); + value->SetString(kURL, extension->app_launch_url().spec()); values->Append(value.release()); } else { NavigationEntry* entry = tab_contents->controller().GetActiveEntry(); diff --git a/chrome/browser/tabs/tab_strip_model_unittest.cc b/chrome/browser/tabs/tab_strip_model_unittest.cc index ac5881a2..4b67a43 100644 --- a/chrome/browser/tabs/tab_strip_model_unittest.cc +++ b/chrome/browser/tabs/tab_strip_model_unittest.cc @@ -1362,7 +1362,7 @@ TEST_F(TabStripModelTest, Apps) { FilePath path(FILE_PATH_LITERAL("/foo")); #endif Extension app_extension(path); - app_extension.launch_web_url_ = "http://www.google.com"; + app_extension.app_launch_url_ = GURL("http://www.google.com"); TabContents* contents1 = CreateTabContents(); contents1->SetAppExtension(&app_extension); TabContents* contents2 = CreateTabContents(); diff --git a/chrome/browser/views/extensions/extension_install_prompt.cc b/chrome/browser/views/extensions/extension_install_prompt.cc index 7e45c67..482cb3c 100644 --- a/chrome/browser/views/extensions/extension_install_prompt.cc +++ b/chrome/browser/views/extensions/extension_install_prompt.cc @@ -44,7 +44,7 @@ class InstallDialogContent : public views::View, public views::DialogDelegate { ExtensionInstallUI::PromptType type) : delegate_(delegate), icon_(NULL), warning_(NULL), create_shortcut_(NULL), type_(type) { - if (extension->GetFullLaunchURL().is_valid()) { + if (extension->IsApp()) { icon_size_ = kIconSizeApp; right_column_width_ = kRightColumnWidthApp; } else { @@ -69,8 +69,7 @@ class InstallDialogContent : public views::View, public views::DialogDelegate { heading_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); AddChildView(heading_); - if (type_ == ExtensionInstallUI::INSTALL_PROMPT && - extension->GetFullLaunchURL().is_valid()) { + if (type_ == ExtensionInstallUI::INSTALL_PROMPT && extension->IsApp()) { create_shortcut_ = new views::Checkbox( l10n_util::GetString(IDS_EXTENSION_PROMPT_CREATE_SHORTCUT)); create_shortcut_->SetChecked(true); diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi index 761f521..76489ee 100644 --- a/chrome/chrome_common.gypi +++ b/chrome/chrome_common.gypi @@ -153,8 +153,6 @@ 'common/extensions/extension_error_reporter.h', 'common/extensions/extension_error_utils.cc', 'common/extensions/extension_error_utils.h', - 'common/extensions/extension_extent.cc', - 'common/extensions/extension_extent.h', 'common/extensions/extension_file_util.cc', 'common/extensions/extension_file_util.h', 'common/extensions/extension_l10n_util.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index eae0f1f..25e7e7c 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -916,11 +916,9 @@ 'common/extensions/extension_action_unittest.cc', 'common/extensions/extension_file_util_unittest.cc', 'common/extensions/extension_l10n_util_unittest.cc', - 'common/extensions/extension_manifests_unittest.cc', 'common/extensions/extension_message_bundle_unittest.cc', 'common/extensions/extension_message_filter_peer_unittest.cc', 'common/extensions/extension_resource_unittest.cc', - 'common/extensions/extension_extent_unittest.cc', 'common/extensions/extension_unittest.cc', 'common/extensions/extension_unpacker_unittest.cc', 'common/extensions/update_manifest_unittest.cc', diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc index 81e15d1..b12c764 100644 --- a/chrome/common/extensions/extension.cc +++ b/chrome/common/extensions/extension.cc @@ -488,185 +488,98 @@ bool Extension::ContainsNonThemeKeys(const DictionaryValue& source) { return false; } -bool Extension::CheckAppsAreEnabled(const DictionaryValue* manifest, - std::string* error) { - if (!apps_enabled_) { - if (manifest->HasKey(keys::kWebContent) || - manifest->HasKey(keys::kLaunch)) { - *error = errors::kAppsNotEnabled; - return false; - } - } - - return true; -} - -bool Extension::LoadWebContentEnabled(const DictionaryValue* manifest, - std::string* error) { - Value* temp = NULL; - if (manifest->Get(keys::kWebContentEnabled, &temp)) { - if (!temp->GetAsBoolean(&web_content_enabled_)) { - *error = errors::kInvalidWebContentEnabled; - return false; - } - } - - // The enabled flag must be set to use the web_content dictionary at all. - if (!web_content_enabled_ && manifest->HasKey(keys::kWebContent)) { - *error = errors::kWebContentMustBeEnabled; - return false; - } - - return true; +// We're likely going to want to restrict apps away from certain APIs/features. +// TODO(erikkay) - figure out what APIs to block. +bool Extension::ContainsNonAppKeys(const DictionaryValue& source) { + return false; } -bool Extension::LoadWebOrigin(const DictionaryValue* manifest, - std::string* error) { - Value* temp = NULL; - if (!manifest->Get(keys::kWebOrigin, &temp)) - return true; - - // Check datatype. - std::string origin_string; - if (!temp->GetAsString(&origin_string)) { - *error = errors::kInvalidWebOrigin; - return false; - } - - // Origin must be a valid URL. - GURL origin_gurl(origin_string); - if (!origin_gurl.is_valid() || origin_gurl.is_empty()) { - *error = errors::kInvalidWebOrigin; - return false; - } - - // Origins can only be http or https. - if (!origin_gurl.SchemeIs(chrome::kHttpScheme) && - !origin_gurl.SchemeIs(chrome::kHttpsScheme)) { - *error = errors::kInvalidWebOrigin; +bool Extension::LoadAppHelper(const DictionaryValue* app, std::string* error) { + // launch URL + std::string launch_url_spec; + if (!app->GetString(keys::kAppLaunchUrl, &launch_url_spec)) { + *error = errors::kInvalidAppLaunchUrl; return false; } - - // Check that the origin doesn't include any extraneous information. - if (origin_gurl.GetOrigin() != origin_gurl) { - *error = errors::kInvalidWebOrigin; - return false; - } - - web_extent_.set_origin(origin_gurl); - return true; -} - -bool Extension::LoadWebPaths(const DictionaryValue* manifest, - std::string* error) { - Value* temp = NULL; - if (!manifest->Get(keys::kWebPaths, &temp)) - return true; - - // Check datatype. - if (!temp->IsType(Value::TYPE_LIST)) { - *error = errors::kInvalidWebPaths; + app_launch_url_ = GURL(launch_url_spec); + if (!app_launch_url_.is_valid()) { + *error = errors::kInvalidAppLaunchUrl; return false; } - ListValue* web_paths = static_cast<ListValue*>(temp); - for (size_t i = 0; i < web_paths->GetSize(); ++i) { - // Get item and check datatype. - std::string item; - if (!web_paths->GetString(i, &item) || item.empty()) { - *error = ExtensionErrorUtils::FormatErrorMessage( - errors::kInvalidWebPath, IntToString(i)); - return false; - } - - // Ensure the path is a valid relative URL by resolving it against the - // extension root. - // TODO(aa): This is hacky. Is there another way to know whether a string - // is a valid relative URL? - GURL resolved = extension_url_.Resolve(item); - if (!resolved.is_valid() || resolved.GetOrigin() != extension_url_) { - *error = ExtensionErrorUtils::FormatErrorMessage( - errors::kInvalidWebPath, IntToString(i)); + // launch type + app_launch_type_ = LAUNCH_WINDOW; // TODO(erikkay) LAUNCH_TAB? + std::string launch_type_string; + if (app->GetString(keys::kAppLaunchType, &launch_type_string)) { + if (launch_type_string == std::string(values::kLaunchTypePanel)) { + app_launch_type_ = LAUNCH_PANEL; + } else if (launch_type_string == std::string(values::kLaunchTypeTab)) { + app_launch_type_ = LAUNCH_TAB; + } else if (launch_type_string != std::string(values::kLaunchTypeWindow)) { + *error = errors::kInvalidAppLaunchType; return false; } - - web_extent_.add_path(item); } - return true; -} + // The launch URL is automatically added to the extent. + URLPattern pattern; + pattern.set_scheme(app_launch_url_.scheme()); + pattern.set_host(app_launch_url_.host()); + pattern.set_path(app_launch_url_.path()); + app_extent_.push_back(pattern); -bool Extension::LoadLaunchURL(const DictionaryValue* manifest, - std::string* error) { - Value* temp = NULL; - - // launch URL can be either local (to chrome-extension:// root) or web (either - // relative to the origin, or an absolute URL). - if (manifest->Get(keys::kLaunchLocalPath, &temp)) { - if (manifest->Get(keys::kLaunchWebURL, NULL)) { - *error = errors::kLaunchPathAndURLAreExclusive; + // extent + if (app->HasKey(keys::kAppExtent)) { + ListValue* extent; + if (!app->GetList(keys::kAppExtent, &extent)) { + *error = errors::kInvalidAppExtent; return false; } + for (ListValue::const_iterator iter = extent->begin(); + iter != extent->end(); ++iter) { + std::string item; + if (!(*iter)->GetAsString(&item) || item.empty()) { + *error = ExtensionErrorUtils::FormatErrorMessage( + errors::kInvalidAppExtentPattern, item); + return false; + } + if (!pattern.Parse(item)) { + *error = ExtensionErrorUtils::FormatErrorMessage( + errors::kInvalidAppExtentPattern, item); + return false; + } + app_extent_.push_back(pattern); + } + } - std::string launch_path; - if (!temp->GetAsString(&launch_path)) { - *error = errors::kInvalidLaunchLocalPath; + if (app->HasKey(keys::kAppOrigin)) { + std::string origin_string; + if (!app->GetString(keys::kAppOrigin, &origin_string)) { + *error = errors::kInvalidAppOrigin; return false; } - // Ensure the launch path is a valid relative URL. - GURL resolved = extension_url_.Resolve(launch_path); - if (!resolved.is_valid() || resolved.GetOrigin() != extension_url_) { - *error = errors::kInvalidLaunchLocalPath; + // Origin must be a valid URL. + GURL origin_gurl(origin_string); + if (!origin_gurl.is_valid() || origin_gurl.is_empty()) { + *error = errors::kInvalidAppOrigin; return false; } - launch_local_path_ = launch_path; - } else if (manifest->Get(keys::kLaunchWebURL, &temp)) { - std::string launch_url; - if (!temp->GetAsString(&launch_url)) { - *error = errors::kInvalidLaunchWebURL; + // Origins can only be http or https. + if (!origin_gurl.SchemeIs(chrome::kHttpScheme) && + !origin_gurl.SchemeIs(chrome::kHttpsScheme)) { + *error = errors::kInvalidAppOrigin; return false; } - // Ensure the launch URL is a valid relative or absolute URL. - if (!extension_url_.Resolve(launch_url).is_valid()) { - *error = errors::kInvalidLaunchWebURL; + // Check that the origin doesn't include any extraneous information. + if (origin_gurl.GetOrigin() != origin_gurl) { + *error = errors::kInvalidAppOrigin; return false; } - launch_web_url_ = launch_url; - } - - return true; -} - -bool Extension::LoadLaunchContainer(const DictionaryValue* manifest, - std::string* error) { - Value* temp = NULL; - if (!manifest->Get(keys::kLaunchContainer, &temp)) - return true; - - std::string launch_container_string; - if (!temp->GetAsString(&launch_container_string)) { - *error = errors::kInvalidLaunchContainer; - return false; - } - - if (launch_local_path_.empty() && launch_web_url_.empty()) { - *error = errors::kLaunchContainerWithoutURL; - return false; - } - - if (launch_container_string == values::kLaunchContainerPanel) { - launch_container_ = LAUNCH_PANEL; - } else if (launch_container_string == values::kLaunchContainerTab) { - launch_container_ = LAUNCH_TAB; - } else if (launch_container_string == values::kLaunchContainerWindow) { - launch_container_ = LAUNCH_WINDOW; - } else { - *error = errors::kInvalidLaunchContainer; - return false; + app_origin_ = origin_gurl; } return true; @@ -675,14 +588,9 @@ bool Extension::LoadLaunchContainer(const DictionaryValue* manifest, Extension::Extension(const FilePath& path) : converted_from_user_script_(false), is_theme_(false), - web_content_enabled_(false), - launch_container_(LAUNCH_TAB), background_page_ready_(false), being_upgraded_(false) { DCHECK(path.IsAbsolute()); - - apps_enabled_ = CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableExtensionApps); location_ = INVALID; #if defined(OS_WIN) @@ -1385,13 +1293,20 @@ bool Extension::InitFromValue(const DictionaryValue& source, bool require_key, } } - if (!CheckAppsAreEnabled(manifest_value_.get(), error) || - !LoadWebContentEnabled(manifest_value_.get(), error) || - !LoadWebOrigin(manifest_value_.get(), error) || - !LoadWebPaths(manifest_value_.get(), error) || - !LoadLaunchURL(manifest_value_.get(), error) || - !LoadLaunchContainer(manifest_value_.get(), error)) { - return false; + // If it's an app, load the appropriate keys, etc. + if (source.HasKey(keys::kApp)) { + if (ContainsNonAppKeys(source)) { + *error = errors::kInvalidApp; + return false; + } + DictionaryValue* app; + if (!source.GetDictionary(keys::kApp, &app)) { + *error = errors::kInvalidApp; + return false; + } + if (!LoadAppHelper(app, error)) { + return false; + } } // Although |source| is passed in as a const, it's still possible to modify @@ -1445,21 +1360,6 @@ std::set<FilePath> Extension::GetBrowserImages() { return image_paths; } -GURL Extension::GetFullLaunchURL() const { - if (!launch_local_path_.empty()) { - return extension_url_.Resolve(launch_local_path_); - } else if (!launch_web_url_.empty()) { - // If there is a web origin, we interpret the launch URL relatively to that. - // Otherwise, hopefully it was an absolute URL. - if (web_extent_.origin().is_valid()) - return web_extent_.origin().Resolve(launch_web_url_); - else - return GURL(launch_web_url_); - } else { - return GURL(); - } -} - bool Extension::GetBackgroundPageReady() { return background_page_ready_ || background_url().is_empty(); } diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h index 418a01a..50fe957 100644 --- a/chrome/common/extensions/extension.h +++ b/chrome/common/extensions/extension.h @@ -15,7 +15,6 @@ #include "base/values.h" #include "base/version.h" #include "chrome/common/extensions/extension_action.h" -#include "chrome/common/extensions/extension_extent.h" #include "chrome/common/extensions/extension_resource.h" #include "chrome/common/extensions/user_script.h" #include "chrome/common/extensions/url_pattern.h" @@ -68,15 +67,12 @@ class Extension { EXTENSION_ICON_BITTY = 16, }; - enum LaunchContainer { + enum AppLaunchType { LAUNCH_WINDOW, LAUNCH_PANEL, LAUNCH_TAB }; - bool apps_enabled() const { return apps_enabled_; } - void set_apps_enabled(bool val) { apps_enabled_ = val; } - // Icon sizes used by the extension system. static const int kIconSizes[]; @@ -292,15 +288,12 @@ class Extension { return chrome_url_overrides_; } - bool web_content_enabled() const { return web_content_enabled_; } - const ExtensionExtent& web_extent() const { return web_extent_; } - - const std::string& launch_local_path() const { return launch_local_path_; } - const std::string& launch_web_url() const { return launch_web_url_; } - const LaunchContainer launch_container() const { return launch_container_; } - - // Gets the fully resolved absolute launch URL. - GURL GetFullLaunchURL() const; + // App stuff. + const URLPatternList& app_extent() const { return app_extent_; } + const GURL& app_launch_url() const { return app_launch_url_; } + bool IsApp() const { return !app_launch_url_.is_empty(); } + AppLaunchType app_launch_type() { return app_launch_type_; } + const GURL& app_origin() const { return app_origin_; } // Runtime data: // Put dynamic data about the state of a running extension below. @@ -333,18 +326,6 @@ class Extension { void(UserScript::*add_method)(const std::string& glob), UserScript *instance); - // Checks that apps features are enabled if the manifest tries to use any of - // them. - bool CheckAppsAreEnabled(const DictionaryValue* manifest, std::string* error); - - // Helpers to load various chunks of the manifest. - bool LoadWebContentEnabled(const DictionaryValue* manifest, - std::string* error); - bool LoadWebOrigin(const DictionaryValue* manifest, std::string* error); - bool LoadWebPaths(const DictionaryValue* manifest, std::string* error); - bool LoadLaunchContainer(const DictionaryValue* manifest, std::string* error); - bool LoadLaunchURL(const DictionaryValue* manifest, std::string* error); - // Helper method to load an ExtensionAction from the page_action or // browser_action entries in the manifest. ExtensionAction* LoadExtensionActionHelper( @@ -354,6 +335,13 @@ class Extension { // don't want to allow scripts and such to be bundled with themes. bool ContainsNonThemeKeys(const DictionaryValue& source); + // Apps don't have access to all extension features. This enforces those + // restrictions. + bool ContainsNonAppKeys(const DictionaryValue& source); + + // Helper method to verify the app section of the manifest. + bool LoadAppHelper(const DictionaryValue* app, std::string* error); + // Returns true if the string is one of the known api permissions (see // kPermissionNames). bool IsAPIPermission(const std::string& permission); @@ -451,26 +439,18 @@ class Extension { // which override the handling of those URLs. URLOverrideMap chrome_url_overrides_; - // Whether apps-related features can be parsed during InitFromValue(). - // Defaults to the value from --enable-extension-apps. - bool apps_enabled_; - - // Whether the extension can contain live web content. Defaults to false. - bool web_content_enabled_; - - // Defines the set of URLs in the extension's web content. - ExtensionExtent web_extent_; - - // The local path inside the extension to use with the launcher. - std::string launch_local_path_; + // Describes the space of URLs that are displayed in the app's custom frame. + URLPatternList app_extent_; - // A web url to use with the launcher. Note that this might be relative or - // absolute. If relative, it is relative to web_origin_. - std::string launch_web_url_; + // The URL an app should launch to. + GURL app_launch_url_; - // The type of container to launch into. - LaunchContainer launch_container_; + // How to start when the application is launched. + AppLaunchType app_launch_type_; + // The web security origin associated with the app. This origin will be + // granted the permissions the app requests. + GURL app_origin_; // Runtime data: diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc index f28fad1..1c9c5c9 100644 --- a/chrome/common/extensions/extension_constants.cc +++ b/chrome/common/extensions/extension_constants.cc @@ -7,6 +7,11 @@ namespace extension_manifest_keys { const wchar_t* kAllFrames = L"all_frames"; +const wchar_t* kApp = L"app"; +const wchar_t* kAppExtent = L"extent"; +const wchar_t* kAppLaunchUrl = L"launch.url"; +const wchar_t* kAppLaunchType = L"launch.window_type"; // TODO(erikkay) rename +const wchar_t* kAppOrigin = L"origin"; const wchar_t* kBackground = L"background_page"; const wchar_t* kBrowserAction = L"browser_action"; const wchar_t* kChromeURLOverrides = L"chrome_url_overrides"; @@ -18,10 +23,6 @@ const wchar_t* kDefaultLocale = L"default_locale"; const wchar_t* kDescription = L"description"; const wchar_t* kIcons = L"icons"; const wchar_t* kJs = L"js"; -const wchar_t* kLaunch = L"launch"; -const wchar_t* kLaunchContainer = L"launch.container"; -const wchar_t* kLaunchLocalPath = L"launch.local_path"; -const wchar_t* kLaunchWebURL = L"launch.web_url"; const wchar_t* kMatches = L"matches"; const wchar_t* kMinimumChromeVersion = L"minimum_chrome_version"; const wchar_t* kIncludeGlobs = L"include_globs"; @@ -57,10 +58,6 @@ const wchar_t* kType = L"type"; const wchar_t* kVersion = L"version"; const wchar_t* kUpdateURL = L"update_url"; const wchar_t* kOptionsPage = L"options_page"; -const wchar_t* kWebContent = L"web_content"; -const wchar_t* kWebContentEnabled = L"web_content.enabled"; -const wchar_t* kWebOrigin = L"web_content.origin"; -const wchar_t* kWebPaths = L"web_content.paths"; } // namespace extension_manifest_keys namespace extension_manifest_values { @@ -69,9 +66,9 @@ const char* kRunAtDocumentEnd = "document_end"; const char* kRunAtDocumentIdle = "document_idle"; const char* kPageActionTypeTab = "tab"; const char* kPageActionTypePermanent = "permanent"; -const char* kLaunchContainerPanel = "panel"; -const char* kLaunchContainerTab = "tab"; -const char* kLaunchContainerWindow = "window"; +const char* kLaunchTypePanel = "panel"; +const char* kLaunchTypeTab = "tab"; +const char* kLaunchTypeWindow = "window"; } // namespace extension_manifest_values // Extension-related error messages. Some of these are simple patterns, where a @@ -79,11 +76,21 @@ const char* kLaunchContainerWindow = "window"; // printf because we want to unit test them and scanf is hard to make // cross-platform. namespace extension_manifest_errors { -const char* kAppsNotEnabled = "Apps are not enabled."; +const char* kAppsDisabled = "Apps are disabled."; const char* kChromeVersionTooLow = "This extension requires * version * or greater."; const char* kInvalidAllFrames = "Invalid value for 'content_scripts[*].all_frames'."; +const char* kInvalidApp = "Invalid app."; +const char* kInvalidAppExtent = "Invalid value for app.extent."; +const char* kInvalidAppExtentPattern = "Invalid value for app.extent[*]."; +const char* kInvalidAppLaunchType = + "Invalid value for 'app.launch.window_type'."; +const char* kInvalidAppLaunchUrl = + "Required value 'app.launch.url' is missing or invalid."; +const char* kInvalidAppOrigin = + "Invalid value for 'app.origin'. Value must be a URL of the form " + "scheme://host[:port]/ where scheme is http or https."; const char* kInvalidBrowserAction = "Invalid value for 'browser_action'."; const char* kInvalidChromeURLOverrides = @@ -110,12 +117,6 @@ const char* kInvalidJs = "Invalid value for 'content_scripts[*].js[*]'."; const char* kInvalidJsList = "Required value 'content_scripts[*].js' is invalid."; -const char* kInvalidLaunchContainer = - "Invalid value for 'launch.container'."; -const char* kInvalidLaunchLocalPath = - "Invalid value for 'launch.local_path'."; -const char* kInvalidLaunchWebURL = - "Invalid value for 'launch.web_url'."; const char* kInvalidKey = "Value 'key' is missing or invalid."; const char* kInvalidManifest = @@ -202,24 +203,12 @@ const char* kInvalidThemeTints = "Invalid value for theme images - tints must be decimal numbers."; const char* kInvalidUpdateURL = "Invalid value for update url: '[*]'."; -const char* kInvalidWebContentEnabled = - "Invalid value for 'web_content.enabled'."; -const char* kInvalidWebOrigin = - "Invalid value for 'web_content.origin'."; -const char* kInvalidWebPaths = - "Invalid value for 'web_content.paths'."; -const char* kInvalidWebPath = - "Invalid value for 'web_contents.paths[*]'."; const char* kInvalidDefaultLocale = "Invalid value for default locale - locale name must be a string."; const char* kOneUISurfaceOnly = "An extension cannot have both a page action and a browser action."; const char* kThemesCannotContainExtensions = "A theme cannot contain extensions code."; -const char* kLaunchContainerWithoutURL = - "Launch container specified, but no local_path or web_url to launch."; -const char* kLaunchPathAndURLAreExclusive = - "The 'launch.local_path' and 'launch.web_url' keys cannot both be set."; const char* kLocalesNoDefaultLocaleSpecified = "Localization used, but default_locale wasn't specified in the manifest."; const char* kLocalesNoDefaultMessages = @@ -237,8 +226,6 @@ const char* kReservedMessageFound = const char* kCannotAccessPage = "Cannot access contents of url \"*\". " "Extension manifest must request permission to access this host."; const char* kCannotScriptGallery = "The extensions gallery cannot be scripted."; -const char* kWebContentMustBeEnabled = "The 'web_content.enabled' property " - "must be set to true in order to use any other web content features."; } // namespace extension_manifest_errors namespace extension_urls { diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h index e3f1a0c..453fb1c 100644 --- a/chrome/common/extensions/extension_constants.h +++ b/chrome/common/extensions/extension_constants.h @@ -8,6 +8,11 @@ // Keys used in JSON representation of extensions. namespace extension_manifest_keys { extern const wchar_t* kAllFrames; + extern const wchar_t* kApp; + extern const wchar_t* kAppExtent; + extern const wchar_t* kAppLaunchUrl; + extern const wchar_t* kAppLaunchType; + extern const wchar_t* kAppOrigin; extern const wchar_t* kBackground; extern const wchar_t* kBrowserAction; extern const wchar_t* kMinimumChromeVersion; @@ -21,10 +26,6 @@ namespace extension_manifest_keys { extern const wchar_t* kExcludeGlobs; extern const wchar_t* kIcons; extern const wchar_t* kIncludeGlobs; - extern const wchar_t* kLaunch; - extern const wchar_t* kLaunchContainer; - extern const wchar_t* kLaunchLocalPath; - extern const wchar_t* kLaunchWebURL; extern const wchar_t* kJs; extern const wchar_t* kMatches; extern const wchar_t* kName; @@ -58,11 +59,6 @@ namespace extension_manifest_keys { extern const wchar_t* kVersion; extern const wchar_t* kUpdateURL; extern const wchar_t* kOptionsPage; - extern const wchar_t* kWebContent; - extern const wchar_t* kWebContentEnabled; - extern const wchar_t* kWebLaunchUrl; - extern const wchar_t* kWebOrigin; - extern const wchar_t* kWebPaths; } // namespace extension_manifest_keys // Some values expected in manifests. @@ -72,16 +68,22 @@ namespace extension_manifest_values { extern const char* kRunAtDocumentIdle; extern const char* kPageActionTypeTab; extern const char* kPageActionTypePermanent; - extern const char* kLaunchContainerPanel; - extern const char* kLaunchContainerTab; - extern const char* kLaunchContainerWindow; + extern const char* kLaunchTypePanel; + extern const char* kLaunchTypeTab; + extern const char* kLaunchTypeWindow; } // namespace extension_manifest_values // Error messages returned from Extension::InitFromValue(). namespace extension_manifest_errors { - extern const char* kAppsNotEnabled; + extern const char* kAppsDisabled; extern const char* kChromeVersionTooLow; extern const char* kInvalidAllFrames; + extern const char* kInvalidApp; + extern const char* kInvalidAppExtent; + extern const char* kInvalidAppExtentPattern; + extern const char* kInvalidAppLaunchType; + extern const char* kInvalidAppLaunchUrl; + extern const char* kInvalidAppOrigin; extern const char* kInvalidBackground; extern const char* kInvalidBrowserAction; extern const char* kInvalidChromeURLOverrides; @@ -97,9 +99,6 @@ namespace extension_manifest_errors { extern const char* kInvalidJs; extern const char* kInvalidJsList; extern const char* kInvalidKey; - extern const char* kInvalidLaunchContainer; - extern const char* kInvalidLaunchLocalPath; - extern const char* kInvalidLaunchWebURL; extern const char* kInvalidManifest; extern const char* kInvalidMatchCount; extern const char* kInvalidMatch; @@ -109,6 +108,7 @@ namespace extension_manifest_errors { extern const char* kInvalidPlugins; extern const char* kInvalidPluginsPath; extern const char* kInvalidPluginsPublic; + extern const char* kInvalidRunAt; extern const char* kInvalidSignature; extern const char* kInvalidToolstrip; @@ -135,10 +135,6 @@ namespace extension_manifest_errors { extern const char* kInvalidThemeImages; extern const char* kInvalidThemeColors; extern const char* kInvalidThemeTints; - extern const char* kInvalidWebContentEnabled; - extern const char* kInvalidWebOrigin; - extern const char* kInvalidWebPaths; - extern const char* kInvalidWebPath; extern const char* kOneUISurfaceOnly; extern const char* kThemesCannotContainExtensions; extern const char* kManifestParseError; @@ -146,8 +142,6 @@ namespace extension_manifest_errors { extern const char* kMissingFile; extern const char* kInvalidUpdateURL; extern const char* kInvalidDefaultLocale; - extern const char* kLaunchContainerWithoutURL; - extern const char* kLaunchPathAndURLAreExclusive; extern const char* kLocalesNoDefaultLocaleSpecified; extern const char* kLocalesNoDefaultMessages; extern const char* kLocalesNoValidLocaleNamesListed; @@ -157,7 +151,6 @@ namespace extension_manifest_errors { extern const char* kReservedMessageFound; extern const char* kCannotAccessPage; extern const char* kCannotScriptGallery; - extern const char* kWebContentMustBeEnabled; } // namespace extension_manifest_errors namespace extension_urls { diff --git a/chrome/common/extensions/extension_extent.cc b/chrome/common/extensions/extension_extent.cc deleted file mode 100644 index 310673e..0000000 --- a/chrome/common/extensions/extension_extent.cc +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2010 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 "chrome/common/extensions/extension_extent.h" - -#include "base/string_util.h" - -bool ExtensionExtent::ContainsURL(const GURL& url) { - if (!url.is_valid()) - return false; - - if (url.GetOrigin() != origin_) - return false; - - if (paths_.empty()) - return true; - - for (size_t i = 0; i < paths_.size(); ++i) { - if (StartsWithASCII(url.path(), - std::string("/") + paths_[i], - false)) { // not case sensitive - return true; - } - } - - return false; -} diff --git a/chrome/common/extensions/extension_extent.h b/chrome/common/extensions/extension_extent.h deleted file mode 100644 index 76670ab..0000000 --- a/chrome/common/extensions/extension_extent.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2010 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. - -#ifndef CHROME_COMMON_EXTENSIONS_EXTENSION_EXTENT_H_ -#define CHROME_COMMON_EXTENSIONS_EXTENSION_EXTENT_H_ - -#include <string> -#include <vector> - -#include "googleurl/src/gurl.h" - -// Represents the set of URLs an extension uses for web content. -class ExtensionExtent { - public: - const std::vector<std::string>& paths() const { return paths_; } - void add_path(const std::string& val) { paths_.push_back(val); } - void clear_paths() { paths_.clear(); } - - const GURL& origin() const { return origin_; } - void set_origin(const GURL& val) { origin_ = val; } - - bool ContainsURL(const GURL& url); - - private: - // The security origin (scheme+host+port) of the extent. - GURL origin_; - - // A set of path prefixes that further restrict the set of valid URLs below - // origin_. This may be empty. - std::vector<std::string> paths_; -}; - -#endif // CHROME_COMMON_EXTENSIONS_EXTENSION_EXTENT_H_ diff --git a/chrome/common/extensions/extension_extent_unittest.cc b/chrome/common/extensions/extension_extent_unittest.cc deleted file mode 100644 index 4e308fa..0000000 --- a/chrome/common/extensions/extension_extent_unittest.cc +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) 2010 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 "chrome/common/extensions/extension.h" - -#include "googleurl/src/gurl.h" -#include "testing/gtest/include/gtest/gtest.h" - -TEST(ExtensionExtentTest, Empty) { - ExtensionExtent extent; - EXPECT_FALSE(extent.ContainsURL(GURL("http://www.foo.com/bar"))); - EXPECT_FALSE(extent.ContainsURL(GURL())); - EXPECT_FALSE(extent.ContainsURL(GURL("invalid"))); -} - -TEST(ExtensionExtentTest, OriginOnly) { - ExtensionExtent extent; - extent.set_origin(GURL("http://www.google.com/")); - - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/"))); - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/foo"))); - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/foobar"))); - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/foo/bar"))); - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/?stuff#here"))); - - EXPECT_FALSE(extent.ContainsURL(GURL("https://www.google.com/"))); - EXPECT_FALSE(extent.ContainsURL(GURL("http://www.google.com:8080/"))); -} - -TEST(ExtensionExtentTest, OriginAndOnePath) { - ExtensionExtent extent; - extent.set_origin(GURL("http://www.google.com/")); - extent.add_path("foo"); - - EXPECT_FALSE(extent.ContainsURL(GURL("http://www.google.com/"))); - EXPECT_FALSE(extent.ContainsURL(GURL("http://www.google.com/fo"))); - - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/foo"))); - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/FOO"))); - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/foobar"))); - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/foo/bar"))); -} - -TEST(ExtensionExtentTest, OriginAndTwoPaths) { - ExtensionExtent extent; - extent.set_origin(GURL("http://www.google.com/")); - extent.add_path("foo"); - extent.add_path("hot"); - - EXPECT_FALSE(extent.ContainsURL(GURL("http://www.google.com/monkey"))); - - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/foo"))); - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/hot"))); - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/foobar"))); - EXPECT_TRUE(extent.ContainsURL(GURL("http://www.google.com/hotdog"))); -} diff --git a/chrome/common/extensions/extension_manifests_unittest.cc b/chrome/common/extensions/extension_manifests_unittest.cc deleted file mode 100644 index d7a5c2b..0000000 --- a/chrome/common/extensions/extension_manifests_unittest.cc +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (c) 2010 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/file_path.h" -#include "base/file_util.h" -#include "base/path_service.h" -#include "base/scoped_ptr.h" -#include "chrome/common/chrome_paths.h" -#include "chrome/common/extensions/extension.h" -#include "chrome/common/extensions/extension_constants.h" -#include "chrome/common/extensions/extension_error_utils.h" -#include "chrome/common/json_value_serializer.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace errors = extension_manifest_errors; - -class ManifestTest : public testing::Test { - public: - ManifestTest() : enable_apps_(true) {} - - protected: - Extension* LoadExtension(const std::string& name, - std::string* error) { - FilePath path; - PathService::Get(chrome::DIR_TEST_DATA, &path); - path = path.AppendASCII("extensions") - .AppendASCII("manifest_tests") - .AppendASCII(name.c_str()); - EXPECT_TRUE(file_util::PathExists(path)); - - JSONFileValueSerializer serializer(path); - scoped_ptr<DictionaryValue> value( - static_cast<DictionaryValue*>(serializer.Deserialize(error))); - if (!value.get()) - return NULL; - - scoped_ptr<Extension> extension(new Extension(path.DirName())); - if (enable_apps_) - extension->set_apps_enabled(true); - - if (!extension->InitFromValue(*value, false, error)) - return NULL; - - return extension.release(); - } - - Extension* LoadAndExpectSuccess(const std::string& name) { - std::string error; - Extension* extension = LoadExtension(name, &error); - EXPECT_TRUE(extension); - EXPECT_EQ("", error); - return extension; - } - - void LoadAndExpectError(const std::string& name, - const std::string& expected_error) { - std::string error; - scoped_ptr<Extension> extension(LoadExtension(name, &error)); - EXPECT_FALSE(extension.get()) << - "Expected failure loading extension '" << name << - "', but didn't get one."; - EXPECT_EQ(expected_error, error); - } - - bool enable_apps_; -}; - -TEST_F(ManifestTest, AppsDisabledByDefault) { - enable_apps_ = false; - LoadAndExpectError("web_content_disabled.json", errors::kAppsNotEnabled); - LoadAndExpectError("launch_local_path.json", errors::kAppsNotEnabled); -} - -TEST_F(ManifestTest, ValidApp) { - scoped_ptr<Extension> extension(LoadAndExpectSuccess("valid_app.json")); - EXPECT_TRUE(extension->web_content_enabled()); - EXPECT_EQ(GURL("http://www.google.com/"), extension->web_extent().origin()); - EXPECT_EQ(2u, extension->web_extent().paths().size()); - EXPECT_EQ("mail/", extension->web_extent().paths()[0]); - EXPECT_EQ("foobar/", extension->web_extent().paths()[1]); - EXPECT_EQ(Extension::LAUNCH_WINDOW, extension->launch_container()); - EXPECT_EQ("mail/", extension->launch_web_url()); -} - -TEST_F(ManifestTest, AppWebContentEnabled) { - LoadAndExpectError("web_content_enabled_invalid.json", - errors::kInvalidWebContentEnabled); - LoadAndExpectError("web_content_disabled.json", - errors::kWebContentMustBeEnabled); - LoadAndExpectError("web_content_not_enabled.json", - errors::kWebContentMustBeEnabled); -} - -TEST_F(ManifestTest, AppWebOrigin) { - LoadAndExpectError("web_origin_wrong_type.json", - errors::kInvalidWebOrigin); - LoadAndExpectError("web_origin_invalid_1.json", - errors::kInvalidWebOrigin); - LoadAndExpectError("web_origin_invalid_2.json", - errors::kInvalidWebOrigin); - LoadAndExpectError("web_origin_invalid_3.json", - errors::kInvalidWebOrigin); -} - -TEST_F(ManifestTest, AppWebPaths) { - LoadAndExpectError("web_paths_wrong_type.json", - errors::kInvalidWebPaths); - LoadAndExpectError("web_paths_invalid_path_1.json", - ExtensionErrorUtils::FormatErrorMessage( - errors::kInvalidWebPath, "0")); - LoadAndExpectError("web_paths_invalid_path_2.json", - ExtensionErrorUtils::FormatErrorMessage( - errors::kInvalidWebPath, "0")); -} - -TEST_F(ManifestTest, AppLaunchContainer) { - scoped_ptr<Extension> extension; - - extension.reset(LoadAndExpectSuccess("launch_tab.json")); - EXPECT_EQ(Extension::LAUNCH_TAB, extension->launch_container()); - - extension.reset(LoadAndExpectSuccess("launch_window.json")); - EXPECT_EQ(Extension::LAUNCH_WINDOW, extension->launch_container()); - - extension.reset(LoadAndExpectSuccess("launch_panel.json")); - EXPECT_EQ(Extension::LAUNCH_PANEL, extension->launch_container()); - - extension.reset(LoadAndExpectSuccess("launch_default.json")); - EXPECT_EQ(Extension::LAUNCH_TAB, extension->launch_container()); - - LoadAndExpectError("launch_container_invalid_type.json", - errors::kInvalidLaunchContainer); - LoadAndExpectError("launch_container_invalid_value.json", - errors::kInvalidLaunchContainer); - LoadAndExpectError("launch_container_without_launch_url.json", - errors::kLaunchContainerWithoutURL); -} - -TEST_F(ManifestTest, AppLaunchURL) { - LoadAndExpectError("launch_path_and_url.json", - errors::kLaunchPathAndURLAreExclusive); - LoadAndExpectError("launch_path_invalid_type.json", - errors::kInvalidLaunchLocalPath); - LoadAndExpectError("launch_path_invalid_value.json", - errors::kInvalidLaunchLocalPath); - LoadAndExpectError("launch_url_invalid_type.json", - errors::kInvalidLaunchWebURL); - - scoped_ptr<Extension> extension; - extension.reset(LoadAndExpectSuccess("launch_local_path.json")); - EXPECT_EQ(extension->url().spec() + "launch.html", - extension->GetFullLaunchURL().spec()); - - extension.reset(LoadAndExpectSuccess("launch_web_url_relative.json")); - EXPECT_EQ(GURL("http://www.google.com/launch.html"), - extension->GetFullLaunchURL()); - - extension.reset(LoadAndExpectSuccess("launch_web_url_absolute.json")); - EXPECT_EQ(GURL("http://www.google.com/launch.html"), - extension->GetFullLaunchURL()); -} diff --git a/chrome/common/extensions/extension_unittest.cc b/chrome/common/extensions/extension_unittest.cc index d046503..4dbb7e3 100644 --- a/chrome/common/extensions/extension_unittest.cc +++ b/chrome/common/extensions/extension_unittest.cc @@ -36,13 +36,6 @@ TEST(ExtensionTest, LocationValuesTest) { ASSERT_EQ(5, Extension::COMPONENT); } - -// Please don't put any more manifest tests here!! -// Move them to extension_manifest_unittest.cc instead and make them use the -// more data-driven style there instead. -// Bug: http://crbug.com/38462 - - TEST(ExtensionTest, InitFromValueInvalid) { #if defined(OS_WIN) FilePath path(FILE_PATH_LITERAL("c:\\foo")); @@ -281,6 +274,58 @@ TEST(ExtensionTest, InitFromValueInvalid) { EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); EXPECT_TRUE(MatchPatternASCII(error, errors::kChromeVersionTooLow)); #endif + + // Test invalid app. + input_value.reset(static_cast<DictionaryValue*>(valid_value->DeepCopy())); + input_value->Set(keys::kApp, Value::CreateIntegerValue(42)); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); + EXPECT_EQ(errors::kInvalidApp, error); + + // Test invalid launch URLs. + DictionaryValue* app = new DictionaryValue(); + input_value->Set(keys::kApp, app); + + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); + EXPECT_EQ(errors::kInvalidAppLaunchUrl, error); + + Value* invalid_launch_urls[] = { + Value::CreateStringValue(""), + Value::CreateIntegerValue(42), + Value::CreateStringValue("foobar") + }; + + for (size_t i = 0; i < arraysize(invalid_launch_urls); ++i) { + app->Set(keys::kAppLaunchUrl, invalid_launch_urls[i]); + error.clear(); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); + EXPECT_EQ(errors::kInvalidAppLaunchUrl, error); + } + + // Test valid launch URL. + app->Set(keys::kAppLaunchUrl, + Value::CreateStringValue("http://www.google.com/index.html")); + EXPECT_TRUE(extension.InitFromValue(*input_value, true, &error)); + + // Test invalid app origins. + Value* invalid_origins[] = { + Value::CreateStringValue(""), + Value::CreateIntegerValue(42), + Value::CreateStringValue("foobar"), + Value::CreateStringValue("file:///c:/foo.txt"), + Value::CreateStringValue("ftp://www.google.com/") + }; + + for (size_t i = 0; i < arraysize(invalid_origins); ++i) { + app->Set(keys::kAppOrigin, invalid_origins[i]); + error.clear(); + EXPECT_FALSE(extension.InitFromValue(*input_value, true, &error)); + EXPECT_EQ(errors::kInvalidAppOrigin, error); + } + + // Test valid origin. + app->Set(keys::kAppOrigin, + Value::CreateStringValue("http://www.google.com/")); + EXPECT_TRUE(extension.InitFromValue(*input_value, true, &error)); } TEST(ExtensionTest, InitFromValueValid) { diff --git a/chrome/test/data/extensions/manifest_tests/launch_container_invalid_type.json b/chrome/test/data/extensions/manifest_tests/launch_container_invalid_type.json deleted file mode 100644 index 3aa5a52..0000000 --- a/chrome/test/data/extensions/manifest_tests/launch_container_invalid_type.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "test", - "version": "1", - "launch": { - "container": 42, - "local_path": "hot.html" - } -} diff --git a/chrome/test/data/extensions/manifest_tests/launch_container_invalid_value.json b/chrome/test/data/extensions/manifest_tests/launch_container_invalid_value.json deleted file mode 100644 index f1b2ed6..0000000 --- a/chrome/test/data/extensions/manifest_tests/launch_container_invalid_value.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "test", - "version": "1", - "launch": { - "container": "foobar", - "local_path": "dog.html" - } -} diff --git a/chrome/test/data/extensions/manifest_tests/launch_container_without_launch_url.json b/chrome/test/data/extensions/manifest_tests/launch_container_without_launch_url.json deleted file mode 100644 index 66ea2e5..0000000 --- a/chrome/test/data/extensions/manifest_tests/launch_container_without_launch_url.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "test", - "version": "1", - "launch": { - "container": "tab" - } -} diff --git a/chrome/test/data/extensions/manifest_tests/launch_default.json b/chrome/test/data/extensions/manifest_tests/launch_default.json deleted file mode 100644 index 0d9792a..0000000 --- a/chrome/test/data/extensions/manifest_tests/launch_default.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "test", - "version": "1" -} diff --git a/chrome/test/data/extensions/manifest_tests/launch_local_path.json b/chrome/test/data/extensions/manifest_tests/launch_local_path.json deleted file mode 100644 index 72dd2e0..0000000 --- a/chrome/test/data/extensions/manifest_tests/launch_local_path.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "test", - "version": "1", - "launch": { - "local_path": "launch.html" - } -} diff --git a/chrome/test/data/extensions/manifest_tests/launch_panel.json b/chrome/test/data/extensions/manifest_tests/launch_panel.json deleted file mode 100644 index 381cf35..0000000 --- a/chrome/test/data/extensions/manifest_tests/launch_panel.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "test", - "version": "1", - "launch": { - "container": "panel", - "web_url": "http://www.google.com/hot.html" - } -} diff --git a/chrome/test/data/extensions/manifest_tests/launch_path_and_url.json b/chrome/test/data/extensions/manifest_tests/launch_path_and_url.json deleted file mode 100644 index 93cb1bc..0000000 --- a/chrome/test/data/extensions/manifest_tests/launch_path_and_url.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "test", - "version": "1", - "launch": { - "local_path": "foo", - "web_url": "http://www.google.com/" - } -} diff --git a/chrome/test/data/extensions/manifest_tests/launch_path_invalid_type.json b/chrome/test/data/extensions/manifest_tests/launch_path_invalid_type.json deleted file mode 100644 index 583c61b..0000000 --- a/chrome/test/data/extensions/manifest_tests/launch_path_invalid_type.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "test", - "version": "1", - "launch": { - "local_path": 42 - } -} diff --git a/chrome/test/data/extensions/manifest_tests/launch_path_invalid_value.json b/chrome/test/data/extensions/manifest_tests/launch_path_invalid_value.json deleted file mode 100644 index fd95800..0000000 --- a/chrome/test/data/extensions/manifest_tests/launch_path_invalid_value.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "test", - "version": "1", - "launch": { - "local_path": "http://www.google.com/" - } -} diff --git a/chrome/test/data/extensions/manifest_tests/launch_tab.json b/chrome/test/data/extensions/manifest_tests/launch_tab.json deleted file mode 100644 index 650dd95..0000000 --- a/chrome/test/data/extensions/manifest_tests/launch_tab.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "test", - "version": "1", - "launch": { - "container": "tab", - "local_path": "foo.html" - } -} diff --git a/chrome/test/data/extensions/manifest_tests/launch_url_invalid_type.json b/chrome/test/data/extensions/manifest_tests/launch_url_invalid_type.json deleted file mode 100644 index e6fa384..0000000 --- a/chrome/test/data/extensions/manifest_tests/launch_url_invalid_type.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "test", - "version": "1", - "launch": { - "web_url": 42 - } -} diff --git a/chrome/test/data/extensions/manifest_tests/launch_web_url_absolute.json b/chrome/test/data/extensions/manifest_tests/launch_web_url_absolute.json deleted file mode 100644 index b3e4270..0000000 --- a/chrome/test/data/extensions/manifest_tests/launch_web_url_absolute.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "test", - "version": "1", - "launch": { - "web_url": "http://www.google.com/launch.html" - } -} diff --git a/chrome/test/data/extensions/manifest_tests/launch_web_url_relative.json b/chrome/test/data/extensions/manifest_tests/launch_web_url_relative.json deleted file mode 100644 index f62dad9..0000000 --- a/chrome/test/data/extensions/manifest_tests/launch_web_url_relative.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "test", - "version": "1", - "web_content": { - "enabled": true, - "origin": "http://www.google.com/" - }, - "launch": { - "web_url": "launch.html" - } -} diff --git a/chrome/test/data/extensions/manifest_tests/launch_window.json b/chrome/test/data/extensions/manifest_tests/launch_window.json deleted file mode 100644 index d73a9bf..0000000 --- a/chrome/test/data/extensions/manifest_tests/launch_window.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "test", - "version": "1", - "launch": { - "container": "window", - "local_path": "bar.html" - } -} diff --git a/chrome/test/data/extensions/manifest_tests/valid_app.json b/chrome/test/data/extensions/manifest_tests/valid_app.json deleted file mode 100644 index 734cffb..0000000 --- a/chrome/test/data/extensions/manifest_tests/valid_app.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "test", - "version": "1", - "web_content": { - "enabled": true, - "origin": "http://www.google.com/", - "paths": [ - "mail/", - "foobar/" - ] - }, - "launch": { - "container": "window", - "web_url": "mail/" - }, - "permissions": [ - "notifications" - ] -} diff --git a/chrome/test/data/extensions/manifest_tests/web_content_disabled.json b/chrome/test/data/extensions/manifest_tests/web_content_disabled.json deleted file mode 100644 index a355142..0000000 --- a/chrome/test/data/extensions/manifest_tests/web_content_disabled.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "test", - "version": "1", - "web_content": { - "enabled": false - } -} diff --git a/chrome/test/data/extensions/manifest_tests/web_content_enabled_invalid.json b/chrome/test/data/extensions/manifest_tests/web_content_enabled_invalid.json deleted file mode 100644 index 2411c2d..0000000 --- a/chrome/test/data/extensions/manifest_tests/web_content_enabled_invalid.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "test", - "version": "1", - "web_content": { - "enabled": 42 - } -} diff --git a/chrome/test/data/extensions/manifest_tests/web_content_not_enabled.json b/chrome/test/data/extensions/manifest_tests/web_content_not_enabled.json deleted file mode 100644 index 28f6469a..0000000 --- a/chrome/test/data/extensions/manifest_tests/web_content_not_enabled.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "test", - "version": "1", - "web_content": { - } -} diff --git a/chrome/test/data/extensions/manifest_tests/web_origin_invalid_1.json b/chrome/test/data/extensions/manifest_tests/web_origin_invalid_1.json deleted file mode 100644 index 69ad622..0000000 --- a/chrome/test/data/extensions/manifest_tests/web_origin_invalid_1.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "test", - "version": "1", - "web_content": { - "enabled": true, - "origin": "wiggity" - } -} diff --git a/chrome/test/data/extensions/manifest_tests/web_origin_invalid_2.json b/chrome/test/data/extensions/manifest_tests/web_origin_invalid_2.json deleted file mode 100644 index 801b0b9..0000000 --- a/chrome/test/data/extensions/manifest_tests/web_origin_invalid_2.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "test", - "version": "1", - "web_content": { - "enabled": true, - "origin": "ftp://www.google.com/" - } -} diff --git a/chrome/test/data/extensions/manifest_tests/web_origin_invalid_3.json b/chrome/test/data/extensions/manifest_tests/web_origin_invalid_3.json deleted file mode 100644 index c6c3672..0000000 --- a/chrome/test/data/extensions/manifest_tests/web_origin_invalid_3.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "test", - "version": "1", - "web_content": { - "enabled": true, - "origin": "https://www.google.com/monkey" - } -} diff --git a/chrome/test/data/extensions/manifest_tests/web_origin_web_content_disabled.json b/chrome/test/data/extensions/manifest_tests/web_origin_web_content_disabled.json deleted file mode 100644 index 5389879..0000000 --- a/chrome/test/data/extensions/manifest_tests/web_origin_web_content_disabled.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "test", - "version": "1", - "web_content": { - "origin": "http://www.google.com/" - } -} diff --git a/chrome/test/data/extensions/manifest_tests/web_origin_wrong_type.json b/chrome/test/data/extensions/manifest_tests/web_origin_wrong_type.json deleted file mode 100644 index 42a2ae3..0000000 --- a/chrome/test/data/extensions/manifest_tests/web_origin_wrong_type.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "test", - "version": "1", - "web_content": { - "enabled": true, - "origin": 42 - } -} diff --git a/chrome/test/data/extensions/manifest_tests/web_paths_invalid_path_1.json b/chrome/test/data/extensions/manifest_tests/web_paths_invalid_path_1.json deleted file mode 100644 index f259790..0000000 --- a/chrome/test/data/extensions/manifest_tests/web_paths_invalid_path_1.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "test", - "version": "1", - "web_content": { - "enabled": true, - "paths": [ - 42 - ] - } -} diff --git a/chrome/test/data/extensions/manifest_tests/web_paths_invalid_path_2.json b/chrome/test/data/extensions/manifest_tests/web_paths_invalid_path_2.json deleted file mode 100644 index d435ee4..0000000 --- a/chrome/test/data/extensions/manifest_tests/web_paths_invalid_path_2.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "test", - "version": "1", - "web_content": { - "enabled": true, - "paths": [ - "http://www.google.com/monkey" - ] - } -} diff --git a/chrome/test/data/extensions/manifest_tests/web_paths_wrong_type.json b/chrome/test/data/extensions/manifest_tests/web_paths_wrong_type.json deleted file mode 100644 index 56e0b28..0000000 --- a/chrome/test/data/extensions/manifest_tests/web_paths_wrong_type.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "test", - "version": "1", - "web_content": { - "enabled": true, - "paths": 42 - } -} |