1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/search/contextual_search_promo_source_android.h"
9 #include "base/json/json_string_value_serializer.h"
10 #include "base/memory/ref_counted_memory.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/stringprintf.h"
13 #include "base/values.h"
14 #include "chrome/common/url_constants.h"
15 #include "chrome/grit/chromium_strings.h"
16 #include "components/variations/variations_associated_data.h"
17 #include "grit/browser_resources.h"
18 #include "ui/base/l10n/l10n_util.h"
19 #include "ui/base/resource/resource_bundle.h"
20 #include "ui/base/webui/jstemplate_builder.h"
25 const char kPromoConfigPath
[] = "/config.js";
26 const char kPromoHTMLPath
[] = "/promo.html";
27 const char kPromoCSSPath
[] = "/promo.css";
28 const char kPromoJSPath
[] = "/promo.js";
29 const char kRobotoWoffPath
[] = "/roboto.woff";
30 const char kRobotoWoff2Path
[] = "/roboto.woff2";
32 // Field trial related constants.
33 const char kContextualSearchFieldTrialName
[] = "ContextualSearch";
34 const char kContextualSearchHidePromoHeaderParam
[] = "hide_promo_header";
35 const char kContextualSearchEnabledValue
[] = "enabled";
37 // Returns whether we should hide the first-run promo header.
38 bool ShouldHidePromoHeader() {
39 return variations::GetVariationParamValue(
40 kContextualSearchFieldTrialName
, kContextualSearchHidePromoHeaderParam
) ==
41 kContextualSearchEnabledValue
;
44 // Returns a JS dictionary of configuration data for the Contextual Search
46 std::string
GetConfigData() {
47 base::DictionaryValue config_data
;
48 config_data
.SetBoolean("hideHeader", ShouldHidePromoHeader());
50 // Serialize the dictionary.
52 JSONStringValueSerializer
serializer(&js_text
);
53 serializer
.Serialize(config_data
);
55 std::string config_data_js
;
56 config_data_js
.append("var config = ");
57 config_data_js
.append(js_text
);
58 config_data_js
.append(";");
59 return config_data_js
;
64 ContextualSearchPromoSourceAndroid::ContextualSearchPromoSourceAndroid() {}
66 ContextualSearchPromoSourceAndroid::~ContextualSearchPromoSourceAndroid() {}
68 void ContextualSearchPromoSourceAndroid::StartDataRequest(
69 const std::string
& path_and_query
, int render_process_id
,
71 const content::URLDataSource::GotDataCallback
& callback
) {
72 GURL
url(std::string(chrome::kChromeUIContextualSearchPromoURL
) + "/" +
74 std::string
path(url
.path());
75 if (path
== kPromoHTMLPath
) {
76 SendHtmlWithStrings(callback
);
77 } else if (path
== kPromoCSSPath
) {
78 SendResource(IDR_CONTEXTUAL_SEARCH_PROMO_CSS
, callback
);
79 } else if (path
== kPromoJSPath
) {
80 SendResource(IDR_CONTEXTUAL_SEARCH_PROMO_JS
, callback
);
81 } else if (path
== kPromoConfigPath
) {
82 SendConfigResource(callback
);
83 } else if (path
== kRobotoWoffPath
) {
84 SendResource(IDR_ROBOTO_WOFF
, callback
);
85 } else if (path
== kRobotoWoff2Path
) {
86 SendResource(IDR_ROBOTO_WOFF2
, callback
);
92 std::string
ContextualSearchPromoSourceAndroid::GetSource() const {
93 return chrome::kChromeUIContextualSearchPromoHost
;
96 std::string
ContextualSearchPromoSourceAndroid::GetMimeType(
97 const std::string
& path_and_query
) const {
98 std::string
path(GURL("chrome://host/" + path_and_query
).path());
99 if (EndsWith(path
, ".js", false)) return "application/javascript";
100 if (EndsWith(path
, ".png", false)) return "image/png";
101 if (EndsWith(path
, ".css", false)) return "text/css";
102 if (EndsWith(path
, ".html", false)) return "text/html";
103 if (EndsWith(path
, ".woff", false)) return "font/woff";
104 if (EndsWith(path
, ".woff2", false)) return "font/woff2";
108 bool ContextualSearchPromoSourceAndroid::ShouldDenyXFrameOptions() const {
113 ContextualSearchPromoSourceAndroid::ShouldAddContentSecurityPolicy() const {
117 void ContextualSearchPromoSourceAndroid::SendResource(
118 int resource_id
, const content::URLDataSource::GotDataCallback
& callback
) {
119 scoped_refptr
<base::RefCountedStaticMemory
> response(
120 ResourceBundle::GetSharedInstance().LoadDataResourceBytes(resource_id
));
121 callback
.Run(response
.get());
124 void ContextualSearchPromoSourceAndroid::SendConfigResource(
125 const content::URLDataSource::GotDataCallback
& callback
) {
126 std::string response
= GetConfigData();
127 callback
.Run(base::RefCountedString::TakeString(&response
));
130 void ContextualSearchPromoSourceAndroid::SendHtmlWithStrings(
131 const content::URLDataSource::GotDataCallback
& callback
) {
132 base::DictionaryValue strings_data
;
133 // The three following statements are part of the description paragraph.
134 strings_data
.SetString(
136 l10n_util::GetStringUTF16(IDS_CONTEXTUAL_SEARCH_PROMO_DESCRIPTION_1
));
137 strings_data
.SetString(
139 l10n_util::GetStringUTF16(IDS_CONTEXTUAL_SEARCH_PROMO_FEATURE_NAME
));
140 strings_data
.SetString(
142 l10n_util::GetStringUTF16(IDS_CONTEXTUAL_SEARCH_PROMO_DESCRIPTION_2
));
144 strings_data
.SetString(
145 "heading", l10n_util::GetStringUTF16(IDS_CONTEXTUAL_SEARCH_HEADER
));
146 strings_data
.SetString(
147 "optIn", l10n_util::GetStringUTF16(IDS_CONTEXTUAL_SEARCH_PROMO_OPTIN
));
148 strings_data
.SetString(
149 "optOut", l10n_util::GetStringUTF16(IDS_CONTEXTUAL_SEARCH_PROMO_OPTOUT
));
150 base::StringPiece
html(
151 ResourceBundle::GetSharedInstance().GetRawDataResource(
152 IDR_CONTEXTUAL_SEARCH_PROMO_HTML
));
153 std::string
response(webui::GetI18nTemplateHtml(html
, &strings_data
));
154 callback
.Run(base::RefCountedString::TakeString(&response
));