chromium/ash/webui/eche_app_ui/eche_app_ui.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 "ash/webui/eche_app_ui/eche_app_ui.h"

#include <memory>

#include "ash/webui/eche_app_ui/eche_app_manager.h"
#include "ash/webui/eche_app_ui/mojom/eche_app.mojom.h"
#include "ash/webui/eche_app_ui/url_constants.h"
#include "ash/webui/grit/ash_eche_app_resources.h"
#include "ash/webui/grit/ash_eche_bundle_resources.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "content/public/browser/web_ui_data_source.h"
#include "content/public/common/url_constants.h"
#include "mojo/public/js/grit/mojo_bindings_resources.h"
#include "third_party/blink/public/common/web_preferences/web_preferences.h"
#include "ui/webui/webui_allowlist.h"

namespace ash::eche_app {

EcheAppUI::EcheAppUI(content::WebUI* web_ui, EcheAppManager* manager)
    : ui::MojoWebUIController(web_ui), manager_(manager) {
  auto* browser_context = web_ui->GetWebContents()->GetBrowserContext();
  content::WebUIDataSource* html_source =
      content::WebUIDataSource::CreateAndAdd(browser_context,
                                             kChromeUIEcheAppHost);

  html_source->AddResourcePath("", IDR_ASH_ECHE_INDEX_HTML);
  html_source->AddResourcePath("system_assets/app_icon_32.png",
                               IDR_ASH_ECHE_APP_ICON_32_PNG);
  html_source->AddResourcePath("system_assets/app_icon_256.png",
                               IDR_ASH_ECHE_APP_ICON_256_PNG);
  html_source->AddResourcePath("js/app_bundle.js", IDR_ASH_ECHE_APP_BUNDLE_JS);
  html_source->AddResourcePath("assets/app_bundle.css",
                               IDR_ASH_ECHE_APP_BUNDLE_CSS);
  html_source->AddResourcePath("big_buffer.mojom-lite.js",
                               IDR_MOJO_BIG_BUFFER_MOJOM_LITE_JS);
  html_source->AddResourcePath("string16.mojom-lite.js",
                               IDR_MOJO_STRING16_MOJOM_LITE_JS);
  html_source->AddResourcePath(
      "eche_app.mojom-lite.js",
      IDR_ASH_ECHE_APP_ASH_WEBUI_ECHE_APP_UI_MOJOM_ECHE_APP_MOJOM_LITE_JS);
  html_source->AddResourcePath("message_pipe.js",
                               IDR_ASH_ECHE_APP_MESSAGE_PIPE_JS);
  html_source->AddResourcePath("message_types.js",
                               IDR_ASH_ECHE_APP_MESSAGE_TYPES_JS);
  html_source->AddResourcePath("browser_proxy.js",
                               IDR_ASH_ECHE_APP_BROWSER_PROXY_JS);
  html_source->AddResourcePath("mojo_bindings_lite.js",
                               IDR_MOJO_MOJO_BINDINGS_LITE_JS);

  // DisableTrustedTypesCSP to support TrustedTypePolicy named 'goog#html'.
  // It is the Closure templating system that renders our UI, as it does many
  // other web apps using it.
  html_source->DisableTrustedTypesCSP();
  // The guest is in an <iframe>. Add it to CSP.
  std::string csp = std::string("frame-src ") + kChromeUIEcheAppGuestURL + ";";
  html_source->OverrideContentSecurityPolicy(
      network::mojom::CSPDirectiveName::FrameSrc, csp);
  html_source->OverrideContentSecurityPolicy(
      network::mojom::CSPDirectiveName::ScriptSrc,
      "script-src chrome://resources chrome://webui-test 'self';");

  // Add ability to request chrome-untrusted: URLs.
  web_ui->AddRequestableScheme(content::kChromeUIUntrustedScheme);

  // Register common permissions for chrome-untrusted:// pages.
  // TODO(crbug.com/40710326): Remove this after common permissions are
  // granted by default.
  auto* webui_allowlist = WebUIAllowlist::GetOrCreate(browser_context);
  const url::Origin untrusted_eche_app_origin =
      url::Origin::Create(GURL(kChromeUIEcheAppGuestURL));
  for (const auto& permission : {
           ContentSettingsType::COOKIES,
           ContentSettingsType::JAVASCRIPT,
           ContentSettingsType::IMAGES,
           ContentSettingsType::SOUND,
       }) {
    webui_allowlist->RegisterAutoGrantedPermission(untrusted_eche_app_origin,
                                                   permission);
  }

  // Set untrusted URL of Eche app in WebApp scope for allowing AutoPlay.
  auto* web_contents = web_ui->GetWebContents();
  auto prefs = web_contents->GetOrCreateWebPreferences();
  prefs.web_app_scope = GURL(kChromeUIEcheAppGuestURL);
  web_contents->SetWebPreferences(prefs);
}

EcheAppUI::~EcheAppUI() = default;

void EcheAppUI::BindInterface(
    mojo::PendingReceiver<mojom::SignalingMessageExchanger> receiver) {
  if (manager_) {
    manager_->BindSignalingMessageExchangerInterface(std::move(receiver));
  }
}

void EcheAppUI::BindInterface(
    mojo::PendingReceiver<mojom::SystemInfoProvider> receiver) {
  if (manager_) {
    manager_->BindSystemInfoProviderInterface(std::move(receiver));
  }
}

void EcheAppUI::BindInterface(
    mojo::PendingReceiver<mojom::AccessibilityProvider> receiver) {
  if (manager_) {
    manager_->BindAccessibilityProviderInterface(std::move(receiver));
  }
}

void EcheAppUI::BindInterface(
    mojo::PendingReceiver<mojom::UidGenerator> receiver) {
  if (manager_) {
    manager_->BindUidGeneratorInterface(std::move(receiver));
  }
}

void EcheAppUI::BindInterface(
    mojo::PendingReceiver<mojom::NotificationGenerator> receiver) {
  if (manager_) {
    manager_->BindNotificationGeneratorInterface(std::move(receiver));
  }
}

void EcheAppUI::BindInterface(
    mojo::PendingReceiver<mojom::DisplayStreamHandler> receiver) {
  if (manager_) {
    manager_->BindDisplayStreamHandlerInterface(std::move(receiver));
  }
}

void EcheAppUI::BindInterface(
    mojo::PendingReceiver<mojom::StreamOrientationObserver> receiver) {
  if (manager_) {
    manager_->BindStreamOrientationObserverInterface(std::move(receiver));
  }
}

void EcheAppUI::BindInterface(
    mojo::PendingReceiver<mojom::ConnectionStatusObserver> receiver) {
  if (manager_) {
    manager_->BindConnectionStatusObserverInterface(std::move(receiver));
  }
}

void EcheAppUI::BindInterface(
    mojo::PendingReceiver<mojom::KeyboardLayoutHandler> receiver) {
  if (manager_) {
    manager_->BindKeyboardLayoutHandlerInterface(std::move(receiver));
  }
}

WEB_UI_CONTROLLER_TYPE_IMPL(EcheAppUI)

}  // namespace ash::eche_app