 Chromium Code Reviews
 Chromium Code Reviews Issue 1413153007:
  arc-app-launcher: Minimal support for ARC app launcher.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 1413153007:
  arc-app-launcher: Minimal support for ARC app launcher.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| 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()); | 
| +} |