| Index: chrome/browser/ui/ash/launcher/arc_app_window.cc
|
| diff --git a/chrome/browser/ui/ash/launcher/arc_app_window.cc b/chrome/browser/ui/ash/launcher/arc_app_window.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..10d5a6affab02487aff6bea9a486f7020f269956
|
| --- /dev/null
|
| +++ b/chrome/browser/ui/ash/launcher/arc_app_window.cc
|
| @@ -0,0 +1,227 @@
|
| +// Copyright 2017 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/ash/launcher/arc_app_window.h"
|
| +
|
| +#include "chrome/browser/ui/app_list/arc/arc_app_utils.h"
|
| +#include "chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h"
|
| +#include "chrome/browser/ui/ash/launcher/arc_app_window_launcher_item_controller.h"
|
| +#include "components/exo/shell_surface.h"
|
| +#include "extensions/common/constants.h"
|
| +#include "ui/aura/window.h"
|
| +#include "ui/gfx/codec/png_codec.h"
|
| +#include "ui/gfx/image/image_skia_operations.h"
|
| +#include "ui/gfx/image/image_skia_source.h"
|
| +#include "ui/views/widget/widget.h"
|
| +
|
| +namespace {
|
| +
|
| +// Set to true for unit tests to avoid IPC icon decoding.
|
| +bool disable_safe_icon_decoding = false;
|
| +
|
| +// Source of the custom icon of ARC app window. It takes reference bitmap and
|
| +// resizes to required scale factor on demand.
|
| +class CustomIconSource : public gfx::ImageSkiaSource {
|
| + public:
|
| + explicit CustomIconSource(const SkBitmap& base_image)
|
| + : base_image_(base_image) {}
|
| + ~CustomIconSource() override = default;
|
| +
|
| + private:
|
| + // gfx::ImageSkiaSource overrides:
|
| + gfx::ImageSkiaRep GetImageForScale(float scale) override {
|
| + const gfx::Size target_pixel_size =
|
| + gfx::ScaleToCeiledSize(gfx::Size(extension_misc::EXTENSION_ICON_SMALL,
|
| + extension_misc::EXTENSION_ICON_SMALL),
|
| + scale);
|
| +
|
| + const SkBitmap resized = skia::ImageOperations::Resize(
|
| + base_image_, skia::ImageOperations::RESIZE_BEST,
|
| + target_pixel_size.width(), target_pixel_size.height());
|
| + return gfx::ImageSkiaRep(resized, scale);
|
| + }
|
| +
|
| + const SkBitmap base_image_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(CustomIconSource);
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +ArcAppWindow::ArcAppWindow(int task_id,
|
| + const arc::ArcAppShelfId& app_shelf_id,
|
| + views::Widget* widget,
|
| + ArcAppWindowLauncherController* owner)
|
| + : task_id_(task_id),
|
| + app_shelf_id_(app_shelf_id),
|
| + widget_(widget),
|
| + owner_(owner) {
|
| + ExtractIconFromWindow();
|
| + GetNativeWindow()->AddObserver(this);
|
| +}
|
| +
|
| +ArcAppWindow::~ArcAppWindow() {
|
| + ImageDecoder::Cancel(this);
|
| + if (GetNativeWindow())
|
| + GetNativeWindow()->RemoveObserver(this);
|
| +}
|
| +
|
| +// static
|
| +void ArcAppWindow::DisableSafeIconDecodingForTesting() {
|
| + disable_safe_icon_decoding = true;
|
| +}
|
| +
|
| +void ArcAppWindow::SetController(
|
| + ArcAppWindowLauncherItemController* controller) {
|
| + DCHECK(!controller_ && controller);
|
| + controller_ = controller;
|
| +}
|
| +
|
| +void ArcAppWindow::ResetController() {
|
| + controller_ = nullptr;
|
| +}
|
| +
|
| +void ArcAppWindow::SetFullscreenMode(FullScreenMode mode) {
|
| + DCHECK(mode != FullScreenMode::NOT_DEFINED);
|
| + fullscreen_mode_ = mode;
|
| +}
|
| +
|
| +bool ArcAppWindow::IsActive() const {
|
| + return widget_->IsActive() && owner_->active_task_id() == task_id_;
|
| +}
|
| +
|
| +bool ArcAppWindow::IsMaximized() const {
|
| + NOTREACHED();
|
| + return false;
|
| +}
|
| +
|
| +bool ArcAppWindow::IsMinimized() const {
|
| + NOTREACHED();
|
| + return false;
|
| +}
|
| +
|
| +bool ArcAppWindow::IsFullscreen() const {
|
| + NOTREACHED();
|
| + return false;
|
| +}
|
| +
|
| +gfx::NativeWindow ArcAppWindow::GetNativeWindow() const {
|
| + return widget_->GetNativeWindow();
|
| +}
|
| +
|
| +gfx::Rect ArcAppWindow::GetRestoredBounds() const {
|
| + NOTREACHED();
|
| + return gfx::Rect();
|
| +}
|
| +
|
| +ui::WindowShowState ArcAppWindow::GetRestoredState() const {
|
| + NOTREACHED();
|
| + return ui::SHOW_STATE_NORMAL;
|
| +}
|
| +
|
| +gfx::Rect ArcAppWindow::GetBounds() const {
|
| + NOTREACHED();
|
| + return gfx::Rect();
|
| +}
|
| +
|
| +void ArcAppWindow::Show() {
|
| + widget_->Show();
|
| +}
|
| +
|
| +void ArcAppWindow::ShowInactive() {
|
| + NOTREACHED();
|
| +}
|
| +
|
| +void ArcAppWindow::Hide() {
|
| + NOTREACHED();
|
| +}
|
| +
|
| +void ArcAppWindow::Close() {
|
| + arc::CloseTask(task_id_);
|
| +}
|
| +
|
| +void ArcAppWindow::Activate() {
|
| + widget_->Activate();
|
| +}
|
| +
|
| +void ArcAppWindow::Deactivate() {
|
| + NOTREACHED();
|
| +}
|
| +
|
| +void ArcAppWindow::Maximize() {
|
| + NOTREACHED();
|
| +}
|
| +
|
| +void ArcAppWindow::Minimize() {
|
| + widget_->Minimize();
|
| +}
|
| +
|
| +void ArcAppWindow::Restore() {
|
| + NOTREACHED();
|
| +}
|
| +
|
| +void ArcAppWindow::SetBounds(const gfx::Rect& bounds) {
|
| + NOTREACHED();
|
| +}
|
| +
|
| +void ArcAppWindow::FlashFrame(bool flash) {
|
| + NOTREACHED();
|
| +}
|
| +
|
| +bool ArcAppWindow::IsAlwaysOnTop() const {
|
| + NOTREACHED();
|
| + return false;
|
| +}
|
| +
|
| +void ArcAppWindow::SetAlwaysOnTop(bool always_on_top) {
|
| + NOTREACHED();
|
| +}
|
| +
|
| +void ArcAppWindow::ResetIcon() {
|
| + if (image_skia_.isNull())
|
| + return;
|
| + image_skia_ = gfx::ImageSkia();
|
| + controller()->OnWindowChanged(this);
|
| +}
|
| +
|
| +void ArcAppWindow::ExtractIconFromWindow() {
|
| + ImageDecoder::Cancel(this);
|
| + const std::string* unsafe_icon_data =
|
| + exo::ShellSurface::GetUnsafeIconPngData(GetNativeWindow());
|
| + if (unsafe_icon_data && !unsafe_icon_data->empty()) {
|
| + if (disable_safe_icon_decoding) {
|
| + SkBitmap bitmap;
|
| + if (gfx::PNGCodec::Decode(reinterpret_cast<const unsigned char*>(
|
| + &unsafe_icon_data->front()),
|
| + unsafe_icon_data->length(), &bitmap)) {
|
| + OnImageDecoded(bitmap);
|
| + } else {
|
| + OnDecodeImageFailed();
|
| + }
|
| + } else {
|
| + ImageDecoder::Start(this, *unsafe_icon_data);
|
| + }
|
| + } else {
|
| + ResetIcon();
|
| + }
|
| +}
|
| +
|
| +void ArcAppWindow::OnWindowPropertyChanged(aura::Window* window,
|
| + const void* key,
|
| + intptr_t old) {
|
| + if (!exo::ShellSurface::IsUnsafeIconPngDataKey(key))
|
| + return;
|
| + ExtractIconFromWindow();
|
| +}
|
| +
|
| +void ArcAppWindow::OnImageDecoded(const SkBitmap& decoded_image) {
|
| + image_skia_ = gfx::ImageSkia(new CustomIconSource(decoded_image),
|
| + gfx::Size(extension_misc::EXTENSION_ICON_SMALL,
|
| + extension_misc::EXTENSION_ICON_SMALL));
|
| + controller()->OnWindowChanged(this);
|
| +}
|
| +
|
| +void ArcAppWindow::OnDecodeImageFailed() {
|
| + ResetIcon();
|
| +}
|
|
|