Chromium Code Reviews| Index: chrome/browser/ui/app_list/arc_app_item.cc |
| diff --git a/chrome/browser/ui/app_list/arc_app_item.cc b/chrome/browser/ui/app_list/arc_app_item.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..f374e7ea2cd53dfff137854cffc65d014ab26d76 |
| --- /dev/null |
| +++ b/chrome/browser/ui/app_list/arc_app_item.cc |
| @@ -0,0 +1,169 @@ |
| +// Copyright (c) 2015 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 "chrome/browser/ui/app_list/arc_app_item.h" |
| + |
| +#include "base/files/file_path.h" |
| +#include "base/files/file_util.h" |
| +#include "base/task_runner_util.h" |
| +#include "chrome/browser/ui/app_list/arc_app_prefs.h" |
| +#include "chromeos/dbus/arc_bridge_client.h" |
| +#include "chromeos/dbus/dbus_thread_manager.h" |
| +#include "content/public/browser/browser_thread.h" |
| +#include "ui/app_list/resources/grit/app_list_resources.h" |
| +#include "ui/base/resource/resource_bundle.h" |
| +#include "ui/gfx/codec/png_codec.h" |
| +#include "ui/gfx/color_utils.h" |
| +#include "ui/gfx/image/image_skia_operations.h" |
| + |
| +namespace { |
| + |
| +gfx::ImageSkia CreateDisabledIcon(const gfx::ImageSkia& icon) { |
| + const color_utils::HSL shift = {-1, 0, 0.6}; |
| + return gfx::ImageSkiaOperations::CreateHSLShiftedImage(icon, shift); |
| +} |
| + |
| +} |
| + |
| +// static |
| +const char ArcAppItem::kItemType[] = "ArcAppItem"; |
| + |
| +ArcAppItem::ArcAppItem(content::BrowserContext* context, |
| + const std::string& id, |
| + const std::string& name, |
| + bool enabled) |
| + : app_list::AppListItem(id), |
| + context_(context), |
| + enabled_(enabled), |
| + weak_ptr_factory_(this) { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| + |
| + SetName(name); |
| + set_position(syncer::StringOrdinal("nq")); |
|
elijahtaylor1
2015/10/28 06:32:38
can you comment how this interacts with other apps
|
| + |
| + UpdateIcon(ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
| + IDR_APP_LIST_ARC_APP_DEFAULT)); |
| +} |
| + |
| +ArcAppItem::~ArcAppItem() { |
| +} |
| + |
| +const char* ArcAppItem::GetItemType() const { |
| + return ArcAppItem::kItemType; |
| +} |
| + |
| +void ArcAppItem::Activate(int event_flags) { |
| + ArcAppPrefs* prefs = ArcAppPrefs::Get(context_); |
| + scoped_ptr<ArcAppPrefs::AppInfo> app_info = prefs->GetApp(id()); |
| + DCHECK(app_info != nullptr); |
| + if (!app_info) { |
| + return; |
| + } |
| + |
| + chromeos::DBusThreadManager::Get()->GetArcBridgeClient()-> |
| + LaunchApp(app_info->package, app_info->activity); |
| +} |
| + |
| +void ArcAppItem::SetEnabled(bool enabled) { |
| + if (enabled_ == enabled) { |
| + return; |
| + } |
| + enabled_ = enabled; |
| + UpdateIcon(); |
| +} |
| + |
| +void ArcAppItem::SetName(const std::string& name) { |
| + SetNameAndShortName(name, name); |
| +} |
| + |
| +void ArcAppItem::UpdateIcon() { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| + |
| + gfx::ImageSkia icon = image_skia_; |
| + if (!enabled_) { |
| + icon = CreateDisabledIcon(icon); |
| + } |
| + |
| + SetIcon(icon); |
| +} |
| + |
| +void ArcAppItem::UpdateIcon(const gfx::ImageSkia* image) { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| + |
| + if (!image || image->isNull()) { |
| + return; |
| + } |
| + |
| + std::vector<gfx::ImageSkiaRep> reps = image->image_reps(); |
| + for (const auto& image_rep : reps) { |
| + if (ui::IsSupportedScale(image_rep.scale())) { |
| + image_skia_.RemoveRepresentation(image_rep.scale()); |
| + image_skia_.AddRepresentation(image_rep); |
| + } |
| + } |
| + image_ = gfx::Image(image_skia_); |
| + |
| + UpdateIcon(); |
| +} |
| + |
| +void ArcAppItem::UpdateIcon(ui::ScaleFactor scale_factor, |
| + const base::FilePath& path) { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| + |
| + base::Closure task = base::Bind(&ArcAppItem::UpdateIconFromFileThread, |
| + base::Unretained(this), |
| + scale_factor, |
| + path); |
| + content::BrowserThread::PostTask(content::BrowserThread::FILE, |
| + FROM_HERE, |
| + task); |
| +} |
| + |
| +void ArcAppItem::UpdateIconFromFileThread(ui::ScaleFactor scale_factor, |
| + const base::FilePath& path) { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); |
| + |
| + // Read the file from disk. |
| + std::string file_contents; |
| + if (path.empty() || !base::ReadFileToString(path, &file_contents)) { |
| + return; |
| + } |
| + |
| + SkBitmap bitmap; |
| + const unsigned char* data = |
| + reinterpret_cast<const unsigned char*>(file_contents.data()); |
| + gfx::PNGCodec::Decode(data, file_contents.length(), &bitmap); |
|
elijahtaylor1
2015/10/28 06:32:38
I don't know if this is considered safe to do in t
khmel1
2015/10/29 08:12:18
I changed similar to extensions::ImageLoader by us
|
| + |
| + if (bitmap.isNull() || bitmap.empty()) { |
| + return; |
| + } |
| + |
| + gfx::ImageSkia image_skia; |
| + image_skia.AddRepresentation(gfx::ImageSkiaRep( |
| + bitmap, |
| + ui::GetScaleForScaleFactor(scale_factor))); |
| + |
| + gfx::Image image; |
| + if (!image_skia.isNull()) { |
| + image_skia.MakeThreadSafe(); |
| + image = gfx::Image(image_skia); |
| + } |
| + |
| + base::Closure task = base::Bind(&ArcAppItem::OnIconLoaded, |
| + base::Unretained(this), |
| + image); |
| + content::BrowserThread::PostTask(content::BrowserThread::UI, |
| + FROM_HERE, |
| + task); |
| +} |
| + |
| +void ArcAppItem::OnIconLoaded(const gfx::Image& image_in) { |
| + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| + |
| + if (image_in.IsEmpty()) { |
| + return; |
| + } |
| + |
| + UpdateIcon(image_in.ToImageSkia()); |
| +} |