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.
5 #include "chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h"
7 #include "base/android/jni_android.h"
8 #include "chrome/browser/android/compositor/layer/tab_handle_layer.h"
9 #include "chrome/browser/android/compositor/layer_title_cache.h"
10 #include "content/public/browser/android/compositor.h"
11 #include "jni/TabStripSceneLayer_jni.h"
12 #include "ui/android/resources/resource_manager_impl.h"
13 #include "ui/android/resources/ui_resource_android.h"
18 TabStripSceneLayer::TabStripSceneLayer(JNIEnv
* env
, jobject jobj
)
19 : SceneLayer(env
, jobj
),
21 cc::SolidColorLayer::Create(content::Compositor::LayerSettings())),
23 cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
24 model_selector_button_(
25 cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
26 background_tab_brightness_(1.f
),
29 content_tree_(nullptr) {
30 new_tab_button_
->SetIsDrawable(true);
31 model_selector_button_
->SetIsDrawable(true);
32 tab_strip_layer_
->SetBackgroundColor(SK_ColorBLACK
);
33 tab_strip_layer_
->SetIsDrawable(true);
34 tab_strip_layer_
->AddChild(new_tab_button_
);
35 tab_strip_layer_
->AddChild(model_selector_button_
);
36 layer()->AddChild(tab_strip_layer_
);
39 TabStripSceneLayer::~TabStripSceneLayer() {
42 void TabStripSceneLayer::SetContentTree(JNIEnv
* env
,
44 jobject jcontent_tree
) {
45 SceneLayer
* content_tree
= FromJavaObject(env
, jcontent_tree
);
47 (!content_tree_
->layer()->parent() ||
48 content_tree_
->layer()->parent()->id() != layer()->id()))
49 content_tree_
= nullptr;
51 if (content_tree
!= content_tree_
) {
53 content_tree_
->layer()->RemoveFromParent();
54 content_tree_
= content_tree
;
56 layer()->InsertChild(content_tree
->layer(), 0);
57 content_tree
->layer()->SetPosition(
58 gfx::PointF(0, -layer()->position().y()));
63 void TabStripSceneLayer::BeginBuildingFrame(JNIEnv
* env
,
67 tab_strip_layer_
->SetHideLayerAndSubtree(!visible
);
70 void TabStripSceneLayer::FinishBuildingFrame(JNIEnv
* env
, jobject jobj
) {
71 if (tab_strip_layer_
->hide_layer_and_subtree())
74 for (unsigned i
= write_index_
; i
< tab_handle_layers_
.size(); ++i
)
75 tab_handle_layers_
[i
]->layer()->RemoveFromParent();
77 tab_handle_layers_
.erase(tab_handle_layers_
.begin() + write_index_
,
78 tab_handle_layers_
.end());
81 void TabStripSceneLayer::UpdateTabStripLayer(JNIEnv
* env
,
86 jfloat background_tab_brightness
,
88 jboolean should_readd_background
) {
89 background_tab_brightness_
= background_tab_brightness
;
90 gfx::RectF
content(0, y_offset
, width
, height
);
91 layer()->SetPosition(gfx::PointF(0, y_offset
));
92 tab_strip_layer_
->SetBounds(gfx::Size(width
, height
));
94 if (brightness
!= brightness_
) {
95 brightness_
= brightness
;
96 cc::FilterOperations filters
;
97 if (brightness_
< 1.f
)
98 filters
.Append(cc::FilterOperation::CreateBrightnessFilter(brightness_
));
99 tab_strip_layer_
->SetFilters(filters
);
102 // Content tree should not be affected by tab strip scene layer visibility.
104 content_tree_
->layer()->SetPosition(gfx::PointF(0, -y_offset
));
106 // Make sure tab strip changes are committed after rotating the device.
107 // See https://crbug.com/503930 for more details.
108 // InsertChild() forces the tree sync, which seems to fix the problem.
109 // Note that this is a workaround.
110 // TODO(changwan): find out why the update is not committed after rotation.
111 if (should_readd_background
) {
112 int background_index
= 0;
113 if (content_tree_
&& content_tree_
->layer()) {
114 background_index
= 1;
116 DCHECK(layer()->children()[background_index
] == tab_strip_layer_
);
117 layer()->InsertChild(tab_strip_layer_
, background_index
);
121 void TabStripSceneLayer::UpdateNewTabButton(JNIEnv
* env
,
129 jobject jresource_manager
) {
130 ui::ResourceManager
* resource_manager
=
131 ui::ResourceManagerImpl::FromJavaObject(jresource_manager
);
132 ui::ResourceManager::Resource
* button_resource
=
133 resource_manager
->GetResource(ui::ANDROID_RESOURCE_TYPE_STATIC
,
136 new_tab_button_
->SetUIResourceId(button_resource
->ui_resource
->id());
137 float left_offset
= (width
- button_resource
->size
.width()) / 2;
138 float top_offset
= (height
- button_resource
->size
.height()) / 2;
139 new_tab_button_
->SetPosition(gfx::PointF(x
+ left_offset
, y
+ top_offset
));
140 new_tab_button_
->SetBounds(button_resource
->size
);
141 new_tab_button_
->SetHideLayerAndSubtree(!visible
);
144 void TabStripSceneLayer::UpdateModelSelectorButton(JNIEnv
* env
,
153 jobject jresource_manager
) {
154 ui::ResourceManager
* resource_manager
=
155 ui::ResourceManagerImpl::FromJavaObject(jresource_manager
);
156 ui::ResourceManager::Resource
* button_resource
=
157 resource_manager
->GetResource(ui::ANDROID_RESOURCE_TYPE_STATIC
,
160 model_selector_button_
->SetUIResourceId(button_resource
->ui_resource
->id());
161 float left_offset
= (width
- button_resource
->size
.width()) / 2;
162 float top_offset
= (height
- button_resource
->size
.height()) / 2;
163 model_selector_button_
->SetPosition(
164 gfx::PointF(x
+ left_offset
, y
+ top_offset
));
165 model_selector_button_
->SetBounds(button_resource
->size
);
166 model_selector_button_
->SetHideLayerAndSubtree(!visible
);
169 void TabStripSceneLayer::PutStripTabLayer(JNIEnv
* env
,
172 jint close_resource_id
,
173 jint handle_resource_id
,
175 jboolean close_pressed
,
176 jfloat toolbar_width
,
181 jfloat content_offset_x
,
182 jfloat close_button_alpha
,
184 jfloat spinner_rotation
,
185 jfloat border_opacity
,
186 jobject jlayer_title_cache
,
187 jobject jresource_manager
) {
188 LayerTitleCache
* layer_title_cache
=
189 LayerTitleCache::FromJavaObject(jlayer_title_cache
);
190 ui::ResourceManager
* resource_manager
=
191 ui::ResourceManagerImpl::FromJavaObject(jresource_manager
);
192 scoped_refptr
<TabHandleLayer
> layer
= GetNextLayer(layer_title_cache
);
193 ui::ResourceManager::Resource
* tab_handle_resource
=
194 resource_manager
->GetResource(ui::ANDROID_RESOURCE_TYPE_STATIC
,
196 ui::ResourceManager::Resource
* close_button_resource
=
197 resource_manager
->GetResource(ui::ANDROID_RESOURCE_TYPE_STATIC
,
199 layer
->SetProperties(id
, close_button_resource
, tab_handle_resource
,
200 foreground
, close_pressed
, toolbar_width
, x
, y
, width
,
201 height
, content_offset_x
, close_button_alpha
, is_loading
,
202 spinner_rotation
, background_tab_brightness_
,
206 scoped_refptr
<TabHandleLayer
> TabStripSceneLayer::GetNextLayer(
207 LayerTitleCache
* layer_title_cache
) {
208 if (write_index_
< tab_handle_layers_
.size())
209 return tab_handle_layers_
[write_index_
++];
211 scoped_refptr
<TabHandleLayer
> layer_tree
=
212 TabHandleLayer::Create(layer_title_cache
);
213 tab_handle_layers_
.push_back(layer_tree
);
214 tab_strip_layer_
->AddChild(layer_tree
->layer());
219 static jlong
Init(JNIEnv
* env
, const JavaParamRef
<jobject
>& jobj
) {
220 // This will automatically bind to the Java object and pass ownership there.
221 TabStripSceneLayer
* scene_layer
= new TabStripSceneLayer(env
, jobj
);
222 return reinterpret_cast<intptr_t>(scene_layer
);
225 bool RegisterTabStripSceneLayer(JNIEnv
* env
) {
226 return RegisterNativesImpl(env
);
229 } // namespace android
230 } // namespace chrome