chromium/components/omnibox/browser/suggestion_answer.cc

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

#include "components/omnibox/browser/suggestion_answer.h"

#include <stddef.h>

#include <memory>

#include "base/feature_list.h"
#include "base/i18n/rtl.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/escape.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/trace_event/memory_usage_estimator.h"
#include "build/build_config.h"
#include "third_party/omnibox_proto/answer_type.pb.h"
#include "url/url_constants.h"

#if BUILDFLAG(IS_ANDROID)
#include "base/android/jni_string.h"
#include "components/omnibox/browser/jni_headers/SuggestionAnswer_jni.h"

using base::android::ScopedJavaLocalRef;
#endif

namespace {

// All of these are defined here (even though most are only used once each) so
// the format details are easy to locate and update or compare to the spec doc.
static constexpr char kAnswerJsonLines[] =;
static constexpr char kAnswerJsonImageLine[] =;
static constexpr char kAnswerJsonText[] =;
static constexpr char kAnswerJsonAdditionalText[] =;
static constexpr char kAnswerJsonStatusText[] =;
static constexpr char kAnswerJsonAccessibilityLabel[] =;
static constexpr char kAnswerJsonTextType[] =;
static constexpr char kAnswerJsonNumLines[] =;
static constexpr char kAnswerJsonImage[] =;
static constexpr char kAnswerJsonImageData[] =;

constexpr char kAnswerUsedUmaHistogramName[] =;

void AppendWithSpace(const SuggestionAnswer::TextField* text,
                     std::u16string* output) {}

}  // namespace

namespace omnibox::answer_data_parser {

// If necessary, concatenate scheme and host/path using only ':' as
// separator. This is due to the results delivering strings of the form
// "//host/path", which is web-speak for "use the enclosing page's scheme",
// but not a valid path of a URL. The GWS frontend commonly (always?)
// redirects to HTTPS, so we just default to that here.
GURL GetFormattedURL(const std::string* url_string) {}

void SetColorType(int text_type,
                  omnibox::FormattedString::FormattedStringFragment* fragment) {}

bool ParseJsonToFormattedStringFragment(
    const base::Value::Dict& field_json,
    omnibox::FormattedString* formatted_string) {}

bool ParseJsonToFormattedString(const base::Value::Dict& line_json,
                                omnibox::FormattedString* formatted_string,
                                omnibox::Image* image) {}

bool ParseJsonToAnswerData(const base::Value::Dict& answer_json,
                           omnibox::RichAnswerTemplate* answer_template) {}

void LogAnswerUsed(omnibox::AnswerType answer_type) {}

}  // namespace omnibox::answer_data_parser

// SuggestionAnswer::TextField -------------------------------------------------

SuggestionAnswer::TextField::TextField() = default;
SuggestionAnswer::TextField::~TextField() = default;
SuggestionAnswer::TextField::TextField(const TextField&) = default;
SuggestionAnswer::TextField::TextField(TextField&&) noexcept = default;
SuggestionAnswer::TextField& SuggestionAnswer::TextField::operator=(
    const TextField&) = default;
SuggestionAnswer::TextField& SuggestionAnswer::TextField::operator=(
    TextField&&) noexcept = default;

// static
bool SuggestionAnswer::TextField::ParseTextField(
    const base::Value::Dict& field_json,
    TextField* text_field) {}

bool SuggestionAnswer::TextField::Equals(const TextField& field) const {}

size_t SuggestionAnswer::TextField::EstimateMemoryUsage() const {}

// SuggestionAnswer::ImageLine -------------------------------------------------

SuggestionAnswer::ImageLine::ImageLine() :{}
SuggestionAnswer::ImageLine::ImageLine(const ImageLine& line) = default;
SuggestionAnswer::ImageLine::ImageLine(ImageLine&&) noexcept = default;

SuggestionAnswer::ImageLine& SuggestionAnswer::ImageLine::operator=(
    const ImageLine& line) = default;
SuggestionAnswer::ImageLine& SuggestionAnswer::ImageLine::operator=(
    ImageLine&&) noexcept = default;

