| Index: content/browser/android/system_ui_resource_manager_impl.cc
|
| 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 0000000000000000000000000000000000000000..385bbcb6d76ab86029d8c8a9e75b067c2671535b
|
| --- /dev/null
|
| +++ b/content/browser/android/system_ui_resource_manager_impl.cc
|
| @@ -0,0 +1,162 @@
|
| +// 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/browser/android/system_ui_resource.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/base/android/system_ui_resource_layer.h"
|
| +#include "ui/gfx/android/java_bitmap.h"
|
| +
|
| +namespace content {
|
| +
|
| +class SystemUIResourceManagerImpl::Entry : public SystemUIResourceClient {
|
| + public:
|
| + Entry() {}
|
| + virtual ~Entry() {
|
| + if (resource_)
|
| + resource_->SetClient(NULL);
|
| + }
|
| + void Subscribe(ui::SystemUIResourceLayer* layer) {
|
| + DCHECK(layer);
|
| + if (resource_)
|
| + layer->SetUIResourceId(resource_->id());
|
| +
|
| + if (!subscribers_.HasObserver(layer))
|
| + subscribers_.AddObserver(layer);
|
| + }
|
| +
|
| + void Unsubscribe(ui::SystemUIResourceLayer* layer) {
|
| + DCHECK(layer);
|
| + layer->SetUIResourceId(0);
|
| + subscribers_.RemoveObserver(layer);
|
| + }
|
| +
|
| + void SetResource(scoped_ptr<SystemUIResource> resource) {
|
| + DCHECK(resource);
|
| + DCHECK(!resource_);
|
| + resource_ = resource.Pass();
|
| + resource_->SetClient(this);
|
| + RefreshResource();
|
| + }
|
| +
|
| + void RefreshResource() {
|
| + if (!resource_)
|
| + return;
|
| + resource_->Load();
|
| + FOR_EACH_OBSERVER(ui::SystemUIResourceLayer,
|
| + subscribers_,
|
| + SetUIResourceId(resource_->id()));
|
| + }
|
| +
|
| + bool HasResource() { return resource_; }
|
| +
|
| + // Implements SystemUIResourceClient.
|
| + virtual void OnUIResourceIdChanged() OVERRIDE {
|
| + DCHECK(resource_);
|
| + FOR_EACH_OBSERVER(ui::SystemUIResourceLayer,
|
| + subscribers_,
|
| + SetUIResourceId(resource_->id()));
|
| + }
|
| +
|
| + private:
|
| + typedef ObserverList<ui::SystemUIResourceLayer> Subscribers;
|
| + scoped_ptr<SystemUIResource> resource_;
|
| + Subscribers subscribers_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(Entry);
|
| +};
|
| +
|
| +SystemUIResourceManagerImpl::SystemUIResourceManagerImpl(
|
| + UIResourceProvider* ui_resource_provider)
|
| + : ui_resource_provider_(ui_resource_provider), weak_factory_(this) {
|
| +}
|
| +
|
| +SystemUIResourceManagerImpl::~SystemUIResourceManagerImpl() {
|
| +}
|
| +
|
| +void SystemUIResourceManagerImpl::Subscribe(
|
| + ui::SystemUIResourceManager::Type type,
|
| + ui::SystemUIResourceLayer* layer) {
|
| + DCHECK(layer);
|
| + GetEntry(type)->Subscribe(layer);
|
| +}
|
| +
|
| +void SystemUIResourceManagerImpl::Unsubscribe(
|
| + ui::SystemUIResourceManager::Type type,
|
| + ui::SystemUIResourceLayer* layer) {
|
| + DCHECK(layer);
|
| + GetEntry(type)->Unsubscribe(layer);
|
| +}
|
| +
|
| +void SystemUIResourceManagerImpl::RefreshResources() {
|
| + GetEntry(ui::SystemUIResourceManager::OVERSCROLL_GLOW)->RefreshResource();
|
| + GetEntry(ui::SystemUIResourceManager::OVERSCROLL_EDGE)->RefreshResource();
|
| +}
|
| +
|
| +SystemUIResourceManagerImpl::Entry* SystemUIResourceManagerImpl::GetEntry(
|
| + ui::SystemUIResourceManager::Type type) {
|
| + SystemUIResourceMap::iterator iter = resource_map_.find(type);
|
| + if (iter == resource_map_.end()) {
|
| + scoped_ptr<Entry> resource_entry = make_scoped_ptr(new Entry());
|
| + resource_map_.set(type, resource_entry.Pass());
|
| +
|
| + // Lazily build the resource.
|
| + BuildResource(type);
|
| + }
|
| + return resource_map_.get(type);
|
| +}
|
| +
|
| +void SystemUIResourceManagerImpl::BuildResource(
|
| + ui::SystemUIResourceManager::Type type) {
|
| + DCHECK(!GetEntry(type)->HasResource());
|
| +
|
| + // 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(
|
| + ui::SystemUIResourceManager::Type 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(
|
| + ui::SystemUIResourceManager::Type type,
|
| + SkBitmap* bitmap_holder) {
|
| + scoped_ptr<SystemUIResource> resource =
|
| + SystemUIResource::Create(*bitmap_holder, ui_resource_provider_);
|
| + GetEntry(type)->SetResource(resource.Pass());
|
| +}
|
| +
|
| +} // namespace content
|
|
|