| // Copyright 2014 The Chromium Authors |
| // 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/layer_title_cache.h" |
| |
| #include <android/bitmap.h> |
| |
| #include <memory> |
| |
| #include "base/android/token_android.h" |
| #include "cc/layers/layer.h" |
| #include "cc/layers/ui_resource_layer.h" |
| #include "chrome/browser/android/compositor/decoration_icon_title.h" |
| #include "chrome/browser/android/compositor/decoration_tab_title.h" |
| #include "chrome/browser/android/compositor/decoration_title.h" |
| #include "ui/android/resources/resource_manager.h" |
| #include "ui/android/resources/resource_manager_impl.h" |
| #include "ui/gfx/android/java_bitmap.h" |
| #include "ui/gfx/geometry/point_f.h" |
| #include "ui/gfx/geometry/rect_f.h" |
| #include "ui/gfx/geometry/size.h" |
| |
| // Must come after all headers that specialize FromJniType() / ToJniType(). |
| #include "chrome/android/chrome_jni_headers/LayerTitleCache_jni.h" |
| |
| using base::android::JavaParamRef; |
| using base::android::JavaRef; |
| |
| namespace android { |
| |
| // static |
| LayerTitleCache* LayerTitleCache::FromJavaObject(const JavaRef<jobject>& jobj) { |
| if (jobj.is_null()) |
| return nullptr; |
| return reinterpret_cast<LayerTitleCache*>(Java_LayerTitleCache_getNativePtr( |
| base::android::AttachCurrentThread(), jobj)); |
| } |
| |
| LayerTitleCache::LayerTitleCache(JNIEnv* env, |
| const jni_zero::JavaRef<jobject>& obj, |
| jint fade_width, |
| jint icon_start_padding, |
| jint icon_end_padding, |
| jint spinner_resource_id, |
| jint spinner_incognito_resource_id, |
| jint bubble_inner_dimension, |
| jint bubble_outer_dimension, |
| jint bubble_offset, |
| jint bubble_inner_tint, |
| jint bubble_outer_tint, |
| ui::ResourceManager* resource_manager) |
| : weak_java_title_cache_(env, obj), |
| fade_width_(fade_width), |
| icon_start_padding_(icon_start_padding), |
| icon_end_padding_(icon_end_padding), |
| spinner_resource_id_(spinner_resource_id), |
| spinner_incognito_resource_id_(spinner_incognito_resource_id), |
| bubble_inner_dimension_(bubble_inner_dimension), |
| bubble_outer_dimension_(bubble_outer_dimension), |
| bubble_offset_(bubble_offset), |
| bubble_inner_tint_(bubble_inner_tint), |
| bubble_outer_tint_(bubble_outer_tint), |
| resource_manager_(resource_manager) {} |
| |
| void LayerTitleCache::Destroy(JNIEnv* env) { |
| delete this; |
| } |
| |
| void LayerTitleCache::UpdateLayer(JNIEnv* env, |
| jint tab_id, |
| jint title_resource_id, |
| jint icon_resource_id, |
| bool is_incognito, |
| bool is_rtl, |
| bool show_bubble) { |
| DecorationTabTitle* title_layer = layer_cache_.Lookup(tab_id); |
| if (title_layer) { |
| if (title_resource_id != ui::Resource::kInvalidResourceId && |
| icon_resource_id != ui::Resource::kInvalidResourceId) { |
| title_layer->Update(title_resource_id, icon_resource_id, fade_width_, |
| icon_start_padding_, icon_end_padding_, is_incognito, |
| is_rtl, show_bubble); |
| } else { |
| layer_cache_.Remove(tab_id); |
| } |
| } else { |
| layer_cache_.AddWithID( |
| std::make_unique<DecorationTabTitle>( |
| resource_manager_, title_resource_id, icon_resource_id, |
| spinner_resource_id_, spinner_incognito_resource_id_, fade_width_, |
| icon_start_padding_, icon_end_padding_, is_incognito, is_rtl, |
| show_bubble, bubble_inner_dimension_, bubble_outer_dimension_, |
| bubble_offset_, bubble_inner_tint_, bubble_outer_tint_), |
| tab_id); |
| } |
| } |
| |
| void LayerTitleCache::UpdateGroupLayer( |
| JNIEnv* env, |
| const base::android::JavaParamRef<jobject>& jgroup_token, |
| jint title_resource_id, |
| jint avatar_resource_id, |
| jint avatar_padding, |
| bool is_incognito, |
| bool is_rtl) { |
| const tab_groups::TabGroupId& group_token = |
| tab_groups::TabGroupId::FromRawToken( |
| base::android::TokenAndroid::FromJavaToken(env, jgroup_token)); |
| auto it = group_layer_cache_.find(group_token); |
| if (it != group_layer_cache_.end()) { |
| DecorationIconTitle* title_layer = it->second.get(); |
| if (title_resource_id != ui::Resource::kInvalidResourceId) { |
| title_layer->Update(title_resource_id, avatar_resource_id, fade_width_, |
| kEmptyWidth, avatar_padding, is_incognito, is_rtl); |
| } else { |
| group_layer_cache_.erase(it); |
| } |
| } else { |
| group_layer_cache_.emplace( |
| group_token, |
| std::make_unique<DecorationIconTitle>( |
| resource_manager_, title_resource_id, avatar_resource_id, |
| fade_width_, kEmptyWidth, avatar_padding, is_incognito, is_rtl)); |
| } |
| } |
| |
| void LayerTitleCache::UpdateIcon(JNIEnv* env, |
| jint tab_id, |
| jint icon_resource_id, |
| bool show_bubble) { |
| DecorationTabTitle* title_layer = layer_cache_.Lookup(tab_id); |
| if (title_layer && icon_resource_id != ui::Resource::kInvalidResourceId) { |
| title_layer->SetIconResourceId(icon_resource_id); |
| } |
| } |
| |
| void LayerTitleCache::UpdateTabBubble(JNIEnv* env, |
| jint tab_id, |
| bool show_bubble) { |
| DecorationTabTitle* title_layer = layer_cache_.Lookup(tab_id); |
| if (title_layer) { |
| title_layer->SetShowBubble(show_bubble); |
| } |
| } |
| |
| DecorationTabTitle* LayerTitleCache::GetTitleLayer(int tab_id) { |
| if (!layer_cache_.Lookup(tab_id)) { |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| Java_LayerTitleCache_buildUpdatedTitle(env, weak_java_title_cache_.get(env), |
| tab_id); |
| } |
| |
| return layer_cache_.Lookup(tab_id); |
| } |
| |
| DecorationIconTitle* LayerTitleCache::GetGroupTitleLayer( |
| const tab_groups::TabGroupId& group_token, |
| bool incognito) { |
| auto it = group_layer_cache_.find(group_token); |
| if (it != group_layer_cache_.end()) { |
| return it->second.get(); |
| } |
| |
| JNIEnv* env = base::android::AttachCurrentThread(); |
| Java_LayerTitleCache_buildUpdatedGroupTitle( |
| env, weak_java_title_cache_.get(env), |
| base::android::TokenAndroid::Create(env, group_token.token()), incognito); |
| |
| // Retry the find. |
| it = group_layer_cache_.find(group_token); |
| return it == group_layer_cache_.end() ? nullptr : it->second.get(); |
| } |
| |
| LayerTitleCache::~LayerTitleCache() = default; |
| |
| // ---------------------------------------------------------------------------- |
| // Native JNI methods |
| // ---------------------------------------------------------------------------- |
| |
| jlong JNI_LayerTitleCache_Init(JNIEnv* env, |
| const JavaParamRef<jobject>& obj, |
| jint fade_width, |
| jint icon_start_padding, |
| jint icon_end_padding, |
| jint spinner_resource_id, |
| jint spinner_incognito_resource_id, |
| jint bubble_inner_dimension, |
| jint bubble_outer_dimension, |
| jint bubble_offset, |
| jint bubble_inner_tint, |
| jint bubble_outer_tint, |
| const JavaParamRef<jobject>& jresource_manager) { |
| ui::ResourceManager* resource_manager = |
| ui::ResourceManagerImpl::FromJavaObject(jresource_manager); |
| LayerTitleCache* cache = new LayerTitleCache( |
| env, obj, fade_width, icon_start_padding, icon_end_padding, |
| spinner_resource_id, spinner_incognito_resource_id, |
| bubble_inner_dimension, bubble_outer_dimension, bubble_offset, |
| bubble_inner_tint, bubble_outer_tint, resource_manager); |
| return reinterpret_cast<intptr_t>(cache); |
| } |
| |
| } // namespace android |