chromium/chrome/browser/web_applications/app_service/web_apps_browsertest.cc

// Copyright 2020 The Chromium Authors
// 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/app_service/web_apps.h"

#include <vector>

#include "base/files/file_path.h"
#include "base/run_loop.h"
#include "base/test/bind.h"
#include "chrome/browser/apps/app_service/app_service_proxy.h"
#include "chrome/browser/apps/app_service/app_service_proxy_factory.h"
#include "chrome/browser/apps/app_service/intent_util.h"
#include "chrome/browser/apps/app_service/launch_utils.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/web_applications/test/web_app_browsertest_util.h"
#include "chrome/browser/ui/web_applications/web_app_browsertest_base.h"
#include "chrome/browser/ui/web_applications/web_app_launch_process.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chromeos/ash/components/dbus/cros_disks/cros_disks_client.h"
#include "components/services/app_service/public/cpp/app_launch_util.h"
#include "components/services/app_service/public/cpp/intent.h"
#include "components/services/app_service/public/cpp/intent_util.h"
#include "components/webapps/common/web_app_id.h"
#include "content/public/test/browser_test.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "ui/base/window_open_disposition.h"
#include "ui/display/types/display_constants.h"
#include "url/gurl.h"

namespace web_app {

using WebAppsBrowserTest = WebAppBrowserTestBase;

IN_PROC_BROWSER_TEST_F(WebAppsBrowserTest, LaunchWithIntent) {
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL app_url(
      embedded_test_server()->GetURL("/web_share_target/charts.html"));
  Profile* const profile = browser()->profile();
  const webapps::AppId app_id = InstallWebAppFromManifest(browser(), app_url);

  base::RunLoop run_loop;
  WebAppLaunchProcess::SetOpenApplicationCallbackForTesting(
      base::BindLambdaForTesting([&run_loop](apps::AppLaunchParams params) {
        EXPECT_EQ(params.intent->action, apps_util::kIntentActionSend);
        EXPECT_EQ(*params.intent->mime_type, "text/csv");
        EXPECT_EQ(params.intent->files.size(), 1U);
        run_loop.Quit();
      }));

  std::vector<base::FilePath> file_paths(
      {ash::CrosDisksClient::GetArchiveMountPoint().Append("numbers.csv")});
  std::vector<std::string> content_types({"text/csv"});
  apps::IntentPtr intent = apps_util::CreateShareIntentFromFiles(
      profile, std::move(file_paths), std::move(content_types));
  const int32_t event_flags =
      apps::GetEventFlags(WindowOpenDisposition::NEW_WINDOW,
                          /*prefer_container=*/true);
  apps::AppServiceProxyFactory::GetForProfile(profile)->LaunchAppWithIntent(
      app_id, event_flags, std::move(intent),
      apps::LaunchSource::kFromSharesheet,
      std::make_unique<apps::WindowInfo>(display::kDefaultDisplayId),
      base::DoNothing());
  run_loop.Run();
}

IN_PROC_BROWSER_TEST_F(WebAppsBrowserTest, IntentWithoutFiles) {
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL app_url(
      embedded_test_server()->GetURL("/web_share_target/poster.html"));
  Profile* const profile = browser()->profile();
  const webapps::AppId app_id = InstallWebAppFromManifest(browser(), app_url);

  base::RunLoop run_loop;
  WebAppLaunchProcess::SetOpenApplicationCallbackForTesting(
      base::BindLambdaForTesting([&run_loop](apps::AppLaunchParams params) {
        EXPECT_EQ(params.intent->action, apps_util::kIntentActionSendMultiple);
        EXPECT_EQ(*params.intent->mime_type, "*/*");
        EXPECT_EQ(params.intent->files.size(), 0U);
        run_loop.Quit();
      }));

  apps::IntentPtr intent = apps_util::CreateShareIntentFromFiles(
      profile, /*file_paths=*/std::vector<base::FilePath>(),
      /*mime_types=*/std::vector<std::string>(),
      /*share_text=*/"Message",
      /*share_title=*/"Subject");

  const int32_t event_flags =
      apps::GetEventFlags(WindowOpenDisposition::NEW_WINDOW,
                          /*prefer_container=*/true);
  apps::AppServiceProxyFactory::GetForProfile(profile)->LaunchAppWithIntent(
      app_id, event_flags, std::move(intent),
      apps::LaunchSource::kFromSharesheet,
      std::make_unique<apps::WindowInfo>(display::kDefaultDisplayId),
      base::DoNothing());
  run_loop.Run();
}

IN_PROC_BROWSER_TEST_F(WebAppsBrowserTest, ExposeAppServicePublisherId) {
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL app_url(embedded_test_server()->GetURL("/web_apps/basic.html"));

  // Install file handling web app.
  const webapps::AppId app_id = InstallWebAppFromManifest(browser(), app_url);
  const WebAppRegistrar& registrar =
      WebAppProvider::GetForTest(browser()->profile())->registrar_unsafe();
  const WebApp* web_app = registrar.GetAppById(app_id);
  ASSERT_TRUE(web_app);

  // Check the publisher_id is the app's start url.
  apps::AppServiceProxyFactory::GetForProfile(browser()->profile())
      ->AppRegistryCache()
      .ForOneApp(app_id, [&](const apps::AppUpdate& update) {
        EXPECT_EQ(web_app->start_url().spec(), update.PublisherId());
      });
}

IN_PROC_BROWSER_TEST_F(WebAppsBrowserTest, LaunchAppIconKeyUnchanged) {
  ASSERT_TRUE(embedded_test_server()->Start());
  const GURL app_url(embedded_test_server()->GetURL("/web_apps/basic.html"));
  const webapps::AppId app_id = InstallWebAppFromManifest(browser(), app_url);
  auto* proxy =
      apps::AppServiceProxyFactory::GetForProfile(browser()->profile());

  std::optional<apps::IconKey> original_key;
  proxy->AppRegistryCache().ForOneApp(
      app_id, [&original_key](const apps::AppUpdate& update) {
        original_key = update.IconKey();
      });

  const int32_t event_flags =
      apps::GetEventFlags(WindowOpenDisposition::NEW_WINDOW,
                          /*prefer_container=*/true);
  proxy->Launch(app_id, event_flags, apps::LaunchSource::kUnknown,
                std::make_unique<apps::WindowInfo>(display::kDefaultDisplayId));

  proxy->AppRegistryCache().ForOneApp(
      app_id, [&original_key](const apps::AppUpdate& update) {
        ASSERT_EQ(original_key, update.IconKey());
      });
}

}  // namespace web_app