1 // Copyright 2014 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 "content/browser/android/composited_touch_handle_drawable.h"
7 #include "base/lazy_instance.h"
8 #include "base/logging.h"
9 #include "base/trace_event/trace_event.h"
10 #include "cc/layers/ui_resource_layer.h"
11 #include "jni/HandleViewResources_jni.h"
12 #include "ui/gfx/android/java_bitmap.h"
18 static SkBitmap
CreateSkBitmapFromJavaBitmap(
19 base::android::ScopedJavaLocalRef
<jobject
> jbitmap
) {
20 return jbitmap
.is_null()
22 : CreateSkBitmapFromJavaBitmap(gfx::JavaBitmap(jbitmap
.obj()));
25 class HandleResources
{
27 HandleResources() : loaded_(false) {
30 void LoadIfNecessary(jobject context
) {
36 TRACE_EVENT0("browser", "HandleResources::Create");
37 JNIEnv
* env
= base::android::AttachCurrentThread();
39 context
= base::android::GetApplicationContext();
41 left_bitmap_
= CreateSkBitmapFromJavaBitmap(
42 Java_HandleViewResources_getLeftHandleBitmap(env
, context
));
43 right_bitmap_
= CreateSkBitmapFromJavaBitmap(
44 Java_HandleViewResources_getRightHandleBitmap(env
, context
));
45 center_bitmap_
= CreateSkBitmapFromJavaBitmap(
46 Java_HandleViewResources_getCenterHandleBitmap(env
, context
));
48 left_bitmap_
.setImmutable();
49 right_bitmap_
.setImmutable();
50 center_bitmap_
.setImmutable();
53 const SkBitmap
& GetBitmap(ui::TouchHandleOrientation orientation
) {
55 switch (orientation
) {
56 case ui::TouchHandleOrientation::LEFT
:
58 case ui::TouchHandleOrientation::RIGHT
:
60 case ui::TouchHandleOrientation::CENTER
:
61 return center_bitmap_
;
62 case ui::TouchHandleOrientation::UNDEFINED
:
63 NOTREACHED() << "Invalid touch handle orientation.";
65 return center_bitmap_
;
69 SkBitmap left_bitmap_
;
70 SkBitmap right_bitmap_
;
71 SkBitmap center_bitmap_
;
74 DISALLOW_COPY_AND_ASSIGN(HandleResources
);
77 base::LazyInstance
<HandleResources
>::Leaky g_selection_resources
;
81 CompositedTouchHandleDrawable::CompositedTouchHandleDrawable(
82 cc::Layer
* root_layer
,
85 : dpi_scale_(dpi_scale
),
86 orientation_(ui::TouchHandleOrientation::UNDEFINED
),
87 layer_(cc::UIResourceLayer::Create()) {
88 g_selection_resources
.Get().LoadIfNecessary(context
);
90 root_layer
->AddChild(layer_
.get());
93 CompositedTouchHandleDrawable::~CompositedTouchHandleDrawable() {
97 void CompositedTouchHandleDrawable::SetEnabled(bool enabled
) {
98 layer_
->SetIsDrawable(enabled
);
99 // Force a position update in case the disabled layer's properties are stale.
101 UpdateLayerPosition();
104 void CompositedTouchHandleDrawable::SetOrientation(
105 ui::TouchHandleOrientation orientation
) {
106 DCHECK(layer_
->parent());
107 orientation_
= orientation
;
109 const SkBitmap
& bitmap
= g_selection_resources
.Get().GetBitmap(orientation
);
110 layer_
->SetBitmap(bitmap
);
111 layer_
->SetBounds(gfx::Size(bitmap
.width(), bitmap
.height()));
113 switch (orientation_
) {
114 case ui::TouchHandleOrientation::LEFT
:
115 focal_offset_from_origin_
= gfx::Vector2dF(bitmap
.width() * 0.75f
, 0);
117 case ui::TouchHandleOrientation::RIGHT
:
118 focal_offset_from_origin_
= gfx::Vector2dF(bitmap
.width() * 0.25f
, 0);
120 case ui::TouchHandleOrientation::CENTER
:
121 focal_offset_from_origin_
= gfx::Vector2dF(bitmap
.width() * 0.5f
, 0);
123 case ui::TouchHandleOrientation::UNDEFINED
:
124 NOTREACHED() << "Invalid touch handle orientation.";
128 UpdateLayerPosition();
131 void CompositedTouchHandleDrawable::SetAlpha(float alpha
) {
132 DCHECK(layer_
->parent());
133 alpha
= std::max(0.f
, std::min(1.f
, alpha
));
134 bool hidden
= alpha
<= 0;
135 layer_
->SetOpacity(alpha
);
136 layer_
->SetHideLayerAndSubtree(hidden
);
139 void CompositedTouchHandleDrawable::SetFocus(const gfx::PointF
& position
) {
140 DCHECK(layer_
->parent());
141 focal_position_
= gfx::ScalePoint(position
, dpi_scale_
);
142 UpdateLayerPosition();
145 gfx::RectF
CompositedTouchHandleDrawable::GetVisibleBounds() const {
146 return gfx::ScaleRect(gfx::RectF(layer_
->position().x(),
147 layer_
->position().y(),
148 layer_
->bounds().width(),
149 layer_
->bounds().height()),
153 void CompositedTouchHandleDrawable::DetachLayer() {
154 layer_
->RemoveFromParent();
157 void CompositedTouchHandleDrawable::UpdateLayerPosition() {
158 layer_
->SetPosition(focal_position_
- focal_offset_from_origin_
);
162 bool CompositedTouchHandleDrawable::RegisterHandleViewResources(JNIEnv
* env
) {
163 return RegisterNativesImpl(env
);
166 } // namespace content