SuggestionAnswer::ImageLine::~ImageLine() = default;

// static
bool SuggestionAnswer::ImageLine::ParseImageLine(
    const base::Value::Dict& line_json,
    ImageLine* image_line) {}

bool SuggestionAnswer::ImageLine::Equals(const ImageLine& line) const {}

// TODO(jdonnelly): When updating the display of answers in RTL languages,
// modify this to be consistent.
std::u16string SuggestionAnswer::ImageLine::AccessibleText() const {}

size_t SuggestionAnswer::ImageLine::EstimateMemoryUsage() const {}

void SuggestionAnswer::ImageLine::SetTextStyles(
    int from_type,
    SuggestionAnswer::TextStyle style) {}

// SuggestionAnswer ------------------------------------------------------------

SuggestionAnswer::SuggestionAnswer() = default;

SuggestionAnswer::SuggestionAnswer(const SuggestionAnswer& answer) = default;

SuggestionAnswer::SuggestionAnswer(SuggestionAnswer&&) noexcept = default;

SuggestionAnswer& SuggestionAnswer::operator=(const SuggestionAnswer& answer) =
    default;

SuggestionAnswer& SuggestionAnswer::operator=(SuggestionAnswer&&) noexcept =
    default;

SuggestionAnswer::~SuggestionAnswer() = default;

// static
bool SuggestionAnswer::ParseAnswer(const base::Value::Dict& answer_json,
                                   omnibox::AnswerType answer_type,
                                   SuggestionAnswer* result) {}

bool SuggestionAnswer::Equals(const SuggestionAnswer& answer) const {}

size_t SuggestionAnswer::EstimateMemoryUsage() const {}

void SuggestionAnswer::InterpretTextTypes(omnibox::AnswerType answer_type) {}

bool SuggestionAnswer::IsExceptedFromLineReversal(
    omnibox::AnswerType answer_type) const {}

#if BUILDFLAG(IS_ANDROID)
namespace {

ScopedJavaLocalRef<jobject> CreateJavaTextField(
    JNIEnv* env,
    const SuggestionAnswer::TextField& text_field) {
  return Java_SuggestionAnswer_createTextField(
      env, text_field.type(),
      base::android::ConvertUTF16ToJavaString(env, text_field.text()),
      static_cast<int>(text_field.style()), text_field.num_lines());
}

ScopedJavaLocalRef<jobject> CreateJavaImageLine(
    JNIEnv* env,
    const SuggestionAnswer::ImageLine* image_line) {
  ScopedJavaLocalRef<jobject> jtext_fields =
      Java_SuggestionAnswer_createTextFieldList(env);
  for (const SuggestionAnswer::TextField& text_field :
       image_line->text_fields()) {
    Java_SuggestionAnswer_addTextFieldToList(
        env, jtext_fields, CreateJavaTextField(env, text_field));
  }

  ScopedJavaLocalRef<jobject> jadditional_text;
  if (image_line->additional_text()) {
    jadditional_text = CreateJavaTextField(env, *image_line->additional_text());
  }

  ScopedJavaLocalRef<jobject> jstatus_text;
  if (image_line->status_text()) {
    jstatus_text = CreateJavaTextField(env, *image_line->status_text());
  }

  ScopedJavaLocalRef<jstring> jimage_url;
  if (image_line->image_url().is_valid()) {
    jimage_url = base::android::ConvertUTF8ToJavaString(
        env, image_line->image_url().spec());
  }

  return Java_SuggestionAnswer_createImageLine(
      env, jtext_fields, jadditional_text, jstatus_text, jimage_url);
}

}  // namespace

ScopedJavaLocalRef<jobject> SuggestionAnswer::CreateJavaObject(
    omnibox::AnswerType answer_type) const {
  JNIEnv* env = jni_zero::AttachCurrentThread();
  return Java_SuggestionAnswer_createSuggestionAnswer(
      env, answer_type, CreateJavaImageLine(env, &first_line_),
      CreateJavaImageLine(env, &second_line_));
}
#endif  // BUILDFLAG(IS_ANDROID)