chromium/components/content_capture/android/test_support/content_capture_test_support_android.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 <optional>
#include <string>

#include "base/android/jni_string.h"
#include "base/check_deref.h"
#include "base/json/json_reader.h"
#include "base/notreached.h"
#include "base/values.h"
#include "components/content_capture/browser/content_capture_receiver.h"
#include "components/content_capture/browser/onscreen_content_provider.h"
#include "content/public/browser/web_contents.h"
#include "third_party/blink/public/mojom/favicon/favicon_url.mojom.h"
#include "ui/gfx/geometry/size.h"

// Must come after all headers that specialize FromJniType() / ToJniType().
#include "components/content_capture/android/test_support/jni_headers/ContentCaptureTestSupport_jni.h"

namespace content_capture {

namespace {
blink::mojom::FaviconIconType ToType(std::string type) {
  if (type == "favicon")
    return blink::mojom::FaviconIconType::kFavicon;
  else if (type == "touch icon")
    return blink::mojom::FaviconIconType::kTouchIcon;
  else if (type == "touch precomposed icon")
    return blink::mojom::FaviconIconType::kTouchPrecomposedIcon;
  NOTREACHED_IN_MIGRATION();
  return blink::mojom::FaviconIconType::kInvalid;
}

}  // namespace

static void JNI_ContentCaptureTestSupport_DisableGetFaviconFromWebContents(
    JNIEnv* env) {
  ContentCaptureReceiver::DisableGetFaviconFromWebContentsForTesting();
}

static void JNI_ContentCaptureTestSupport_SimulateDidUpdateFaviconURL(
    JNIEnv* env,
    const base::android::JavaParamRef<jobject>& jwebContents,
    const base::android::JavaParamRef<jstring>& jfaviconJson) {
  content::WebContents* web_contents =
      content::WebContents::FromJavaWebContents(jwebContents);
  CHECK(web_contents);
  OnscreenContentProvider* provider =
      OnscreenContentProvider::FromWebContents(web_contents);
  CHECK(provider);

  std::string json = base::android::ConvertJavaStringToUTF8(env, jfaviconJson);
  std::optional<base::Value> root = base::JSONReader::Read(json);
  CHECK(root);
  CHECK(root->is_list());
  std::vector<blink::mojom::FaviconURLPtr> favicon_urls;
  for (const base::Value& icon_val : root->GetList()) {
    const base::Value::Dict& icon = icon_val.GetDict();
    std::vector<gfx::Size> sizes;
    // The sizes is optional.
    if (const base::Value::List* icon_sizes = icon.FindList("sizes")) {
      for (const base::Value& size_val : CHECK_DEREF(icon_sizes)) {
        const base::Value::Dict& size = size_val.GetDict();

        const std::optional<int> width = size.FindInt("width");
        const std::optional<int> height = size.FindInt("height");
        CHECK(width);
        CHECK(height);
        sizes.emplace_back(width.value(), height.value());
      }
    }

    const std::string* url = icon.FindString("url");
    const std::string* type = icon.FindString("type");
    CHECK(url);
    CHECK(type);
    favicon_urls.push_back(blink::mojom::FaviconURL::New(
        GURL(*url), ToType(*type), sizes, /*is_default_icon=*/false));
  }
  CHECK(!favicon_urls.empty());
  provider->NotifyFaviconURLUpdatedForTesting(
      web_contents->GetPrimaryMainFrame(), favicon_urls);
}

}  // namespace content_capture