1 // Copyright 2015 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.
4
5 #include "chrome/browser/android/compositor/scene_layer/contextual_search_scene_layer.h"
6
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_array.h"
9 #include "base/android/jni_string.h"
10 #include "cc/layers/solid_color_layer.h"
11 #include "chrome/android/chrome_jni_headers/ContextualSearchSceneLayer_jni.h"
12 #include "chrome/browser/android/compositor/layer/contextual_search_layer.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/profiles/profile_android.h"
15 #include "content/public/browser/storage_partition.h"
16 #include "content/public/browser/web_contents.h"
17 #include "net/base/load_flags.h"
18 #include "net/traffic_annotation/network_traffic_annotation.h"
19 #include "net/url_request/referrer_policy.h"
20 #include "services/network/public/mojom/url_loader_factory.mojom.h"
21 #include "ui/android/resources/resource_manager_impl.h"
22 #include "ui/android/view_android.h"
23 #include "ui/gfx/android/java_bitmap.h"
24 #include "ui/gfx/geometry/size_conversions.h"
25
26 using base::android::JavaParamRef;
27 using base::android::JavaRef;
28
29 namespace android {
30
ContextualSearchSceneLayer(JNIEnv * env,const JavaRef<jobject> & jobj)31 ContextualSearchSceneLayer::ContextualSearchSceneLayer(
32 JNIEnv* env,
33 const JavaRef<jobject>& jobj)
34 : SceneLayer(env, jobj),
35 env_(env),
36 object_(jobj),
37 color_overlay_(cc::SolidColorLayer::Create()),
38 content_container_(cc::Layer::Create()) {
39 // Responsible for moving the base page without modifying the layer itself.
40 content_container_->SetIsDrawable(true);
41 content_container_->SetPosition(gfx::PointF(0.0f, 0.0f));
42 layer()->AddChild(content_container_);
43
44 color_overlay_->SetIsDrawable(true);
45 color_overlay_->SetOpacity(0.0f);
46 color_overlay_->SetBackgroundColor(SK_ColorBLACK);
47 color_overlay_->SetPosition(gfx::PointF(0.f, 0.f));
48 layer()->AddChild(color_overlay_);
49 }
50
CreateContextualSearchLayer(JNIEnv * env,const JavaParamRef<jobject> & object,const JavaParamRef<jobject> & jresource_manager)51 void ContextualSearchSceneLayer::CreateContextualSearchLayer(
52 JNIEnv* env,
53 const JavaParamRef<jobject>& object,
54 const JavaParamRef<jobject>& jresource_manager) {
55 ui::ResourceManager* resource_manager =
56 ui::ResourceManagerImpl::FromJavaObject(jresource_manager);
57 contextual_search_layer_ = ContextualSearchLayer::Create(resource_manager);
58
59 // The Contextual Search layer is initially invisible.
60 contextual_search_layer_->layer()->SetHideLayerAndSubtree(true);
61
62 layer()->AddChild(contextual_search_layer_->layer());
63 }
64
~ContextualSearchSceneLayer()65 ContextualSearchSceneLayer::~ContextualSearchSceneLayer() {
66 }
67
UpdateContextualSearchLayer(JNIEnv * env,const JavaParamRef<jobject> & object,jint search_bar_background_resource_id,jint search_bar_background_color,jint search_context_resource_id,jint search_term_resource_id,jint search_caption_resource_id,jint search_bar_shadow_resource_id,jint search_provider_icon_resource_id,jint quick_action_icon_resource_id,jint arrow_up_resource_id,jint drag_handlebar_resource_id,jint open_tab_icon_resource_id,jint close_icon_resource_id,jint progress_bar_background_resource_id,jint progress_bar_resource_id,jint search_promo_resource_id,jint bar_banner_ripple_resource_id,jint bar_banner_text_resource_id,jfloat dp_to_px,jfloat layout_width,jfloat layout_height,jfloat base_page_brightness,jfloat base_page_offset,const JavaParamRef<jobject> & jweb_contents,jboolean search_promo_visible,jfloat search_promo_height,jfloat search_promo_opacity,jint search_promo_background_color,jboolean search_bar_banner_visible,jfloat search_bar_banner_height,jfloat search_bar_banner_padding,jfloat search_bar_banner_ripple_width,jfloat search_bar_banner_ripple_opacity,jfloat search_bar_banner_text_opacity,jfloat search_panel_x,jfloat search_panel_y,jfloat search_panel_width,jfloat search_panel_height,jfloat search_bar_margin_side,jfloat search_bar_margin_top,jfloat search_bar_height,jfloat search_context_opacity,jfloat search_text_layer_min_height,jfloat search_term_opacity,jfloat search_term_caption_spacing,jfloat search_caption_animation_percentage,jboolean search_caption_visible,jboolean search_bar_border_visible,jfloat search_bar_border_height,jboolean quick_action_icon_visible,jboolean thumbnail_visible,jstring j_thumbnail_url,jfloat custom_image_visibility_percentage,jint bar_image_size,jint icon_color,jint drag_handlebar_color,jfloat arrow_icon_opacity,jfloat arrow_icon_rotation,jfloat close_icon_opacity,jboolean progress_bar_visible,jfloat progress_bar_height,jfloat progress_bar_opacity,jfloat progress_bar_completion,jfloat divider_line_visibility_percentage,jfloat divider_line_width,jfloat divider_line_height,jint divider_line_color,jfloat divider_line_x_offset,jboolean touch_highlight_visible,jfloat touch_highlight_x_offset,jfloat touch_highlight_width,const JavaRef<jobject> & j_profile,jint rounded_bar_top_resource_id,jint separator_line_color)68 void ContextualSearchSceneLayer::UpdateContextualSearchLayer(
69 JNIEnv* env,
70 const JavaParamRef<jobject>& object,
71 jint search_bar_background_resource_id,
72 jint search_bar_background_color,
73 jint search_context_resource_id,
74 jint search_term_resource_id,
75 jint search_caption_resource_id,
76 jint search_bar_shadow_resource_id,
77 jint search_provider_icon_resource_id,
78 jint quick_action_icon_resource_id,
79 jint arrow_up_resource_id,
80 jint drag_handlebar_resource_id,
81 jint open_tab_icon_resource_id,
82 jint close_icon_resource_id,
83 jint progress_bar_background_resource_id,
84 jint progress_bar_resource_id,
85 jint search_promo_resource_id,
86 jint bar_banner_ripple_resource_id,
87 jint bar_banner_text_resource_id,
88 jfloat dp_to_px,
89 jfloat layout_width,
90 jfloat layout_height,
91 jfloat base_page_brightness,
92 jfloat base_page_offset,
93 const JavaParamRef<jobject>& jweb_contents,
94 jboolean search_promo_visible,
95 jfloat search_promo_height,
96 jfloat search_promo_opacity,
97 jint search_promo_background_color,
98 jboolean search_bar_banner_visible,
99 jfloat search_bar_banner_height,
100 jfloat search_bar_banner_padding,
101 jfloat search_bar_banner_ripple_width,
102 jfloat search_bar_banner_ripple_opacity,
103 jfloat search_bar_banner_text_opacity,
104 jfloat search_panel_x,
105 jfloat search_panel_y,
106 jfloat search_panel_width,
107 jfloat search_panel_height,
108 jfloat search_bar_margin_side,
109 jfloat search_bar_margin_top,
110 jfloat search_bar_height,
111 jfloat search_context_opacity,
112 jfloat search_text_layer_min_height,
113 jfloat search_term_opacity,
114 jfloat search_term_caption_spacing,
115 jfloat search_caption_animation_percentage,
116 jboolean search_caption_visible,
117 jboolean search_bar_border_visible,
118 jfloat search_bar_border_height,
119 jboolean quick_action_icon_visible,
120 jboolean thumbnail_visible,
121 jstring j_thumbnail_url,
122 jfloat custom_image_visibility_percentage,
123 jint bar_image_size,
124 jint icon_color,
125 jint drag_handlebar_color,
126 jfloat arrow_icon_opacity,
127 jfloat arrow_icon_rotation,
128 jfloat close_icon_opacity,
129 jboolean progress_bar_visible,
130 jfloat progress_bar_height,
131 jfloat progress_bar_opacity,
132 jfloat progress_bar_completion,
133 jfloat divider_line_visibility_percentage,
134 jfloat divider_line_width,
135 jfloat divider_line_height,
136 jint divider_line_color,
137 jfloat divider_line_x_offset,
138 jboolean touch_highlight_visible,
139 jfloat touch_highlight_x_offset,
140 jfloat touch_highlight_width,
141 const JavaRef<jobject>& j_profile,
142 jint rounded_bar_top_resource_id,
143 jint separator_line_color) {
144 // Load the thumbnail if necessary.
145 std::string thumbnail_url =
146 base::android::ConvertJavaStringToUTF8(env, j_thumbnail_url);
147 if (thumbnail_url != thumbnail_url_) {
148 thumbnail_url_ = thumbnail_url;
149 FetchThumbnail(j_profile);
150 }
151
152 // NOTE(pedrosimonetti): The WebContents might not exist at this time if
153 // the Contextual Search Result has not been requested yet. In this case,
154 // we'll pass NULL to Contextual Search's Layer Tree.
155 content::WebContents* web_contents =
156 content::WebContents::FromJavaWebContents(jweb_contents);
157
158 scoped_refptr<cc::Layer> content_layer =
159 web_contents ? web_contents->GetNativeView()->GetLayer() : nullptr;
160
161 // Fade the base page out.
162 color_overlay_->SetOpacity(1.f - base_page_brightness);
163 color_overlay_->SetBounds(
164 gfx::ToCeiledSize(gfx::SizeF(layout_width, layout_height)));
165
166 // Move the base page contents up.
167 content_container_->SetPosition(gfx::PointF(0.0f, base_page_offset));
168
169 contextual_search_layer_->SetProperties(
170 search_bar_background_resource_id, search_bar_background_color,
171 search_context_resource_id, search_term_resource_id,
172 search_caption_resource_id, search_bar_shadow_resource_id,
173 search_provider_icon_resource_id, quick_action_icon_resource_id,
174 arrow_up_resource_id, drag_handlebar_resource_id,
175 open_tab_icon_resource_id, close_icon_resource_id,
176 progress_bar_background_resource_id, progress_bar_resource_id,
177 search_promo_resource_id, bar_banner_ripple_resource_id,
178 bar_banner_text_resource_id, dp_to_px, content_layer,
179 search_promo_visible, search_promo_height, search_promo_opacity,
180 search_promo_background_color, search_bar_banner_visible,
181 search_bar_banner_height, search_bar_banner_padding,
182 search_bar_banner_ripple_width, search_bar_banner_ripple_opacity,
183 search_bar_banner_text_opacity, search_panel_x, search_panel_y,
184 search_panel_width, search_panel_height, search_bar_margin_side,
185 search_bar_margin_top, search_bar_height, search_context_opacity,
186 search_text_layer_min_height, search_term_opacity,
187 search_term_caption_spacing, search_caption_animation_percentage,
188 search_caption_visible, search_bar_border_visible,
189 search_bar_border_height, quick_action_icon_visible, thumbnail_visible,
190 custom_image_visibility_percentage, bar_image_size, icon_color,
191 drag_handlebar_color, arrow_icon_opacity, arrow_icon_rotation,
192 close_icon_opacity, progress_bar_visible, progress_bar_height,
193 progress_bar_opacity, progress_bar_completion,
194 divider_line_visibility_percentage, divider_line_width,
195 divider_line_height, divider_line_color, divider_line_x_offset,
196 touch_highlight_visible, touch_highlight_x_offset, touch_highlight_width,
197 rounded_bar_top_resource_id, separator_line_color);
198
199 // Make the layer visible if it is not already.
200 contextual_search_layer_->layer()->SetHideLayerAndSubtree(false);
201 }
202
FetchThumbnail(const JavaRef<jobject> & j_profile)203 void ContextualSearchSceneLayer::FetchThumbnail(
204 const JavaRef<jobject>& j_profile) {
205 if (thumbnail_url_.empty())
206 return;
207
208 GURL gurl(thumbnail_url_);
209 Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
210 network::mojom::URLLoaderFactory* loader_factory =
211 content::BrowserContext::GetDefaultStoragePartition(profile)
212 ->GetURLLoaderFactoryForBrowserProcess()
213 .get();
214 fetcher_ =
215 std::make_unique<BitmapFetcher>(gurl, this, NO_TRAFFIC_ANNOTATION_YET);
216 fetcher_->Init(
217 std::string(),
218 net::ReferrerPolicy::REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
219 network::mojom::CredentialsMode::kInclude);
220 fetcher_->Start(loader_factory);
221 }
222
OnFetchComplete(const GURL & url,const SkBitmap * bitmap)223 void ContextualSearchSceneLayer::OnFetchComplete(const GURL& url,
224 const SkBitmap* bitmap) {
225 bool success = bitmap && !bitmap->drawsNothing();
226 Java_ContextualSearchSceneLayer_onThumbnailFetched(env_, object_, success);
227 if (success)
228 contextual_search_layer_->SetThumbnail(bitmap);
229
230 fetcher_.reset();
231 }
232
SetContentTree(JNIEnv * env,const JavaParamRef<jobject> & jobj,const JavaParamRef<jobject> & jcontent_tree)233 void ContextualSearchSceneLayer::SetContentTree(
234 JNIEnv* env,
235 const JavaParamRef<jobject>& jobj,
236 const JavaParamRef<jobject>& jcontent_tree) {
237 SceneLayer* content_tree = FromJavaObject(env, jcontent_tree);
238 if (!content_tree || !content_tree->layer()) return;
239
240 if (!content_tree->layer()->parent()
241 || (content_tree->layer()->parent()->id() != content_container_->id())) {
242 content_container_->AddChild(content_tree->layer());
243 }
244 }
245
HideTree(JNIEnv * env,const JavaParamRef<jobject> & jobj)246 void ContextualSearchSceneLayer::HideTree(JNIEnv* env,
247 const JavaParamRef<jobject>& jobj) {
248 // TODO(mdjones): Create super class for this logic.
249 if (contextual_search_layer_) {
250 contextual_search_layer_->layer()->SetHideLayerAndSubtree(true);
251 }
252 // Reset base page brightness.
253 color_overlay_->SetOpacity(0.f);
254 // Reset base page offset.
255 content_container_->SetPosition(gfx::PointF(0.0f, 0.0f));
256 }
257
JNI_ContextualSearchSceneLayer_Init(JNIEnv * env,const JavaParamRef<jobject> & jobj)258 static jlong JNI_ContextualSearchSceneLayer_Init(
259 JNIEnv* env,
260 const JavaParamRef<jobject>& jobj) {
261 // This will automatically bind to the Java object and pass ownership there.
262 ContextualSearchSceneLayer* tree_provider =
263 new ContextualSearchSceneLayer(env, jobj);
264 return reinterpret_cast<intptr_t>(tree_provider);
265 }
266
267 } // namespace android
268