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..e2348e495db089eb87876d39f6b2e6c49817de5c |
--- /dev/null |
+++ b/chrome/browser/ui/app_list/arc_app_item.cc |
@@ -0,0 +1,167 @@ |
+// 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 "extensions/grit/extensions_browser_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 ready) |
+ : app_list::AppListItem(id), |
+ context_(context), |
+ ready_(ready), |
+ weak_ptr_factory_(this) { |
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
+ |
+ SetName(name); |
+ set_position(syncer::StringOrdinal("nq")); |
elijahtaylor1
2015/11/03 22:38:19
I had a comment on the earlier patch, can you comm
|
+ |
+ UpdateIcon(ResourceBundle::GetSharedInstance().GetImageSkiaNamed( |
+ IDR_APP_DEFAULT_ICON)); |
+} |
+ |
+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::SetReady(bool ready) { |
+ if (ready_ == ready) { |
+ return; |
+ } |
+ ready_ = ready; |
+ 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 (!ready_) { |
+ 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::UpdateIconOnBlockingThread, |
+ base::Unretained(this), |
+ scale_factor, |
+ path); |
+ content::BrowserThread::GetBlockingPool()->PostTask(FROM_HERE, task); |
+} |
+ |
+void ArcAppItem::UpdateIconOnBlockingThread(ui::ScaleFactor scale_factor, |
+ const base::FilePath& path) { |
+ DCHECK(content::BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread()); |
+ |
+ // 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/11/03 22:38:19
I'm still skeptical that this will pass security a
khmel1
2015/11/12 08:05:29
Agree, I changed icon workflow and implemented uti
|
+ |
+ 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()); |
+} |