File: suggestion_answer.h

package info (click to toggle)
chromium-browser 70.0.3538.110-1~deb9u1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 1,619,476 kB
  • sloc: cpp: 13,024,755; ansic: 1,349,823; python: 916,672; xml: 314,489; java: 280,047; asm: 276,936; perl: 75,771; objc: 66,634; sh: 45,860; cs: 28,354; php: 11,064; makefile: 10,911; yacc: 9,109; tcl: 8,403; ruby: 4,065; lex: 1,779; pascal: 1,411; lisp: 1,055; awk: 41; jsp: 39; sed: 17; sql: 3
file content (235 lines) | stat: -rw-r--r-- 8,324 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_OMNIBOX_BROWSER_SUGGESTION_ANSWER_H_
#define COMPONENTS_OMNIBOX_BROWSER_SUGGESTION_ANSWER_H_

#include <memory>
#include <string>
#include <vector>

#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/optional.h"
#include "url/gurl.h"

namespace base {
class DictionaryValue;
}

// Structured representation of the JSON payload of a suggestion with an answer.
// An answer has exactly two image lines, so called because they are a
// combination of text and an optional image URL.  Each image line has 1 or more
// text fields, each of which is required to contain a string and an integer
// type.  The text fields are contained in a non-empty vector and two optional
// named properties, referred to as "additional text" and "status text".
//
// When represented in the UI, these elements should be styled and laid out
// according to the specification at https://goto.google.com/ais_api.
class SuggestionAnswer {
 public:
  class TextField;
  typedef std::vector<TextField> TextFields;
  typedef std::vector<GURL> URLs;

  // These values are based on the server-side type AnswerTriggererKey. Do not
  // remove values from this enum (or the client/server will become out of
  // sync).
  enum AnswerType {
    ANSWER_TYPE_INVALID,
    ANSWER_TYPE_DICTIONARY,
    ANSWER_TYPE_FINANCE,
    ANSWER_TYPE_KNOWLEDGE_GRAPH,
    ANSWER_TYPE_LOCAL,
    ANSWER_TYPE_SPORTS,
    ANSWER_TYPE_SUNRISE,
    ANSWER_TYPE_TRANSLATION,
    ANSWER_TYPE_WEATHER,
    ANSWER_TYPE_WHEN_IS,
    ANSWER_TYPE_CURRENCY,
    ANSWER_TYPE_LOCAL_TIME,
    ANSWER_TYPE_PLAY_INSTALL,
  };
  static_assert(ANSWER_TYPE_PLAY_INSTALL == 12,
                "Do not remove enums from AnswerType");

  // These values are named and numbered to match a specification at go/ais_api.
  // The values are only used for answer results.
  enum TextType {
    // Deprecated: ANSWER = 1,
    // Deprecated: HEADLINE = 2,
    TOP_ALIGNED = 3,
    // Deprecated: DESCRIPTION = 4,
    DESCRIPTION_NEGATIVE = 5,
    DESCRIPTION_POSITIVE = 6,
    // Deprecated: MORE_INFO = 7,
    SUGGESTION = 8,
    // Deprecated: SUGGESTION_POSITIVE = 9,
    // Deprecated: SUGGESTION_NEGATIVE = 10,
    // Deprecated: SUGGESTION_LINK = 11,
    // Deprecated: STATUS = 12,
    PERSONALIZED_SUGGESTION = 13,
    // Deprecated: IMMERSIVE_DESCRIPTION_TEXT = 14,
    // Deprecated: DATE_TEXT = 15,
    // Deprecated: PREVIEW_TEXT = 16,
    ANSWER_TEXT_MEDIUM = 17,
    ANSWER_TEXT_LARGE = 18,
    SUGGESTION_SECONDARY_TEXT_SMALL = 19,
    SUGGESTION_SECONDARY_TEXT_MEDIUM = 20,
  };

  // The above TextType values match what is sent by server, but are not used
  // normally by new answers.  These enum values are used instead, styling
  // answer text through a client-side process of interpretation that depends
  // on answer type, text type, and even line rank (first|second).  This
  // interpretation process happens during answer parsing and allows
  // downstream logic to remain simple, deciding how to present answers
  // based on a finite set of text types instead of answer properties and rules.
  // Performance is also improved by doing this once at parse time instead of
  // every time render text is invalidated.
  enum class TextStyle {
    NONE,
    NORMAL,
    NORMAL_DIM,
    SECONDARY,
    BOLD,
    POSITIVE,
    NEGATIVE,
    SUPERIOR,  // This is not superscript (see gfx::BaselineStyle).
  };

