desktop-pwas: support reparenting into PWA windows
The code reparenting tabs was needlessly extensions specific.
[email protected]
[email protected]
Bug: 966288
Change-Id: I6e82e205c15018f52d028709b05ff59aac7bf8b8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1743299
Commit-Queue: Eric Willigers <[email protected]>
Reviewed-by: Alexey Baskakov <[email protected]>
Reviewed-by: Alan Cutter <[email protected]>
Reviewed-by: Michael Wasserman <[email protected]>
Cr-Commit-Position: refs/heads/master@{#687914}
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn
index ba41be2..b79b932d 100644
--- a/chrome/browser/ui/BUILD.gn
+++ b/chrome/browser/ui/BUILD.gn
@@ -3757,6 +3757,8 @@
"web_applications/web_app_dialog_utils.h",
"web_applications/web_app_launch_manager.cc",
"web_applications/web_app_launch_manager.h",
+ "web_applications/web_app_launch_utils.cc",
+ "web_applications/web_app_launch_utils.h",
"web_applications/web_app_metrics.cc",
"web_applications/web_app_metrics.h",
"web_applications/web_app_metrics_factory.cc",
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc
index 3b69230..e83107e5 100644
--- a/chrome/browser/ui/browser_command_controller.cc
+++ b/chrome/browser/ui/browser_command_controller.cc
@@ -38,12 +38,11 @@
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/chrome_pages.h"
-#include "chrome/browser/ui/extensions/application_launch.h"
-#include "chrome/browser/ui/extensions/hosted_app_browser_controller.h"
#include "chrome/browser/ui/page_info/page_info_dialog.h"
#include "chrome/browser/ui/singleton_tabs.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/web_applications/app_browser_controller.h"
+#include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
#include "chrome/browser/ui/webui/inspect_ui.h"
#include "chrome/common/content_restriction.h"
#include "chrome/common/pref_names.h"
@@ -458,7 +457,7 @@
break;
case IDC_OPEN_IN_PWA_WINDOW:
base::RecordAction(base::UserMetricsAction("OpenActiveTabInPwaWindow"));
- ReparentSecureActiveTabIntoPwaWindow(browser_);
+ web_app::ReparentWebAppForSecureActiveTab(browser_);
break;
#if defined(OS_CHROMEOS)
diff --git a/chrome/browser/ui/extensions/application_launch.cc b/chrome/browser/ui/extensions/application_launch.cc
index b5baf44..47f664ae 100644
--- a/chrome/browser/ui/extensions/application_launch.cc
+++ b/chrome/browser/ui/extensions/application_launch.cc
@@ -9,7 +9,6 @@
#include "apps/launcher.h"
#include "base/bind.h"
-#include "base/feature_list.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
#include "base/time/time.h"
@@ -32,7 +31,6 @@
#include "chrome/browser/ui/extensions/extension_enable_flow.h"
#include "chrome/browser/ui/extensions/extension_enable_flow_delegate.h"
#include "chrome/browser/ui/extensions/hosted_app_browser_controller.h"
-#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/web_applications/components/web_app_helpers.h"
#include "chrome/browser/web_applications/components/web_app_tab_helper.h"
#include "chrome/browser/web_launch/web_launch_files_helper.h"
@@ -344,26 +342,6 @@
return tab;
}
-Browser* ReparentWebContentsWithBrowserCreateParams(
- content::WebContents* contents,
- const Browser::CreateParams& browser_params) {
- Browser* source_browser = chrome::FindBrowserWithWebContents(contents);
- Browser* target_browser = Browser::Create(browser_params);
-
- TabStripModel* source_tabstrip = source_browser->tab_strip_model();
- // Avoid causing the existing browser window to close if this is the last tab
- // remaining.
- if (source_tabstrip->count() == 1)
- chrome::NewTab(source_browser);
- target_browser->tab_strip_model()->AppendWebContents(
- source_tabstrip->DetachWebContentsAt(
- source_tabstrip->GetIndexOfWebContents(contents)),
- true);
- target_browser->window()->Show();
-
- return target_browser;
-}
-
} // namespace
WebContents* OpenApplication(const AppLaunchParams& params) {
@@ -495,38 +473,3 @@
extensions::FeatureProvider::GetAPIFeature("app.runtime");
return feature && feature->IsAvailableToExtension(extension).is_available();
}
-
-Browser* ReparentWebContentsIntoAppBrowser(content::WebContents* contents,
- const std::string& app_id) {
- Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
- // Incognito tabs reparent correctly, but remain incognito without any
- // indication to the user, so disallow it.
- DCHECK(!profile->IsOffTheRecord());
- Browser::CreateParams browser_params(Browser::CreateParams::CreateForApp(
- web_app::GenerateApplicationNameFromAppId(app_id),
- true /* trusted_source */, gfx::Rect(), profile,
- true /* user_gesture */));
- return ReparentWebContentsWithBrowserCreateParams(contents, browser_params);
-}
-
-Browser* ReparentWebContentsForFocusMode(content::WebContents* contents) {
- DCHECK(base::FeatureList::IsEnabled(features::kFocusMode));
- Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
- // TODO(crbug.com/941577): Remove DCHECK when focus mode is permitted in guest
- // and incognito sessions.
- DCHECK(!profile->IsOffTheRecord());
- Browser::CreateParams browser_params(Browser::CreateParams::CreateForApp(
- web_app::GenerateApplicationNameForFocusMode(), true /* trusted_source */,
- gfx::Rect(), profile, true /* user_gesture */));
- browser_params.is_focus_mode = true;
- return ReparentWebContentsWithBrowserCreateParams(contents, browser_params);
-}
-
-Browser* ReparentSecureActiveTabIntoPwaWindow(Browser* browser) {
- const extensions::Extension* extension =
- extensions::util::GetPwaForSecureActiveTab(browser);
- if (!extension)
- return nullptr;
- return ReparentWebContentsIntoAppBrowser(
- browser->tab_strip_model()->GetActiveWebContents(), extension->id());
-}
diff --git a/chrome/browser/ui/extensions/application_launch.h b/chrome/browser/ui/extensions/application_launch.h
index 189e0cea..558b180 100644
--- a/chrome/browser/ui/extensions/application_launch.h
+++ b/chrome/browser/ui/extensions/application_launch.h
@@ -54,18 +54,4 @@
// chrome.app.runtime.onLaunched event.
bool CanLaunchViaEvent(const extensions::Extension* extension);
-// Reparents |contents| into a new app browser for |app_id|.
-// TODO(loyso): Move this util to ui/web_applications/ directory. It is
-// universal for any AppBrowserController.
-Browser* ReparentWebContentsIntoAppBrowser(content::WebContents* contents,
- const std::string& app_id);
-
-// Reparents contents to a new app browser when entering the Focus Mode.
-Browser* ReparentWebContentsForFocusMode(content::WebContents* contents);
-
-// Reparents the active tab into a new app browser for the PWA that has the
-// tab's URL in its scope. Does nothing if the tab is not secure or there is no
-// applicable PWA.
-Browser* ReparentSecureActiveTabIntoPwaWindow(Browser* browser);
-
#endif // CHROME_BROWSER_UI_EXTENSIONS_APPLICATION_LAUNCH_H_
diff --git a/chrome/browser/ui/extensions/application_launch_browsertest.cc b/chrome/browser/ui/extensions/application_launch_browsertest.cc
index 2d0fa5a..53f03db 100644
--- a/chrome/browser/ui/extensions/application_launch_browsertest.cc
+++ b/chrome/browser/ui/extensions/application_launch_browsertest.cc
@@ -5,7 +5,7 @@
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/ui/browser_tabstrip.h"
-#include "chrome/browser/ui/extensions/application_launch.h"
+#include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
#include "chrome/common/chrome_features.h"
#include "chrome/test/base/chrome_test_suite.h"
#include "chrome/test/base/test_launcher_utils.h"
@@ -31,8 +31,8 @@
const GURL url("http://aaa.com/empty.html");
ui_test_utils::NavigateToURL(browser(), url);
- Browser* app_browser =
- ReparentWebContentsForFocusMode(GetWebContentsForTab(browser(), 0));
+ Browser* app_browser = web_app::ReparentWebContentsForFocusMode(
+ GetWebContentsForTab(browser(), 0));
EXPECT_TRUE(app_browser->is_type_app());
EXPECT_NE(app_browser, browser());
@@ -57,8 +57,8 @@
EXPECT_FALSE(browser()->is_focus_mode());
ASSERT_EQ(3, browser()->tab_strip_model()->count());
- Browser* app_browser =
- ReparentWebContentsForFocusMode(GetWebContentsForTab(browser(), 1));
+ Browser* app_browser = web_app::ReparentWebContentsForFocusMode(
+ GetWebContentsForTab(browser(), 1));
EXPECT_TRUE(app_browser->is_type_app());
EXPECT_NE(app_browser, browser());
EXPECT_EQ(url, GetWebContentsForTab(app_browser, 0)->GetURL());
diff --git a/chrome/browser/ui/extensions/hosted_app_browsertest.cc b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
index 0af72f5..bbec492 100644
--- a/chrome/browser/ui/extensions/hosted_app_browsertest.cc
+++ b/chrome/browser/ui/extensions/hosted_app_browsertest.cc
@@ -40,13 +40,13 @@
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/extensions/app_launch_params.h"
-#include "chrome/browser/ui/extensions/application_launch.h"
#include "chrome/browser/ui/extensions/hosted_app_menu_model.h"
#include "chrome/browser/ui/page_info/page_info_dialog.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/toolbar/app_menu_model.h"
#include "chrome/browser/ui/web_applications/app_browser_controller.h"
#include "chrome/browser/ui/web_applications/web_app_dialog_utils.h"
+#include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
#include "chrome/browser/web_applications/components/web_app_constants.h"
#include "chrome/browser/web_applications/components/web_app_helpers.h"
#include "chrome/common/chrome_features.h"
@@ -537,7 +537,7 @@
}
// Tests that the WebContents of an app window launched using
-// ReparentWebContentsIntoAppBrowser has the correct prefs.
+// web_app::ReparentWebContentsIntoAppBrowser has the correct prefs.
IN_PROC_BROWSER_TEST_P(HostedAppTest, WebContentsPrefsReparentWebContents) {
SetupApp("https_app");
@@ -546,7 +546,7 @@
CheckWebContentsDoesNotHaveAppPrefs(current_tab);
Browser* app_browser =
- ReparentWebContentsIntoAppBrowser(current_tab, app_->id());
+ web_app::ReparentWebContentsIntoAppBrowser(current_tab, app_->id());
ASSERT_NE(browser(), app_browser);
CheckWebContentsHasAppPrefs(
@@ -1225,7 +1225,7 @@
// Tests that the command for OpenActiveTabInPwaWindow is available for secure
// pages in an app's scope.
-IN_PROC_BROWSER_TEST_P(SharedPWATest, ReparentSecureActiveTabIntoPwaWindow) {
+IN_PROC_BROWSER_TEST_P(SharedPWATest, ReparentWebAppForSecureActiveTab) {
ASSERT_TRUE(https_server()->Start());
ASSERT_TRUE(embedded_test_server()->Start());
@@ -1239,7 +1239,7 @@
EXPECT_EQ(GetAppMenuCommandState(IDC_OPEN_IN_PWA_WINDOW, browser()),
kEnabled);
- Browser* app_browser = ReparentSecureActiveTabIntoPwaWindow(browser());
+ Browser* app_browser = web_app::ReparentWebAppForSecureActiveTab(browser());
ASSERT_EQ(app_browser->app_controller()->GetAppId(), app_->id());
}
@@ -1252,7 +1252,7 @@
InstallSecurePWA();
NavigateToURLAndWait(browser(), GetSecureAppURL());
- Browser* app_browser = ReparentSecureActiveTabIntoPwaWindow(browser());
+ Browser* app_browser = web_app::ReparentWebAppForSecureActiveTab(browser());
ASSERT_EQ(app_browser->app_controller()->GetAppId(), app_->id());
ASSERT_TRUE(IsBrowserOpen(browser()));
@@ -1331,11 +1331,11 @@
CheckMixedContentLoaded(browser());
EXPECT_EQ(GetAppMenuCommandState(IDC_OPEN_IN_PWA_WINDOW, browser()),
kNotPresent);
- EXPECT_EQ(ReparentSecureActiveTabIntoPwaWindow(browser()), nullptr);
+ EXPECT_EQ(web_app::ReparentWebAppForSecureActiveTab(browser()), nullptr);
}
-// Tests that when calling ReparentWebContentsIntoAppBrowser, mixed content
-// cannot be loaded in the new app window.
+// Tests that when calling web_app::ReparentWebContentsIntoAppBrowser, mixed
+// content cannot be loaded in the new app window.
IN_PROC_BROWSER_TEST_P(HostedAppPWAOnlyTestWithAutoupgradesDisabled,
MixedContentReparentWebContentsIntoAppBrowser) {
ASSERT_TRUE(https_server()->Start());
@@ -1354,7 +1354,7 @@
kNotPresent);
Browser* app_browser =
- ReparentWebContentsIntoAppBrowser(tab_contents, app_->id());
+ web_app::ReparentWebContentsIntoAppBrowser(tab_contents, app_->id());
ASSERT_NE(app_browser, browser());
ASSERT_EQ(GetMixedContentAppURL(), app_browser->tab_strip_model()
@@ -1399,7 +1399,7 @@
NavigateToURLAndWait(browser(), GetSecureIFrameAppURL());
CheckMixedContentFailedToLoad(browser());
- app_browser_ = ReparentWebContentsIntoAppBrowser(
+ app_browser_ = web_app::ReparentWebContentsIntoAppBrowser(
browser()->tab_strip_model()->GetActiveWebContents(), app_->id());
CheckMixedContentFailedToLoad(app_browser_);
diff --git a/chrome/browser/ui/manifest_web_app_browsertest.cc b/chrome/browser/ui/manifest_web_app_browsertest.cc
index edc92df3..fed1acdb 100644
--- a/chrome/browser/ui/manifest_web_app_browsertest.cc
+++ b/chrome/browser/ui/manifest_web_app_browsertest.cc
@@ -9,8 +9,8 @@
#include "chrome/browser/extensions/extension_browsertest.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/browser_window.h"
-#include "chrome/browser/ui/extensions/application_launch.h"
#include "chrome/browser/ui/manifest_web_app_browser_controller.h"
+#include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
#include "chrome/common/chrome_features.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/test/browser_test_utils.h"
@@ -40,7 +40,7 @@
feature_list.InitAndEnableFeature(features::kFocusMode);
const GURL url("http://example.org/");
ui_test_utils::NavigateToURL(browser(), url);
- Browser* app_browser = ReparentWebContentsForFocusMode(
+ Browser* app_browser = web_app::ReparentWebContentsForFocusMode(
browser()->tab_strip_model()->GetWebContentsAt(0));
ASSERT_TRUE(app_browser->is_focus_mode());
ASSERT_FALSE(browser()->is_focus_mode());
@@ -58,7 +58,7 @@
IN_PROC_BROWSER_TEST_F(ManifestWebAppTest, MetricsTest) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(features::kFocusMode);
- Browser* app_browser = ReparentWebContentsForFocusMode(
+ Browser* app_browser = web_app::ReparentWebContentsForFocusMode(
browser()->tab_strip_model()->GetWebContentsAt(0));
const base::TimeDelta duration = base::TimeDelta::FromSeconds(5);
diff --git a/chrome/browser/ui/tabs/tab_strip_model.cc b/chrome/browser/ui/tabs/tab_strip_model.cc
index 57699df..9f1a114 100644
--- a/chrome/browser/ui/tabs/tab_strip_model.cc
+++ b/chrome/browser/ui/tabs/tab_strip_model.cc
@@ -28,13 +28,13 @@
#include "chrome/browser/send_tab_to_self/send_tab_to_self_util.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
-#include "chrome/browser/ui/extensions/application_launch.h"
#include "chrome/browser/ui/tabs/tab_group_id.h"
#include "chrome/browser/ui/tabs/tab_group_visual_data.h"
#include "chrome/browser/ui/tabs/tab_strip_model_delegate.h"
#include "chrome/browser/ui/tabs/tab_strip_model_order_controller.h"
#include "chrome/browser/ui/tabs/tab_utils.h"
#include "chrome/browser/ui/web_applications/web_app_dialog_utils.h"
+#include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
#include "chrome/browser/ui/web_contents_sizer.h"
#include "chrome/common/url_constants.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
@@ -1293,7 +1293,7 @@
base::RecordAction(UserMetricsAction("TabContextMenu_FocusMode"));
std::vector<int> indices = GetIndicesForCommand(context_index);
WebContents* contents = GetWebContentsAt(indices[0]);
- ReparentWebContentsForFocusMode(contents);
+ web_app::ReparentWebContentsForFocusMode(contents);
break;
}
diff --git a/chrome/browser/ui/toolbar/app_menu_model.cc b/chrome/browser/ui/toolbar/app_menu_model.cc
index 2ff10a67..ee9d26b 100644
--- a/chrome/browser/ui/toolbar/app_menu_model.cc
+++ b/chrome/browser/ui/toolbar/app_menu_model.cc
@@ -23,7 +23,6 @@
#include "chrome/browser/banners/app_banner_manager.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/defaults.h"
-#include "chrome/browser/extensions/extension_util.h"
#include "chrome/browser/media/router/media_router_feature.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/profiles/profile.h"
@@ -44,7 +43,9 @@
#include "chrome/browser/ui/toolbar/recent_tabs_sub_menu_model.h"
#include "chrome/browser/ui/toolbar/toolbar_actions_bar.h"
#include "chrome/browser/ui/ui_features.h"
+#include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
#include "chrome/browser/upgrade_detector/upgrade_detector.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
@@ -776,14 +777,17 @@
AddItemWithStringId(IDC_FIND, IDS_FIND);
- const extensions::Extension* pwa =
- extensions::util::GetPwaForSecureActiveTab(browser_);
- if (pwa) {
+ base::Optional<web_app::AppId> app_id =
+ web_app::GetPwaForSecureActiveTab(browser());
+ if (app_id) {
+ auto* provider = web_app::WebAppProvider::Get(browser()->profile());
AddItem(IDC_OPEN_IN_PWA_WINDOW,
l10n_util::GetStringFUTF16(
IDS_OPEN_IN_APP_WINDOW,
- gfx::TruncateString(base::UTF8ToUTF16(pwa->name()),
- kMaxAppNameLength, gfx::CHARACTER_BREAK)));
+ gfx::TruncateString(
+ base::UTF8ToUTF16(
+ provider->registrar().GetAppShortName(*app_id)),
+ kMaxAppNameLength, gfx::CHARACTER_BREAK)));
} else {
base::Optional<base::string16> install_pwa_item_name =
GetInstallPWAAppMenuItemName(browser_);
diff --git a/chrome/browser/ui/web_applications/web_app_launch_utils.cc b/chrome/browser/ui/web_applications/web_app_launch_utils.cc
new file mode 100644
index 0000000..ae616ea
--- /dev/null
+++ b/chrome/browser/ui/web_applications/web_app_launch_utils.cc
@@ -0,0 +1,104 @@
+// 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/ui/web_applications/web_app_launch_utils.h"
+
+#include "base/feature_list.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_commands.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/browser_window.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
+#include "chrome/browser/web_applications/components/app_registrar.h"
+#include "chrome/browser/web_applications/web_app_provider.h"
+#include "chrome/common/chrome_features.h"
+#include "components/omnibox/browser/location_bar_model.h"
+#include "content/public/browser/web_contents.h"
+
+namespace {
+
+Browser* ReparentWebContentsWithBrowserCreateParams(
+ content::WebContents* contents,
+ const Browser::CreateParams& browser_params) {
+ Browser* source_browser = chrome::FindBrowserWithWebContents(contents);
+ Browser* target_browser = Browser::Create(browser_params);
+
+ TabStripModel* source_tabstrip = source_browser->tab_strip_model();
+ // Avoid causing the existing browser window to close if this is the last tab
+ // remaining.
+ if (source_tabstrip->count() == 1)
+ chrome::NewTab(source_browser);
+ target_browser->tab_strip_model()->AppendWebContents(
+ source_tabstrip->DetachWebContentsAt(
+ source_tabstrip->GetIndexOfWebContents(contents)),
+ true);
+ target_browser->window()->Show();
+
+ return target_browser;
+}
+
+} // namespace
+
+namespace web_app {
+
+base::Optional<AppId> GetPwaForSecureActiveTab(Browser* browser) {
+ switch (browser->location_bar_model()->GetSecurityLevel()) {
+ case security_state::SECURITY_LEVEL_COUNT:
+ NOTREACHED();
+ FALLTHROUGH;
+ case security_state::NONE:
+ case security_state::HTTP_SHOW_WARNING:
+ case security_state::DANGEROUS:
+ return base::nullopt;
+ case security_state::EV_SECURE:
+ case security_state::SECURE:
+ case security_state::SECURE_WITH_POLICY_INSTALLED_CERT:
+ break;
+ }
+ content::WebContents* web_contents =
+ browser->tab_strip_model()->GetActiveWebContents();
+ WebAppProvider* provider = WebAppProvider::Get(browser->profile());
+ if (!provider)
+ return base::nullopt;
+
+ return provider->registrar().FindAppWithUrlInScope(
+ web_contents->GetMainFrame()->GetLastCommittedURL());
+}
+
+Browser* ReparentWebAppForSecureActiveTab(Browser* browser) {
+ base::Optional<AppId> app_id = GetPwaForSecureActiveTab(browser);
+ if (!app_id)
+ return nullptr;
+ return ReparentWebContentsIntoAppBrowser(
+ browser->tab_strip_model()->GetActiveWebContents(), *app_id);
+}
+
+Browser* ReparentWebContentsIntoAppBrowser(content::WebContents* contents,
+ const AppId& app_id) {
+ Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
+ // Incognito tabs reparent correctly, but remain incognito without any
+ // indication to the user, so disallow it.
+ DCHECK(!profile->IsOffTheRecord());
+ Browser::CreateParams browser_params(Browser::CreateParams::CreateForApp(
+ web_app::GenerateApplicationNameFromAppId(app_id),
+ true /* trusted_source */, gfx::Rect(), profile,
+ true /* user_gesture */));
+ return ReparentWebContentsWithBrowserCreateParams(contents, browser_params);
+}
+
+Browser* ReparentWebContentsForFocusMode(content::WebContents* contents) {
+ DCHECK(base::FeatureList::IsEnabled(features::kFocusMode));
+ Profile* profile = Profile::FromBrowserContext(contents->GetBrowserContext());
+ // TODO(crbug.com/941577): Remove DCHECK when focus mode is permitted in guest
+ // and incognito sessions.
+ DCHECK(!profile->IsOffTheRecord());
+ Browser::CreateParams browser_params(Browser::CreateParams::CreateForApp(
+ web_app::GenerateApplicationNameForFocusMode(), true /* trusted_source */,
+ gfx::Rect(), profile, true /* user_gesture */));
+ browser_params.is_focus_mode = true;
+ return ReparentWebContentsWithBrowserCreateParams(contents, browser_params);
+}
+
+} // namespace web_app
diff --git a/chrome/browser/ui/web_applications/web_app_launch_utils.h b/chrome/browser/ui/web_applications/web_app_launch_utils.h
new file mode 100644
index 0000000..bddc37d
--- /dev/null
+++ b/chrome/browser/ui/web_applications/web_app_launch_utils.h
@@ -0,0 +1,37 @@
+// 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_UI_WEB_APPLICATIONS_WEB_APP_LAUNCH_UTILS_H_
+#define CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_LAUNCH_UTILS_H_
+
+#include <string>
+
+#include "base/optional.h"
+#include "chrome/browser/web_applications/components/web_app_helpers.h"
+
+class Browser;
+
+namespace content {
+class WebContents;
+}
+
+namespace web_app {
+
+base::Optional<AppId> GetPwaForSecureActiveTab(Browser* browser);
+
+// Reparents the active tab into a new app browser for the web app that has the
+// tab's URL in its scope. Does nothing if the tab is not secure or there is no
+// applicable web app.
+Browser* ReparentWebAppForSecureActiveTab(Browser* browser);
+
+// Reparents |contents| into a new app browser for |app_id|.
+Browser* ReparentWebContentsIntoAppBrowser(content::WebContents* contents,
+ const AppId& app_id);
+
+// Reparents contents to a new app browser when entering the Focus Mode.
+Browser* ReparentWebContentsForFocusMode(content::WebContents* contents);
+
+} // namespace web_app
+
+#endif // CHROME_BROWSER_UI_WEB_APPLICATIONS_WEB_APP_LAUNCH_UTILS_H_
diff --git a/chrome/browser/ui/web_applications/web_app_ui_manager_impl.cc b/chrome/browser/ui/web_applications/web_app_ui_manager_impl.cc
index b464137..a58aee1d 100644
--- a/chrome/browser/ui/web_applications/web_app_ui_manager_impl.cc
+++ b/chrome/browser/ui/web_applications/web_app_ui_manager_impl.cc
@@ -11,9 +11,9 @@
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list.h"
-#include "chrome/browser/ui/extensions/application_launch.h"
#include "chrome/browser/ui/web_applications/app_browser_controller.h"
#include "chrome/browser/ui/web_applications/web_app_dialog_manager.h"
+#include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
#include "chrome/browser/web_applications/system_web_app_manager.h"
#include "chrome/browser/web_applications/web_app_provider.h"