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