  class TextField {
   public:
    TextField();
    ~TextField();

    // Parses |field_json| and populates |text_field| with the contents.  If any
    // of the required elements is missing, returns false and leaves text_field
    // in a partially populated state.
    static bool ParseTextField(const base::DictionaryValue* field_json,
                               TextField* text_field);

    const base::string16& text() const { return text_; }
    int type() const { return type_; }
    TextStyle style() const { return style_; }
    void set_style(TextStyle style) { style_ = style; }
    bool has_num_lines() const { return has_num_lines_; }
    int num_lines() const { return num_lines_; }

    bool Equals(const TextField& field) const;

    // Estimates dynamic memory usage.
    // See base/trace_event/memory_usage_estimator.h for more info.
    size_t EstimateMemoryUsage() const;

   private:
    base::string16 text_;
    int type_ = -1;
    bool has_num_lines_ = false;
    int num_lines_ = 1;
    TextStyle style_ = TextStyle::NONE;

    FRIEND_TEST_ALL_PREFIXES(SuggestionAnswerTest, DifferentValuesAreUnequal);

    // No DISALLOW_COPY_AND_ASSIGN since we depend on the copy constructor in
    // SuggestionAnswer::copy and the assignment operator as values in vector.
  };

  class ImageLine {
   public:
    ImageLine();
    explicit ImageLine(const ImageLine& line);
    ImageLine& operator=(const ImageLine& line);
    ~ImageLine();

    // Parses |line_json| and populates |image_line| with the contents.  If any
    // of the required elements is missing, returns false and leaves text_field
    // in a partially populated state.
    static bool ParseImageLine(const base::DictionaryValue* line_json,
                               ImageLine* image_line);

    const TextFields& text_fields() const { return text_fields_; }
    int num_text_lines() const { return num_text_lines_; }
    const TextField* additional_text() const {
      if (additional_text_)
        return &additional_text_.value();
      else
        return nullptr;
    }
    const TextField* status_text() const {
      if (status_text_)
        return &status_text_.value();
      else
        return nullptr;
    }
    const GURL& image_url() const { return image_url_; }

    bool Equals(const ImageLine& line) const;

    // Returns a string appropriate for use as a readable representation of the
    // content of this line.
    base::string16 AccessibleText() const;

    // Estimates dynamic memory usage.
    // See base/trace_event/memory_usage_estimator.h for more info.
    size_t EstimateMemoryUsage() const;

    // Set text style on all fields where text type matches from_type and style
    // is not already set. Using from_type = 0 matches all values from TextType.
    void SetTextStyles(int from_type, TextStyle style);

   private:
    TextFields text_fields_;
    int num_text_lines_;
    base::Optional<TextField> additional_text_;
    base::Optional<TextField> status_text_;
    GURL image_url_;

    FRIEND_TEST_ALL_PREFIXES(SuggestionAnswerTest, DifferentValuesAreUnequal);
  };

  SuggestionAnswer();
  SuggestionAnswer(const SuggestionAnswer& answer);
  SuggestionAnswer& operator=(const SuggestionAnswer& answer);
  ~SuggestionAnswer();

  // Parses |answer_json| and fills a SuggestionAnswer containing the
  // contents. Returns true on success. If the supplied data is not well
  // formed or is missing required elements, returns false instead.
  static bool ParseAnswer(const base::DictionaryValue* answer_json,
                          const base::string16& answer_type_str,
                          SuggestionAnswer* answer);

  const GURL& image_url() const { return image_url_; }
  const ImageLine& first_line() const { return first_line_; }
  const ImageLine& second_line() const { return second_line_; }

  // Answer type accessors.  Valid types are non-negative and defined at
  // https://goto.google.com/visual_element_configuration.
  int type() const { return type_; }
  void set_type(int type) { type_ = type; }

  bool Equals(const SuggestionAnswer& answer) const;

  // Retrieves any image URLs appearing in this answer and adds them to |urls|.
  void AddImageURLsTo(URLs* urls) const;

  // Estimates dynamic memory usage.
  // See base/trace_event/memory_usage_estimator.h for more info.
  size_t EstimateMemoryUsage() const;

  // For new answers, replace old answer text types with appropriate new types.
  void InterpretTextTypes();

 private:
  GURL image_url_;
  ImageLine first_line_;
  ImageLine second_line_;
  int type_ = -1;

  FRIEND_TEST_ALL_PREFIXES(SuggestionAnswerTest, DifferentValuesAreUnequal);
};

#endif  // COMPONENTS_OMNIBOX_BROWSER_SUGGESTION_ANSWER_H_