Commit c0fe69d8 authored by Trent Apted's avatar Trent Apted Committed by Commit Bot

Reland "Hook up chrome://media-app as a file handler for image/*"

This is a reland of f8263a71

The earlier patch failed on the chromeos MSan bot only because that builder
uses include_js_tests = false, so was missing a transitive dep on
//chromeos/components/media_app_ui:browser_test_support .

Original change's description:
> Hook up chrome://media-app as a file handler for image/*
>
> Adds a consumer for window.launchQueue in chrome://media-app that
> opens the file and sends it to the existing loadBlob(), which sends
> the blob to the unprivileged guest app to load.
>
> Adds an integration test that ensures launch params passed via the
> AppService OpenApplication() will correctly open an image in the media
> app.
>
> SystemWebAppManagerBrowserTest is refactored away from extensions slightly.
> Rather than use extensions::browsertest_util::LaunchAppBrowser(), it uses
> LaunchService::OpenApplication(AppLaunchParams) directly. Mostly this just
> avoids having to fetch the Extension* only to use extension->id() to get the
> app_id back again.
>
> Bug: 996088, 1023742
> Change-Id: I85624e93618d82ccce1c80d04d21d81303579a99
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1913282
> Reviewed-by: Xiyuan Xia <xiyuan@chromium.org>
> Reviewed-by: Giovanni Ortuño Urquidi <ortuno@chromium.org>
> Commit-Queue: Trent Apted <tapted@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#720681}

TBR=ortuno@chromium.org

