diff options
author | benwells@chromium.org <benwells@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-26 07:09:36 +0000 |
---|---|---|
committer | benwells@chromium.org <benwells@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-05-26 07:09:36 +0000 |
commit | 12e54045b113f6aca10188b012b1ea529cec6bf2 (patch) | |
tree | fe3df5477fdf7c7dd0fe6a5f83c8a87b3f5d155b /chrome | |
parent | 7dc1be3f8b949012bb88a49faf0f81f0be363f06 (diff) | |
download | chromium_src-12e54045b113f6aca10188b012b1ea529cec6bf2.zip chromium_src-12e54045b113f6aca10188b012b1ea529cec6bf2.tar.gz chromium_src-12e54045b113f6aca10188b012b1ea529cec6bf2.tar.bz2 |
Pass command line arguments onto platform apps which provide the right intent.
Any command line arguments which are file names are passed through in
launchData.intent
BUG=None
TEST=New tests added
Review URL: https://chromiumcodereview.appspot.com/10332071
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@139195 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
43 files changed, 785 insertions, 30 deletions
diff --git a/chrome/browser/autocomplete/extension_app_provider.cc b/chrome/browser/autocomplete/extension_app_provider.cc index e57a429..b538469 100644 --- a/chrome/browser/autocomplete/extension_app_provider.cc +++ b/chrome/browser/autocomplete/extension_app_provider.cc @@ -51,7 +51,7 @@ void ExtensionAppProvider::LaunchAppFromOmnibox( extension, ExtensionPrefs::LAUNCH_REGULAR); application_launch::OpenApplication(profile, extension, launch_container, - GURL(), disposition); + GURL(), disposition, NULL); } void ExtensionAppProvider::AddExtensionAppForTesting( diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc index eea9313..037af48 100644 --- a/chrome/browser/automation/testing_automation_provider.cc +++ b/chrome/browser/automation/testing_automation_provider.cc @@ -5651,7 +5651,7 @@ void TestingAutomationProvider::LaunchApp( new AppLaunchObserver(&old_contents->GetController(), this, reply_message, launch_container); application_launch::OpenApplication(profile(), extension, launch_container, - GURL(), CURRENT_TAB); + GURL(), CURRENT_TAB, NULL); } // Sample JSON input: { "command": "SetAppLaunchType", diff --git a/chrome/browser/background/background_mode_manager.cc b/chrome/browser/background/background_mode_manager.cc index 2aa6f00..76d079d 100644 --- a/chrome/browser/background/background_mode_manager.cc +++ b/chrome/browser/background/background_mode_manager.cc @@ -267,7 +267,7 @@ void BackgroundModeManager::LaunchBackgroundApplication( service->extension_prefs()->GetLaunchContainer( extension, ExtensionPrefs::LAUNCH_REGULAR); application_launch::OpenApplication(profile, extension, launch_container, - GURL(), NEW_FOREGROUND_TAB); + GURL(), NEW_FOREGROUND_TAB, NULL); } bool BackgroundModeManager::IsBackgroundModeActiveForTest() { diff --git a/chrome/browser/chromeos/extensions/file_manager_util.cc b/chrome/browser/chromeos/extensions/file_manager_util.cc index 5d2bf9d..6e8ef44 100644 --- a/chrome/browser/chromeos/extensions/file_manager_util.cc +++ b/chrome/browser/chromeos/extensions/file_manager_util.cc @@ -471,8 +471,8 @@ void OpenFileBrowser(const FilePath& path, GetLaunchContainer(extension, ExtensionPrefs::LAUNCH_DEFAULT); content::RecordAction(UserMetricsAction("ShowFileBrowserFullTab")); - application_launch::OpenApplication( - profile, extension, launch_container, GURL(url), NEW_FOREGROUND_TAB); + application_launch::OpenApplication(profile, extension, launch_container, + GURL(url), NEW_FOREGROUND_TAB, NULL); } void ViewRemovableDrive(const FilePath& path) { diff --git a/chrome/browser/extensions/api/app/app_api.cc b/chrome/browser/extensions/api/app/app_api.cc index 14c9ece..3b74ab0 100644 --- a/chrome/browser/extensions/api/app/app_api.cc +++ b/chrome/browser/extensions/api/app/app_api.cc @@ -4,8 +4,10 @@ #include "chrome/browser/extensions/api/app/app_api.h" +#include "base/json/json_writer.h" #include "base/values.h" #include "base/time.h" +#include "base/utf_string_conversions.h" #include "chrome/browser/extensions/app_notification_manager.h" #include "chrome/browser/extensions/extension_event_router.h" #include "chrome/browser/extensions/extension_service.h" @@ -121,4 +123,27 @@ void AppEventRouter::DispatchOnLaunchedEvent( extension->id(), kOnLaunchedEvent, "[]", NULL, GURL()); } +// static. +void AppEventRouter::DispatchOnLaunchedEventWithFileEntry( + Profile* profile, const Extension* extension, const string16& action, + const std::string& file_system_id, const FilePath& base_name) { + ListValue args; + DictionaryValue* launch_data = new DictionaryValue(); + DictionaryValue* intent = new DictionaryValue(); + intent->SetString("action", UTF16ToUTF8(action)); + launch_data->Set("intent", intent); + intent->SetString("type", "chrome-extension://fileentry"); + args.Append(launch_data); + args.Append(Value::CreateStringValue(file_system_id)); +#if defined(OS_WIN) + args.Append(Value::CreateStringValue(UTF16ToUTF8(base_name.value()))); +#else + args.Append(Value::CreateStringValue(base_name.value())); +#endif + std::string json_args; + base::JSONWriter::Write(&args, &json_args); + profile->GetExtensionEventRouter()->DispatchEventToExtension( + extension->id(), kOnLaunchedEvent, json_args, NULL, GURL()); +} + } // namespace extensions diff --git a/chrome/browser/extensions/api/app/app_api.h b/chrome/browser/extensions/api/app/app_api.h index 306c158..d5690ed 100644 --- a/chrome/browser/extensions/api/app/app_api.h +++ b/chrome/browser/extensions/api/app/app_api.h @@ -9,6 +9,7 @@ #include "chrome/browser/extensions/extension_function.h" class Profile; +class GURL; namespace extensions { @@ -34,9 +35,32 @@ class AppClearAllNotificationsFunction : public SyncExtensionFunction { class AppEventRouter { public: - // Dispatches the onLaunched event to the given app. + // Dispatches the onLaunched event to the given app, providing no launch + // data. static void DispatchOnLaunchedEvent(Profile* profile, const Extension* extension); + + // Dispatches the onLaunched event to the given app, providing launch data of + // the form: + // { + // "intent" : { + // "action" : |action|, + // "type" : "chrome-extension://fileentry", + // "data" : a FileEntry, + // "postResults" : a null function, + // "postFailure" : a null function + // } + // } + + // launchData.intent.data and launchData.intent.postResults are created in a + // custom dispatch event in javascript. The FileEntry is created from + // |file_system_id| and |base_name|. + static void DispatchOnLaunchedEventWithFileEntry( + Profile* profile, + const Extension* extension, + const string16& action, + const std::string& file_system_id, + const FilePath& base_name); }; } // namespace extensions diff --git a/chrome/browser/extensions/app_notification_browsertest.cc b/chrome/browser/extensions/app_notification_browsertest.cc index 639b155..fea0ef3 100644 --- a/chrome/browser/extensions/app_notification_browsertest.cc +++ b/chrome/browser/extensions/app_notification_browsertest.cc @@ -63,7 +63,8 @@ IN_PROC_BROWSER_TEST_F(AppNotificationTest, SaveClientId) { app, extension_misc::LAUNCH_TAB, GURL(), - NEW_FOREGROUND_TAB); + NEW_FOREGROUND_TAB, + NULL); if (!interceptor.was_called()) ui_test_utils::RunMessageLoop(); EXPECT_TRUE(interceptor.was_called()); diff --git a/chrome/browser/extensions/extension_apitest.cc b/chrome/browser/extensions/extension_apitest.cc index e0806b8..1042e32 100644 --- a/chrome/browser/extensions/extension_apitest.cc +++ b/chrome/browser/extensions/extension_apitest.cc @@ -210,12 +210,14 @@ bool ExtensionApiTest::RunExtensionTestImpl(const char* extension_name, ui_test_utils::NavigateToURL(browser(), url); } else if (launch_platform_app) { + CommandLine* command_line = CommandLine::ForCurrentProcess(); application_launch::OpenApplication( browser()->profile(), extension, extension_misc::LAUNCH_NONE, GURL(), - NEW_WINDOW); + NEW_WINDOW, + command_line); } if (!catcher.GetNextResult()) { diff --git a/chrome/browser/extensions/extension_management_api.cc b/chrome/browser/extensions/extension_management_api.cc index f99ec40..8f3da298 100644 --- a/chrome/browser/extensions/extension_management_api.cc +++ b/chrome/browser/extensions/extension_management_api.cc @@ -341,7 +341,7 @@ bool LaunchAppFunction::RunImpl() { service()->extension_prefs()->GetLaunchContainer( extension, ExtensionPrefs::LAUNCH_DEFAULT); application_launch::OpenApplication(profile(), extension, launch_container, - GURL(), NEW_FOREGROUND_TAB); + GURL(), NEW_FOREGROUND_TAB, NULL); #if !defined(OS_ANDROID) AppLauncherHandler::RecordAppLaunchType( extension_misc::APP_LAUNCH_EXTENSION_API); diff --git a/chrome/browser/extensions/platform_app_browsertest.cc b/chrome/browser/extensions/platform_app_browsertest.cc index 325aff9..f21edd9 100644 --- a/chrome/browser/extensions/platform_app_browsertest.cc +++ b/chrome/browser/extensions/platform_app_browsertest.cc @@ -4,7 +4,7 @@ #include "base/command_line.h" #include "base/stringprintf.h" -#include "base/utf_string_conversions.h" +#include "base/string_util.h" #include "base/values.h" #include "chrome/browser/automation/automation_util.h" #include "chrome/browser/extensions/extension_apitest.h" @@ -77,7 +77,8 @@ class PlatformAppBrowserTest : public ExtensionApiTest { extension, extension_misc::LAUNCH_NONE, GURL(), - NEW_WINDOW); + NEW_WINDOW, + NULL); app_loaded_observer.Wait(); @@ -128,6 +129,26 @@ class PlatformAppBrowserTest : public ExtensionApiTest { return ShellWindowRegistry::Get(browser()->profile())-> shell_windows().size(); } + + // The command line already has an argument on it - about:blank, which + // is set by InProcessBrowserTest::PrepareTestCommandLine. For platform app + // launch tests we need to clear this. + void ClearCommandLineArgs() { + CommandLine* command_line = CommandLine::ForCurrentProcess(); + CommandLine::StringVector args = command_line->GetArgs(); + CommandLine::StringVector argv = command_line->argv(); + for (size_t i = 0; i < args.size(); i++) + argv.pop_back(); + command_line->InitFromArgv(argv); + } + + void SetCommandLineArg(const std::string& test_file) { + ClearCommandLineArgs(); + CommandLine* command_line = CommandLine::ForCurrentProcess(); + FilePath test_doc(test_data_dir_.AppendASCII(test_file)); + test_doc = test_doc.NormalizePathSeparators(); + command_line->AppendArgPath(test_doc); + } }; // Tests that platform apps received the "launch" event when launched. @@ -272,3 +293,68 @@ IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, ExtensionWindowingApis) { ASSERT_EQ(1U, RunGetWindowsFunctionForExtension(platform_app)); ASSERT_EQ(1U, RunGetWindowsFunctionForExtension(platform_app2)); } + +// TODO(benwells): fix these tests for ChromeOS. +#if !defined(OS_CHROMEOS) +// Tests that command line parameters get passed through to platform apps +// via launchData correctly when launching with a file. +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithFile) { + SetCommandLineArg( "platform_apps/launch_files/test.txt"); + ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_file")) + << message_; +} + +// Tests that no launch data is sent through if the platform app provides +// an intent with the wrong action. +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithWrongIntent) { + SetCommandLineArg("platform_apps/launch_files/test.txt"); + ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_wrong_intent")) + << message_; +} + +// Tests that no launch data is sent through if the file is of the wrong MIME +// type. +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithWrongType) { + SetCommandLineArg("platform_apps/launch_files/test.txt"); + ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_wrong_type")) + << message_; +} + +// Tests that no launch data is sent through if the platform app does not +// provide an intent. +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithNoIntent) { + SetCommandLineArg("platform_apps/launch_files/test.txt"); + ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_no_intent")) + << message_; +} + +// Tests that no launch data is sent through if the file MIME type cannot +// be read. +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchNoType) { + SetCommandLineArg("platform_apps/launch_files/test.unknownextension"); + ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_invalid")) + << message_; +} + +// Tests that no launch data is sent through if the file does not exist. +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchNoFile) { + SetCommandLineArg("platform_apps/launch_files/doesnotexist.txt"); + ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_invalid")) + << message_; +} + +// Tests that no launch data is sent through if the argument is a directory. +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithDirectory) { + SetCommandLineArg("platform_apps/launch_files"); + ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_invalid")) + << message_; +} + +// Tests that no launch data is sent through if there are no arguments passed +// on the command line +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithNothing) { + ClearCommandLineArgs(); + ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_nothing")) + << message_; +} +#endif // defined(OS_CHROMEOS) diff --git a/chrome/browser/extensions/platform_app_launcher.cc b/chrome/browser/extensions/platform_app_launcher.cc new file mode 100644 index 0000000..47ea21a --- /dev/null +++ b/chrome/browser/extensions/platform_app_launcher.cc @@ -0,0 +1,199 @@ +// Copyright (c) 2012 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/browser/extensions/platform_app_launcher.h" + +#include "base/command_line.h" +#include "base/file_path.h" +#include "base/file_util.h" +#include "base/logging.h" +#include "base/memory/ref_counted.h" +#include "base/string_util.h" +#include "base/utf_string_conversions.h" +#include "chrome/browser/extensions/api/app/app_api.h" +#include "chrome/browser/extensions/extension_host.h" +#include "chrome/browser/extensions/extension_process_manager.h" +#include "chrome/browser/extensions/extension_system.h" +#include "chrome/browser/extensions/lazy_background_task_queue.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/common/extensions/extension.h" +#include "chrome/common/extensions/extension_messages.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/child_process_security_policy.h" +#include "content/public/browser/render_process_host.h" +#include "net/base/mime_util.h" +#include "net/base/net_util.h" +#include "webkit/fileapi/isolated_context.h" +#include "webkit/glue/web_intent_service_data.h" + +using content::BrowserThread; +using extensions::Extension; + +namespace { + +const char kViewIntent[] = "http://webintents.org/view"; + +class PlatformAppLauncher + : public base::RefCountedThreadSafe<PlatformAppLauncher> { + public: + PlatformAppLauncher(Profile* profile, + const Extension* extension, + const CommandLine* command_line) + : profile_(profile), + extension_(extension), + command_line_(command_line) {} + + void Launch() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + if (!command_line_ || !command_line_->GetArgs().size()) { + LaunchWithNoLaunchData(); + return; + } + + FilePath file_path(command_line_->GetArgs()[0]); + BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE, base::Bind( + &PlatformAppLauncher::GetMimeTypeAndLaunch, this, file_path)); + } + + private: + friend class base::RefCountedThreadSafe<PlatformAppLauncher>; + + virtual ~PlatformAppLauncher() {} + + void LaunchWithNoLaunchData() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + extensions::AppEventRouter::DispatchOnLaunchedEvent(profile_, extension_); + } + + void GetMimeTypeAndLaunch(const FilePath& file_path) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); + + // If the file doesn't exist, or is a directory, launch with no launch data. + if (!file_util::PathExists(file_path) || + file_util::DirectoryExists(file_path)) { + LOG(WARNING) << "No file exists with path " << file_path.value(); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( + &PlatformAppLauncher::LaunchWithNoLaunchData, this)); + return; + } + + std::string mime_type; + // If we cannot obtain the MIME type, launch with no launch data. + if (!net::GetMimeTypeFromFile(file_path, &mime_type)) { + LOG(WARNING) << "Could not obtain MIME type for " << file_path.value(); + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( + &PlatformAppLauncher::LaunchWithNoLaunchData, this)); + return; + } + + BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( + &PlatformAppLauncher::LaunchWithMimeTypeAndPath, this, file_path, + mime_type)); + } + + void LaunchWithMimeTypeAndPath(const FilePath& file_path, + const std::string& mime_type) { + // Find the intent service from the platform app for the file being opened. + webkit_glue::WebIntentServiceData service; + bool found_service = false; + + std::vector<webkit_glue::WebIntentServiceData> services = + extension_->intents_services(); + for (size_t i = 0; i < services.size(); i++) { + std::string service_type_ascii = UTF16ToASCII(services[i].type); + if (services[i].action == ASCIIToUTF16(kViewIntent) && + net::MatchesMimeType(service_type_ascii, mime_type)) { + service = services[i]; + found_service = true; + break; + } + } + + // If this app doesn't have an intent that supports the file, launch with + // no launch data. + if (!found_service) { + LOG(WARNING) << "Extension does not provide a valid intent for " + << file_path.value(); + LaunchWithNoLaunchData(); + return; + } + + // We need to grant access to the file for the process associated with the + // extension. To do this we need the ExtensionHost. This might not be + // available, or it might be in the process of being unloaded, in which case + // we can use the lazy background task queue to load the extension and then + // call back to us. + extensions::LazyBackgroundTaskQueue* queue = + ExtensionSystem::Get(profile_)->lazy_background_task_queue(); + if (queue->ShouldEnqueueTask(profile_, extension_)) { + queue->AddPendingTask(profile_, extension_->id(), + base::Bind(&PlatformAppLauncher::GrantAccessToFileAndLaunch, + this, file_path, mime_type)); + return; + } + + ExtensionProcessManager* pm = + ExtensionSystem::Get(profile_)->process_manager(); + ExtensionHost* host = pm->GetBackgroundHostForExtension(extension_->id()); + DCHECK(host); + GrantAccessToFileAndLaunch(file_path, mime_type, host); + } + + void GrantAccessToFileAndLaunch(const FilePath& file_path, + const std::string& mime_type, + ExtensionHost* host) { + // If there was an error loading the app page, |host| will be NULL. + if (!host) { + LOG(ERROR) << "Could not load app page for " << extension_->id(); + return; + } + + content::ChildProcessSecurityPolicy* policy = + content::ChildProcessSecurityPolicy::GetInstance(); + int renderer_id = host->render_process_host()->GetID(); + + // If the renderer already has permission to read these paths, we don't + // regrant, as this would overwrite any other permissions which the renderer + // may already have. + if (!policy->CanReadFile(renderer_id, file_path)) + policy->GrantReadFile(renderer_id, file_path); + + std::set<FilePath> filesets; + filesets.insert(file_path); + + fileapi::IsolatedContext* isolated_context = + fileapi::IsolatedContext::GetInstance(); + DCHECK(isolated_context); + std::string filesystem_id = isolated_context->RegisterIsolatedFileSystem( + filesets); + policy->GrantAccessFileSystem(renderer_id, filesystem_id); + + extensions::AppEventRouter::DispatchOnLaunchedEventWithFileEntry( + profile_, extension_, ASCIIToUTF16(kViewIntent), filesystem_id, + file_path.BaseName()); + } + + Profile* profile_; + const Extension* extension_; + const CommandLine* command_line_; + + DISALLOW_COPY_AND_ASSIGN(PlatformAppLauncher); +}; + +} // namespace + +namespace extensions { + +void LaunchPlatformApp(Profile* profile, + const Extension* extension, + const CommandLine* command_line) { + // launcher will be freed when nothing has a reference to it. The message + // queue will retain a reference for any outstanding task, so when the + // launcher has finished it will be freed. + scoped_refptr<PlatformAppLauncher> launcher = + new PlatformAppLauncher(profile, extension, command_line); + launcher->Launch(); +} + +} // namespace extensions diff --git a/chrome/browser/extensions/platform_app_launcher.h b/chrome/browser/extensions/platform_app_launcher.h new file mode 100644 index 0000000..20181cd --- /dev/null +++ b/chrome/browser/extensions/platform_app_launcher.h @@ -0,0 +1,25 @@ +// Copyright (c) 2012 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_BROWSER_EXTENSIONS_PLATFORM_APP_LAUNCHER_H_ +#define CHROME_BROWSER_EXTENSIONS_PLATFORM_APP_LAUNCHER_H_ +#pragma once + +class CommandLine; +class Profile; + +namespace extensions { + +class Extension; + +// Launches the platform app |extension|. Creates appropriate launch data for +// the |command_line| fields present. |extension| and |profile| must not be +// NULL. A NULL |command_line| means there is no launch data. +void LaunchPlatformApp(Profile* profile, + const Extension* extension, + const CommandLine* command_line); + +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_PLATFORM_APP_LAUNCHER_H_ diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index afa8dc8..e6b3163 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc @@ -48,7 +48,6 @@ #include "chrome/browser/download/download_shelf.h" #include "chrome/browser/download/download_started_animation.h" #include "chrome/browser/download/download_util.h" -#include "chrome/browser/extensions/api/app/app_api.h" #include "chrome/browser/extensions/browser_extension_window_controller.h" #include "chrome/browser/extensions/crx_installer.h" #include "chrome/browser/extensions/default_apps_trial.h" diff --git a/chrome/browser/ui/browser_browsertest.cc b/chrome/browser/ui/browser_browsertest.cc index bc3c43e..46fc8a8 100644 --- a/chrome/browser/ui/browser_browsertest.cc +++ b/chrome/browser/ui/browser_browsertest.cc @@ -1564,7 +1564,8 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, OpenAppWindowLikeNtp) { extension_app, extension_misc::LAUNCH_WINDOW, GURL(), - NEW_WINDOW); + NEW_WINDOW, + NULL); ASSERT_TRUE(app_window); // Apps launched in a window from the NTP do not have extension_app set in diff --git a/chrome/browser/ui/extensions/application_launch.cc b/chrome/browser/ui/extensions/application_launch.cc index 05d59f1d..3446c05 100644 --- a/chrome/browser/ui/extensions/application_launch.cc +++ b/chrome/browser/ui/extensions/application_launch.cc @@ -4,13 +4,14 @@ #include "chrome/browser/ui/extensions/application_launch.h" +#include "base/command_line.h" #include "base/metrics/field_trial.h" #include "base/metrics/histogram.h" -#include "chrome/browser/extensions/api/app/app_api.h" #include "chrome/browser/extensions/default_apps_trial.h" #include "chrome/browser/extensions/extension_prefs.h" #include "chrome/browser/extensions/extension_service.h" #include "chrome/browser/extensions/extension_tab_helper.h" +#include "chrome/browser/extensions/platform_app_launcher.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/browser/ui/browser.h" @@ -81,7 +82,8 @@ WebContents* OpenApplication(Profile* profile, const Extension* extension, extension_misc::LaunchContainer container, const GURL& override_url, - WindowOpenDisposition disposition) { + WindowOpenDisposition disposition, + const CommandLine* command_line) { WebContents* tab = NULL; ExtensionPrefs* prefs = profile->GetExtensionService()->extension_prefs(); prefs->SetActiveBit(extension->id(), true); @@ -93,7 +95,7 @@ WebContents* OpenApplication(Profile* profile, #endif if (extension->is_platform_app()) { - extensions::AppEventRouter::DispatchOnLaunchedEvent(profile, extension); + extensions::LaunchPlatformApp(profile, extension, command_line); return NULL; } diff --git a/chrome/browser/ui/extensions/application_launch.h b/chrome/browser/ui/extensions/application_launch.h index 7bb3dcc..5b9627a 100644 --- a/chrome/browser/ui/extensions/application_launch.h +++ b/chrome/browser/ui/extensions/application_launch.h @@ -10,6 +10,7 @@ #include "webkit/glue/window_open_disposition.h" class Browser; +class CommandLine; class GURL; class Profile; @@ -25,12 +26,17 @@ namespace application_launch { // Open |extension| in |container|, using |disposition| if container type is // TAB. Returns the WebContents* that was created or NULL. If non-empty, -// |override_url| is used in place of the app launch url. +// |override_url| is used in place of the app launch url. Pass relevant +// information in |command_line| onto platform app as launch data. +// |command_line| can be NULL, indicating there is no launch data to pass on. +// TODO(benwells): Put the parameters to this into an ApplicationLaunchParams +// struct. content::WebContents* OpenApplication(Profile* profile, const extensions::Extension* extension, extension_misc::LaunchContainer container, const GURL& override_url, - WindowOpenDisposition disposition); + WindowOpenDisposition disposition, + const CommandLine* command_line); #if defined(USE_ASH) // Opens |url| in a new application panel window for the specified url. diff --git a/chrome/browser/ui/panels/panel_app_browsertest.cc b/chrome/browser/ui/panels/panel_app_browsertest.cc index f62d4a3..93b76f5 100644 --- a/chrome/browser/ui/panels/panel_app_browsertest.cc +++ b/chrome/browser/ui/panels/panel_app_browsertest.cc @@ -55,7 +55,8 @@ class PanelAppBrowserTest : public ExtensionBrowserTest { // Overriding manifest to open in a panel. extension_misc::LAUNCH_PANEL, GURL(), - NEW_WINDOW); + NEW_WINDOW, + NULL); // Now we have a new browser instance. EXPECT_EQ(browser_count + 1, BrowserList::size()); diff --git a/chrome/browser/ui/startup/startup_browser_creator_impl.cc b/chrome/browser/ui/startup/startup_browser_creator_impl.cc index 34e7e3a..5d94e6b 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_impl.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_impl.cc @@ -427,7 +427,8 @@ bool StartupBrowserCreatorImpl::OpenApplicationWindow(Profile* profile) { RecordCmdLineAppHistogram(); WebContents* tab_in_app_window = application_launch::OpenApplication( - profile, extension, launch_container, GURL(), NEW_WINDOW); + profile, extension, launch_container, GURL(), NEW_WINDOW, + &command_line_); // Platform apps fire off a launch event which may or may not open a window. return (tab_in_app_window != NULL || extension->is_platform_app()); } diff --git a/chrome/browser/ui/views/ash/extension_utils.cc b/chrome/browser/ui/views/ash/extension_utils.cc index 586d11e..b0f6c69 100644 --- a/chrome/browser/ui/views/ash/extension_utils.cc +++ b/chrome/browser/ui/views/ash/extension_utils.cc @@ -32,12 +32,12 @@ void OpenExtension(Profile* profile, if (disposition == NEW_FOREGROUND_TAB || disposition == NEW_BACKGROUND_TAB) { // Opens in a tab. application_launch::OpenApplication( - profile, extension, extension_misc::LAUNCH_TAB, url, disposition); + profile, extension, extension_misc::LAUNCH_TAB, url, disposition, NULL); } else if (disposition == NEW_WINDOW) { // Force a new window open. application_launch::OpenApplication( profile, extension, extension_misc::LAUNCH_WINDOW, url, - disposition); + disposition, NULL); } else { // Look at preference to find the right launch container. If no preference // is set, launch as a regular tab. @@ -47,7 +47,7 @@ void OpenExtension(Profile* profile, application_launch::OpenApplication( profile, extension, launch_container, GURL(url), - NEW_FOREGROUND_TAB); + NEW_FOREGROUND_TAB, NULL); } } diff --git a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc index 7cf5db8..212b64f 100644 --- a/chrome/browser/ui/webui/ntp/app_launcher_handler.cc +++ b/chrome/browser/ui/webui/ntp/app_launcher_handler.cc @@ -545,12 +545,13 @@ void AppLauncherHandler::HandleLaunchApp(const ListValue* args) { if (disposition == NEW_FOREGROUND_TAB || disposition == NEW_BACKGROUND_TAB) { // TODO(jamescook): Proper support for background tabs. application_launch::OpenApplication( - profile, extension, extension_misc::LAUNCH_TAB, GURL(url), disposition); + profile, extension, extension_misc::LAUNCH_TAB, GURL(url), disposition, + NULL); } else if (disposition == NEW_WINDOW) { // Force a new window open. application_launch::OpenApplication( profile, extension, extension_misc::LAUNCH_WINDOW, GURL(url), - disposition); + disposition, NULL); } else { // Look at preference to find the right launch container. If no preference // is set, launch as a regular tab. @@ -567,7 +568,7 @@ void AppLauncherHandler::HandleLaunchApp(const ListValue* args) { WebContents* new_contents = application_launch::OpenApplication( profile, extension, launch_container, GURL(url), - old_contents ? CURRENT_TAB : NEW_FOREGROUND_TAB); + old_contents ? CURRENT_TAB : NEW_FOREGROUND_TAB, NULL); // This will also destroy the handler, so do not perform any actions after. if (new_contents != old_contents && browser && browser->tab_count() > 1) diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi index 6f83d81..cde56c6 100644 --- a/chrome/chrome_browser_extensions.gypi +++ b/chrome/chrome_browser_extensions.gypi @@ -407,6 +407,8 @@ 'browser/extensions/pack_extension_job.h', 'browser/extensions/page_action_controller.cc', 'browser/extensions/page_action_controller.h', + 'browser/extensions/platform_app_launcher.cc', + 'browser/extensions/platform_app_launcher.h', 'browser/extensions/pending_extension_info.cc', 'browser/extensions/pending_extension_info.h', 'browser/extensions/pending_extension_manager.cc', diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi index 6a5b1e1..58a9b7b 100644 --- a/chrome/chrome_renderer.gypi +++ b/chrome/chrome_renderer.gypi @@ -78,6 +78,8 @@ 'renderer/extensions/context_menus_custom_bindings.h', 'renderer/extensions/event_bindings.cc', 'renderer/extensions/event_bindings.h', + 'renderer/extensions/experimental.app_custom_bindings.cc', + 'renderer/extensions/experimental.app_custom_bindings.h', 'renderer/extensions/experimental.usb_custom_bindings.cc', 'renderer/extensions/experimental.usb_custom_bindings.h', 'renderer/extensions/extension_custom_bindings.cc', diff --git a/chrome/common/extensions/api/experimental_app.json b/chrome/common/extensions/api/experimental_app.json index a169fe5..0eeb43a 100644 --- a/chrome/common/extensions/api/experimental_app.json +++ b/chrome/common/extensions/api/experimental_app.json @@ -83,7 +83,47 @@ "nodoc": true, "name": "onLaunched", "type": "function", - "description": "Fired when the app is launched." + "description": "Fired when the app is launched.", + "parameters": [ + { + "type": "object", + "name": "launchData", + "description": "Optional data for the launch.", + "optional": true, + "properties": { + "intent": { + "type": "object", + "description": "File being opened in the form of a WebIntents intent object.", + "properties": { + "action": { + "type": "string", + "description": "The WebIntent being invoked." + }, + "type": { + "type": "string", + "description": "The MIME type of the file being opened." + }, + "data": { + "type": "object", + "isInstanceOf": "FileEntry", + "description": "A FileEntry for the file being opened.", + "additionalProperties": { + "type": "any" + } + }, + "postResult": { + "type": "function", + "description": "Null callback to be compatible with WebIntents." + }, + "postFailure": { + "type": "function", + "description": "Null callback to be compatible with WebIntents." + } + } + } + } + } + ] } ] } diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc index bd79d1c..477764f 100644 --- a/chrome/common/extensions/extension.cc +++ b/chrome/common/extensions/extension.cc @@ -1790,13 +1790,13 @@ bool Extension::LoadWebIntentAction(const std::string& action_name, if (href.empty()) { if (is_hosted_app()) { href = launch_web_url(); - } else if (is_packaged_app() || is_platform_app()) { + } else if (is_packaged_app()) { href = launch_local_path(); } } // If we still don't have an href, the manifest is malformed. - if (href.empty()) { + if (href.empty() && !is_platform_app()) { *error = ExtensionErrorUtils::FormatErrorMessageUTF16( errors::kInvalidIntentHrefEmpty, action_name); return false; @@ -1812,7 +1812,7 @@ bool Extension::LoadWebIntentAction(const std::string& action_name, return false; } service.service_url = service_url; - } else { + } else if (!is_platform_app()) { // We do not allow absolute intent URLs in non-hosted apps. if (service_url.is_valid()) { *error = ExtensionErrorUtils::FormatErrorMessageUTF16( diff --git a/chrome/renderer/extensions/experimental.app_custom_bindings.cc b/chrome/renderer/extensions/experimental.app_custom_bindings.cc new file mode 100644 index 0000000..683f883 --- /dev/null +++ b/chrome/renderer/extensions/experimental.app_custom_bindings.cc @@ -0,0 +1,57 @@ +// Copyright (c) 2012 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/renderer/extensions/experimental.app_custom_bindings.h" + +#include <string> + +#include "base/basictypes.h" +#include "base/logging.h" +#include "chrome/common/url_constants.h" +#include "chrome/renderer/extensions/user_script_slave.h" +#include "grit/renderer_resources.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebFileSystem.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" +#include "webkit/fileapi/file_system_types.h" +#include "webkit/fileapi/file_system_util.h" + +namespace { + +static v8::Handle<v8::Value> GetIsolatedFileSystem( + const v8::Arguments& args) { + DCHECK(args.Length() == 1); + DCHECK(args[0]->IsString()); + std::string file_system_id(*v8::String::Utf8Value(args[0])); + WebKit::WebFrame* webframe = WebKit::WebFrame::frameForCurrentContext(); + DCHECK(webframe); + + GURL context_url = UserScriptSlave::GetDataSourceURLForFrame(webframe); + CHECK(context_url.SchemeIs(chrome::kExtensionScheme)); + + std::string name(fileapi::GetFileSystemName(context_url.GetOrigin(), + fileapi::kFileSystemTypeIsolated)); + name.append(file_system_id); + + std::string root(fileapi::GetFileSystemRootURI(context_url.GetOrigin(), + fileapi::kFileSystemTypeIsolated).spec()); + root.append(file_system_id); + root.append("/"); + + return webframe->createFileSystem( + WebKit::WebFileSystem::TypeIsolated, + WebKit::WebString::fromUTF8(name.c_str()), + WebKit::WebString::fromUTF8(root.c_str())); +} + +} // namespace + +namespace extensions { + +ExperimentalAppCustomBindings::ExperimentalAppCustomBindings() + : ChromeV8Extension(NULL) { + RouteStaticFunction("GetIsolatedFileSystem", &GetIsolatedFileSystem); +} + +} // namespace extensions diff --git a/chrome/renderer/extensions/experimental.app_custom_bindings.h b/chrome/renderer/extensions/experimental.app_custom_bindings.h new file mode 100644 index 0000000..aa11c49a --- /dev/null +++ b/chrome/renderer/extensions/experimental.app_custom_bindings.h @@ -0,0 +1,25 @@ +// Copyright (c) 2012 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_RENDERER_EXTENSIONS_EXPERIMENTAL_APP_CUSTOM_BINDINGS_H_ +#define CHROME_RENDERER_EXTENSIONS_EXPERIMENTAL_APP_CUSTOM_BINDINGS_H_ +#pragma once + +#include "base/compiler_specific.h" +#include "chrome/renderer/extensions/chrome_v8_extension.h" + +namespace extensions { + +// Custom bindings for the nativeFileSystem API. +class ExperimentalAppCustomBindings : public ChromeV8Extension { + public: + ExperimentalAppCustomBindings(); + + private: + DISALLOW_COPY_AND_ASSIGN(ExperimentalAppCustomBindings); +}; + +} // namespace extensions + +#endif // CHROME_RENDERER_EXTENSIONS_EXPERIMENTAL_APP_CUSTOM_BINDINGS_H_ diff --git a/chrome/renderer/extensions/extension_dispatcher.cc b/chrome/renderer/extensions/extension_dispatcher.cc index 9895b8a..8226de8 100644 --- a/chrome/renderer/extensions/extension_dispatcher.cc +++ b/chrome/renderer/extensions/extension_dispatcher.cc @@ -25,6 +25,7 @@ #include "chrome/renderer/extensions/chrome_v8_extension.h" #include "chrome/renderer/extensions/context_menus_custom_bindings.h" #include "chrome/renderer/extensions/event_bindings.h" +#include "chrome/renderer/extensions/experimental.app_custom_bindings.h" #include "chrome/renderer/extensions/experimental.usb_custom_bindings.h" #include "chrome/renderer/extensions/extension_custom_bindings.h" #include "chrome/renderer/extensions/extension_groups.h" @@ -75,6 +76,7 @@ using extensions::ApiDefinitionsNatives; using extensions::AppWindowCustomBindings; using extensions::ContextMenusCustomBindings; using extensions::Extension; +using extensions::ExperimentalAppCustomBindings; using extensions::ExperimentalUsbCustomBindings; using extensions::ExtensionAPI; using extensions::ExtensionCustomBindings; @@ -503,6 +505,8 @@ void ExtensionDispatcher::RegisterNativeHandlers(ModuleSystem* module_system, new ExtensionCustomBindings(this))); module_system->RegisterNativeHandler("experimental_mediaGalleries", scoped_ptr<NativeHandler>(new MediaGalleryCustomBindings())); + module_system->RegisterNativeHandler("experimental_app", + scoped_ptr<NativeHandler>(new ExperimentalAppCustomBindings())); module_system->RegisterNativeHandler("experimental_usb", scoped_ptr<NativeHandler>(new ExperimentalUsbCustomBindings())); module_system->RegisterNativeHandler("file_browser_handler", @@ -552,6 +556,8 @@ void ExtensionDispatcher::PopulateSourceMap() { source_map_.RegisterSource("declarativeWebRequest", IDR_DECLARATIVE_WEBREQUEST_CUSTOM_BINDINGS_JS); source_map_.RegisterSource("devtools", IDR_DEVTOOLS_CUSTOM_BINDINGS_JS); + source_map_.RegisterSource("experimental.app", + IDR_EXPERIMENTAL_APP_CUSTOM_BINDINGS_JS); source_map_.RegisterSource("experimental.mediaGalleries", IDR_MEDIA_GALLERY_CUSTOM_BINDINGS_JS); source_map_.RegisterSource("experimental.offscreen", diff --git a/chrome/renderer/renderer_resources.grd b/chrome/renderer/renderer_resources.grd index 5699b6a..1edc9ec 100644 --- a/chrome/renderer/renderer_resources.grd +++ b/chrome/renderer/renderer_resources.grd @@ -43,6 +43,7 @@ without changes to the corresponding grd file. fb9 --> <include name="IDR_CONTEXT_MENUS_CUSTOM_BINDINGS_JS" file="resources\extensions\context_menus_custom_bindings.js" type="BINDATA" /> <include name="IDR_DECLARATIVE_WEBREQUEST_CUSTOM_BINDINGS_JS" file="resources\extensions\declarative_webrequest_custom_bindings.js" type="BINDATA" /> <include name="IDR_DEVTOOLS_CUSTOM_BINDINGS_JS" file="resources\extensions\devtools_custom_bindings.js" type="BINDATA" /> + <include name="IDR_EXPERIMENTAL_APP_CUSTOM_BINDINGS_JS" file="resources\extensions\experimental.app_custom_bindings.js" type="BINDATA" /> <include name="IDR_EXPERIMENTAL_OFFSCREENTABS_CUSTOM_BINDINGS_JS" file="resources\extensions\experimental.offscreenTabs_custom_bindings.js" type="BINDATA" /> <include name="IDR_EXPERIMENTAL_USB_CUSTOM_BINDINGS_JS" file="resources\extensions\experimental.usb_custom_bindings.js" type="BINDATA" /> <include name="IDR_EXTENSION_CUSTOM_BINDINGS_JS" file="resources\extensions\extension_custom_bindings.js" type="BINDATA" /> diff --git a/chrome/renderer/resources/extensions/experimental.app_custom_bindings.js b/chrome/renderer/resources/extensions/experimental.app_custom_bindings.js new file mode 100644 index 0000000..575ca47 --- /dev/null +++ b/chrome/renderer/resources/extensions/experimental.app_custom_bindings.js @@ -0,0 +1,35 @@ +// Copyright (c) 2012 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. + +// Custom bindings for the experimental.app API. + +var chromeHidden = requireNative('chrome_hidden').GetChromeHidden(); +var experimentalAppNatives = requireNative('experimental_app'); +var GetIsolatedFileSystem = experimentalAppNatives.GetIsolatedFileSystem; + +chromeHidden.registerCustomHook('experimental.app', function(bindingsAPI) { + chrome.experimental.app.onLaunched.dispatch = + function(launchData, fileSystemId, baseName) { + if (launchData) { + event = this; + fs = GetIsolatedFileSystem(fileSystemId); + try { + fs.root.getFile(baseName, {}, function(fileEntry) { + launchData.intent.data = fileEntry; + launchData.intent.postResult = function() {}; + launchData.intent.postFailure = function() {}; + chrome.Event.prototype.dispatch.call(event, launchData); + }, function(fileError) { + console.error('Error getting fileEntry, code: ' + fileError.code); + chrome.Event.prototype.dispatch.call(event); + }); + } catch (e) { + console.error('Error in event handler for onLaunched: ' + e.stack); + chrome.Event.prototype.dispatch.call(event); + } + } else { + chrome.Event.prototype.dispatch.call(this); + } + }; +}); diff --git a/chrome/test/data/extensions/platform_apps/launch_file/manifest.json b/chrome/test/data/extensions/platform_apps/launch_file/manifest.json new file mode 100644 index 0000000..2f31fff --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/launch_file/manifest.json @@ -0,0 +1,18 @@ +{ + "name": "Platform App Launch Test", + "platform_app": true, + "version": "1", + "manifest_version": 2, + "intents": { + "http://webintents.org/view": { + "type": [ + "text/*" + ], + "title": "Test editor" + } + }, + "permissions": ["experimental"], + "background": { + "scripts": ["test.js"] + } +} diff --git a/chrome/test/data/extensions/platform_apps/launch_file/test.js b/chrome/test/data/extensions/platform_apps/launch_file/test.js new file mode 100644 index 0000000..210234e --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/launch_file/test.js @@ -0,0 +1,35 @@ +// Copyright (c) 2012 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. + +// Test that there is a launchData.intent, it is set up proerly, and that the +// FileEntry in launchData.intent.data can be read. +function onLaunched(launchData) { + chrome.test.runTests([ + function testIntent() { + chrome.test.assertFalse(!launchData, "No launchData"); + chrome.test.assertFalse(!launchData.intent, "No launchData.intent"); + chrome.test.assertEq(launchData.intent.action, + "http://webintents.org/view"); + chrome.test.assertEq(launchData.intent.type, + "chrome-extension://fileentry"); + chrome.test.assertFalse(!launchData.intent.data, + "No launchData.intent.data"); + + launchData.intent.data.file(function(file) { + var reader = new FileReader(); + reader.onloadend = function(e) { + chrome.test.assertEq( + reader.result.indexOf("This is a test. Word."), 0); + chrome.test.succeed(); + }; + reader.onerror = function(e) { + chrome.test.fail("Error reading file contents."); + }; + reader.readAsText(file); + }); + } + ]); +} + +chrome.experimental.app.onLaunched.addListener(onLaunched); diff --git a/chrome/test/data/extensions/platform_apps/launch_files/test.txt b/chrome/test/data/extensions/platform_apps/launch_files/test.txt new file mode 100644 index 0000000..9a0b99f --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/launch_files/test.txt @@ -0,0 +1,2 @@ +This is a test. Word. + diff --git a/chrome/test/data/extensions/platform_apps/launch_files/test.unknownextension b/chrome/test/data/extensions/platform_apps/launch_files/test.unknownextension new file mode 100644 index 0000000..9a0b99f --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/launch_files/test.unknownextension @@ -0,0 +1,2 @@ +This is a test. Word. + diff --git a/chrome/test/data/extensions/platform_apps/launch_invalid/manifest.json b/chrome/test/data/extensions/platform_apps/launch_invalid/manifest.json new file mode 100644 index 0000000..2f31fff --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/launch_invalid/manifest.json @@ -0,0 +1,18 @@ +{ + "name": "Platform App Launch Test", + "platform_app": true, + "version": "1", + "manifest_version": 2, + "intents": { + "http://webintents.org/view": { + "type": [ + "text/*" + ], + "title": "Test editor" + } + }, + "permissions": ["experimental"], + "background": { + "scripts": ["test.js"] + } +} diff --git a/chrome/test/data/extensions/platform_apps/launch_invalid/test.js b/chrome/test/data/extensions/platform_apps/launch_invalid/test.js new file mode 100644 index 0000000..4ec872a --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/launch_invalid/test.js @@ -0,0 +1,15 @@ +// Copyright (c) 2012 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. + +// Check that there is no launch data. +function onLaunched(launchData) { + chrome.test.runTests([ + function testIntent() { + chrome.test.assertTrue(!launchData, "LaunchData found"); + chrome.test.succeed(); + } + ]); +} + +chrome.experimental.app.onLaunched.addListener(onLaunched); diff --git a/chrome/test/data/extensions/platform_apps/launch_no_intent/manifest.json b/chrome/test/data/extensions/platform_apps/launch_no_intent/manifest.json new file mode 100644 index 0000000..084addf --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/launch_no_intent/manifest.json @@ -0,0 +1,10 @@ +{ + "name": "Platform App Launch Test", + "platform_app": true, + "version": "1", + "manifest_version": 2, + "permissions": ["experimental"], + "background": { + "scripts": ["test.js"] + } +} diff --git a/chrome/test/data/extensions/platform_apps/launch_no_intent/test.js b/chrome/test/data/extensions/platform_apps/launch_no_intent/test.js new file mode 100644 index 0000000..4ec872a --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/launch_no_intent/test.js @@ -0,0 +1,15 @@ +// Copyright (c) 2012 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. + +// Check that there is no launch data. +function onLaunched(launchData) { + chrome.test.runTests([ + function testIntent() { + chrome.test.assertTrue(!launchData, "LaunchData found"); + chrome.test.succeed(); + } + ]); +} + +chrome.experimental.app.onLaunched.addListener(onLaunched); diff --git a/chrome/test/data/extensions/platform_apps/launch_nothing/manifest.json b/chrome/test/data/extensions/platform_apps/launch_nothing/manifest.json new file mode 100644 index 0000000..2f31fff --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/launch_nothing/manifest.json @@ -0,0 +1,18 @@ +{ + "name": "Platform App Launch Test", + "platform_app": true, + "version": "1", + "manifest_version": 2, + "intents": { + "http://webintents.org/view": { + "type": [ + "text/*" + ], + "title": "Test editor" + } + }, + "permissions": ["experimental"], + "background": { + "scripts": ["test.js"] + } +} diff --git a/chrome/test/data/extensions/platform_apps/launch_nothing/test.js b/chrome/test/data/extensions/platform_apps/launch_nothing/test.js new file mode 100644 index 0000000..9f9f30f --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/launch_nothing/test.js @@ -0,0 +1,15 @@ +// Copyright (c) 2012 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. + +// Check that there is no launchData. +function onLaunched(launchData) { + chrome.test.runTests([ + function testIntent() { + chrome.test.assertTrue(!launchData, "LaunchData found"); + chrome.test.succeed(); + } + ]); +} + +chrome.experimental.app.onLaunched.addListener(onLaunched); diff --git a/chrome/test/data/extensions/platform_apps/launch_wrong_intent/manifest.json b/chrome/test/data/extensions/platform_apps/launch_wrong_intent/manifest.json new file mode 100644 index 0000000..91e2ea7 --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/launch_wrong_intent/manifest.json @@ -0,0 +1,18 @@ +{ + "name": "Platform App Launch Test", + "platform_app": true, + "version": "1", + "manifest_version": 2, + "intents": { + "http://webintents.org/share": { + "type": [ + "text/*" + ], + "title": "Test editor" + } + }, + "permissions": ["experimental"], + "background": { + "scripts": ["test.js"] + } +} diff --git a/chrome/test/data/extensions/platform_apps/launch_wrong_intent/test.js b/chrome/test/data/extensions/platform_apps/launch_wrong_intent/test.js new file mode 100644 index 0000000..4ec872a --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/launch_wrong_intent/test.js @@ -0,0 +1,15 @@ +// Copyright (c) 2012 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. + +// Check that there is no launch data. +function onLaunched(launchData) { + chrome.test.runTests([ + function testIntent() { + chrome.test.assertTrue(!launchData, "LaunchData found"); + chrome.test.succeed(); + } + ]); +} + +chrome.experimental.app.onLaunched.addListener(onLaunched); diff --git a/chrome/test/data/extensions/platform_apps/launch_wrong_type/manifest.json b/chrome/test/data/extensions/platform_apps/launch_wrong_type/manifest.json new file mode 100644 index 0000000..d29492a --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/launch_wrong_type/manifest.json @@ -0,0 +1,18 @@ +{ + "name": "Platform App Launch Test", + "platform_app": true, + "version": "1", + "manifest_version": 2, + "intents": { + "http://webintents.org/view": { + "type": [ + "image/*" + ], + "title": "Test editor" + } + }, + "permissions": ["experimental"], + "background": { + "scripts": ["test.js"] + } +} diff --git a/chrome/test/data/extensions/platform_apps/launch_wrong_type/test.js b/chrome/test/data/extensions/platform_apps/launch_wrong_type/test.js new file mode 100644 index 0000000..4ec872a --- /dev/null +++ b/chrome/test/data/extensions/platform_apps/launch_wrong_type/test.js @@ -0,0 +1,15 @@ +// Copyright (c) 2012 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. + +// Check that there is no launch data. +function onLaunched(launchData) { + chrome.test.runTests([ + function testIntent() { + chrome.test.assertTrue(!launchData, "LaunchData found"); + chrome.test.succeed(); + } + ]); +} + +chrome.experimental.app.onLaunched.addListener(onLaunched); |