summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/autocomplete/extension_app_provider.cc5
-rw-r--r--chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.cc4
-rw-r--r--chrome/browser/chromeos/screensaver/screensaver_controller.cc4
-rw-r--r--chrome/browser/extensions/api/developer_private/developer_private_api.cc3
-rw-r--r--chrome/browser/extensions/api/management/management_api.cc3
-rw-r--r--chrome/browser/extensions/convert_web_app_browsertest.cc6
-rw-r--r--chrome/browser/extensions/convert_web_app_unittest.cc5
-rw-r--r--chrome/browser/extensions/extension_prefs.cc3
-rw-r--r--chrome/browser/extensions/extension_service.cc5
-rw-r--r--chrome/browser/extensions/extension_service_unittest.cc25
-rw-r--r--chrome/browser/extensions/tab_helper.cc3
-rw-r--r--chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.cc9
-rw-r--r--chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser.cc4
-rw-r--r--chrome/browser/ui/browser_browsertest.cc4
-rw-r--r--chrome/browser/ui/extensions/application_launch.cc9
-rw-r--r--chrome/browser/ui/tabs/pinned_tab_codec.cc4
-rw-r--r--chrome/browser/ui/web_applications/web_app_ui.cc3
-rw-r--r--chrome/browser/ui/webui/extensions/extension_icon_source.cc4
-rw-r--r--chrome/browser/ui/webui/ntp/app_launcher_handler.cc7
-rw-r--r--chrome/browser/ui/webui/options/content_settings_handler.cc12
-rw-r--r--chrome/browser/web_applications/web_app.cc5
-rw-r--r--chrome/chrome_common.gypi2
-rw-r--r--chrome/common/extensions/chrome_manifest_handlers.cc2
-rw-r--r--chrome/common/extensions/extension.cc217
-rw-r--r--chrome/common/extensions/extension.h36
-rw-r--r--chrome/common/extensions/extension_manifest_constants.cc4
-rw-r--r--chrome/common/extensions/extension_manifest_constants.h4
-rw-r--r--chrome/common/extensions/manifest_handlers/app_launch_info.cc325
-rw-r--r--chrome/common/extensions/manifest_handlers/app_launch_info.h83
-rw-r--r--chrome/common/extensions/manifest_tests/extension_manifests_launch_unittest.cc40
-rw-r--r--chrome/common/extensions/manifest_tests/extension_manifests_validapp_unittest.cc18
31 files changed, 534 insertions, 324 deletions
diff --git a/chrome/browser/autocomplete/extension_app_provider.cc b/chrome/browser/autocomplete/extension_app_provider.cc
index 788d096..984358d 100644
--- a/chrome/browser/autocomplete/extension_app_provider.cc
+++ b/chrome/browser/autocomplete/extension_app_provider.cc
@@ -19,6 +19,7 @@
#include "chrome/browser/ui/webui/ntp/app_launcher_handler.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "content/public/browser/notification_source.h"
#include "ui/base/l10n/l10n_util.h"
@@ -164,8 +165,8 @@ void ExtensionAppProvider::RefreshAppList() {
!extension_service->CanLoadInIncognito(app))
continue;
- GURL launch_url =
- app->is_platform_app() ? app->url() : app->GetFullLaunchURL();
+ GURL launch_url = app->is_platform_app() ?
+ app->url() : extensions::AppLaunchInfo::GetFullLaunchURL(app);
DCHECK(launch_url.is_valid());
ExtensionApp extension_app = {
diff --git a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.cc b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.cc
index abf843e..d9ace4b 100644
--- a/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.cc
+++ b/chrome/browser/chromeos/kiosk_mode/kiosk_mode_screensaver.cc
@@ -24,6 +24,7 @@
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_file_util.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chromeos/login/login_state.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
@@ -222,7 +223,8 @@ void KioskModeScreensaver::SetupScreensaver(
if (default_profile) {
extensions::ExtensionSystem::Get(default_profile)->extension_service()->
AddExtension(extension);
- ash::ShowScreensaver(extension->GetFullLaunchURL());
+ ash::ShowScreensaver(
+ extensions::AppLaunchInfo::GetFullLaunchURL(extension));
} else {
LOG(ERROR) << "Couldn't get default profile. Unable to load screensaver!";
ShutdownKioskModeScreensaver();
diff --git a/chrome/browser/chromeos/screensaver/screensaver_controller.cc b/chrome/browser/chromeos/screensaver/screensaver_controller.cc
index dcb8784..9eca8e7 100644
--- a/chrome/browser/chromeos/screensaver/screensaver_controller.cc
+++ b/chrome/browser/chromeos/screensaver/screensaver_controller.cc
@@ -15,6 +15,7 @@
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/power_manager_client.h"
#include "content/public/browser/notification_service.h"
@@ -134,7 +135,8 @@ void ScreensaverController::IdleNotify(int64 threshold) {
const extensions::Extension* screensaver_extension =
service->GetExtensionById(screensaver_extension_id_,
ExtensionService::INCLUDE_ENABLED);
- ash::ShowScreensaver(screensaver_extension->GetFullLaunchURL());
+ ash::ShowScreensaver(
+ extensions::AppLaunchInfo::GetFullLaunchURL(screensaver_extension));
if (!ash::Shell::GetInstance()->user_activity_detector()->HasObserver(this))
ash::Shell::GetInstance()->user_activity_detector()->AddObserver(this);
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api.cc b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
index dc3ac18..67ae7f6 100644
--- a/chrome/browser/extensions/api/developer_private/developer_private_api.cc
+++ b/chrome/browser/extensions/api/developer_private/developer_private_api.cc
@@ -35,6 +35,7 @@
#include "chrome/common/extensions/background_info.h"
#include "chrome/common/extensions/extension_icon_set.h"
#include "chrome/common/extensions/incognito_handler.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
#include "chrome/common/extensions/manifest_handlers/offline_enabled_info.h"
#include "chrome/common/extensions/manifest_url_handler.h"
@@ -234,7 +235,7 @@ scoped_ptr<developer::ItemInfo>
if (item.is_app()) {
info->app_launch_url.reset(new std::string(
- item.GetFullLaunchURL().spec()));
+ extensions::AppLaunchInfo::GetFullLaunchURL(&item).spec()));
}
info->may_disable = system->management_policy()->
diff --git a/chrome/browser/extensions/api/management/management_api.cc b/chrome/browser/extensions/api/management/management_api.cc
index 6c15861..acf6b52 100644
--- a/chrome/browser/extensions/api/management/management_api.cc
+++ b/chrome/browser/extensions/api/management/management_api.cc
@@ -34,6 +34,7 @@
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_icon_set.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
#include "chrome/common/extensions/manifest_handlers/offline_enabled_info.h"
#include "chrome/common/extensions/manifest_url_handler.h"
@@ -138,7 +139,7 @@ scoped_ptr<management::ExtensionInfo> CreateExtensionInfo(
if (extension.is_app()) {
info->app_launch_url.reset(new std::string(
- extension.GetFullLaunchURL().spec()));
+ AppLaunchInfo::GetFullLaunchURL(&extension).spec()));
}
const ExtensionIconSet::IconMap& icons =
diff --git a/chrome/browser/extensions/convert_web_app_browsertest.cc b/chrome/browser/extensions/convert_web_app_browsertest.cc
index 95e1415..bf1f816 100644
--- a/chrome/browser/extensions/convert_web_app_browsertest.cc
+++ b/chrome/browser/extensions/convert_web_app_browsertest.cc
@@ -12,6 +12,7 @@
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_icon_set.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
#include "chrome/common/extensions/permissions/permission_set.h"
#include "chrome/test/base/in_process_browser_test.h"
@@ -81,9 +82,10 @@ IN_PROC_BROWSER_TEST_F(ExtensionFromWebAppTest, MAYBE_Basic) {
EXPECT_TRUE(installed_extension_->is_hosted_app());
EXPECT_EQ("Test application", installed_extension_->name());
EXPECT_EQ("", installed_extension_->description());
- EXPECT_EQ("http://www.example.com/", installed_extension_->launch_web_url());
+ EXPECT_EQ(GURL("http://www.example.com/"),
+ AppLaunchInfo::GetLaunchWebURL(installed_extension_));
EXPECT_EQ(extension_misc::LAUNCH_TAB,
- installed_extension_->launch_container());
+ AppLaunchInfo::GetLaunchContainer(installed_extension_));
EXPECT_EQ(0u, installed_extension_->GetActivePermissions()->apis().size());
EXPECT_EQ(0u, IconsInfo::GetIcons(installed_extension_).map().size());
}
diff --git a/chrome/browser/extensions/convert_web_app_unittest.cc b/chrome/browser/extensions/convert_web_app_unittest.cc
index dba15f8..5468b68 100644
--- a/chrome/browser/extensions/convert_web_app_unittest.cc
+++ b/chrome/browser/extensions/convert_web_app_unittest.cc
@@ -18,6 +18,7 @@
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_icon_set.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
#include "chrome/common/extensions/permissions/permission_set.h"
#include "chrome/common/web_application_info.h"
@@ -130,7 +131,7 @@ TEST(ExtensionFromWebApp, Basic) {
EXPECT_EQ("1978.12.11.0", extension->version()->GetString());
EXPECT_EQ(UTF16ToUTF8(web_app.title), extension->name());
EXPECT_EQ(UTF16ToUTF8(web_app.description), extension->description());
- EXPECT_EQ(web_app.app_url, extension->GetFullLaunchURL());
+ EXPECT_EQ(web_app.app_url, AppLaunchInfo::GetFullLaunchURL(extension));
EXPECT_EQ(2u, extension->GetActivePermissions()->apis().size());
EXPECT_TRUE(extension->HasAPIPermission("geolocation"));
EXPECT_TRUE(extension->HasAPIPermission("notifications"));
@@ -180,7 +181,7 @@ TEST(ExtensionFromWebApp, Minimal) {
EXPECT_EQ("1978.12.11.0", extension->version()->GetString());
EXPECT_EQ(UTF16ToUTF8(web_app.title), extension->name());
EXPECT_EQ("", extension->description());
- EXPECT_EQ(web_app.app_url, extension->GetFullLaunchURL());
+ EXPECT_EQ(web_app.app_url, AppLaunchInfo::GetFullLaunchURL(extension));
EXPECT_EQ(0u, IconsInfo::GetIcons(extension.get()).map().size());
EXPECT_EQ(0u, extension->GetActivePermissions()->apis().size());
ASSERT_EQ(1u, extension->web_extent().patterns().size());
diff --git a/chrome/browser/extensions/extension_prefs.cc b/chrome/browser/extensions/extension_prefs.cc
index c8ecea0..79ff1b4 100644
--- a/chrome/browser/extensions/extension_prefs.cc
+++ b/chrome/browser/extensions/extension_prefs.cc
@@ -21,6 +21,7 @@
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/feature_switch.h"
#include "chrome/common/extensions/manifest.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/extensions/permissions/permission_set.h"
#include "chrome/common/extensions/permissions/permissions_info.h"
#include "chrome/common/pref_names.h"
@@ -1128,7 +1129,7 @@ extension_misc::LaunchContainer ExtensionPrefs::GetLaunchContainer(
const Extension* extension,
ExtensionPrefs::LaunchType default_pref_value) {
extension_misc::LaunchContainer manifest_launch_container =
- extension->launch_container();
+ AppLaunchInfo::GetLaunchContainer(extension);
const extension_misc::LaunchContainer kInvalidLaunchContainer =
static_cast<extension_misc::LaunchContainer>(-1);
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc
index 93c9492..3a5c832 100644
--- a/chrome/browser/extensions/extension_service.cc
+++ b/chrome/browser/extensions/extension_service.cc
@@ -84,6 +84,7 @@
#include "chrome/common/extensions/incognito_handler.h"
#include "chrome/common/extensions/manifest.h"
#include "chrome/common/extensions/manifest_handlers/app_isolation_info.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/extensions/manifest_url_handler.h"
#include "chrome/common/extensions/permissions/permissions_data.h"
#include "chrome/common/pref_names.h"
@@ -797,8 +798,8 @@ bool ExtensionService::UninstallExtension(
NOTREACHED();
}
- GURL launch_web_url_origin(extension->launch_web_url());
- launch_web_url_origin = launch_web_url_origin.GetOrigin();
+ GURL launch_web_url_origin(
+ extensions::AppLaunchInfo::GetLaunchWebURL(extension).GetOrigin());
bool is_storage_isolated =
extensions::AppIsolationInfo::HasIsolatedStorage(extension.get());
diff --git a/chrome/browser/extensions/extension_service_unittest.cc b/chrome/browser/extensions/extension_service_unittest.cc
index 534a50798..e8ef59d 100644
--- a/chrome/browser/extensions/extension_service_unittest.cc
+++ b/chrome/browser/extensions/extension_service_unittest.cc
@@ -67,6 +67,7 @@
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_l10n_util.h"
#include "chrome/common/extensions/extension_manifest_constants.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "chrome/common/extensions/manifest_url_handler.h"
#include "chrome/common/extensions/permissions/permission_set.h"
@@ -2414,8 +2415,9 @@ TEST_F(ExtensionServiceTest, InstallAppsWithUnlimitedStorage) {
EXPECT_TRUE(extension->HasAPIPermission(
APIPermission::kUnlimitedStorage));
EXPECT_TRUE(extension->web_extent().MatchesURL(
- extension->GetFullLaunchURL()));
- const GURL origin1(extension->GetFullLaunchURL().GetOrigin());
+ extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
+ const GURL origin1(
+ extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
IsStorageUnlimited(origin1));
@@ -2427,8 +2429,9 @@ TEST_F(ExtensionServiceTest, InstallAppsWithUnlimitedStorage) {
EXPECT_TRUE(extension->HasAPIPermission(
APIPermission::kUnlimitedStorage));
EXPECT_TRUE(extension->web_extent().MatchesURL(
- extension->GetFullLaunchURL()));
- const GURL origin2(extension->GetFullLaunchURL().GetOrigin());
+ extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
+ const GURL origin2(
+ extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
EXPECT_EQ(origin1, origin2);
EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
IsStorageUnlimited(origin2));
@@ -2461,7 +2464,8 @@ TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
ASSERT_EQ(1u, service_->extensions()->size());
EXPECT_TRUE(extension->is_app());
const std::string id1 = extension->id();
- const GURL origin1(extension->GetFullLaunchURL().GetOrigin());
+ const GURL origin1(
+ extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
IsStorageProtected(origin1));
@@ -2470,7 +2474,8 @@ TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
ValidatePrefKeyCount(++pref_count);
ASSERT_EQ(2u, service_->extensions()->size());
const std::string id2 = extension->id();
- const GURL origin2(extension->GetFullLaunchURL().GetOrigin());
+ const GURL origin2(
+ extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
ASSERT_NE(origin1, origin2);
EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
IsStorageProtected(origin2));
@@ -3975,7 +3980,8 @@ TEST_F(ExtensionServiceTest, ClearAppData) {
const std::string id1 = extension->id();
EXPECT_TRUE(extension->HasAPIPermission(
APIPermission::kUnlimitedStorage));
- const GURL origin1(extension->GetFullLaunchURL().GetOrigin());
+ const GURL origin1(
+ extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
IsStorageUnlimited(origin1));
base::string16 origin_id = webkit_base::GetOriginIdentifierFromURL(origin1);
@@ -3988,8 +3994,9 @@ TEST_F(ExtensionServiceTest, ClearAppData) {
EXPECT_TRUE(extension->HasAPIPermission(
APIPermission::kUnlimitedStorage));
EXPECT_TRUE(extension->web_extent().MatchesURL(
- extension->GetFullLaunchURL()));
- const GURL origin2(extension->GetFullLaunchURL().GetOrigin());
+ extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
+ const GURL origin2(
+ extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
EXPECT_EQ(origin1, origin2);
EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
IsStorageUnlimited(origin2));
diff --git a/chrome/browser/extensions/tab_helper.cc b/chrome/browser/extensions/tab_helper.cc
index 1bd1011..25a9b2c 100644
--- a/chrome/browser/extensions/tab_helper.cc
+++ b/chrome/browser/extensions/tab_helper.cc
@@ -31,6 +31,7 @@
#include "chrome/common/extensions/extension_icon_set.h"
#include "chrome/common/extensions/extension_messages.h"
#include "chrome/common/extensions/feature_switch.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
#include "content/public/browser/invalidate_type.h"
#include "content/public/browser/navigation_controller.h"
@@ -156,7 +157,7 @@ bool TabHelper::CanCreateApplicationShortcuts() const {
}
void TabHelper::SetExtensionApp(const Extension* extension) {
- DCHECK(!extension || extension->GetFullLaunchURL().is_valid());
+ DCHECK(!extension || AppLaunchInfo::GetFullLaunchURL(extension).is_valid());
extension_app_ = extension;
UpdateExtensionAppIcon(extension_app_);
diff --git a/chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.cc b/chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.cc
index 95a3112..9c79c19 100644
--- a/chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.cc
+++ b/chrome/browser/ui/ash/launcher/app_shortcut_launcher_item_controller.cc
@@ -18,6 +18,7 @@
#include "chrome/browser/ui/extensions/native_app_window.h"
#include "chrome/browser/ui/host_desktop.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "content/public/browser/web_contents.h"
#include "ui/aura/window.h"
#include "ui/base/events/event.h"
@@ -37,9 +38,11 @@ AppShortcutLauncherItemController::AppShortcutLauncherItemController(
// used URL. This will also work with applications like Google Drive.
const Extension* extension =
launcher_controller()->GetExtensionForAppID(app_id);
- // Some unit tests have no real extension and will set their
- if (extension)
- set_refocus_url(GURL(extension->launch_web_url() + "*"));
+ // Some unit tests have no real extension.
+ if (extension) {
+ set_refocus_url(GURL(
+ extensions::AppLaunchInfo::GetLaunchWebURL(extension).spec() + "*"));
+ }
}
AppShortcutLauncherItemController::~AppShortcutLauncherItemController() {
diff --git a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser.cc b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser.cc
index bda943d..4a64c70 100644
--- a/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser.cc
+++ b/chrome/browser/ui/ash/launcher/chrome_launcher_controller_per_browser.cc
@@ -45,6 +45,7 @@
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
@@ -81,7 +82,8 @@ class AppShortcutLauncherItemController : public LauncherItemController {
if (app_id == "apdfllckaahabafndbhieahigkjlhalf") {
const Extension* extension =
launcher_controller()->GetExtensionForAppID(app_id);
- refocus_url_ = GURL(extension->launch_web_url() + "*");
+ refocus_url_ = GURL(
+ extensions::AppLaunchInfo::GetLaunchWebURL(extension).spec() + "*");
}
}
diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc
index e78b818..a0b07ad 100644
--- a/chrome/browser/ui/browser_browsertest.cc
+++ b/chrome/browser/ui/browser_browsertest.cc
@@ -47,6 +47,7 @@
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/language_detection_details.h"
#include "chrome/common/url_constants.h"
#include "chrome/test/base/in_process_browser_test.h"
@@ -1239,7 +1240,8 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, OpenAppWindowLikeNtp) {
ASSERT_TRUE(extensions::TabHelper::FromWebContents(app_window));
EXPECT_FALSE(
extensions::TabHelper::FromWebContents(app_window)->extension_app());
- EXPECT_EQ(extension_app->GetFullLaunchURL(), app_window->GetURL());
+ EXPECT_EQ(extensions::AppLaunchInfo::GetFullLaunchURL(extension_app),
+ app_window->GetURL());
// The launch should have created a new browser.
ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
diff --git a/chrome/browser/ui/extensions/application_launch.cc b/chrome/browser/ui/extensions/application_launch.cc
index a080aa3..06d250c 100644
--- a/chrome/browser/ui/extensions/application_launch.cc
+++ b/chrome/browser/ui/extensions/application_launch.cc
@@ -26,6 +26,7 @@
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_constants.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/extensions/manifest_url_handler.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/render_view_host.h"
@@ -63,7 +64,7 @@ GURL UrlForExtension(const Extension* extension,
override_url.GetOrigin() == extension->url());
url = override_url;
} else {
- url = extension->GetFullLaunchURL();
+ url = extensions::AppLaunchInfo::GetFullLaunchURL(extension);
}
// For extensions lacking launch urls, determine a reasonable fallback.
@@ -124,8 +125,10 @@ WebContents* OpenApplicationWindow(
gfx::Rect window_bounds;
if (extension) {
- window_bounds.set_width(extension->launch_width());
- window_bounds.set_height(extension->launch_height());
+ window_bounds.set_width(
+ extensions::AppLaunchInfo::GetLaunchWidth(extension));
+ window_bounds.set_height(
+ extensions::AppLaunchInfo::GetLaunchHeight(extension));
}
if (!override_bounds.IsEmpty())
window_bounds = override_bounds;
diff --git a/chrome/browser/ui/tabs/pinned_tab_codec.cc b/chrome/browser/ui/tabs/pinned_tab_codec.cc
index 951fece..b917135 100644
--- a/chrome/browser/ui/tabs/pinned_tab_codec.cc
+++ b/chrome/browser/ui/tabs/pinned_tab_codec.cc
@@ -14,6 +14,7 @@
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/pref_names.h"
#include "components/user_prefs/pref_registry_syncable.h"
#include "content/public/browser/navigation_entry.h"
@@ -62,7 +63,8 @@ static void EncodePinnedTab(TabStripModel* model,
// For apps we use the launch url. We do this because the user is
// effectively restarting the app, so returning them to the app's launch
// page seems closest to what they expect.
- value->SetString(kURL, extension->GetFullLaunchURL().spec());
+ value->SetString(
+ kURL, extensions::AppLaunchInfo::GetFullLaunchURL(extension).spec());
values->Append(value.release());
} else {
NavigationEntry* entry = web_contents->GetController().GetActiveEntry();
diff --git a/chrome/browser/ui/web_applications/web_app_ui.cc b/chrome/browser/ui/web_applications/web_app_ui.cc
index fd4a9da..b807bc7 100644
--- a/chrome/browser/ui/web_applications/web_app_ui.cc
+++ b/chrome/browser/ui/web_applications/web_app_ui.cc
@@ -18,6 +18,7 @@
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_details.h"
@@ -417,7 +418,7 @@ void UpdateShortcutInfoForApp(const extensions::Extension& app,
ShellIntegration::ShortcutInfo* shortcut_info) {
shortcut_info->extension_id = app.id();
shortcut_info->is_platform_app = app.is_platform_app();
- shortcut_info->url = GURL(app.launch_web_url());
+ shortcut_info->url = extensions::AppLaunchInfo::GetLaunchWebURL(&app);
shortcut_info->title = UTF8ToUTF16(app.name());
shortcut_info->description = UTF8ToUTF16(app.description());
shortcut_info->extension_path = app.path();
diff --git a/chrome/browser/ui/webui/extensions/extension_icon_source.cc b/chrome/browser/ui/webui/extensions/extension_icon_source.cc
index 00a6fae..2df1a33 100644
--- a/chrome/browser/ui/webui/extensions/extension_icon_source.cc
+++ b/chrome/browser/ui/webui/extensions/extension_icon_source.cc
@@ -21,6 +21,7 @@
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_constants.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
#include "chrome/common/url_constants.h"
#include "extensions/common/extension_resource.h"
@@ -218,7 +219,8 @@ void ExtensionIconSource::LoadFaviconImage(int request_id) {
return;
}
- GURL favicon_url = GetData(request_id)->extension->GetFullLaunchURL();
+ GURL favicon_url = extensions::AppLaunchInfo::GetFullLaunchURL(
+ GetData(request_id)->extension);
favicon_service->GetRawFaviconForURL(
FaviconService::FaviconForURLParams(
profile_, favicon_url, chrome::FAVICON, gfx::kFaviconSize),
diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
index c05e142..43d258c 100644
--- a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
+++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc
@@ -40,6 +40,7 @@
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/common/extensions/extension_icon_set.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chrome/common/web_application_info.h"
@@ -100,7 +101,8 @@ void AppLauncherHandler::CreateAppInfo(
// impede our ability to determine directionality.
string16 name = UTF8ToUTF16(extension->name());
base::i18n::UnadjustStringForLocaleDirection(&name);
- NewTabUI::SetUrlTitleAndDirection(value, name, extension->GetFullLaunchURL());
+ NewTabUI::SetUrlTitleAndDirection(
+ value, name, extensions::AppLaunchInfo::GetFullLaunchURL(extension));
bool enabled = service->IsExtensionEnabled(extension->id()) &&
!service->GetTerminatedExtension(extension->id());
@@ -127,7 +129,8 @@ void AppLauncherHandler::CreateAppInfo(
false, &icon_small_exists);
value->SetString("icon_small", icon_small.spec());
value->SetBoolean("icon_small_exists", icon_small_exists);
- value->SetInteger("launch_container", extension->launch_container());
+ value->SetInteger("launch_container",
+ extensions::AppLaunchInfo::GetLaunchContainer(extension));
ExtensionPrefs* prefs = service->extension_prefs();
value->SetInteger("launch_type",
prefs->GetLaunchType(extension,
diff --git a/chrome/browser/ui/webui/options/content_settings_handler.cc b/chrome/browser/ui/webui/options/content_settings_handler.cc
index 4ef629e..4c4b94b 100644
--- a/chrome/browser/ui/webui/options/content_settings_handler.cc
+++ b/chrome/browser/ui/webui/options/content_settings_handler.cc
@@ -31,6 +31,7 @@
#include "chrome/common/content_settings.h"
#include "chrome/common/content_settings_pattern.h"
#include "chrome/common/extensions/extension_set.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/extensions/permissions/api_permission.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
@@ -224,7 +225,8 @@ void AddExceptionsGrantedByHostedApps(
for (ExtensionSet::const_iterator extension = extensions->begin();
extension != extensions->end(); ++extension) {
- if (!app_filter(**extension, profile)) continue;
+ if (!app_filter(**extension, profile))
+ continue;
extensions::URLPatternSet web_extent = (*extension)->web_extent();
// Add patterns from web extent.
@@ -234,11 +236,11 @@ void AddExceptionsGrantedByHostedApps(
AddExceptionForHostedApp(url_pattern, **extension, exceptions);
}
// Retrieve the launch URL.
- std::string launch_url_string = (*extension)->launch_web_url();
- GURL launch_url(launch_url_string);
+ GURL launch_url = extensions::AppLaunchInfo::GetLaunchWebURL(*extension);
// Skip adding the launch URL if it is part of the web extent.
- if (web_extent.MatchesURL(launch_url)) continue;
- AddExceptionForHostedApp(launch_url_string, **extension, exceptions);
+ if (web_extent.MatchesURL(launch_url))
+ continue;
+ AddExceptionForHostedApp(launch_url.spec(), **extension, exceptions);
}
}
diff --git a/chrome/browser/web_applications/web_app.cc b/chrome/browser/web_applications/web_app.cc
index be91cd7..72e670c 100644
--- a/chrome/browser/web_applications/web_app.cc
+++ b/chrome/browser/web_applications/web_app.cc
@@ -14,6 +14,7 @@
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/common/constants.h"
@@ -109,7 +110,9 @@ base::FilePath GetWebAppDataDirectory(const base::FilePath& profile_path,
base::FilePath GetWebAppDataDirectory(const base::FilePath& profile_path,
const extensions::Extension& extension) {
return GetWebAppDataDirectory(
- profile_path, extension.id(), GURL(extension.launch_web_url()));
+ profile_path,
+ extension.id(),
+ GURL(extensions::AppLaunchInfo::GetLaunchWebURL(&extension)));
}
std::string GenerateApplicationNameFromInfo(
diff --git a/chrome/chrome_common.gypi b/chrome/chrome_common.gypi
index bfbe953..47c7a06 100644
--- a/chrome/chrome_common.gypi
+++ b/chrome/chrome_common.gypi
@@ -256,6 +256,8 @@
'common/extensions/manifest_handler_helpers.h',
'common/extensions/manifest_handlers/app_isolation_info.cc',
'common/extensions/manifest_handlers/app_isolation_info.h',
+ 'common/extensions/manifest_handlers/app_launch_info.cc',
+ 'common/extensions/manifest_handlers/app_launch_info.h',
'common/extensions/manifest_handlers/content_scripts_handler.cc',
'common/extensions/manifest_handlers/content_scripts_handler.h',
'common/extensions/manifest_handlers/externally_connectable.cc',
diff --git a/chrome/common/extensions/chrome_manifest_handlers.cc b/chrome/common/extensions/chrome_manifest_handlers.cc
index aa17bc3..7cfec7e 100644
--- a/chrome/common/extensions/chrome_manifest_handlers.cc
+++ b/chrome/common/extensions/chrome_manifest_handlers.cc
@@ -25,6 +25,7 @@
#include "chrome/common/extensions/csp_handler.h"
#include "chrome/common/extensions/incognito_handler.h"
#include "chrome/common/extensions/manifest_handlers/app_isolation_info.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "chrome/common/extensions/manifest_handlers/externally_connectable.h"
#include "chrome/common/extensions/manifest_handlers/icons_handler.h"
@@ -44,6 +45,7 @@ namespace extensions {
void RegisterChromeManifestHandlers() {
#if defined(ENABLE_EXTENSIONS)
(new AppIsolationHandler)->Register();
+ (new AppLaunchManifestHandler)->Register();
(new BackgroundManifestHandler)->Register();
(new BrowserActionHandler)->Register();
(new CommandsHandler)->Register();
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
index bfe41ee..fcce634 100644
--- a/chrome/common/extensions/extension.cc
+++ b/chrome/common/extensions/extension.cc
@@ -107,30 +107,6 @@ class ExtensionConfig {
Extension::ScriptingWhitelist scripting_whitelist_;
};
-bool ReadLaunchDimension(const extensions::Manifest* manifest,
- const char* key,
- int* target,
- bool is_valid_container,
- string16* error) {
- const Value* temp = NULL;
- if (manifest->Get(key, &temp)) {
- if (!is_valid_container) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidLaunchValueContainer,
- key);
- return false;
- }
- if (!temp->GetAsInteger(target) || *target < 0) {
- *target = 0;
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidLaunchValue,
- key);
- return false;
- }
- }
- return true;
-}
-
} // namespace
#if defined(OS_WIN)
@@ -396,11 +372,6 @@ bool Extension::ShowConfigureContextMenus() const {
return location() != Manifest::COMPONENT;
}
-GURL Extension::GetFullLaunchURL() const {
- return launch_local_path().empty() ? GURL(launch_web_url()) :
- url().Resolve(launch_local_path());
-}
-
bool Extension::OverlapsWithOrigin(const GURL& origin) const {
if (url() == origin)
return true;
@@ -640,9 +611,6 @@ Extension::Extension(const base::FilePath& path,
converted_from_user_script_(false),
manifest_(manifest.release()),
finished_parsing_manifest_(false),
- launch_container_(extension_misc::LAUNCH_TAB),
- launch_width_(0),
- launch_height_(0),
display_in_launcher_(true),
display_in_new_tab_page_(true),
wants_file_access_(false),
@@ -737,9 +705,7 @@ bool Extension::LoadVersion(string16* error) {
bool Extension::LoadAppFeatures(string16* error) {
if (!LoadExtent(keys::kWebURLs, &extent_,
- errors::kInvalidWebURLs, errors::kInvalidWebURL, error) ||
- !LoadLaunchURL(error) ||
- !LoadLaunchContainer(error)) {
+ errors::kInvalidWebURLs, errors::kInvalidWebURL, error)) {
return false;
}
if (manifest_->HasKey(keys::kDisplayInLauncher) &&
@@ -834,163 +800,6 @@ bool Extension::LoadExtent(const char* key,
return true;
}
-bool Extension::LoadLaunchContainer(string16* error) {
- const Value* tmp_launcher_container = NULL;
- if (!manifest_->Get(keys::kLaunchContainer, &tmp_launcher_container))
- return true;
-
- std::string launch_container_string;
- if (!tmp_launcher_container->GetAsString(&launch_container_string)) {
- *error = ASCIIToUTF16(errors::kInvalidLaunchContainer);
- return false;
- }
-
- if (launch_container_string == values::kLaunchContainerPanel) {
- launch_container_ = extension_misc::LAUNCH_PANEL;
- } else if (launch_container_string == values::kLaunchContainerTab) {
- launch_container_ = extension_misc::LAUNCH_TAB;
- } else {
- *error = ASCIIToUTF16(errors::kInvalidLaunchContainer);
- return false;
- }
-
- bool can_specify_initial_size =
- launch_container_ == extension_misc::LAUNCH_PANEL ||
- launch_container_ == extension_misc::LAUNCH_WINDOW;
-
- // Validate the container width if present.
- if (!ReadLaunchDimension(manifest_.get(),
- keys::kLaunchWidth,
- &launch_width_,
- can_specify_initial_size,
- error)) {
- return false;
- }
-
- // Validate container height if present.
- if (!ReadLaunchDimension(manifest_.get(),
- keys::kLaunchHeight,
- &launch_height_,
- can_specify_initial_size,
- error)) {
- return false;
- }
-
- return true;
-}
-
-bool Extension::LoadLaunchURL(string16* error) {
- const Value* temp = NULL;
-
- // launch URL can be either local (to chrome-extension:// root) or an absolute
- // web URL.
- if (manifest_->Get(keys::kLaunchLocalPath, &temp)) {
- if (manifest_->Get(keys::kLaunchWebURL, NULL)) {
- *error = ASCIIToUTF16(errors::kLaunchPathAndURLAreExclusive);
- return false;
- }
-
- if (manifest_->Get(keys::kWebURLs, NULL)) {
- *error = ASCIIToUTF16(errors::kLaunchPathAndExtentAreExclusive);
- return false;
- }
-
- std::string launch_path;
- if (!temp->GetAsString(&launch_path)) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidLaunchValue,
- keys::kLaunchLocalPath);
- return false;
- }
-
- // Ensure the launch path is a valid relative URL.
- GURL resolved = url().Resolve(launch_path);
- if (!resolved.is_valid() || resolved.GetOrigin() != url()) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidLaunchValue,
- keys::kLaunchLocalPath);
- return false;
- }
-
- launch_local_path_ = launch_path;
- } else if (manifest_->Get(keys::kLaunchWebURL, &temp)) {
- std::string launch_url;
- if (!temp->GetAsString(&launch_url)) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidLaunchValue,
- keys::kLaunchWebURL);
- return false;
- }
-
- // Ensure the launch URL is a valid absolute URL and web extent scheme.
- GURL url(launch_url);
- URLPattern pattern(kValidWebExtentSchemes);
- if (!url.is_valid() || !pattern.SetScheme(url.scheme())) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidLaunchValue,
- keys::kLaunchWebURL);
- return false;
- }
-
- launch_web_url_ = launch_url;
- } else if (is_legacy_packaged_app() || is_hosted_app()) {
- *error = ASCIIToUTF16(errors::kLaunchURLRequired);
- return false;
- }
-
- // If there is no extent, we default the extent based on the launch URL.
- if (web_extent().is_empty() && !launch_web_url().empty()) {
- GURL launch_url(launch_web_url());
- URLPattern pattern(kValidWebExtentSchemes);
- if (!pattern.SetScheme("*")) {
- *error = ErrorUtils::FormatErrorMessageUTF16(
- errors::kInvalidLaunchValue,
- keys::kLaunchWebURL);
- return false;
- }
- pattern.SetHost(launch_url.host());
- pattern.SetPath("/*");
- extent_.AddPattern(pattern);
- }
-
- // In order for the --apps-gallery-url switch to work with the gallery
- // process isolation, we must insert any provided value into the component
- // app's launch url and web extent.
- if (id() == extension_misc::kWebStoreAppId) {
- std::string gallery_url_str = CommandLine::ForCurrentProcess()->
- GetSwitchValueASCII(switches::kAppsGalleryURL);
-
- // Empty string means option was not used.
- if (!gallery_url_str.empty()) {
- GURL gallery_url(gallery_url_str);
- OverrideLaunchUrl(gallery_url);
- }
- } else if (id() == extension_misc::kCloudPrintAppId) {
- // In order for the --cloud-print-service switch to work, we must update
- // the launch URL and web extent.
- // TODO(sanjeevr): Ideally we want to use CloudPrintURL here but that is
- // currently under chrome/browser.
- const CommandLine& command_line = *CommandLine::ForCurrentProcess();
- GURL cloud_print_service_url = GURL(command_line.GetSwitchValueASCII(
- switches::kCloudPrintServiceURL));
- if (!cloud_print_service_url.is_empty()) {
- std::string path(
- cloud_print_service_url.path() + "/enable_chrome_connector");
- GURL::Replacements replacements;
- replacements.SetPathStr(path);
- GURL cloud_print_enable_connector_url =
- cloud_print_service_url.ReplaceComponents(replacements);
- OverrideLaunchUrl(cloud_print_enable_connector_url);
- }
- } else if (id() == extension_misc::kChromeAppId) {
- // Override launch url to new tab.
- launch_web_url_ = chrome::kChromeUINewTabURL;
- extent_.ClearPatterns();
- }
-
- return true;
-}
-
bool Extension::LoadSharedFeatures(string16* error) {
if (!LoadDescription(error) ||
!ManifestHandler::ParseExtension(this, error))
@@ -1034,30 +843,6 @@ bool Extension::LoadManifestVersion(string16* error) {
return true;
}
-void Extension::OverrideLaunchUrl(const GURL& override_url) {
- GURL new_url(override_url);
- if (!new_url.is_valid()) {
- DLOG(WARNING) << "Invalid override url given for " << name();
- } else {
- if (new_url.has_port()) {
- DLOG(WARNING) << "Override URL passed for " << name()
- << " should not contain a port. Removing it.";
-
- GURL::Replacements remove_port;
- remove_port.ClearPort();
- new_url = new_url.ReplaceComponents(remove_port);
- }
-
- launch_web_url_ = new_url.spec();
-
- URLPattern pattern(kValidWebExtentSchemes);
- URLPattern::ParseResult result = pattern.Parse(new_url.spec());
- DCHECK_EQ(result, URLPattern::PARSE_SUCCESS);
- pattern.SetPath(pattern.path() + '*');
- extent_.AddPattern(pattern);
- }
-}
-
bool Extension::CheckMinimumChromeVersion(string16* error) const {
if (!manifest_->HasKey(keys::kMinimumChromeVersion))
return true;
diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h
index 9d198fd..44bc80c 100644
--- a/chrome/common/extensions/extension.h
+++ b/chrome/common/extensions/extension.h
@@ -246,9 +246,6 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
// Whether context menu should be shown for page and browser actions.
bool ShowConfigureContextMenus() const;
- // Gets the fully resolved absolute launch URL.
- GURL GetFullLaunchURL() const;
-
// Returns true if this extension or app includes areas within |origin|.
bool OverlapsWithOrigin(const GURL& origin) const;
@@ -335,15 +332,9 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
bool is_legacy_packaged_app() const;
bool is_extension() const;
bool can_be_incognito_enabled() const;
+
void AddWebExtentPattern(const URLPattern& pattern);
const URLPatternSet& web_extent() const { return extent_; }
- const std::string& launch_local_path() const { return launch_local_path_; }
- const std::string& launch_web_url() const { return launch_web_url_; }
- extension_misc::LaunchContainer launch_container() const {
- return launch_container_;
- }
- int launch_width() const { return launch_width_; }
- int launch_height() const { return launch_height_; }
// Theme-related.
bool is_theme() const;
@@ -386,17 +377,11 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
const char* list_error,
const char* value_error,
string16* error);
- bool LoadLaunchContainer(string16* error);
- bool LoadLaunchURL(string16* error);
bool LoadSharedFeatures(string16* error);
bool LoadDescription(string16* error);
bool LoadManifestVersion(string16* error);
- // Updates the launch URL and extents for the extension using the given
- // |override_url|.
- void OverrideLaunchUrl(const GURL& override_url);
-
bool CheckMinimumChromeVersion(string16* error) const;
// Check that platform app features are valid. Called after InitFromValue.
@@ -464,25 +449,6 @@ class Extension : public base::RefCountedThreadSafe<Extension> {
// parts of the initialization process need information from previous parts).
base::ThreadChecker thread_checker_;
- // The local path inside the extension to use with the launcher.
- std::string launch_local_path_;
-
- // 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 window type that an app's manifest specifies to launch into.
- // This is not always the window type an app will open into, because
- // users can override the way each app launches. See
- // ExtensionPrefs::GetLaunchContainer(), which looks at a per-app pref
- // to decide what container an app will launch in.
- extension_misc::LaunchContainer launch_container_;
-
- // The default size of the container when launching. Only respected for
- // containers like panels and windows.
- int launch_width_;
- int launch_height_;
-
// Should this app be shown in the app launcher.
bool display_in_launcher_;
diff --git a/chrome/common/extensions/extension_manifest_constants.cc b/chrome/common/extensions/extension_manifest_constants.cc
index 98a784c..6dcb67a 100644
--- a/chrome/common/extensions/extension_manifest_constants.cc
+++ b/chrome/common/extensions/extension_manifest_constants.cc
@@ -62,10 +62,6 @@ const char kLaunchContainer[] = "app.launch.container";
const char kLaunchHeight[] = "app.launch.height";
const char kLaunchLocalPath[] = "app.launch.local_path";
const char kLaunchWebURL[] = "app.launch.web_url";
-const char kLaunchMaxHeight[] = "app.launch.max_height";
-const char kLaunchMaxWidth[] = "app.launch.max_width";
-const char kLaunchMinHeight[] = "app.launch.min_height";
-const char kLaunchMinWidth[] = "app.launch.min_width";
const char kLaunchWidth[] = "app.launch.width";
const char kLayouts[] = "layouts";
const char kManifestVersion[] = "manifest_version";
diff --git a/chrome/common/extensions/extension_manifest_constants.h b/chrome/common/extensions/extension_manifest_constants.h
index f806d72b..cfa7111 100644
--- a/chrome/common/extensions/extension_manifest_constants.h
+++ b/chrome/common/extensions/extension_manifest_constants.h
@@ -73,10 +73,6 @@ namespace extension_manifest_keys {
extern const char kLaunchContainer[];
extern const char kLaunchHeight[];
extern const char kLaunchLocalPath[];
- extern const char kLaunchMaxHeight[];
- extern const char kLaunchMaxWidth[];
- extern const char kLaunchMinHeight[];
- extern const char kLaunchMinWidth[];
extern const char kLaunchWebURL[];
extern const char kLaunchWidth[];
extern const char kLayouts[];
diff --git a/chrome/common/extensions/manifest_handlers/app_launch_info.cc b/chrome/common/extensions/manifest_handlers/app_launch_info.cc
new file mode 100644
index 0000000..6ff2491
--- /dev/null
+++ b/chrome/common/extensions/manifest_handlers/app_launch_info.cc
@@ -0,0 +1,325 @@
+// Copyright 2013 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/manifest_handlers/app_launch_info.h"
+
+#include "base/command_line.h"
+#include "base/lazy_instance.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/utf_string_conversions.h"
+#include "base/values.h"
+#include "chrome/common/chrome_switches.h"
+#include "chrome/common/extensions/extension_manifest_constants.h"
+#include "chrome/common/url_constants.h"
+#include "extensions/common/error_utils.h"
+
+namespace keys = extension_manifest_keys;
+namespace values = extension_manifest_values;
+namespace errors = extension_manifest_errors;
+
+namespace extensions {
+
+namespace {
+
+bool ReadLaunchDimension(const extensions::Manifest* manifest,
+ const char* key,
+ int* target,
+ bool is_valid_container,
+ string16* error) {
+ const Value* temp = NULL;
+ if (manifest->Get(key, &temp)) {
+ if (!is_valid_container) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidLaunchValueContainer,
+ key);
+ return false;
+ }
+ if (!temp->GetAsInteger(target) || *target < 0) {
+ *target = 0;
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidLaunchValue,
+ key);
+ return false;
+ }
+ }
+ return true;
+}
+
+static base::LazyInstance<AppLaunchInfo> g_empty_app_launch_info =
+ LAZY_INSTANCE_INITIALIZER;
+
+const AppLaunchInfo& GetAppLaunchInfo(const Extension* extension) {
+ AppLaunchInfo* info = static_cast<AppLaunchInfo*>(
+ extension->GetManifestData(keys::kLaunch));
+ return info ? *info : g_empty_app_launch_info.Get();
+}
+
+} // namespace
+
+AppLaunchInfo::AppLaunchInfo()
+ : launch_container_(extension_misc::LAUNCH_TAB),
+ launch_width_(0),
+ launch_height_(0) {
+}
+
+AppLaunchInfo::~AppLaunchInfo() {
+}
+
+// static
+const std::string& AppLaunchInfo::GetLaunchLocalPath(
+ const Extension* extension) {
+ return GetAppLaunchInfo(extension).launch_local_path_;
+}
+
+// static
+const GURL& AppLaunchInfo::GetLaunchWebURL(
+ const Extension* extension) {
+ return GetAppLaunchInfo(extension).launch_web_url_;
+}
+
+// static
+extension_misc::LaunchContainer AppLaunchInfo::GetLaunchContainer(
+ const Extension* extension) {
+ return GetAppLaunchInfo(extension).launch_container_;
+}
+
+// static
+int AppLaunchInfo::GetLaunchWidth(const Extension* extension) {
+ return GetAppLaunchInfo(extension).launch_width_;
+}
+
+// static
+int AppLaunchInfo::GetLaunchHeight(const Extension* extension) {
+ return GetAppLaunchInfo(extension).launch_height_;
+}
+
+// static
+GURL AppLaunchInfo::GetFullLaunchURL(const Extension* extension) {
+ const AppLaunchInfo& info = GetAppLaunchInfo(extension);
+ if (info.launch_local_path_.empty())
+ return info.launch_web_url_;
+ else
+ return extension->url().Resolve(info.launch_local_path_);
+}
+
+bool AppLaunchInfo::Parse(Extension* extension, string16* error) {
+ if (!LoadLaunchURL(extension, error) ||
+ !LoadLaunchContainer(extension, error))
+ return false;
+ return true;
+}
+
+bool AppLaunchInfo::LoadLaunchURL(Extension* extension, string16* error) {
+ const Value* temp = NULL;
+
+ // Launch URL can be either local (to chrome-extension:// root) or an absolute
+ // web URL.
+ if (extension->manifest()->Get(keys::kLaunchLocalPath, &temp)) {
+ if (extension->manifest()->Get(keys::kLaunchWebURL, NULL)) {
+ *error = ASCIIToUTF16(errors::kLaunchPathAndURLAreExclusive);
+ return false;
+ }
+
+ if (extension->manifest()->Get(keys::kWebURLs, NULL)) {
+ *error = ASCIIToUTF16(errors::kLaunchPathAndExtentAreExclusive);
+ return false;
+ }
+
+ std::string launch_path;
+ if (!temp->GetAsString(&launch_path)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidLaunchValue,
+ keys::kLaunchLocalPath);
+ 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 = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidLaunchValue,
+ keys::kLaunchLocalPath);
+ return false;
+ }
+
+ launch_local_path_ = launch_path;
+ } else if (extension->manifest()->Get(keys::kLaunchWebURL, &temp)) {
+ std::string launch_url;
+ if (!temp->GetAsString(&launch_url)) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidLaunchValue,
+ keys::kLaunchWebURL);
+ return false;
+ }
+
+ // Ensure the launch web URL is a valid absolute URL and web extent scheme.
+ GURL url(launch_url);
+ URLPattern pattern(Extension::kValidWebExtentSchemes);
+ if (!url.is_valid() || !pattern.SetScheme(url.scheme())) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidLaunchValue,
+ keys::kLaunchWebURL);
+ return false;
+ }
+
+ launch_web_url_ = url;
+ } else if (extension->is_legacy_packaged_app()) {
+ *error = ASCIIToUTF16(errors::kLaunchURLRequired);
+ return false;
+ }
+
+ // For the Chrome component app, override launch url to new tab.
+ if (extension->id() == extension_misc::kChromeAppId) {
+ launch_web_url_ = GURL(chrome::kChromeUINewTabURL);
+ return true;
+ }
+
+ // If there is no extent, we default the extent based on the launch URL.
+ if (extension->web_extent().is_empty() && !launch_web_url_.is_empty()) {
+ URLPattern pattern(Extension::kValidWebExtentSchemes);
+ if (!pattern.SetScheme("*")) {
+ *error = ErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidLaunchValue,
+ keys::kLaunchWebURL);
+ return false;
+ }
+ pattern.SetHost(launch_web_url_.host());
+ pattern.SetPath("/*");
+ extension->AddWebExtentPattern(pattern);
+ }
+
+ // In order for the --apps-gallery-url switch to work with the gallery
+ // process isolation, we must insert any provided value into the component
+ // app's launch url and web extent.
+ if (extension->id() == extension_misc::kWebStoreAppId) {
+ std::string gallery_url_str = CommandLine::ForCurrentProcess()->
+ GetSwitchValueASCII(switches::kAppsGalleryURL);
+
+ // Empty string means option was not used.
+ if (!gallery_url_str.empty()) {
+ GURL gallery_url(gallery_url_str);
+ OverrideLaunchURL(extension, gallery_url);
+ }
+ } else if (extension->id() == extension_misc::kCloudPrintAppId) {
+ // In order for the --cloud-print-service switch to work, we must update
+ // the launch URL and web extent.
+ // TODO(sanjeevr): Ideally we want to use CloudPrintURL here but that is
+ // currently under chrome/browser.
+ const CommandLine& command_line = *CommandLine::ForCurrentProcess();
+ GURL cloud_print_service_url = GURL(command_line.GetSwitchValueASCII(
+ switches::kCloudPrintServiceURL));
+ if (!cloud_print_service_url.is_empty()) {
+ std::string path(
+ cloud_print_service_url.path() + "/enable_chrome_connector");
+ GURL::Replacements replacements;
+ replacements.SetPathStr(path);
+ GURL cloud_print_enable_connector_url =
+ cloud_print_service_url.ReplaceComponents(replacements);
+ OverrideLaunchURL(extension, cloud_print_enable_connector_url);
+ }
+ }
+
+ return true;
+}
+
+bool AppLaunchInfo::LoadLaunchContainer(Extension* extension,
+ string16* error) {
+ const Value* tmp_launcher_container = NULL;
+ if (!extension->manifest()->Get(keys::kLaunchContainer,
+ &tmp_launcher_container))
+ return true;
+
+ std::string launch_container_string;
+ if (!tmp_launcher_container->GetAsString(&launch_container_string)) {
+ *error = ASCIIToUTF16(errors::kInvalidLaunchContainer);
+ return false;
+ }
+
+ if (launch_container_string == values::kLaunchContainerPanel) {
+ launch_container_ = extension_misc::LAUNCH_PANEL;
+ } else if (launch_container_string == values::kLaunchContainerTab) {
+ launch_container_ = extension_misc::LAUNCH_TAB;
+ } else {
+ *error = ASCIIToUTF16(errors::kInvalidLaunchContainer);
+ return false;
+ }
+
+ bool can_specify_initial_size =
+ launch_container_ == extension_misc::LAUNCH_PANEL;
+
+ // Validate the container width if present.
+ if (!ReadLaunchDimension(extension->manifest(),
+ keys::kLaunchWidth,
+ &launch_width_,
+ can_specify_initial_size,
+ error)) {
+ return false;
+ }
+
+ // Validate container height if present.
+ if (!ReadLaunchDimension(extension->manifest(),
+ keys::kLaunchHeight,
+ &launch_height_,
+ can_specify_initial_size,
+ error)) {
+ return false;
+ }
+
+ return true;
+}
+
+void AppLaunchInfo::OverrideLaunchURL(Extension* extension,
+ GURL override_url) {
+ if (!override_url.is_valid()) {
+ DLOG(WARNING) << "Invalid override url given for " << extension->name();
+ return;
+ }
+ if (override_url.has_port()) {
+ DLOG(WARNING) << "Override URL passed for " << extension->name()
+ << " should not contain a port. Removing it.";
+
+ GURL::Replacements remove_port;
+ remove_port.ClearPort();
+ override_url = override_url.ReplaceComponents(remove_port);
+ }
+
+ launch_web_url_ = override_url;
+
+ URLPattern pattern(Extension::kValidWebExtentSchemes);
+ URLPattern::ParseResult result = pattern.Parse(override_url.spec());
+ DCHECK_EQ(result, URLPattern::PARSE_SUCCESS);
+ pattern.SetPath(pattern.path() + '*');
+ extension->AddWebExtentPattern(pattern);
+}
+
+AppLaunchManifestHandler::AppLaunchManifestHandler() {
+}
+
+AppLaunchManifestHandler::~AppLaunchManifestHandler() {
+}
+
+bool AppLaunchManifestHandler::Parse(Extension* extension, string16* error) {
+ scoped_ptr<AppLaunchInfo> info(new AppLaunchInfo);
+ if (!info->Parse(extension, error))
+ return false;
+ extension->SetManifestData(keys::kLaunch, info.release());
+ return true;
+}
+
+bool AppLaunchManifestHandler::AlwaysParseForType(Manifest::Type type) const {
+ return type == Manifest::TYPE_LEGACY_PACKAGED_APP;
+}
+
+const std::vector<std::string> AppLaunchManifestHandler::Keys() const {
+ static const char* keys[] = {
+ keys::kLaunchLocalPath,
+ keys::kLaunchWebURL,
+ keys::kLaunchContainer,
+ keys::kLaunchHeight,
+ keys::kLaunchWidth
+ };
+ return std::vector<std::string>(keys, keys + arraysize(keys));
+}
+
+} // namespace extensions
diff --git a/chrome/common/extensions/manifest_handlers/app_launch_info.h b/chrome/common/extensions/manifest_handlers/app_launch_info.h
new file mode 100644
index 0000000..f048ed7
--- /dev/null
+++ b/chrome/common/extensions/manifest_handlers/app_launch_info.h
@@ -0,0 +1,83 @@
+// Copyright 2013 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_MANIFEST_HANDLERS_APP_LAUNCH_INFO_H_
+#define CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_APP_LAUNCH_INFO_H_
+
+#include <string>
+#include <vector>
+
+#include "chrome/common/extensions/extension.h"
+#include "chrome/common/extensions/extension_constants.h"
+#include "chrome/common/extensions/manifest.h"
+#include "chrome/common/extensions/manifest_handler.h"
+#include "googleurl/src/gurl.h"
+
+namespace extensions {
+
+// Container that holds the parsed app launch data.
+class AppLaunchInfo : public Extension::ManifestData {
+ public:
+ AppLaunchInfo();
+ virtual ~AppLaunchInfo();
+
+ // Get the local path inside the extension to use with the launcher.
+ static const std::string& GetLaunchLocalPath(const Extension* extension);
+
+ // Get the absolute web url to use with the launcher.
+ static const GURL& GetLaunchWebURL(const Extension* extension);
+
+ // The window type that an app's manifest specifies to launch into.
+ // This is not always the window type an app will open into, because
+ // users can override the way each app launches. See
+ // ExtensionPrefs::GetLaunchContainer(), which looks at a per-app pref
+ // to decide what container an app will launch in.
+ static extension_misc::LaunchContainer GetLaunchContainer(
+ const Extension* extension);
+
+ // The default size of the container when launching. Only respected for
+ // containers like panels and windows.
+ static int GetLaunchWidth(const Extension* extension);
+ static int GetLaunchHeight(const Extension* extension);
+
+ // Get the fully resolved absolute launch URL.
+ static GURL GetFullLaunchURL(const Extension* extension);
+
+ bool Parse(Extension* extension, string16* error);
+
+ private:
+ bool LoadLaunchURL(Extension* extension, string16* error);
+ bool LoadLaunchContainer(Extension* extension, string16* error);
+ void OverrideLaunchURL(Extension* extension, GURL override_url);
+
+ std::string launch_local_path_;
+
+ GURL launch_web_url_;
+
+ extension_misc::LaunchContainer launch_container_;
+
+ int launch_width_;
+ int launch_height_;
+
+ DISALLOW_COPY_AND_ASSIGN(AppLaunchInfo);
+};
+
+// Parses all app launch related keys in the manifest.
+class AppLaunchManifestHandler : public ManifestHandler {
+ public:
+ AppLaunchManifestHandler();
+ virtual ~AppLaunchManifestHandler();
+
+ virtual bool Parse(Extension* extension, string16* error) OVERRIDE;
+ virtual bool AlwaysParseForType(Manifest::Type type) const OVERRIDE;
+
+ private:
+ virtual const std::vector<std::string> Keys() const OVERRIDE;
+
+ DISALLOW_COPY_AND_ASSIGN(AppLaunchManifestHandler);
+};
+
+} // namespace extensions
+
+#endif // CHROME_COMMON_EXTENSIONS_MANIFEST_HANDLERS_APP_LAUNCH_INFO_H_
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_launch_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_launch_unittest.cc
index 4cf2475..456122e 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_launch_unittest.cc
+++ b/chrome/common/extensions/manifest_tests/extension_manifests_launch_unittest.cc
@@ -2,37 +2,43 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/common/extensions/manifest_tests/extension_manifest_test.h"
-
#include "base/command_line.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_manifest_constants.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
+#include "chrome/common/extensions/manifest_tests/extension_manifest_test.h"
#include "extensions/common/error_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace errors = extension_manifest_errors;
namespace keys = extension_manifest_keys;
-using extensions::ErrorUtils;
+namespace extensions {
-TEST_F(ExtensionManifestTest, AppLaunchContainer) {
- scoped_refptr<extensions::Extension> extension;
+class AppLaunchManifestTest : public ExtensionManifestTest {
+};
+
+TEST_F(AppLaunchManifestTest, AppLaunchContainer) {
+ scoped_refptr<Extension> extension;
extension = LoadAndExpectSuccess("launch_tab.json");
- EXPECT_EQ(extension_misc::LAUNCH_TAB, extension->launch_container());
+ EXPECT_EQ(extension_misc::LAUNCH_TAB,
+ AppLaunchInfo::GetLaunchContainer(extension));
extension = LoadAndExpectSuccess("launch_panel.json");
- EXPECT_EQ(extension_misc::LAUNCH_PANEL, extension->launch_container());
+ EXPECT_EQ(extension_misc::LAUNCH_PANEL,
+ AppLaunchInfo::GetLaunchContainer(extension));
extension = LoadAndExpectSuccess("launch_default.json");
- EXPECT_EQ(extension_misc::LAUNCH_TAB, extension->launch_container());
+ EXPECT_EQ(extension_misc::LAUNCH_TAB,
+ AppLaunchInfo::GetLaunchContainer(extension));
extension = LoadAndExpectSuccess("launch_width.json");
- EXPECT_EQ(640, extension->launch_width());
+ EXPECT_EQ(640, AppLaunchInfo::GetLaunchWidth(extension));
extension = LoadAndExpectSuccess("launch_height.json");
- EXPECT_EQ(480, extension->launch_height());
+ EXPECT_EQ(480, AppLaunchInfo::GetLaunchHeight(extension));
Testcase testcases[] = {
Testcase("launch_window.json", errors::kInvalidLaunchContainer),
@@ -63,7 +69,7 @@ TEST_F(ExtensionManifestTest, AppLaunchContainer) {
EXPECT_TYPE_ERROR);
}
-TEST_F(ExtensionManifestTest, AppLaunchURL) {
+TEST_F(AppLaunchManifestTest, AppLaunchURL) {
Testcase testcases[] = {
Testcase("launch_path_and_url.json",
errors::kLaunchPathAndURLAreExclusive),
@@ -101,14 +107,14 @@ TEST_F(ExtensionManifestTest, AppLaunchURL) {
RunTestcases(testcases, arraysize(testcases),
EXPECT_TYPE_ERROR);
- scoped_refptr<extensions::Extension> extension;
+ scoped_refptr<Extension> extension;
extension = LoadAndExpectSuccess("launch_local_path.json");
EXPECT_EQ(extension->url().spec() + "launch.html",
- extension->GetFullLaunchURL().spec());
+ AppLaunchInfo::GetFullLaunchURL(extension).spec());
extension = LoadAndExpectSuccess("launch_local_path_localized.json");
EXPECT_EQ(extension->url().spec() + "launch.html",
- extension->GetFullLaunchURL().spec());
+ AppLaunchInfo::GetFullLaunchURL(extension).spec());
LoadAndExpectError("launch_web_url_relative.json",
ErrorUtils::FormatErrorMessage(
@@ -117,8 +123,10 @@ TEST_F(ExtensionManifestTest, AppLaunchURL) {
extension = LoadAndExpectSuccess("launch_web_url_absolute.json");
EXPECT_EQ(GURL("http://www.google.com/launch.html"),
- extension->GetFullLaunchURL());
+ AppLaunchInfo::GetFullLaunchURL(extension));
extension = LoadAndExpectSuccess("launch_web_url_localized.json");
EXPECT_EQ(GURL("http://www.google.com/launch.html"),
- extension->GetFullLaunchURL());
+ AppLaunchInfo::GetFullLaunchURL(extension));
}
+
+} // namespace extensions
diff --git a/chrome/common/extensions/manifest_tests/extension_manifests_validapp_unittest.cc b/chrome/common/extensions/manifest_tests/extension_manifests_validapp_unittest.cc
index 75aa59f..684f690 100644
--- a/chrome/common/extensions/manifest_tests/extension_manifests_validapp_unittest.cc
+++ b/chrome/common/extensions/manifest_tests/extension_manifests_validapp_unittest.cc
@@ -2,24 +2,28 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/common/extensions/manifest_tests/extension_manifest_test.h"
-
-#include "base/values.h"
#include "base/memory/scoped_ptr.h"
+#include "base/values.h"
+#include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
+#include "chrome/common/extensions/manifest_tests/extension_manifest_test.h"
#include "testing/gtest/include/gtest/gtest.h"
-TEST_F(ExtensionManifestTest, ValidApp) {
+typedef ExtensionManifestTest ValidAppManifestTest;
+
+TEST_F(ValidAppManifestTest, ValidApp) {
scoped_refptr<extensions::Extension> extension(
LoadAndExpectSuccess("valid_app.json"));
extensions::URLPatternSet expected_patterns;
AddPattern(&expected_patterns, "http://www.google.com/mail/*");
AddPattern(&expected_patterns, "http://www.google.com/foobar/*");
EXPECT_EQ(expected_patterns, extension->web_extent());
- EXPECT_EQ(extension_misc::LAUNCH_TAB, extension->launch_container());
- EXPECT_EQ("http://www.google.com/mail/", extension->launch_web_url());
+ EXPECT_EQ(extension_misc::LAUNCH_TAB,
+ extensions::AppLaunchInfo::GetLaunchContainer(extension));
+ EXPECT_EQ(GURL("http://www.google.com/mail/"),
+ extensions::AppLaunchInfo::GetLaunchWebURL(extension));
}
-TEST_F(ExtensionManifestTest, AllowUnrecognizedPermissions) {
+TEST_F(ValidAppManifestTest, AllowUnrecognizedPermissions) {
std::string error;
scoped_ptr<DictionaryValue> manifest(LoadManifest("valid_app.json", &error));
ListValue* permissions = NULL;