Bug: 996088, 1023742
Fixed: 1030105
Change-Id: Ifb0c66efccf0411c8bd9766e17ac61676a6a4ea3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1947604
Commit-Queue: Trent Apted <tapted@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarTrent Apted <tapted@chromium.org>
Cr-Commit-Position: refs/heads/master@{#720805}
parent 2bd736b9
tapted@chromium.org
dstockwell@chromium.org
bugsnash@chromium.org
ortuno@chromium.org
# TEAM: cros-essential-apps-dev@chromium.org
# COMPONENT: Platform>Apps>SystemWebApps
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/chromeos/web_applications/system_web_app_integration_test.h"
#include "chrome/browser/web_applications/system_web_app_manager.h"
#include "chromeos/components/help_app_ui/url_constants.h"
#include "chromeos/constants/chromeos_features.h"
#include "testing/gtest/include/gtest/gtest.h"
class HelpAppIntegrationTest : public SystemWebAppIntegrationTest {
public:
HelpAppIntegrationTest() {
scoped_feature_list_.InitWithFeatures({chromeos::features::kHelpAppV2}, {});
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
};
// Test that the Help App installs and launches correctly. Runs some spot
// checks on the manifest.
IN_PROC_BROWSER_TEST_F(HelpAppIntegrationTest, HelpAppV2) {
const GURL url(chromeos::kChromeUIHelpAppURL);
EXPECT_NO_FATAL_FAILURE(
ExpectSystemWebAppValid(web_app::SystemAppType::HELP, url, "Help App"));
}
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/apps/app_service/app_launch_params.h"
#include "chrome/browser/chromeos/web_applications/system_web_app_integration_test.h"
#include "chrome/browser/web_applications/system_web_app_manager.h"
#include "chrome/common/chrome_paths.h"
#include "chromeos/components/media_app_ui/test/media_app_ui_browsertest.h"
#include "chromeos/components/media_app_ui/url_constants.h"
#include "chromeos/constants/chromeos_features.h"
#include "content/public/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
using web_app::SystemAppType;
namespace {
// Path to a subfolder in chrome/test/data that holds test files.
constexpr base::FilePath::CharType kTestFilesFolderInTestData[] =
FILE_PATH_LITERAL("chromeos/file_manager");
// An 800x600 image/png (all blue pixels).
constexpr char kFilePng800x600[] = "image.png";
class MediaAppIntegrationTest : public SystemWebAppIntegrationTest {
public:
MediaAppIntegrationTest() {
scoped_feature_list_.InitWithFeatures({chromeos::features::kMediaApp}, {});
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
};
// Gets the base::FilePath for a named file in the test folder.
base::FilePath TestFile(const std::string& ascii_name) {
base::FilePath path;
EXPECT_TRUE(base::PathService::Get(chrome::DIR_TEST_DATA, &path));
path = path.Append(kTestFilesFolderInTestData);
path = path.AppendASCII(ascii_name);
base::ScopedAllowBlockingForTesting allow_blocking;
EXPECT_TRUE(base::PathExists(path));
return path;
}
// Runs |script| in the unprivileged app frame of |web_ui|.
content::EvalJsResult EvalJsInAppFrame(content::WebContents* web_ui,
const std::string& script) {
// Clients of this helper all run in the same isolated world.
constexpr int kWorldId = 1;
// GetAllFrames does a breadth-first traversal. Assume the first subframe
// is the app.
std::vector<content::RenderFrameHost*> frames = web_ui->GetAllFrames();
EXPECT_EQ(2u, frames.size());
content::RenderFrameHost* app_frame = frames[1];
EXPECT_TRUE(app_frame);
return EvalJs(app_frame, script, content::EXECUTE_SCRIPT_DEFAULT_OPTIONS,
kWorldId);
}
} // namespace
// Test that the Media App installs and launches correctly. Runs some spot
// checks on the manifest.
IN_PROC_BROWSER_TEST_F(MediaAppIntegrationTest, MediaApp) {
const GURL url(chromeos::kChromeUIMediaAppURL);
EXPECT_NO_FATAL_FAILURE(
ExpectSystemWebAppValid(web_app::SystemAppType::MEDIA, url, "Media App"));
}
// Test that the MediaApp successfully loads a file passed in on its launch
// params.
IN_PROC_BROWSER_TEST_F(MediaAppIntegrationTest, MediaAppLaunchWithFile) {
WaitForTestSystemAppInstall();
auto params = LaunchParamsForApp(web_app::SystemAppType::MEDIA);
// Add the 800x600 PNG image to launch params.
params.launch_files.push_back(TestFile(kFilePng800x600));
content::WebContents* app = LaunchApp(params);
EXPECT_TRUE(WaitForLoadStop(app));
EXPECT_EQ(nullptr,
EvalJsInAppFrame(app, MediaAppUiBrowserTest::AppJsTestLibrary()));
// Returns a promise that resolves with image dimensions, once an <img>
// element appears in the light DOM that is backed by a blob URL.
constexpr char kScript[] = R"(
(async () => {
const img = await waitForNode('img[src^="blob:"]');
return `${img.naturalWidth}x${img.naturalHeight}`;
})();
)";
EXPECT_EQ("800x600", EvalJsInAppFrame(app, kScript));
// TODO(crbug/1027030): Add tests for re-launching with new files.
}
// Copyright 2019 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/chromeos/web_applications/system_web_app_integration_test.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/web_applications/system_web_app_manager.h"
#include "content/public/browser/web_ui.h"
#include "content/public/test/test_navigation_observer.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/window.h"
SystemWebAppIntegrationTest::SystemWebAppIntegrationTest()
: SystemWebAppManagerBrowserTest(false /* install_mock */) {}
SystemWebAppIntegrationTest::~SystemWebAppIntegrationTest() = default;
void SystemWebAppIntegrationTest::ExpectSystemWebAppValid(
web_app::SystemAppType app_type,
const GURL& url,
const std::string& title) {
Browser* app_browser = WaitForSystemAppInstallAndLaunch(app_type);
const extensions::Extension* installed_app =
extensions::util::GetInstalledPwaForUrl(browser()->profile(), url);
EXPECT_TRUE(GetManager().IsSystemWebApp(installed_app->id()));
EXPECT_TRUE(installed_app->from_bookmark());
EXPECT_EQ(title, installed_app->name());
EXPECT_EQ(base::ASCIIToUTF16(title),
app_browser->window()->GetNativeWindow()->GetTitle());
EXPECT_EQ(extensions::Manifest::EXTERNAL_COMPONENT,
installed_app->location());
// The installed app should match the opened app window.
EXPECT_EQ(installed_app, GetExtensionForAppBrowser(app_browser));
content::WebContents* web_contents =
app_browser->tab_strip_model()->GetActiveWebContents();
// The opened window should be showing the url with attached WebUI.
EXPECT_EQ(url, web_contents->GetVisibleURL());
content::TestNavigationObserver observer(web_contents);
observer.WaitForNavigationFinished();
EXPECT_EQ(url, web_contents->GetLastCommittedURL());
content::WebUI* web_ui = web_contents->GetCommittedWebUI();
ASSERT_TRUE(web_ui);
EXPECT_TRUE(web_ui->GetController());
// A completed navigation could change the window title. Check again.
EXPECT_EQ(base::ASCIIToUTF16(title),
app_browser->window()->GetNativeWindow()->GetTitle());
}
// Copyright 2019 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_CHROMEOS_WEB_APPLICATIONS_SYSTEM_WEB_APP_INTEGRATION_TEST_H_
#define CHROME_BROWSER_CHROMEOS_WEB_APPLICATIONS_SYSTEM_WEB_APP_INTEGRATION_TEST_H_
#include <string>
#include "chrome/browser/web_applications/extensions/system_web_app_manager_browsertest.h"
#include "url/gurl.h"
namespace web_app {
enum class SystemAppType;
}
// Test harness for how ChromeOS System Web Apps integrate with the System Web
// App platform.
class SystemWebAppIntegrationTest
: public web_app::SystemWebAppManagerBrowserTest {
public:
SystemWebAppIntegrationTest();
~SystemWebAppIntegrationTest() override;
// Runs basic tests on a System Web App. E.g. ensures it exists, and
// loads/navigates with an expected title that matches the manifest app name.
void ExpectSystemWebAppValid(web_app::SystemAppType app_type,
const GURL& url,
const std::string& title);
};
#endif // CHROME_BROWSER_CHROMEOS_WEB_APPLICATIONS_SYSTEM_WEB_APP_INTEGRATION_TEST_H_
...@@ -84,7 +84,6 @@ source_set("browser_tests") { ...@@ -84,7 +84,6 @@ source_set("browser_tests") {
"bookmark_app_registrar_browsertest.cc", "bookmark_app_registrar_browsertest.cc",
"system_web_app_manager_browsertest.cc", "system_web_app_manager_browsertest.cc",
"system_web_app_manager_browsertest.h", "system_web_app_manager_browsertest.h",
"system_web_app_manager_browsertest_chromeos.cc",
"web_app_audio_focus_browsertest.cc", "web_app_audio_focus_browsertest.cc",
] ]
...@@ -109,12 +108,4 @@ source_set("browser_tests") { ...@@ -109,12 +108,4 @@ source_set("browser_tests") {
"//extensions/common", "//extensions/common",
"//net:test_support", "//net:test_support",
] ]
if (is_chromeos) {
deps += [
"//chromeos/components/help_app_ui",
"//chromeos/components/media_app_ui",
"//chromeos/constants",
]
}
} }
...@@ -14,9 +14,9 @@ ...@@ -14,9 +14,9 @@
#include "base/test/scoped_feature_list.h" #include "base/test/scoped_feature_list.h"
#include "chrome/browser/apps/app_service/app_launch_params.h" #include "chrome/browser/apps/app_service/app_launch_params.h"
#include "chrome/browser/apps/launch_service/launch_service.h" #include "chrome/browser/apps/launch_service/launch_service.h"
#include "chrome/browser/extensions/browsertest_util.h"
#include "chrome/browser/extensions/extension_browsertest.h" #include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_util.h" #include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/extensions/application_launch.h" #include "chrome/browser/ui/extensions/application_launch.h"
#include "chrome/browser/ui/extensions/hosted_app_browser_controller.h" #include "chrome/browser/ui/extensions/hosted_app_browser_controller.h"
#include "chrome/browser/web_applications/components/web_app_constants.h" #include "chrome/browser/web_applications/components/web_app_constants.h"
...@@ -211,18 +211,32 @@ void SystemWebAppManagerBrowserTest::WaitForTestSystemAppInstall() { ...@@ -211,18 +211,32 @@ void SystemWebAppManagerBrowserTest::WaitForTestSystemAppInstall() {
Browser* SystemWebAppManagerBrowserTest::WaitForSystemAppInstallAndLaunch( Browser* SystemWebAppManagerBrowserTest::WaitForSystemAppInstallAndLaunch(
SystemAppType system_app_type) { SystemAppType system_app_type) {
WaitForTestSystemAppInstall(); WaitForTestSystemAppInstall();
apps::AppLaunchParams params = LaunchParamsForApp(system_app_type);
content::WebContents* web_contents = LaunchApp(params);
Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
EXPECT_EQ(web_app::GetAppIdFromApplicationName(browser->app_name()),
params.app_id);
return browser;
}
apps::AppLaunchParams SystemWebAppManagerBrowserTest::LaunchParamsForApp(
SystemAppType system_app_type) {
base::Optional<AppId> app_id = base::Optional<AppId> app_id =
GetManager().GetAppIdForSystemApp(system_app_type); GetManager().GetAppIdForSystemApp(system_app_type);
DCHECK(app_id.has_value()); DCHECK(app_id.has_value());
return apps::AppLaunchParams(
*app_id, apps::mojom::LaunchContainer::kLaunchContainerWindow,
WindowOpenDisposition::CURRENT_TAB,
apps::mojom::AppLaunchSource::kSourceTest);
}
Profile* profile = browser()->profile(); content::WebContents* SystemWebAppManagerBrowserTest::LaunchApp(
const extensions::Extension* app = const apps::AppLaunchParams& params) {
extensions::ExtensionRegistry::Get(profile)->enabled_extensions().GetByID( // Use apps::LaunchService::OpenApplication() to get the most coverage. E.g.,
app_id.value()); // this is what is invoked by file_manager::file_tasks::ExecuteWebTask() on
DCHECK(app); // ChromeOS.
return apps::LaunchService::Get(browser()->profile())
return extensions::browsertest_util::LaunchAppBrowser(profile, app); ->OpenApplication(params);
} }
// Test that System Apps install correctly with a manifest. // Test that System Apps install correctly with a manifest.
...@@ -275,15 +289,8 @@ IN_PROC_BROWSER_TEST_F(SystemWebAppManagerBrowserTest, ...@@ -275,15 +289,8 @@ IN_PROC_BROWSER_TEST_F(SystemWebAppManagerBrowserTest,
IN_PROC_BROWSER_TEST_F(SystemWebAppManagerBrowserTest, IN_PROC_BROWSER_TEST_F(SystemWebAppManagerBrowserTest,
LaunchFilesForSystemWebApp) { LaunchFilesForSystemWebApp) {
WaitForTestSystemAppInstall(); WaitForTestSystemAppInstall();
apps::AppLaunchParams params = LaunchParamsForApp(SystemAppType::SETTINGS);
base::Optional<AppId> app_id = params.source = apps::mojom::AppLaunchSource::kSourceChromeInternal;
GetManager().GetAppIdForSystemApp(SystemAppType::SETTINGS);
ASSERT_TRUE(app_id.has_value());
apps::AppLaunchParams params(
app_id.value(), apps::mojom::LaunchContainer::kLaunchContainerWindow,
WindowOpenDisposition::NEW_WINDOW,
apps::mojom::AppLaunchSource::kSourceChromeInternal);
base::ScopedAllowBlockingForTesting allow_blocking; base::ScopedAllowBlockingForTesting allow_blocking;
base::ScopedTempDir temp_directory; base::ScopedTempDir temp_directory;
...@@ -292,11 +299,11 @@ IN_PROC_BROWSER_TEST_F(SystemWebAppManagerBrowserTest, ...@@ -292,11 +299,11 @@ IN_PROC_BROWSER_TEST_F(SystemWebAppManagerBrowserTest,
ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_directory.GetPath(), ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_directory.GetPath(),
&temp_file_path)); &temp_file_path));
params.launch_files = std::vector<base::FilePath>{temp_file_path}; params.launch_files = {temp_file_path};
const GURL& launch_url = WebAppProvider::Get(browser()->profile()) const GURL& launch_url = WebAppProvider::Get(browser()->profile())
->registrar() ->registrar()
.GetAppLaunchURL(app_id.value()); .GetAppLaunchURL(params.app_id);
content::TestNavigationObserver navigation_observer(launch_url); content::TestNavigationObserver navigation_observer(launch_url);
navigation_observer.StartWatchingNewWebContents(); navigation_observer.StartWatchingNewWebContents();
......
...@@ -15,6 +15,14 @@ ...@@ -15,6 +15,14 @@
class Browser; class Browser;
class KeyedService; class KeyedService;
namespace apps {
struct AppLaunchParams;
}
namespace content {
class WebContents;
}
namespace extensions { namespace extensions {
class Extension; class Extension;
} }
...@@ -45,8 +53,18 @@ class SystemWebAppManagerBrowserTest : public InProcessBrowserTest { ...@@ -45,8 +53,18 @@ class SystemWebAppManagerBrowserTest : public InProcessBrowserTest {
SystemWebAppManager& GetManager(); SystemWebAppManager& GetManager();
void WaitForTestSystemAppInstall(); void WaitForTestSystemAppInstall();
// Wait for system apps to install, then launch one. Returns the browser that
// contains it.
Browser* WaitForSystemAppInstallAndLaunch(SystemAppType system_app_type); Browser* WaitForSystemAppInstallAndLaunch(SystemAppType system_app_type);
// Creates a default AppLaunchParams for |system_app_type|. Launches a window.
// Uses kSourceTest as the AppLaunchSource.
apps::AppLaunchParams LaunchParamsForApp(SystemAppType system_app_type);
// Invokes OpenApplication() using the test's Profile.
content::WebContents* LaunchApp(const apps::AppLaunchParams& params);
private: private:
std::unique_ptr<KeyedService> CreateWebAppProvider(Profile* profile); std::unique_ptr<KeyedService> CreateWebAppProvider(Profile* profile);
......
// Copyright 2019 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/web_applications/extensions/system_web_app_manager_browsertest.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/web_applications/system_web_app_manager.h"
#include "chromeos/components/help_app_ui/url_constants.h"
#include "chromeos/components/media_app_ui/url_constants.h"
#include "chromeos/constants/chromeos_features.h"
#include "content/public/browser/web_ui.h"
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/test_utils.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/aura/window.h"
namespace web_app {
namespace {
class SystemWebAppManagerBrowserTestChromeos
: public SystemWebAppManagerBrowserTest {
public:
SystemWebAppManagerBrowserTestChromeos()
: SystemWebAppManagerBrowserTest(false /* install_mock */) {
scoped_feature_list_.InitWithFeatures(
{chromeos::features::kHelpAppV2, chromeos::features::kMediaApp}, {});
}
// Runs basic tests on a System Web App. E.g. ensures it exists, and
// loads/navigates with an expected title that matches the manifest app name.
void ExpectSystemWebAppValid(SystemAppType app_type,
const GURL& url,
const std::string& title) {
Browser* app_browser = WaitForSystemAppInstallAndLaunch(app_type);
const extensions::Extension* installed_app =
extensions::util::GetInstalledPwaForUrl(browser()->profile(), url);
EXPECT_TRUE(GetManager().IsSystemWebApp(installed_app->id()));
EXPECT_TRUE(installed_app->from_bookmark());
EXPECT_EQ(title, installed_app->name());
EXPECT_EQ(base::ASCIIToUTF16(title),
app_browser->window()->GetNativeWindow()->GetTitle());
EXPECT_EQ(extensions::Manifest::EXTERNAL_COMPONENT,
installed_app->location());
// The installed app should match the opened app window.
EXPECT_EQ(installed_app, GetExtensionForAppBrowser(app_browser));
content::WebContents* web_contents =
app_browser->tab_strip_model()->GetActiveWebContents();
// The opened window should be showing the url with attached WebUI.
EXPECT_EQ(url, web_contents->GetVisibleURL());
content::TestNavigationObserver observer(web_contents);
observer.WaitForNavigationFinished();
EXPECT_EQ(url, web_contents->GetLastCommittedURL());
content::WebUI* web_ui = web_contents->GetCommittedWebUI();
ASSERT_TRUE(web_ui);
EXPECT_TRUE(web_ui->GetController());
// A completed navigation could change the window title. Check again.
EXPECT_EQ(base::ASCIIToUTF16(title),
app_browser->window()->GetNativeWindow()->GetTitle());
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
};
} // namespace
// Test that the Media App installs and launches correctly. Runs some spot
// checks on the manifest.
IN_PROC_BROWSER_TEST_F(SystemWebAppManagerBrowserTestChromeos, MediaApp) {
const GURL* url = new GURL(chromeos::kChromeUIMediaAppURL);
EXPECT_NO_FATAL_FAILURE(
ExpectSystemWebAppValid(SystemAppType::MEDIA, *url, "Media App"));
}
// Test that the Help App installs and launches correctly. Runs some spot
// checks on the manifest.
IN_PROC_BROWSER_TEST_F(SystemWebAppManagerBrowserTestChromeos, HelpAppV2) {
const GURL* url = new GURL(chromeos::kChromeUIHelpAppURL);
EXPECT_NO_FATAL_FAILURE(
ExpectSystemWebAppValid(SystemAppType::HELP, *url, "Help App"));
}
} // namespace web_app
...@@ -1457,6 +1457,7 @@ if (!is_android) { ...@@ -1457,6 +1457,7 @@ if (!is_android) {
"//chrome/services/file_util/public/cpp:browser_tests", "//chrome/services/file_util/public/cpp:browser_tests",
"//chromeos:test_support", "//chromeos:test_support",
"//chromeos/components/drivefs:test_support", "//chromeos/components/drivefs:test_support",
"//chromeos/components/media_app_ui:browser_test_support",
"//chromeos/dbus:test_support", "//chromeos/dbus:test_support",
"//chromeos/dbus/services:test_support", "//chromeos/dbus/services:test_support",
"//chromeos/dbus/session_manager", "//chromeos/dbus/session_manager",
...@@ -2330,6 +2331,10 @@ if (!is_android) { ...@@ -2330,6 +2331,10 @@ if (!is_android) {
"../browser/chromeos/startup_settings_cache_browsertest.cc", "../browser/chromeos/startup_settings_cache_browsertest.cc",
"../browser/chromeos/system/device_disabling_browsertest.cc", "../browser/chromeos/system/device_disabling_browsertest.cc",
"../browser/chromeos/system/tray_accessibility_browsertest.cc", "../browser/chromeos/system/tray_accessibility_browsertest.cc",
"../browser/chromeos/web_applications/help_app_integration_browsertest.cc",
"../browser/chromeos/web_applications/media_app_integration_browsertest.cc",
"../browser/chromeos/web_applications/system_web_app_integration_test.cc",
"../browser/chromeos/web_applications/system_web_app_integration_test.h",
"../browser/download/notification/download_notification_browsertest.cc", "../browser/download/notification/download_notification_browsertest.cc",
"../browser/drive/drive_notification_manager_factory_browsertest.cc", "../browser/drive/drive_notification_manager_factory_browsertest.cc",
"../browser/extensions/api/certificate_provider/certificate_provider_apitest.cc", "../browser/extensions/api/certificate_provider/certificate_provider_apitest.cc",
......
...@@ -18,7 +18,10 @@ js_type_check("closure_compile") { ...@@ -18,7 +18,10 @@ js_type_check("closure_compile") {
} }
js_library("launch") { js_library("launch") {
externs_list = [ "dom_draft.externs.js" ] externs_list = [
"web_app_file_handling.externs.js",
"dom_draft.externs.js",
]
} }
js_library("receiver") { js_library("receiver") {
......
...@@ -28,3 +28,30 @@ async function loadBlob(blob) { ...@@ -28,3 +28,30 @@ async function loadBlob(blob) {
const buffer = await blob.arrayBuffer(); const buffer = await blob.arrayBuffer();
postToGuestWindow({'buffer': buffer, 'type': blob.type}); postToGuestWindow({'buffer': buffer, 'type': blob.type});
} }
/**
* Loads a file from a handle received via the fileHandling API.
*
* @param {FileSystemHandle} handle
*/
async function loadFileFromHandle(handle) {
if (!handle.isFile) {
return;
}
const fileHandle = /** @type{FileSystemFileHandle} */ (handle);
const file = await fileHandle.getFile();
loadBlob(file);
}
// Wait for 'load' (and not DOMContentLoaded) to ensure the subframe has been
// loaded and is ready to respond to postMessage.
window.addEventListener('load', () => {
window.launchQueue.setConsumer(params => {
if (!params || !params.files || params.files.length == 0) {
return;
}
loadFileFromHandle(params.files[0]);
});
});
// Copyright 2019 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.
/**
* @fileoverview @externs
* Externs for interfaces in //third_party/blink/renderer/modules/launch/*
* This file can be removed when upstreamed to the closure compiler.
*/
class FileSystemWriter {
/**
* @param {number} position
* @param {BufferSource|Blob|string} data
*/
async write(position, data) {}
/**
* @param {number} size
*/
async truncate(size) {}
async close() {}
}
/** @typedef {{writable: boolean}} */
var FileSystemHandlePermissionDescriptor;
class FileSystemHandle {
constructor() {
/** @type {boolean} */
this.isFile;
/** @type {boolean} */
this.isDirectory;
/** @type {string} */
this.name;
}
/**
* @param {FileSystemHandlePermissionDescriptor} descriptor
* @return {Promise<PermissionState>}
*/
queryPermission(descriptor) {}
/**
* @param {FileSystemHandlePermissionDescriptor} descriptor
* @return {Promise<PermissionState>}
*/
requestPermission(descriptor) {}
}
/** @typedef {{keepExistingData: boolean}} */
var FileSystemCreateWriterOptions;
class FileSystemFileHandle extends FileSystemHandle {
/**
* @param {?FileSystemCreateWriterOptions} opt_options
* @return {Promise<FileSystemWriter>}
*/
createWriter(opt_options) {}
/** @return {Promise<File>} */
getFile() {}
}
class LaunchParams {
constructor() {
/** @type{Array<FileSystemHandle>} */
this.files;
/** @type{Request} */
this.request;
}
}
/** @typedef function(LaunchParams) */
var LaunchConsumer;
class LaunchQueue {
/** @param{LaunchConsumer} consumer */
setConsumer(consumer) {}
}
/** @type {LaunchQueue} */
window.launchQueue;
...@@ -11,5 +11,16 @@ ...@@ -11,5 +11,16 @@
"sizes": "256x256", "sizes": "256x256",
"type": "image/png" "type": "image/png"
} }
] ],
"file_handler": {
"action": ".",
"files": [
{
"name": "Image File",
"accept": [
"image/*"
]
}
]
}
} }
...@@ -38,19 +38,11 @@ class MediaAppUiBrowserTest::TestCodeInjector ...@@ -38,19 +38,11 @@ class MediaAppUiBrowserTest::TestCodeInjector
GURL(chromeos::kChromeUIMediaAppGuestURL)) GURL(chromeos::kChromeUIMediaAppGuestURL))
return; return;
base::FilePath source_root;
ASSERT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &source_root));
const auto script_path = source_root.AppendASCII(kTestScriptPath);
base::ScopedAllowBlockingForTesting allow_blocking;
std::string injected_content;
ASSERT_TRUE(base::ReadFileToString(script_path, &injected_content));
auto* render_frame_host = navigation_handle->GetRenderFrameHost(); auto* render_frame_host = navigation_handle->GetRenderFrameHost();
// Use ExecuteScript(), not ExecJs(), because of Content Security Policy // Use ExecuteScript(), not ExecJs(), because of Content Security Policy
// directive: "script-src chrome://resources 'self'" // directive: "script-src chrome://resources 'self'"
ASSERT_TRUE(content::ExecuteScript(render_frame_host, injected_content)); ASSERT_TRUE(content::ExecuteScript(render_frame_host, AppJsTestLibrary()));
TestNavigationObserver::OnDidFinishNavigation(navigation_handle); TestNavigationObserver::OnDidFinishNavigation(navigation_handle);
} }
}; };
...@@ -59,6 +51,18 @@ MediaAppUiBrowserTest::MediaAppUiBrowserTest() = default; ...@@ -59,6 +51,18 @@ MediaAppUiBrowserTest::MediaAppUiBrowserTest() = default;
MediaAppUiBrowserTest::~MediaAppUiBrowserTest() = default; MediaAppUiBrowserTest::~MediaAppUiBrowserTest() = default;
// static
std::string MediaAppUiBrowserTest::AppJsTestLibrary() {
base::FilePath source_root;
EXPECT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &source_root));
const auto script_path = source_root.AppendASCII(kTestScriptPath);
base::ScopedAllowBlockingForTesting allow_blocking;
std::string injected_content;
EXPECT_TRUE(base::ReadFileToString(script_path, &injected_content));
return injected_content;
}
void MediaAppUiBrowserTest::SetUpOnMainThread() { void MediaAppUiBrowserTest::SetUpOnMainThread() {
injector_ = std::make_unique<TestCodeInjector>(); injector_ = std::make_unique<TestCodeInjector>();
MojoWebUIBrowserTest::SetUpOnMainThread(); MojoWebUIBrowserTest::SetUpOnMainThread();
......
...@@ -15,6 +15,10 @@ class MediaAppUiBrowserTest : public MojoWebUIBrowserTest { ...@@ -15,6 +15,10 @@ class MediaAppUiBrowserTest : public MojoWebUIBrowserTest {
MediaAppUiBrowserTest(); MediaAppUiBrowserTest();
~MediaAppUiBrowserTest() override; ~MediaAppUiBrowserTest() override;
// Returns the contents of the JavaScript library used to help test the
// MediaApp guest frame.
static std::string AppJsTestLibrary();
// MojoWebUIBrowserTest: // MojoWebUIBrowserTest:
void SetUpOnMainThread() override; void SetUpOnMainThread() override;
......
...@@ -37,7 +37,15 @@ var MediaAppUIBrowserTest = class extends testing.Test { ...@@ -37,7 +37,15 @@ var MediaAppUIBrowserTest = class extends testing.Test {
/** @override */ /** @override */
get featureList() { get featureList() {
return {enabled: ['chromeos::features::kMediaApp']}; // Note the error `Cannot read property 'setConsumer' of undefined"` will be
// raised if kFileHandlingAPI is omitted.
return {
enabled: [
'chromeos::features::kMediaApp',
'blink::features::kNativeFileSystemAPI',
'blink::features::kFileHandlingAPI'
]
};
} }
/** @override */ /** @override */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment