chromium/chrome/browser/lacros/lacros_url_handling.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 "chrome/browser/lacros/lacros_url_handling.h"

#include "base/check_is_test.h"
#include "chrome/browser/ui/browser_navigator_params.h"
#include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
#include "chrome/common/webui_url_constants.h"
#include "chromeos/crosapi/cpp/gurl_os_handler_utils.h"
#include "chromeos/crosapi/mojom/url_handler.mojom.h"
#include "chromeos/lacros/lacros_service.h"
#include "chromeos/startup/browser_params_proxy.h"
#include "url/gurl.h"

namespace lacros_url_handling {

bool IsNavigationInterceptable(const NavigateParams& params,
                               const GURL& source_url) {
  const auto qualifier = PageTransitionGetQualifier(params.transition);
  // True if this was triggered by the user typing into the Omnibox or via
  // crosapi (see BrowserServiceLacros::OpenUrlImpl).
  const bool is_omnibox_or_crosapi_navigation =
      (PageTransitionCoreTypeIs(params.transition, ui::PAGE_TRANSITION_TYPED) ||
       PageTransitionCoreTypeIs(params.transition,
                                ui::PAGE_TRANSITION_GENERATED)) &&
      qualifier & ui::PAGE_TRANSITION_FROM_ADDRESS_BAR;
  // True if this is a bookmark navigation.
  const bool is_bookmark_navigation = PageTransitionCoreTypeIs(
      params.transition, ui::PAGE_TRANSITION_AUTO_BOOKMARK);
  // True if this is a navigation created by the user, clicking on a link on a
  // page with the chrome:// scheme.
  const bool is_system_navigation =
      PageTransitionCoreTypeIs(params.transition, ui::PAGE_TRANSITION_LINK) &&
      source_url.SchemeIs(content::kChromeUIScheme);
  return (is_omnibox_or_crosapi_navigation || is_system_navigation ||
          is_bookmark_navigation);
}

bool MaybeInterceptNavigation(const GURL& url) {
  // Every URL which is supported by Ash but not by Lacros will automatically be
  // forwarded to Ash.
  return !IsUrlHandledByLacros(url) &&
         NavigateInAsh(
             crosapi::gurl_os_handler_utils::GetAshUrlFromLacrosUrl(url));
}

bool IsUrlHandledByLacros(const GURL& url) {
  return ChromeWebUIControllerFactory::GetInstance()->CanHandleUrl(url);
}

bool IsUrlAcceptedByAsh(const GURL& url) {
  auto* init_params = chromeos::BrowserParamsProxy::Get();
  const std::optional<std::vector<GURL>>& accepted_urls =
      init_params->AcceptedInternalAshUrls();
  if (!accepted_urls.has_value()) {
    CHECK_IS_TEST();
    return false;
  }

  return crosapi::gurl_os_handler_utils::IsAshUrlInList(url, *accepted_urls);
}

bool NavigateInAsh(GURL url) {
  if (!IsUrlAcceptedByAsh(url)) {
    return false;
  }

  chromeos::LacrosService* service = chromeos::LacrosService::Get();
  if (!service->IsAvailable<crosapi::mojom::UrlHandler>()) {
    return false;
  }

  service->GetRemote<crosapi::mojom::UrlHandler>()->OpenUrl(url);
  return true;
}

}  // namespace lacros_url_handling