chromium/chrome/browser/ui/ash/system_web_apps/system_web_app_delegate_ui_impl.cc

// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <vector>

#include "base/files/file_path.h"
#include "chrome/browser/apps/app_service/app_launch_params.h"
#include "chrome/browser/ash/system_web_apps/types/system_web_app_delegate.h"
#include "chrome/browser/ui/ash/system_web_apps/system_web_app_ui_utils.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/web_applications/web_app_launch_utils.h"
#include "chrome/browser/web_applications/os_integration/os_integration_manager.h"
#include "chrome/browser/web_applications/web_app_launch_queue.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/browser/web_applications/web_app_tab_helper.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/ui_base_types.h"
#include "ui/base/window_open_disposition.h"
#include "url/gurl.h"

namespace ash {

Browser* SystemWebAppDelegate::GetWindowForLaunch(Profile* profile,
                                                  const GURL& url) const {
  DCHECK(!ShouldShowNewWindowMenuOption())
      << "App can't show 'new window' menu option and reuse windows at "
         "the same time.";
  return FindSystemWebAppBrowser(profile, GetType(), Browser::TYPE_APP);
}

// TODO(crbug.com/40190893): Reduce code duplication between SWA launch code and
// web app launch code, so SWAs can easily maintain feature parity with regular
// web apps (e.g. launch_handler behaviours).
Browser* SystemWebAppDelegate::LaunchAndNavigateSystemWebApp(
    Profile* profile,
    web_app::WebAppProvider* provider,
    const GURL& url,
    const apps::AppLaunchParams& params) const {
  // System Web App windows can't be properly restored without storing the app
  // type. Until that is implemented, skip them for session restore.
  // TODO(crbug.com/40098476): Enable session restore for System Web Apps by
  // passing through the underlying value of params.omit_from_session_restore.
  constexpr bool kOmitFromSessionRestore = true;

  // Always reuse an existing browser for popups. Otherwise let the app decide.
  // TODO(crbug.com/40679012): Allow apps to control whether popups are single.
  Browser* browser =
      (params.disposition == WindowOpenDisposition::NEW_POPUP)
          ? FindSystemWebAppBrowser(profile, GetType(), Browser::TYPE_APP_POPUP)
          : GetWindowForLaunch(profile, url);

  bool started_new_navigation = false;
  if (!browser) {
    Browser::CreateParams create_params = web_app::CreateParamsForApp(
        params.app_id, params.disposition == WindowOpenDisposition::NEW_POPUP,
        /*trusted_source=*/true, /*window_bounds=*/gfx::Rect(), profile,
        /*user_gesture=*/true);
    create_params.restore_id = params.restore_id;
    create_params.omit_from_session_restore = kOmitFromSessionRestore;
    create_params.initial_show_state = ui::SHOW_STATE_DEFAULT;
    create_params.can_resize = ShouldAllowResize();
    create_params.can_maximize = ShouldAllowMaximize();
    create_params.can_fullscreen = ShouldAllowFullscreen();
    browser = web_app::CreateWebAppWindowMaybeWithHomeTab(params.app_id,
                                                          create_params);
    started_new_navigation = true;
  }

  // Navigate application window to application's |url| if necessary.
  // Help app always navigates because its url might not match the url inside
  // the iframe, and the iframe's url is the one that matters.
  content::WebContents* web_contents =
      browser->tab_strip_model()->GetWebContentsAt(0);
  if (!web_contents || web_contents->GetURL() != url ||
      GetType() == SystemWebAppType::HELP) {
    NavigateParams nav_params(browser, url, ui::PAGE_TRANSITION_AUTO_BOOKMARK);
    // TODO(crbug.com/1308961): Migrate to use PWA pinned home tab when ready.
    if (ShouldPinTab(url)) {
      nav_params.tabstrip_add_types |= AddTabTypes::ADD_PINNED;
    }
    web_contents =
        web_app::NavigateWebAppUsingParams(params.app_id, nav_params);
    started_new_navigation = true;
  }

  // Send launch files.
  if (provider->os_integration_manager().IsFileHandlingAPIAvailable(
          params.app_id)) {
    base::FilePath launch_dir = GetLaunchDirectory(params);

    if (!launch_dir.empty() || !params.launch_files.empty()) {
      web_app::WebAppLaunchParams launch_params;
      launch_params.started_new_navigation = started_new_navigation;
      launch_params.app_id = params.app_id;
      launch_params.target_url = web_contents->GetURL();
      launch_params.dir = std::move(launch_dir);
      launch_params.paths = params.launch_files;
      web_app::WebAppTabHelper::FromWebContents(web_contents)
          ->EnsureLaunchQueue()
          .Enqueue(std::move(launch_params));
    }
  }

  return browser;
}

}  // namespace ash