Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2017 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/ui/ash/launcher/arc_app_window.h" | |
| 6 | |
| 7 #include "base/strings/utf_string_conversions.h" | |
| 8 #include "chrome/browser/ui/app_list/arc/arc_app_utils.h" | |
| 9 #include "chrome/browser/ui/ash/launcher/arc_app_window_launcher_controller.h" | |
| 10 #include "chrome/browser/ui/ash/launcher/arc_app_window_launcher_item_controller .h" | |
| 11 #include "components/exo/shell_surface.h" | |
| 12 #include "extensions/common/constants.h" | |
| 13 #include "ui/aura/window.h" | |
| 14 #include "ui/gfx/codec/png_codec.h" | |
| 15 #include "ui/gfx/image/image_skia_operations.h" | |
| 16 #include "ui/gfx/image/image_skia_source.h" | |
| 17 #include "ui/views/widget/widget.h" | |
| 18 | |
| 19 namespace { | |
| 20 | |
| 21 // Set to true for unit tests to avoid IPC icon decoding. | |
|
msw
2017/05/18 18:26:48
nit: explain why that's useful.
khmel
2017/05/18 20:27:50
Done.
| |
| 22 bool disable_safe_icon_decoding = false; | |
|
msw
2017/05/18 18:26:48
nit: append _for_testing to the identifier itself
khmel
2017/05/18 20:27:51
Done.
| |
| 23 | |
| 24 // Source of the custom icon of ARC app window. It takes reference bitmap and | |
| 25 // resizes to required scale factor on demand. | |
| 26 class CustomIconSource : public gfx::ImageSkiaSource { | |
|
xiyuan
2017/05/18 16:22:49
Can we get rid of this class and do something like
khmel
2017/05/18 17:29:34
Yes, if required scale is missing then 1.0 is take
msw
2017/05/18 22:03:38
Nice!
khmel
2017/05/18 22:40:02
Acknowledged.
| |
| 27 public: | |
| 28 explicit CustomIconSource(const SkBitmap& base_image) | |
| 29 : base_image_(base_image) {} | |
| 30 ~CustomIconSource() override = default; | |
| 31 | |
| 32 private: | |
| 33 // gfx::ImageSkiaSource overrides: | |
| 34 gfx::ImageSkiaRep GetImageForScale(float scale) override { | |
| 35 const gfx::Size target_pixel_size = | |
| 36 gfx::ScaleToCeiledSize(gfx::Size(extension_misc::EXTENSION_ICON_SMALL, | |
| 37 extension_misc::EXTENSION_ICON_SMALL), | |
| 38 scale); | |
| 39 | |
| 40 const SkBitmap resized = skia::ImageOperations::Resize( | |
| 41 base_image_, skia::ImageOperations::RESIZE_BEST, | |
| 42 target_pixel_size.width(), target_pixel_size.height()); | |
| 43 return gfx::ImageSkiaRep(resized, scale); | |
| 44 } | |
| 45 | |
| 46 const SkBitmap base_image_; | |
| 47 | |
| 48 DISALLOW_COPY_AND_ASSIGN(CustomIconSource); | |
| 49 }; | |
| 50 | |
| 51 } // namespace | |
| 52 | |
| 53 ArcAppWindow::ArcAppWindow(int task_id, | |
| 54 const arc::ArcAppShelfId& app_shelf_id, | |
| 55 views::Widget* widget, | |
| 56 ArcAppWindowLauncherController* owner) | |
| 57 : task_id_(task_id), | |
| 58 app_shelf_id_(app_shelf_id), | |
| 59 widget_(widget), | |
| 60 owner_(owner) {} | |
| 61 | |
| 62 ArcAppWindow::~ArcAppWindow() { | |
| 63 ImageDecoder::Cancel(this); | |
| 64 } | |
| 65 | |
| 66 // static | |
| 67 void ArcAppWindow::DisableSafeIconDecodingForTesting() { | |
| 68 disable_safe_icon_decoding = true; | |
| 69 } | |
| 70 | |
| 71 void ArcAppWindow::SetController( | |
| 72 ArcAppWindowLauncherItemController* controller) { | |
| 73 DCHECK(!controller_ && controller); | |
| 74 controller_ = controller; | |
|
xiyuan
2017/05/18 16:22:49
Do we need to ensure that the launcher icon is upd
khmel
2017/05/18 17:29:34
Practically no, because AddWindow is called the sa
| |
| 75 } | |
| 76 | |
| 77 void ArcAppWindow::ResetController() { | |
| 78 controller_ = nullptr; | |
| 79 } | |
| 80 | |
| 81 void ArcAppWindow::SetFullscreenMode(FullScreenMode mode) { | |
| 82 DCHECK(mode != FullScreenMode::NOT_DEFINED); | |
| 83 fullscreen_mode_ = mode; | |
| 84 } | |
| 85 | |
| 86 void ArcAppWindow::SetDescription( | |
| 87 const std::string& title, | |
| 88 const std::vector<uint8_t>& unsafe_icon_data_png) { | |
| 89 if (title.length()) | |
|
msw
2017/05/18 18:26:48
nit !empty?
khmel
2017/05/18 20:27:50
Done.
| |
| 90 GetNativeWindow()->SetTitle(base::string16(base::UTF8ToUTF16(title))); | |
|
msw
2017/05/18 18:26:48
nit: base::string16 is probably not needed (adds a
khmel
2017/05/18 20:27:51
Done.
| |
| 91 ImageDecoder::Cancel(this); | |
| 92 if (unsafe_icon_data_png.empty()) { | |
| 93 ResetIcon(); | |
|
msw
2017/05/18 18:26:48
Can we just continue using the current icon until
khmel
2017/05/18 20:27:51
In this case we pass empty data which means custom
msw
2017/05/18 22:03:38
So you're trying to use the app/activity icon inst
khmel
2017/05/18 22:40:02
This makes sense but sounds as refactoring, quite
msw
2017/05/18 22:50:11
I look forward to seeing the cleanup change for ht
| |
| 94 return; | |
| 95 } | |
| 96 | |
| 97 if (disable_safe_icon_decoding) { | |
| 98 SkBitmap bitmap; | |
| 99 if (gfx::PNGCodec::Decode(&unsafe_icon_data_png[0], | |
| 100 unsafe_icon_data_png.size(), &bitmap)) { | |
| 101 OnImageDecoded(bitmap); | |
| 102 } else { | |
| 103 OnDecodeImageFailed(); | |
| 104 } | |
| 105 } else { | |
| 106 ImageDecoder::Start(this, unsafe_icon_data_png); | |
| 107 } | |
| 108 } | |
| 109 | |
| 110 bool ArcAppWindow::IsActive() const { | |
| 111 return widget_->IsActive() && owner_->active_task_id() == task_id_; | |
|
msw
2017/05/18 18:26:48
Do we need to maintain two separate notions of Act
khmel
2017/05/18 20:27:50
Activating ARC app is not straightforward. It may
msw
2017/05/18 22:03:39
It would be nice to clean this up later, this is t
khmel
2017/05/18 22:40:02
Acknowledged.
| |
| 112 } | |
| 113 | |
| 114 bool ArcAppWindow::IsMaximized() const { | |
| 115 NOTREACHED(); | |
| 116 return false; | |
| 117 } | |
| 118 | |
| 119 bool ArcAppWindow::IsMinimized() const { | |
| 120 NOTREACHED(); | |
| 121 return false; | |
| 122 } | |
| 123 | |
| 124 bool ArcAppWindow::IsFullscreen() const { | |
|
msw
2017/05/18 18:26:48
Shouldn't this tie into your fullscreen setting? I
khmel
2017/05/18 20:27:50
Similar to previous comment. I would prefer not to
msw
2017/05/18 22:03:38
Acknowledged.
| |
| 125 NOTREACHED(); | |
| 126 return false; | |
| 127 } | |
| 128 | |
| 129 gfx::NativeWindow ArcAppWindow::GetNativeWindow() const { | |
| 130 return widget_->GetNativeWindow(); | |
| 131 } | |
| 132 | |
| 133 gfx::Rect ArcAppWindow::GetRestoredBounds() const { | |
| 134 NOTREACHED(); | |
| 135 return gfx::Rect(); | |
| 136 } | |
| 137 | |
| 138 ui::WindowShowState ArcAppWindow::GetRestoredState() const { | |
| 139 NOTREACHED(); | |
| 140 return ui::SHOW_STATE_NORMAL; | |
| 141 } | |
| 142 | |
| 143 gfx::Rect ArcAppWindow::GetBounds() const { | |
| 144 NOTREACHED(); | |
| 145 return gfx::Rect(); | |
| 146 } | |
| 147 | |
| 148 void ArcAppWindow::Show() { | |
| 149 widget_->Show(); | |
| 150 } | |
| 151 | |
| 152 void ArcAppWindow::ShowInactive() { | |
| 153 NOTREACHED(); | |
| 154 } | |
| 155 | |
| 156 void ArcAppWindow::Hide() { | |
| 157 NOTREACHED(); | |
| 158 } | |
| 159 | |
| 160 void ArcAppWindow::Close() { | |
| 161 arc::CloseTask(task_id_); | |
| 162 } | |
| 163 | |
| 164 void ArcAppWindow::Activate() { | |
| 165 widget_->Activate(); | |
| 166 } | |
| 167 | |
| 168 void ArcAppWindow::Deactivate() { | |
| 169 NOTREACHED(); | |
| 170 } | |
| 171 | |
| 172 void ArcAppWindow::Maximize() { | |
| 173 NOTREACHED(); | |
| 174 } | |
| 175 | |
| 176 void ArcAppWindow::Minimize() { | |
| 177 widget_->Minimize(); | |
| 178 } | |
| 179 | |
| 180 void ArcAppWindow::Restore() { | |
| 181 NOTREACHED(); | |
| 182 } | |
| 183 | |
| 184 void ArcAppWindow::SetBounds(const gfx::Rect& bounds) { | |
| 185 NOTREACHED(); | |
| 186 } | |
| 187 | |
| 188 void ArcAppWindow::FlashFrame(bool flash) { | |
| 189 NOTREACHED(); | |
| 190 } | |
| 191 | |
| 192 bool ArcAppWindow::IsAlwaysOnTop() const { | |
| 193 NOTREACHED(); | |
| 194 return false; | |
| 195 } | |
| 196 | |
| 197 void ArcAppWindow::SetAlwaysOnTop(bool always_on_top) { | |
| 198 NOTREACHED(); | |
| 199 } | |
| 200 | |
| 201 void ArcAppWindow::ResetIcon() { | |
|
msw
2017/05/18 18:26:48
Is this actually useful? Can we just use the curre
khmel
2017/05/18 20:27:50
I explained in previous comment. App may pass null
| |
| 202 if (image_skia_.isNull()) | |
| 203 return; | |
| 204 image_skia_ = gfx::ImageSkia(); | |
| 205 controller()->OnWindowChanged(this); | |
|
xiyuan
2017/05/18 16:22:48
Do we need to worry about |controller_| is nullptr
khmel
2017/05/18 17:29:34
Yes, it can happen, especially in multi-profile ca
| |
| 206 } | |
| 207 | |
| 208 void ArcAppWindow::OnImageDecoded(const SkBitmap& decoded_image) { | |
| 209 image_skia_ = gfx::ImageSkia(new CustomIconSource(decoded_image), | |
|
msw
2017/05/18 18:26:48
It seems like this calls shouldn't store a separat
khmel
2017/05/18 20:27:50
Hmm. I did similar as extension app window works.
msw
2017/05/18 22:03:38
We should consolidate common behavior on the reusa
khmel
2017/05/18 22:40:02
As above, I suggest to clean up this as separate C
| |
| 210 gfx::Size(extension_misc::EXTENSION_ICON_SMALL, | |
| 211 extension_misc::EXTENSION_ICON_SMALL)); | |
| 212 controller()->OnWindowChanged(this); | |
|
xiyuan
2017/05/18 16:22:48
same here.
khmel
2017/05/18 17:29:34
Done.
| |
| 213 } | |
| 214 | |
| 215 void ArcAppWindow::OnDecodeImageFailed() { | |
| 216 ResetIcon(); | |
|
msw
2017/05/18 18:26:48
Why should the controller be notified when the ico
khmel
2017/05/18 20:27:50
We probably may continue using old icon. And this
| |
| 217 } | |
| OLD | NEW |