summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--content/browser/android/edge_effect.cc139
-rw-r--r--content/browser/android/edge_effect.h20
-rw-r--r--content/browser/android/overscroll_glow.cc97
-rw-r--r--content/browser/android/overscroll_glow.h17
-rw-r--r--content/browser/android/system_ui_resource_manager_impl.cc137
-rw-r--r--content/browser/android/system_ui_resource_manager_impl.h55
-rw-r--r--content/browser/android/system_ui_resource_manager_impl_unittest.cc167
-rw-r--r--content/browser/android/ui_resource_provider_impl.cc8
-rw-r--r--content/browser/android/ui_resource_provider_impl.h5
-rw-r--r--content/browser/renderer_host/compositor_impl_android.cc4
-rw-r--r--content/browser/renderer_host/compositor_impl_android.h7
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.cc38
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.h1
-rw-r--r--content/content_browser.gypi2
-rw-r--r--content/content_tests.gypi1
-rw-r--r--ui/base/BUILD.gn1
-rw-r--r--ui/base/android/system_ui_resource_manager.h41
-rw-r--r--ui/base/android/window_android_compositor.h2
-rw-r--r--ui/base/ui_base.gyp1
-rw-r--r--ui/gfx/android/java_bitmap.cc32
-rw-r--r--ui/gfx/android/java_bitmap.h12
21 files changed, 602 insertions, 185 deletions
diff --git a/content/browser/android/edge_effect.cc b/content/browser/android/edge_effect.cc
index 94e5b51..2979872 100644
--- a/content/browser/android/edge_effect.cc
+++ b/content/browser/android/edge_effect.cc
@@ -5,6 +5,8 @@
#include "content/browser/android/edge_effect.h"
#include "cc/layers/layer.h"
+#include "cc/layers/ui_resource_layer.h"
+#include "ui/base/android/system_ui_resource_manager.h"
namespace content {
@@ -118,52 +120,70 @@ gfx::Size ComputeBounds(EdgeEffect::Edge edge,
};
}
-void DisableLayer(cc::Layer* layer) {
- DCHECK(layer);
- layer->SetIsDrawable(false);
- layer->SetTransform(gfx::Transform());
- layer->SetOpacity(1.f);
-}
+} // namespace
-void UpdateLayer(cc::Layer* layer,
- EdgeEffect::Edge edge,
- const gfx::SizeF& window_size,
- int offset,
- int height,
- float opacity) {
- DCHECK(layer);
- layer->SetIsDrawable(true);
- gfx::Size bounds = ComputeBounds(edge, window_size, height);
- layer->SetTransformOrigin(
- gfx::Point3F(bounds.width() * 0.5f, bounds.height() * 0.5f, 0));
- layer->SetTransform(ComputeTransform(edge, window_size, offset, height));
- layer->SetBounds(bounds);
- layer->SetOpacity(Clamp(opacity, 0.f, 1.f));
-}
+class EdgeEffect::EffectLayer {
+ public:
+ EffectLayer(ui::SystemUIResourceManager::ResourceType resource_type,
+ ui::SystemUIResourceManager* resource_manager)
+ : ui_resource_layer_(cc::UIResourceLayer::Create()),
+ resource_type_(resource_type),
+ resource_manager_(resource_manager) {}
+
+ ~EffectLayer() { ui_resource_layer_->RemoveFromParent(); }
+
+ void SetParent(cc::Layer* parent) {
+ if (ui_resource_layer_->parent() != parent)
+ parent->AddChild(ui_resource_layer_);
+ ui_resource_layer_->SetUIResourceId(
+ resource_manager_->GetUIResourceId(resource_type_));
+ }
+
+ void Disable() { ui_resource_layer_->SetIsDrawable(false); }
+
+ void Update(EdgeEffect::Edge edge,
+ const gfx::SizeF& window_size,
+ int offset,
+ int height,
+ float opacity) {
+ ui_resource_layer_->SetUIResourceId(
+ resource_manager_->GetUIResourceId(resource_type_));
+ ui_resource_layer_->SetIsDrawable(true);
+ gfx::Size bounds = ComputeBounds(edge, window_size, height);
+ ui_resource_layer_->SetTransformOrigin(
+ gfx::Point3F(bounds.width() * 0.5f, bounds.height() * 0.5f, 0));
+ ui_resource_layer_->SetTransform(
+ ComputeTransform(edge, window_size, offset, height));
+ ui_resource_layer_->SetBounds(bounds);
+ ui_resource_layer_->SetOpacity(Clamp(opacity, 0.f, 1.f));
+ }
-} // namespace
-
-EdgeEffect::EdgeEffect(scoped_refptr<cc::Layer> edge,
- scoped_refptr<cc::Layer> glow)
- : edge_(edge)
- , glow_(glow)
- , edge_alpha_(0)
- , edge_scale_y_(0)
- , glow_alpha_(0)
- , glow_scale_y_(0)
- , edge_alpha_start_(0)
- , edge_alpha_finish_(0)
- , edge_scale_y_start_(0)
- , edge_scale_y_finish_(0)
- , glow_alpha_start_(0)
- , glow_alpha_finish_(0)
- , glow_scale_y_start_(0)
- , glow_scale_y_finish_(0)
- , state_(STATE_IDLE)
- , pull_distance_(0) {
- // Prevent the provided layers from drawing until the effect is activated.
- DisableLayer(edge_.get());
- DisableLayer(glow_.get());
+ scoped_refptr<cc::UIResourceLayer> ui_resource_layer_;
+ ui::SystemUIResourceManager::ResourceType resource_type_;
+ ui::SystemUIResourceManager* resource_manager_;
+
+ DISALLOW_COPY_AND_ASSIGN(EffectLayer);
+};
+
+EdgeEffect::EdgeEffect(ui::SystemUIResourceManager* resource_manager)
+ : edge_(new EffectLayer(ui::SystemUIResourceManager::OVERSCROLL_EDGE,
+ resource_manager)),
+ glow_(new EffectLayer(ui::SystemUIResourceManager::OVERSCROLL_GLOW,
+ resource_manager)),
+ edge_alpha_(0),
+ edge_scale_y_(0),
+ glow_alpha_(0),
+ glow_scale_y_(0),
+ edge_alpha_start_(0),
+ edge_alpha_finish_(0),
+ edge_scale_y_start_(0),
+ edge_scale_y_finish_(0),
+ glow_alpha_start_(0),
+ glow_alpha_finish_(0),
+ glow_scale_y_start_(0),
+ glow_scale_y_finish_(0),
+ state_(STATE_IDLE),
+ pull_distance_(0) {
}
EdgeEffect::~EdgeEffect() { }
@@ -173,8 +193,8 @@ bool EdgeEffect::IsFinished() const {
}
void EdgeEffect::Finish() {
- DisableLayer(edge_.get());
- DisableLayer(glow_.get());
+ edge_->Disable();
+ glow_->Disable();
pull_distance_ = 0;
state_ = STATE_IDLE;
}
@@ -359,8 +379,8 @@ void EdgeEffect::ApplyToLayers(gfx::SizeF window_size,
// An empty window size, while meaningless, is also relatively harmless, and
// will simply prevent any drawing of the layers.
if (window_size.IsEmpty()) {
- DisableLayer(edge_.get());
- DisableLayer(glow_.get());
+ edge_->Disable();
+ glow_->Disable();
return;
}
@@ -368,13 +388,26 @@ void EdgeEffect::ApplyToLayers(gfx::SizeF window_size,
const int scaled_glow_height = static_cast<int>(
std::min(glow_height * glow_scale_y_ * kGlowHeightToWidthRatio * 0.6f,
glow_height * kMaxGlowHeight) + 0.5f);
- UpdateLayer(
- glow_.get(), edge, window_size, offset, scaled_glow_height, glow_alpha_);
+ glow_->Update(edge, window_size, offset, scaled_glow_height, glow_alpha_);
// Edge
- const int scaled_edge_height = static_cast<int>(edge_height * edge_scale_y_);
- UpdateLayer(
- edge_.get(), edge, window_size, offset, scaled_edge_height, edge_alpha_);
+ const int scaled_edge_height = static_cast<int>(edge_height * edge_scale_y_);
+ edge_->Update(edge, window_size, offset, scaled_edge_height, edge_alpha_);
+}
+
+void EdgeEffect::SetParent(cc::Layer* parent) {
+ edge_->SetParent(parent);
+ glow_->SetParent(parent);
+}
+
+// static
+void EdgeEffect::PreloadResources(
+ ui::SystemUIResourceManager* resource_manager) {
+ DCHECK(resource_manager);
+ resource_manager->PreloadResource(
+ ui::SystemUIResourceManager::OVERSCROLL_EDGE);
+ resource_manager->PreloadResource(
+ ui::SystemUIResourceManager::OVERSCROLL_GLOW);
}
} // namespace content
diff --git a/content/browser/android/edge_effect.h b/content/browser/android/edge_effect.h
index b8febba..a8f944c 100644
--- a/content/browser/android/edge_effect.h
+++ b/content/browser/android/edge_effect.h
@@ -6,7 +6,7 @@
#define CONTENT_BROWSER_ANDROID_EDGE_EFFECT_H_
#include "base/basictypes.h"
-#include "base/memory/ref_counted.h"
+#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "ui/gfx/size_f.h"
@@ -14,6 +14,10 @@ namespace cc {
class Layer;
}
+namespace ui {
+class SystemUIResourceManager;
+}
+
namespace content {
/* |EdgeEffect| mirrors its Android counterpart, EdgeEffect.java.
@@ -24,7 +28,7 @@ namespace content {
* All coordinates and dimensions are in device pixels.
*/
class EdgeEffect {
-public:
+ public:
enum Edge {
EDGE_TOP = 0,
EDGE_LEFT,
@@ -33,7 +37,7 @@ public:
EDGE_COUNT
};
- EdgeEffect(scoped_refptr<cc::Layer> edge, scoped_refptr<cc::Layer> glow);
+ explicit EdgeEffect(ui::SystemUIResourceManager* resource_manager);
~EdgeEffect();
void Pull(base::TimeTicks current_time, float delta_distance);
@@ -50,8 +54,11 @@ public:
float glow_height,
float offset);
-private:
+ void SetParent(cc::Layer* parent);
+
+ static void PreloadResources(ui::SystemUIResourceManager* resource_manager);
+ private:
enum State {
STATE_IDLE = 0,
STATE_PULL,
@@ -60,8 +67,9 @@ private:
STATE_PULL_DECAY
};
- scoped_refptr<cc::Layer> edge_;
- scoped_refptr<cc::Layer> glow_;
+ class EffectLayer;
+ scoped_ptr<EffectLayer> edge_;
+ scoped_ptr<EffectLayer> glow_;
float edge_alpha_;
float edge_scale_y_;
diff --git a/content/browser/android/overscroll_glow.cc b/content/browser/android/overscroll_glow.cc
index fb491f3..3f316d8 100644
--- a/content/browser/android/overscroll_glow.cc
+++ b/content/browser/android/overscroll_glow.cc
@@ -6,11 +6,8 @@
#include "base/debug/trace_event.h"
#include "base/lazy_instance.h"
-#include "base/threading/worker_pool.h"
-#include "cc/layers/image_layer.h"
+#include "cc/layers/layer.h"
#include "content/browser/android/edge_effect.h"
-#include "skia/ext/image_operations.h"
-#include "ui/gfx/android/java_bitmap.h"
using std::max;
using std::min;
@@ -20,57 +17,9 @@ namespace content {
namespace {
const float kEpsilon = 1e-3f;
-const int kScaledEdgeHeight = 12;
-const int kScaledGlowHeight = 64;
const float kEdgeHeightAtMdpi = 12.f;
const float kGlowHeightAtMdpi = 128.f;
-SkBitmap CreateSkBitmapFromAndroidResource(const char* name, gfx::Size size) {
- base::android::ScopedJavaLocalRef<jobject> jobj =
- gfx::CreateJavaBitmapFromAndroidResource(name, size);
- if (jobj.is_null())
- return SkBitmap();
-
- SkBitmap bitmap = CreateSkBitmapFromJavaBitmap(gfx::JavaBitmap(jobj.obj()));
- if (bitmap.isNull())
- return bitmap;
-
- return skia::ImageOperations::Resize(
- bitmap, skia::ImageOperations::RESIZE_BOX, size.width(), size.height());
-}
-
-class OverscrollResources {
- public:
- OverscrollResources() {
- TRACE_EVENT0("browser", "OverscrollResources::Create");
- edge_bitmap_ =
- CreateSkBitmapFromAndroidResource("android:drawable/overscroll_edge",
- gfx::Size(128, kScaledEdgeHeight));
- glow_bitmap_ =
- CreateSkBitmapFromAndroidResource("android:drawable/overscroll_glow",
- gfx::Size(128, kScaledGlowHeight));
- }
-
- const SkBitmap& edge_bitmap() const { return edge_bitmap_; }
- const SkBitmap& glow_bitmap() const { return glow_bitmap_; }
-
- private:
- SkBitmap edge_bitmap_;
- SkBitmap glow_bitmap_;
-
- DISALLOW_COPY_AND_ASSIGN(OverscrollResources);
-};
-
-// Leaky to allow access from a worker thread.
-base::LazyInstance<OverscrollResources>::Leaky g_overscroll_resources =
- LAZY_INSTANCE_INITIALIZER;
-
-scoped_refptr<cc::Layer> CreateImageLayer(const SkBitmap& bitmap) {
- scoped_refptr<cc::ImageLayer> layer = cc::ImageLayer::Create();
- layer->SetBitmap(bitmap);
- return layer;
-}
-
bool IsApproxZero(float value) {
return std::abs(value) < kEpsilon;
}
@@ -83,25 +32,18 @@ gfx::Vector2dF ZeroSmallComponents(gfx::Vector2dF vector) {
return vector;
}
-// Force loading of any necessary resources. This function is thread-safe.
-void EnsureResources() {
- g_overscroll_resources.Get();
-}
-
-} // namespace
-
-scoped_ptr<OverscrollGlow> OverscrollGlow::Create(bool enabled) {
- // Don't block the main thread with effect resource loading during creation.
- // Effect instantiation is deferred until the effect overscrolls, in which
- // case the main thread may block until the resource has loaded.
- if (enabled && g_overscroll_resources == NULL)
- base::WorkerPool::PostTask(FROM_HERE, base::Bind(EnsureResources), true);
+} // namespace
- return make_scoped_ptr(new OverscrollGlow(enabled));
+scoped_ptr<OverscrollGlow> OverscrollGlow::Create(
+ ui::SystemUIResourceManager* resource_manager) {
+ return make_scoped_ptr(new OverscrollGlow(resource_manager));
}
-OverscrollGlow::OverscrollGlow(bool enabled)
- : enabled_(enabled), initialized_(false) {}
+OverscrollGlow::OverscrollGlow(ui::SystemUIResourceManager* resource_manager)
+ : enabled_(true), initialized_(false), resource_manager_(resource_manager) {
+ DCHECK(resource_manager_);
+ EdgeEffect::PreloadResources(resource_manager_);
+}
OverscrollGlow::~OverscrollGlow() {
Detach();
@@ -222,6 +164,9 @@ void OverscrollGlow::UpdateLayerAttachment(cc::Layer* parent) {
if (root_layer_->parent() != parent)
parent->AddChild(root_layer_);
+
+ for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i)
+ edge_effects_[i]->SetParent(root_layer_);
}
void OverscrollGlow::Detach() {
@@ -234,22 +179,10 @@ bool OverscrollGlow::InitializeIfNecessary() {
if (initialized_)
return true;
- const SkBitmap& edge = g_overscroll_resources.Get().edge_bitmap();
- const SkBitmap& glow = g_overscroll_resources.Get().glow_bitmap();
- if (edge.isNull() || glow.isNull()) {
- Disable();
- return false;
- }
-
DCHECK(!root_layer_);
root_layer_ = cc::Layer::Create();
- for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i) {
- scoped_refptr<cc::Layer> edge_layer = CreateImageLayer(edge);
- scoped_refptr<cc::Layer> glow_layer = CreateImageLayer(glow);
- root_layer_->AddChild(edge_layer);
- root_layer_->AddChild(glow_layer);
- edge_effects_[i] = make_scoped_ptr(new EdgeEffect(edge_layer, glow_layer));
- }
+ for (size_t i = 0; i < EdgeEffect::EDGE_COUNT; ++i)
+ edge_effects_[i] = make_scoped_ptr(new EdgeEffect(resource_manager_));
initialized_ = true;
return true;
diff --git a/content/browser/android/overscroll_glow.h b/content/browser/android/overscroll_glow.h
index 0a555d4..7500940 100644
--- a/content/browser/android/overscroll_glow.h
+++ b/content/browser/android/overscroll_glow.h
@@ -14,8 +14,8 @@
class SkBitmap;
-namespace cc {
-class Layer;
+namespace ui {
+class SystemUIResourceManager;
}
namespace content {
@@ -26,11 +26,11 @@ namespace content {
*/
class OverscrollGlow {
public:
- // Create a new effect. If |enabled| is false, the effect will remain
- // deactivated until explicitly enabled.
- // Note: No resources will be allocated until the effect is both
- // enabled and an overscroll event has occurred.
- static scoped_ptr<OverscrollGlow> Create(bool enabled);
+ // Create a new effect. |resource_manager| provides the resource for the
+ // effect. |resource_manager| must outlive the effect. The effect is
+ // activated by default.
+ static scoped_ptr<OverscrollGlow> Create(
+ ui::SystemUIResourceManager* resource_manager);
~OverscrollGlow();
@@ -70,7 +70,7 @@ class OverscrollGlow {
private:
enum Axis { AXIS_X, AXIS_Y };
- OverscrollGlow(bool enabled);
+ explicit OverscrollGlow(ui::SystemUIResourceManager* resource_manager);
// Returns whether the effect is initialized.
bool InitializeIfNecessary();
@@ -94,6 +94,7 @@ class OverscrollGlow {
bool initialized_;
scoped_refptr<cc::Layer> root_layer_;
+ ui::SystemUIResourceManager* resource_manager_;
DISALLOW_COPY_AND_ASSIGN(OverscrollGlow);
};
diff --git a/content/browser/android/system_ui_resource_manager_impl.cc b/content/browser/android/system_ui_resource_manager_impl.cc
new file mode 100644
index 0000000..6da221b
--- /dev/null
+++ b/content/browser/android/system_ui_resource_manager_impl.cc
@@ -0,0 +1,137 @@
+// Copyright 2014 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 "content/browser/android/system_ui_resource_manager_impl.h"
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/location.h"
+#include "base/observer_list.h"
+#include "base/threading/worker_pool.h"
+#include "cc/resources/ui_resource_bitmap.h"
+#include "content/public/browser/android/ui_resource_client_android.h"
+#include "content/public/browser/android/ui_resource_provider.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "ui/gfx/android/java_bitmap.h"
+
+namespace content {
+
+class SystemUIResourceManagerImpl::Entry
+ : public content::UIResourceClientAndroid {
+ public:
+ explicit Entry(UIResourceProvider* provider) : id_(0), provider_(provider) {
+ DCHECK(provider);
+ }
+
+ virtual ~Entry() {
+ if (id_)
+ provider_->DeleteUIResource(id_);
+ id_ = 0;
+ }
+
+ void SetBitmap(const SkBitmap& bitmap) {
+ DCHECK(bitmap_.empty());
+ DCHECK(!bitmap.empty());
+ DCHECK(!id_);
+ bitmap_ = bitmap;
+ }
+
+ cc::UIResourceId GetUIResourceId() {
+ if (bitmap_.empty())
+ return 0;
+ if (!id_)
+ id_ = provider_->CreateUIResource(this);
+ return id_;
+ }
+
+ // content::UIResourceClient implementation.
+ virtual cc::UIResourceBitmap GetBitmap(cc::UIResourceId uid,
+ bool resource_lost) OVERRIDE {
+ DCHECK(!bitmap_.empty());
+ return cc::UIResourceBitmap(bitmap_);
+ }
+
+ // content::UIResourceClientAndroid implementation.
+ virtual void UIResourceIsInvalid() OVERRIDE { id_ = 0; }
+
+ const SkBitmap& bitmap() const { return bitmap_; }
+
+ private:
+ SkBitmap bitmap_;
+ cc::UIResourceId id_;
+ UIResourceProvider* provider_;
+
+ DISALLOW_COPY_AND_ASSIGN(Entry);
+};
+
+SystemUIResourceManagerImpl::SystemUIResourceManagerImpl(
+ UIResourceProvider* ui_resource_provider)
+ : ui_resource_provider_(ui_resource_provider), weak_factory_(this) {
+}
+
+SystemUIResourceManagerImpl::~SystemUIResourceManagerImpl() {
+}
+
+void SystemUIResourceManagerImpl::PreloadResource(ResourceType type) {
+ GetEntry(type);
+}
+
+cc::UIResourceId SystemUIResourceManagerImpl::GetUIResourceId(
+ ResourceType type) {
+ return GetEntry(type)->GetUIResourceId();
+}
+
+SystemUIResourceManagerImpl::Entry* SystemUIResourceManagerImpl::GetEntry(
+ ResourceType type) {
+ DCHECK_GE(type, RESOURCE_TYPE_FIRST);
+ DCHECK_LE(type, RESOURCE_TYPE_LAST);
+ if (!resource_map_[type]) {
+ resource_map_[type].reset(new Entry(ui_resource_provider_));
+ // Lazily build the resource.
+ BuildResource(type);
+ }
+ return resource_map_[type].get();
+}
+
+void SystemUIResourceManagerImpl::BuildResource(ResourceType type) {
+ DCHECK(GetEntry(type)->bitmap().empty());
+
+ // Instead of blocking the main thread, we post a task to load the bitmap.
+ SkBitmap* bitmap = new SkBitmap();
+ base::Closure load_bitmap =
+ base::Bind(&SystemUIResourceManagerImpl::LoadBitmap, type, bitmap);
+ base::Closure finished_load =
+ base::Bind(&SystemUIResourceManagerImpl::OnFinishedLoadBitmap,
+ weak_factory_.GetWeakPtr(),
+ type,
+ base::Owned(bitmap));
+ base::WorkerPool::PostTaskAndReply(
+ FROM_HERE, load_bitmap, finished_load, true);
+}
+
+void SystemUIResourceManagerImpl::LoadBitmap(ResourceType type,
+ SkBitmap* bitmap_holder) {
+ SkBitmap bitmap;
+ switch (type) {
+ case ui::SystemUIResourceManager::OVERSCROLL_EDGE:
+ bitmap = gfx::CreateSkBitmapFromAndroidResource(
+ "android:drawable/overscroll_edge", gfx::Size(128, 12));
+ break;
+ case ui::SystemUIResourceManager::OVERSCROLL_GLOW:
+ bitmap = gfx::CreateSkBitmapFromAndroidResource(
+ "android:drawable/overscroll_glow", gfx::Size(128, 64));
+ break;
+ }
+ bitmap.setImmutable();
+ *bitmap_holder = bitmap;
+}
+
+void SystemUIResourceManagerImpl::OnFinishedLoadBitmap(
+ ResourceType type,
+ SkBitmap* bitmap_holder) {
+ DCHECK(bitmap_holder);
+ GetEntry(type)->SetBitmap(*bitmap_holder);
+}
+
+} // namespace content
diff --git a/content/browser/android/system_ui_resource_manager_impl.h b/content/browser/android/system_ui_resource_manager_impl.h
new file mode 100644
index 0000000..c5792a1
--- /dev/null
+++ b/content/browser/android/system_ui_resource_manager_impl.h
@@ -0,0 +1,55 @@
+// Copyright 2014 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.
+
+#ifndef CONTENT_BROWSER_ANDROID_SYSTEM_UI_RESOURCE_MANAGER_IMPL_H_
+#define CONTENT_BROWSER_ANDROID_SYSTEM_UI_RESOURCE_MANAGER_IMPL_H_
+
+#include "base/basictypes.h"
+#include "base/containers/scoped_ptr_hash_map.h"
+#include "base/memory/weak_ptr.h"
+#include "content/common/content_export.h"
+#include "ui/base/android/system_ui_resource_manager.h"
+
+class SkBitmap;
+
+namespace cc {
+class UIResourceBitmap;
+}
+
+namespace content {
+
+class UIResourceProvider;
+
+class CONTENT_EXPORT SystemUIResourceManagerImpl
+ : public ui::SystemUIResourceManager {
+ public:
+ explicit SystemUIResourceManagerImpl(
+ UIResourceProvider* ui_resource_provider);
+ virtual ~SystemUIResourceManagerImpl();
+
+ virtual void PreloadResource(ResourceType type) OVERRIDE;
+ virtual cc::UIResourceId GetUIResourceId(ResourceType type) OVERRIDE;
+
+ private:
+ friend class TestSystemUIResourceManagerImpl;
+ class Entry;
+
+ // Start loading the resource bitmap. virtual for testing.
+ virtual void BuildResource(ResourceType type);
+
+ Entry* GetEntry(ResourceType type);
+ static void LoadBitmap(ResourceType, SkBitmap* bitmap_holder);
+ void OnFinishedLoadBitmap(ResourceType, SkBitmap* bitmap_holder);
+
+ scoped_ptr<Entry> resource_map_[RESOURCE_TYPE_LAST + 1];
+ UIResourceProvider* ui_resource_provider_;
+
+ base::WeakPtrFactory<SystemUIResourceManagerImpl> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(SystemUIResourceManagerImpl);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_ANDROID_SYSTEM_UI_RESOURCE_MANAGER_IMPL_H_
diff --git a/content/browser/android/system_ui_resource_manager_impl_unittest.cc b/content/browser/android/system_ui_resource_manager_impl_unittest.cc
new file mode 100644
index 0000000..95a7e9b
--- /dev/null
+++ b/content/browser/android/system_ui_resource_manager_impl_unittest.cc
@@ -0,0 +1,167 @@
+// Copyright 2014 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 "cc/resources/ui_resource_bitmap.h"
+#include "content/browser/android/system_ui_resource_manager_impl.h"
+#include "content/public/browser/android/ui_resource_client_android.h"
+#include "content/public/browser/android/ui_resource_provider.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkCanvas.h"
+
+namespace content {
+
+class TestSystemUIResourceManagerImpl
+ : public content::SystemUIResourceManagerImpl {
+ public:
+ TestSystemUIResourceManagerImpl(content::UIResourceProvider* provider)
+ : SystemUIResourceManagerImpl(provider) {}
+
+ virtual ~TestSystemUIResourceManagerImpl() {}
+
+ virtual void BuildResource(
+ ui::SystemUIResourceManager::ResourceType type) OVERRIDE {}
+
+ void SetResourceAsLoaded(ui::SystemUIResourceManager::ResourceType type) {
+ SkBitmap small_bitmap;
+ SkCanvas canvas(small_bitmap);
+ small_bitmap.allocPixels(
+ SkImageInfo::Make(1, 1, kRGBA_8888_SkColorType, kOpaque_SkAlphaType));
+ canvas.drawColor(SK_ColorWHITE);
+ small_bitmap.setImmutable();
+ OnFinishedLoadBitmap(type, &small_bitmap);
+ }
+};
+
+namespace {
+
+const ui::SystemUIResourceManager::ResourceType TEST_RESOURCE_TYPE =
+ ui::SystemUIResourceManager::OVERSCROLL_GLOW;
+
+class MockUIResourceProvider : public content::UIResourceProvider {
+ public:
+ MockUIResourceProvider()
+ : next_ui_resource_id_(1),
+ has_layer_tree_host_(true),
+ system_ui_resource_manager_(this) {}
+
+ virtual ~MockUIResourceProvider() {}
+
+ virtual cc::UIResourceId CreateUIResource(
+ content::UIResourceClientAndroid* client) OVERRIDE {
+ if (!has_layer_tree_host_)
+ return 0;
+ cc::UIResourceId id = next_ui_resource_id_++;
+ client->GetBitmap(id, false);
+ ui_resource_client_map_[id] = client;
+ return id;
+ }
+
+ virtual void DeleteUIResource(cc::UIResourceId id) OVERRIDE {
+ CHECK(has_layer_tree_host_);
+ ui_resource_client_map_.erase(id);
+ }
+
+ void LayerTreeHostCleared() {
+ has_layer_tree_host_ = false;
+ UIResourceClientMap client_map = ui_resource_client_map_;
+ ui_resource_client_map_.clear();
+ for (UIResourceClientMap::iterator iter = client_map.begin();
+ iter != client_map.end();
+ iter++) {
+ iter->second->UIResourceIsInvalid();
+ }
+ }
+
+ void LayerTreeHostReturned() { has_layer_tree_host_ = true; }
+
+ TestSystemUIResourceManagerImpl& GetSystemUIResourceManager() {
+ return system_ui_resource_manager_;
+ }
+
+ cc::UIResourceId next_ui_resource_id() const { return next_ui_resource_id_; }
+
+ private:
+ typedef base::hash_map<cc::UIResourceId, content::UIResourceClientAndroid*>
+ UIResourceClientMap;
+
+ cc::UIResourceId next_ui_resource_id_;
+ UIResourceClientMap ui_resource_client_map_;
+ bool has_layer_tree_host_;
+
+ // The UIResourceProvider owns the SystemUIResourceManager.
+ TestSystemUIResourceManagerImpl system_ui_resource_manager_;
+};
+
+} // namespace
+
+class SystemUIResourceManagerImplTest : public testing::Test {
+ public:
+ void PreloadResource(ui::SystemUIResourceManager::ResourceType type) {
+ ui_resource_provider_.GetSystemUIResourceManager().PreloadResource(type);
+ }
+
+ cc::UIResourceId GetUIResourceId(
+ ui::SystemUIResourceManager::ResourceType type) {
+ return ui_resource_provider_.GetSystemUIResourceManager().GetUIResourceId(
+ type);
+ }
+
+ void LayerTreeHostCleared() { ui_resource_provider_.LayerTreeHostCleared(); }
+
+ void LayerTreeHostReturned() {
+ ui_resource_provider_.LayerTreeHostReturned();
+ }
+
+ void SetResourceAsLoaded(ui::SystemUIResourceManager::ResourceType type) {
+ ui_resource_provider_.GetSystemUIResourceManager().SetResourceAsLoaded(
+ type);
+ }
+
+ cc::UIResourceId GetNextUIResourceId() const {
+ return ui_resource_provider_.next_ui_resource_id();
+ }
+
+ private:
+ MockUIResourceProvider ui_resource_provider_;
+};
+
+TEST_F(SystemUIResourceManagerImplTest, GetResourceAfterBitmapLoaded) {
+ SetResourceAsLoaded(TEST_RESOURCE_TYPE);
+ EXPECT_NE(0, GetUIResourceId(TEST_RESOURCE_TYPE));
+}
+
+TEST_F(SystemUIResourceManagerImplTest, GetResourceBeforeLoadBitmap) {
+ EXPECT_EQ(0, GetUIResourceId(TEST_RESOURCE_TYPE));
+ SetResourceAsLoaded(TEST_RESOURCE_TYPE);
+ EXPECT_NE(0, GetUIResourceId(TEST_RESOURCE_TYPE));
+}
+
+TEST_F(SystemUIResourceManagerImplTest, PreloadEnsureResource) {
+ // Preloading the resource should trigger bitmap loading, but the actual
+ // resource id will not be generated until it is explicitly requested.
+ cc::UIResourceId first_resource_id = GetNextUIResourceId();
+ PreloadResource(TEST_RESOURCE_TYPE);
+ SetResourceAsLoaded(TEST_RESOURCE_TYPE);
+ EXPECT_EQ(first_resource_id, GetNextUIResourceId());
+ EXPECT_NE(0, GetUIResourceId(TEST_RESOURCE_TYPE));
+ EXPECT_NE(first_resource_id, GetNextUIResourceId());
+}
+
+TEST_F(SystemUIResourceManagerImplTest, ResetLayerTreeHost) {
+ EXPECT_EQ(0, GetUIResourceId(TEST_RESOURCE_TYPE));
+ LayerTreeHostCleared();
+ EXPECT_EQ(0, GetUIResourceId(TEST_RESOURCE_TYPE));
+ LayerTreeHostReturned();
+ EXPECT_EQ(0, GetUIResourceId(TEST_RESOURCE_TYPE));
+
+ SetResourceAsLoaded(TEST_RESOURCE_TYPE);
+ EXPECT_NE(0, GetUIResourceId(TEST_RESOURCE_TYPE));
+ LayerTreeHostCleared();
+ EXPECT_EQ(0, GetUIResourceId(TEST_RESOURCE_TYPE));
+ LayerTreeHostReturned();
+ EXPECT_NE(0, GetUIResourceId(TEST_RESOURCE_TYPE));
+}
+
+} // namespace content
diff --git a/content/browser/android/ui_resource_provider_impl.cc b/content/browser/android/ui_resource_provider_impl.cc
index f97975c..d26d42f 100644
--- a/content/browser/android/ui_resource_provider_impl.cc
+++ b/content/browser/android/ui_resource_provider_impl.cc
@@ -10,7 +10,8 @@
namespace content {
-UIResourceProviderImpl::UIResourceProviderImpl() : host_(NULL) {
+UIResourceProviderImpl::UIResourceProviderImpl()
+ : system_ui_resource_manager_(this), host_(NULL) {
}
UIResourceProviderImpl::~UIResourceProviderImpl() {
@@ -57,4 +58,9 @@ void UIResourceProviderImpl::DeleteUIResource(cc::UIResourceId ui_resource_id) {
host_->DeleteUIResource(ui_resource_id);
}
+ui::SystemUIResourceManager&
+UIResourceProviderImpl::GetSystemUIResourceManager() {
+ return system_ui_resource_manager_;
+}
+
} // namespace content
diff --git a/content/browser/android/ui_resource_provider_impl.h b/content/browser/android/ui_resource_provider_impl.h
index 79c2301..57c9ab8 100644
--- a/content/browser/android/ui_resource_provider_impl.h
+++ b/content/browser/android/ui_resource_provider_impl.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_ANDROID_UI_RESOURCE_PROVIDER_IMPL_H_
#include "base/containers/hash_tables.h"
+#include "content/browser/android/system_ui_resource_manager_impl.h"
#include "content/public/browser/android/ui_resource_provider.h"
namespace cc {
@@ -31,11 +32,13 @@ class UIResourceProviderImpl : public UIResourceProvider {
virtual void DeleteUIResource(cc::UIResourceId resource_id) OVERRIDE;
+ ui::SystemUIResourceManager& GetSystemUIResourceManager();
+
private:
typedef base::hash_map<cc::UIResourceId, UIResourceClientAndroid*>
UIResourceClientMap;
UIResourceClientMap ui_resource_client_map_;
-
+ SystemUIResourceManagerImpl system_ui_resource_manager_;
cc::LayerTreeHost* host_;
DISALLOW_COPY_AND_ASSIGN(UIResourceProviderImpl);
diff --git a/content/browser/renderer_host/compositor_impl_android.cc b/content/browser/renderer_host/compositor_impl_android.cc
index 70ebbfe..d704f28 100644
--- a/content/browser/renderer_host/compositor_impl_android.cc
+++ b/content/browser/renderer_host/compositor_impl_android.cc
@@ -340,6 +340,10 @@ UIResourceProvider& CompositorImpl::GetUIResourceProvider() {
return ui_resource_provider_;
}
+ui::SystemUIResourceManager& CompositorImpl::GetSystemUIResourceManager() {
+ return ui_resource_provider_.GetSystemUIResourceManager();
+}
+
void CompositorImpl::SetRootLayer(scoped_refptr<cc::Layer> root_layer) {
if (subroot_layer_) {
subroot_layer_->RemoveFromParent();
diff --git a/content/browser/renderer_host/compositor_impl_android.h b/content/browser/renderer_host/compositor_impl_android.h
index 4792d90..9b75bd9 100644
--- a/content/browser/renderer_host/compositor_impl_android.h
+++ b/content/browser/renderer_host/compositor_impl_android.h
@@ -8,10 +8,8 @@
#include "base/basictypes.h"
#include "base/cancelable_callback.h"
#include "base/compiler_specific.h"
-#include "base/containers/scoped_ptr_hash_map.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
-#include "cc/resources/ui_resource_client.h"
#include "cc/trees/layer_tree_host_client.h"
#include "cc/trees/layer_tree_host_single_thread_client.h"
#include "content/browser/android/ui_resource_provider_impl.h"
@@ -19,6 +17,7 @@
#include "content/common/content_export.h"
#include "content/public/browser/android/compositor.h"
#include "third_party/khronos/GLES2/gl2.h"
+#include "ui/base/android/system_ui_resource_manager.h"
#include "ui/base/android/window_android_compositor.h"
class SkBitmap;
@@ -98,6 +97,7 @@ class CONTENT_EXPORT CompositorImpl
virtual void OnVSync(base::TimeTicks frame_time,
base::TimeDelta vsync_period) OVERRIDE;
virtual void SetNeedsAnimate() OVERRIDE;
+ virtual ui::SystemUIResourceManager& GetSystemUIResourceManager() OVERRIDE;
enum CompositingTrigger {
DO_NOT_COMPOSITE,
@@ -127,9 +127,6 @@ class CONTENT_EXPORT CompositorImpl
composite_on_vsync_trigger_ = DO_NOT_COMPOSITE;
will_composite_immediately_ = false;
}
- cc::UIResourceId GenerateUIResourceFromUIResourceBitmap(
- const cc::UIResourceBitmap& bitmap,
- bool is_transient);
void OnGpuChannelEstablished();
// root_layer_ is the persistent internal root layer, while subroot_layer_
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index e43f452..c52e845 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -192,7 +192,6 @@ RenderWidgetHostViewAndroid::RenderWidgetHostViewAndroid(
weak_ptr_factory_(this),
overscroll_effect_enabled_(!CommandLine::ForCurrentProcess()->HasSwitch(
switches::kDisableOverscrollEdgeEffect)),
- overscroll_effect_(OverscrollGlow::Create(overscroll_effect_enabled_)),
gesture_provider_(CreateGestureProviderConfig(), this),
gesture_text_selector_(this),
touch_scrolling_(false),
@@ -368,7 +367,7 @@ void RenderWidgetHostViewAndroid::MovePluginWindows(
void RenderWidgetHostViewAndroid::Focus() {
host_->Focus();
host_->SetInputMethodActive(true);
- if (overscroll_effect_enabled_)
+ if (overscroll_effect_)
overscroll_effect_->Enable();
}
@@ -376,7 +375,8 @@ void RenderWidgetHostViewAndroid::Blur() {
host_->ExecuteEditCommand("Unselect", "");
host_->SetInputMethodActive(false);
host_->Blur();
- overscroll_effect_->Disable();
+ if (overscroll_effect_)
+ overscroll_effect_->Disable();
}
bool RenderWidgetHostViewAndroid::HasFocus() const {
@@ -929,8 +929,10 @@ void RenderWidgetHostViewAndroid::ComputeContentsSize(
gfx::Size(texture_size_in_layer_.width() - offset.x(),
texture_size_in_layer_.height() - offset.y());
- overscroll_effect_->UpdateDisplayParameters(
- CreateOverscrollDisplayParameters(frame_metadata));
+ if (overscroll_effect_) {
+ overscroll_effect_->UpdateDisplayParameters(
+ CreateOverscrollDisplayParameters(frame_metadata));
+ }
}
void RenderWidgetHostViewAndroid::InternalSwapCompositorFrame(
@@ -1143,7 +1145,7 @@ void RenderWidgetHostViewAndroid::AttachLayers() {
return;
content_view_core_->AttachLayer(layer_);
- if (overscroll_effect_enabled_)
+ if (overscroll_effect_)
overscroll_effect_->Enable();
layer_->SetHideLayerAndSubtree(!is_showing_);
}
@@ -1156,11 +1158,13 @@ void RenderWidgetHostViewAndroid::RemoveLayers() {
return;
content_view_core_->RemoveLayer(layer_);
- overscroll_effect_->Disable();
+ if (overscroll_effect_)
+ overscroll_effect_->Disable();
}
bool RenderWidgetHostViewAndroid::Animate(base::TimeTicks frame_time) {
- bool needs_animate = overscroll_effect_->Animate(frame_time);
+ bool needs_animate =
+ overscroll_effect_ ? overscroll_effect_->Animate(frame_time) : false;
if (selection_controller_)
needs_animate |= selection_controller_->Animate(frame_time);
return needs_animate;
@@ -1361,8 +1365,8 @@ void RenderWidgetHostViewAndroid::SendMouseWheelEvent(
void RenderWidgetHostViewAndroid::SendGestureEvent(
const blink::WebGestureEvent& event) {
// Sending a gesture that may trigger overscroll should resume the effect.
- if (overscroll_effect_enabled_)
- overscroll_effect_->Enable();
+ if (overscroll_effect_)
+ overscroll_effect_->Enable();
if (host_)
host_->ForwardGestureEventWithLatencyInfo(event, CreateLatencyInfo(event));
@@ -1408,7 +1412,9 @@ void RenderWidgetHostViewAndroid::DidOverscroll(
return;
const float device_scale_factor = content_view_core_->GetDpiScale();
- if (overscroll_effect_->OnOverscrolled(
+
+ if (overscroll_effect_ &&
+ overscroll_effect_->OnOverscrolled(
content_view_core_->GetLayer(),
base::TimeTicks::Now(),
gfx::ScaleVector2d(params.accumulated_overscroll,
@@ -1475,6 +1481,16 @@ void RenderWidgetHostViewAndroid::SetContentViewCore(
if (!selection_controller_)
selection_controller_.reset(new TouchSelectionController(this));
+
+ if (!content_view_core_) {
+ overscroll_effect_.reset();
+ } else if (overscroll_effect_enabled_ && !overscroll_effect_) {
+ DCHECK(content_view_core_->GetWindowAndroid()->GetCompositor());
+ overscroll_effect_ =
+ OverscrollGlow::Create(&content_view_core_->GetWindowAndroid()
+ ->GetCompositor()
+ ->GetSystemUIResourceManager());
+ }
}
void RenderWidgetHostViewAndroid::RunAckCallbacks() {
diff --git a/content/browser/renderer_host/render_widget_host_view_android.h b/content/browser/renderer_host/render_widget_host_view_android.h
index e52652a..91f9d48 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.h
+++ b/content/browser/renderer_host/render_widget_host_view_android.h
@@ -355,7 +355,6 @@ class CONTENT_EXPORT RenderWidgetHostViewAndroid
const bool overscroll_effect_enabled_;
// Used to render overscroll overlays.
- // Note: |overscroll_effect_| will never be NULL, even if it's never enabled.
scoped_ptr<OverscrollGlow> overscroll_effect_;
// Provides gesture synthesis given a stream of touch events (derived from
diff --git a/content/content_browser.gypi b/content/content_browser.gypi
index bd2476f..46b7ca7 100644
--- a/content/content_browser.gypi
+++ b/content/content_browser.gypi
@@ -313,6 +313,8 @@
'browser/android/popup_touch_handle_drawable.h',
'browser/android/surface_texture_peer_browser_impl.cc',
'browser/android/surface_texture_peer_browser_impl.h',
+ 'browser/android/system_ui_resource_manager_impl.cc',
+ 'browser/android/system_ui_resource_manager_impl.h',
'browser/android/tracing_controller_android.cc',
'browser/android/tracing_controller_android.h',
'browser/android/web_contents_observer_android.cc',
diff --git a/content/content_tests.gypi b/content/content_tests.gypi
index b15c5d7..f7a3c38 100644
--- a/content/content_tests.gypi
+++ b/content/content_tests.gypi
@@ -901,6 +901,7 @@
'browser/android/java/gin_java_method_invocation_helper_unittest.cc',
'browser/android/java/java_type_unittest.cc',
'browser/android/java/jni_helper_unittest.cc',
+ 'browser/android/system_ui_resource_manager_impl_unittest.cc',
'renderer/java/gin_java_bridge_value_converter_unittest.cc',
],
'sources!': [
diff --git a/ui/base/BUILD.gn b/ui/base/BUILD.gn
index ddadf1b..76dcaa4 100644
--- a/ui/base/BUILD.gn
+++ b/ui/base/BUILD.gn
@@ -21,6 +21,7 @@ component("base") {
"accelerators/platform_accelerator.h",
"accelerators/platform_accelerator_cocoa.h",
"accelerators/platform_accelerator_cocoa.mm",
+ "android/system_ui_resource_manager.h",
"android/ui_base_jni_registrar.cc",
"android/ui_base_jni_registrar.h",
"android/view_android.cc",
diff --git a/ui/base/android/system_ui_resource_manager.h b/ui/base/android/system_ui_resource_manager.h
new file mode 100644
index 0000000..03a112d
--- /dev/null
+++ b/ui/base/android/system_ui_resource_manager.h
@@ -0,0 +1,41 @@
+// Copyright 2014 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.
+
+#ifndef UI_BASE_ANDROID_SYSTEM_UI_RESOURCE_MANAGER_H_
+#define UI_BASE_ANDROID_SYSTEM_UI_RESOURCE_MANAGER_H_
+
+#include "cc/resources/ui_resource_client.h"
+#include "ui/base/ui_base_export.h"
+
+namespace ui {
+
+// Interface for loading and accessing shared system UI resources.
+class UI_BASE_EXPORT SystemUIResourceManager {
+ public:
+ enum ResourceType {
+ OVERSCROLL_EDGE = 0,
+ OVERSCROLL_GLOW,
+ RESOURCE_TYPE_FIRST = OVERSCROLL_EDGE,
+ RESOURCE_TYPE_LAST = OVERSCROLL_GLOW
+ };
+
+ virtual ~SystemUIResourceManager() {}
+
+ // Optionally trigger bitmap loading for a given |resource|, if necessary.
+ // Note that this operation may be asynchronous, and subsequent queries to
+ // |GetUIResourceId()| will yield a valid result only after loading finishes.
+ // This method is particularly useful for idly loading a resource before an
+ // explicit cc::UIResourceId is required. Repeated calls will be ignored.
+ virtual void PreloadResource(ResourceType resource) = 0;
+
+ // Return the resource id associated with |resource|. If loading hasn't yet
+ // begun for the given |resource|, it will be triggered immediately. If
+ // loading is asynchronous, 0 will be returned until loading has finished, and
+ // the caller is responsible for re-querying until a valid id is returned.
+ virtual cc::UIResourceId GetUIResourceId(ResourceType resource) = 0;
+};
+
+} // namespace ui
+
+#endif // UI_BASE_ANDROID_SYSTEM_UI_RESOURCE_MANAGER_H_
diff --git a/ui/base/android/window_android_compositor.h b/ui/base/android/window_android_compositor.h
index eb55a7b..eee3357 100644
--- a/ui/base/android/window_android_compositor.h
+++ b/ui/base/android/window_android_compositor.h
@@ -6,6 +6,7 @@
#define UI_BASE_ANDROID_WINDOW_ANDROID_COMPOSITOR_H_
#include "cc/output/copy_output_request.h"
+#include "ui/base/android/system_ui_resource_manager.h"
#include "ui/base/ui_base_export.h"
namespace cc {
@@ -25,6 +26,7 @@ class UI_BASE_EXPORT WindowAndroidCompositor {
virtual void OnVSync(base::TimeTicks frame_time,
base::TimeDelta vsync_period) = 0;
virtual void SetNeedsAnimate() = 0;
+ virtual SystemUIResourceManager& GetSystemUIResourceManager() = 0;
};
} // namespace ui
diff --git a/ui/base/ui_base.gyp b/ui/base/ui_base.gyp
index 6e6a316..887e8e4 100644
--- a/ui/base/ui_base.gyp
+++ b/ui/base/ui_base.gyp
@@ -47,6 +47,7 @@
'accelerators/platform_accelerator.h',
'accelerators/platform_accelerator_cocoa.h',
'accelerators/platform_accelerator_cocoa.mm',
+ 'android/system_ui_resource_manager.h',
'android/ui_base_jni_registrar.cc',
'android/ui_base_jni_registrar.h',
'android/view_android.cc',
diff --git a/ui/gfx/android/java_bitmap.cc b/ui/gfx/android/java_bitmap.cc
index 5988befe..d1f644f 100644
--- a/ui/gfx/android/java_bitmap.cc
+++ b/ui/gfx/android/java_bitmap.cc
@@ -9,6 +9,7 @@
#include "base/android/jni_string.h"
#include "base/logging.h"
#include "jni/BitmapHelper_jni.h"
+#include "skia/ext/image_operations.h"
#include "ui/gfx/size.h"
using base::android::AttachCurrentThread;
@@ -68,17 +69,6 @@ ScopedJavaLocalRef<jobject> CreateJavaBitmap(int width,
AttachCurrentThread(), width, height, java_bitmap_config);
}
-ScopedJavaLocalRef<jobject> CreateJavaBitmapFromAndroidResource(
- const char* name,
- gfx::Size size) {
- DCHECK(name);
- DCHECK(!size.IsEmpty());
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jstring> jname(ConvertUTF8ToJavaString(env, name));
- return Java_BitmapHelper_decodeDrawableResource(
- env, jname.obj(), size.width(), size.height());
-}
-
ScopedJavaLocalRef<jobject> ConvertToJavaBitmap(const SkBitmap* skbitmap) {
DCHECK(skbitmap);
DCHECK(!skbitmap->isNull());
@@ -96,6 +86,26 @@ ScopedJavaLocalRef<jobject> ConvertToJavaBitmap(const SkBitmap* skbitmap) {
return jbitmap;
}
+SkBitmap CreateSkBitmapFromAndroidResource(const char* name, gfx::Size size) {
+ DCHECK(name);
+ DCHECK(!size.IsEmpty());
+ JNIEnv* env = AttachCurrentThread();
+ ScopedJavaLocalRef<jstring> jname(ConvertUTF8ToJavaString(env, name));
+ base::android::ScopedJavaLocalRef<jobject> jobj =
+ Java_BitmapHelper_decodeDrawableResource(
+ env, jname.obj(), size.width(), size.height());
+
+ if (jobj.is_null())
+ return SkBitmap();
+
+ SkBitmap bitmap = CreateSkBitmapFromJavaBitmap(gfx::JavaBitmap(jobj.obj()));
+ if (bitmap.isNull())
+ return bitmap;
+
+ return skia::ImageOperations::Resize(
+ bitmap, skia::ImageOperations::RESIZE_BOX, size.width(), size.height());
+}
+
SkBitmap CreateSkBitmapFromJavaBitmap(const JavaBitmap& jbitmap) {
// TODO(jdduke): Convert to DCHECK's when sufficient data has been capture for
// crbug.com/341406.
diff --git a/ui/gfx/android/java_bitmap.h b/ui/gfx/android/java_bitmap.h
index befb09b..34cd26a 100644
--- a/ui/gfx/android/java_bitmap.h
+++ b/ui/gfx/android/java_bitmap.h
@@ -57,12 +57,12 @@ GFX_EXPORT base::android::ScopedJavaLocalRef<jobject> CreateJavaBitmap(
int height,
SkColorType color_type);
-// Loads a Java-backed bitmap (android.graphics.Bitmap) from the provided
-// drawable resource identifier (e.g., android:drawable/overscroll_glow). If the
-// resource loads successfully, it will be integrally scaled down, preserving
-// aspect ratio, to a size no smaller than |size|. Otherwise, null is returned.
-GFX_EXPORT base::android::ScopedJavaLocalRef<jobject>
- CreateJavaBitmapFromAndroidResource(const char* name, gfx::Size size);
+// Loads an SkBitmap from the provided drawable resource identifier (e.g.,
+// android:drawable/overscroll_glow). If the resource loads successfully, it
+// will be integrally scaled down, preserving aspect ratio, to a size no smaller
+// than |size|. Otherwise, an empty bitmap is returned.
+GFX_EXPORT SkBitmap
+ CreateSkBitmapFromAndroidResource(const char* name, gfx::Size size);
// Converts |skbitmap| to a Java-backed bitmap (android.graphics.Bitmap).
// Note: |skbitmap| is assumed to be non-null, non-empty and one of RGBA_8888 or