blob: 90503f46daccedbc5332137409a4235855bb436c [file] [log] [blame]
// Copyright 2015 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.
#include "chrome/browser/android/compositor/scene_layer/contextual_search_scene_layer.h"
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "cc/layers/solid_color_layer.h"
#include "chrome/android/chrome_jni_headers/ContextualSearchSceneLayer_jni.h"
#include "chrome/browser/android/compositor/layer/contextual_search_layer.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_android.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/browser/web_contents.h"
#include "net/base/load_flags.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/referrer_policy.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "ui/android/resources/resource_manager_impl.h"
#include "ui/android/view_android.h"
#include "ui/gfx/android/java_bitmap.h"
#include "ui/gfx/geometry/size_conversions.h"
using base::android::JavaParamRef;
using base::android::JavaRef;
namespace android {
ContextualSearchSceneLayer::ContextualSearchSceneLayer(
JNIEnv* env,
const JavaRef<jobject>& jobj)
: SceneLayer(env, jobj),
env_(env),
object_(jobj),
color_overlay_(cc::SolidColorLayer::Create()),
content_container_(cc::Layer::Create()) {
// Responsible for moving the base page without modifying the layer itself.
content_container_->SetIsDrawable(true);
content_container_->SetPosition(gfx::PointF(0.0f, 0.0f));
layer()->AddChild(content_container_);
color_overlay_->SetIsDrawable(true);
color_overlay_->SetOpacity(0.0f);
color_overlay_->SetBackgroundColor(SK_ColorBLACK);
color_overlay_->SetPosition(gfx::PointF(0.f, 0.f));
layer()->AddChild(color_overlay_);
}
void ContextualSearchSceneLayer::CreateContextualSearchLayer(
JNIEnv* env,
const JavaParamRef<jobject>& object,
const JavaParamRef<jobject>& jresource_manager) {
ui::ResourceManager* resource_manager =
ui::ResourceManagerImpl::FromJavaObject(jresource_manager);
contextual_search_layer_ = ContextualSearchLayer::Create(resource_manager);
// The Contextual Search layer is initially invisible.
contextual_search_layer_->layer()->SetHideLayerAndSubtree(true);
layer()->AddChild(contextual_search_layer_->layer());
}
ContextualSearchSceneLayer::~ContextualSearchSceneLayer() {
}
void ContextualSearchSceneLayer::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 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 close_icon_opacity,
jboolean progress_bar_visible,
jfloat progress_bar_height,
jfloat progress_bar_opacity,
jfloat progress_bar_completion,
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) {
// Load the thumbnail if necessary.
std::string thumbnail_url =
base::android::ConvertJavaStringToUTF8(env, j_thumbnail_url);
if (thumbnail_url != thumbnail_url_) {
thumbnail_url_ = thumbnail_url;
FetchThumbnail(j_profile);
}
// NOTE(pedrosimonetti): The WebContents might not exist at this time if
// the Contextual Search Result has not been requested yet. In this case,
// we'll pass NULL to Contextual Search's Layer Tree.
content::WebContents* web_contents =
content::WebContents::FromJavaWebContents(jweb_contents);
scoped_refptr<cc::Layer> content_layer =
web_contents ? web_contents->GetNativeView()->GetLayer() : nullptr;
// Fade the base page out.
color_overlay_->SetOpacity(1.f - base_page_brightness);
color_overlay_->SetBounds(
gfx::ToCeiledSize(gfx::SizeF(layout_width, layout_height)));
// Move the base page contents up.
content_container_->SetPosition(gfx::PointF(0.0f, base_page_offset));
contextual_search_layer_->SetProperties(
search_bar_background_resource_id, search_bar_background_color,
search_context_resource_id, search_term_resource_id,
search_caption_resource_id, search_bar_shadow_resource_id,
search_provider_icon_resource_id, quick_action_icon_resource_id,
drag_handlebar_resource_id, open_tab_icon_resource_id,
close_icon_resource_id, progress_bar_background_resource_id,
progress_bar_resource_id, search_promo_resource_id,
bar_banner_ripple_resource_id, bar_banner_text_resource_id, dp_to_px,
content_layer, search_promo_visible, search_promo_height,
search_promo_opacity, search_promo_background_color,
search_bar_banner_visible, search_bar_banner_height,
search_bar_banner_padding, search_bar_banner_ripple_width,
search_bar_banner_ripple_opacity, search_bar_banner_text_opacity,
search_panel_x, search_panel_y, search_panel_width, search_panel_height,
search_bar_margin_side, search_bar_margin_top, search_bar_height,
search_context_opacity, search_text_layer_min_height, search_term_opacity,
search_term_caption_spacing, search_caption_animation_percentage,
search_caption_visible, search_bar_border_visible,
search_bar_border_height, quick_action_icon_visible, thumbnail_visible,
custom_image_visibility_percentage, bar_image_size, icon_color,
drag_handlebar_color, close_icon_opacity, progress_bar_visible,
progress_bar_height, progress_bar_opacity, progress_bar_completion,
touch_highlight_visible, touch_highlight_x_offset, touch_highlight_width,
rounded_bar_top_resource_id, separator_line_color);
// Make the layer visible if it is not already.
contextual_search_layer_->layer()->SetHideLayerAndSubtree(false);
}
void ContextualSearchSceneLayer::FetchThumbnail(
const JavaRef<jobject>& j_profile) {
if (thumbnail_url_.empty())
return;
GURL gurl(thumbnail_url_);
Profile* profile = ProfileAndroid::FromProfileAndroid(j_profile);
network::mojom::URLLoaderFactory* loader_factory =
content::BrowserContext::GetDefaultStoragePartition(profile)
->GetURLLoaderFactoryForBrowserProcess()
.get();
fetcher_ =
std::make_unique<BitmapFetcher>(gurl, this, NO_TRAFFIC_ANNOTATION_YET);
fetcher_->Init(
std::string(),
net::ReferrerPolicy::REDUCE_GRANULARITY_ON_TRANSITION_CROSS_ORIGIN,
network::mojom::CredentialsMode::kInclude);
fetcher_->Start(loader_factory);
}
void ContextualSearchSceneLayer::OnFetchComplete(const GURL& url,
const SkBitmap* bitmap) {
bool success = bitmap && !bitmap->drawsNothing();
Java_ContextualSearchSceneLayer_onThumbnailFetched(env_, object_, success);
if (success)
contextual_search_layer_->SetThumbnail(bitmap);
fetcher_.reset();
}
void ContextualSearchSceneLayer::SetContentTree(
JNIEnv* env,
const JavaParamRef<jobject>& jobj,
const JavaParamRef<jobject>& jcontent_tree) {
SceneLayer* content_tree = FromJavaObject(env, jcontent_tree);
if (!content_tree || !content_tree->layer()) return;
if (!content_tree->layer()->parent()
|| (content_tree->layer()->parent()->id() != content_container_->id())) {
content_container_->AddChild(content_tree->layer());
}
}
void ContextualSearchSceneLayer::HideTree(JNIEnv* env,
const JavaParamRef<jobject>& jobj) {
// TODO(mdjones): Create super class for this logic.
if (contextual_search_layer_) {
contextual_search_layer_->layer()->SetHideLayerAndSubtree(true);
}
// Reset base page brightness.
color_overlay_->SetOpacity(0.f);
// Reset base page offset.
content_container_->SetPosition(gfx::PointF(0.0f, 0.0f));
}
static jlong JNI_ContextualSearchSceneLayer_Init(
JNIEnv* env,
const JavaParamRef<jobject>& jobj) {
// This will automatically bind to the Java object and pass ownership there.
ContextualSearchSceneLayer* tree_provider =
new ContextualSearchSceneLayer(env, jobj);
return reinterpret_cast<intptr_t>(tree_provider);
}
} // namespace android