Index: components/exo/shell_surface.cc |
diff --git a/components/exo/shell_surface.cc b/components/exo/shell_surface.cc |
index e4fff6f17a71d2ddb9ce98a97105c2dec3b6f52f..15a7d608f90cb683cce7a8466ee1fe1e507b122b 100644 |
--- a/components/exo/shell_surface.cc |
+++ b/components/exo/shell_surface.cc |
@@ -60,6 +60,10 @@ const struct Accelerator { |
{ui::VKEY_W, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN}, |
{ui::VKEY_F4, ui::EF_ALT_DOWN}}; |
+constexpr uint32_t kFirstIconChunkFlag = 0x1; |
+constexpr uint32_t kLastIconChunkFlag = 0x2; |
+constexpr size_t kMaxIconSize = 32 * 1024; |
+ |
class CustomFrameView : public views::NonClientFrameView { |
public: |
explicit CustomFrameView(views::Widget* widget) : widget_(widget) {} |
@@ -312,6 +316,7 @@ ShellSurface::ScopedAnimationsDisabled::~ScopedAnimationsDisabled() { |
// ShellSurface, public: |
DEFINE_LOCAL_UI_CLASS_PROPERTY_KEY(Surface*, kMainSurfaceKey, nullptr) |
+DEFINE_LOCAL_UI_CLASS_PROPERTY_KEY(std::string*, kUnsafeIconPngDataKey, nullptr) |
ShellSurface::ShellSurface(Surface* surface, |
ShellSurface* parent, |
@@ -521,6 +526,41 @@ void ShellSurface::SetTitle(const base::string16& title) { |
widget_->UpdateWindowTitle(); |
} |
+void ShellSurface::SetIconChunk(uint32_t flags, |
+ const std::string& unsafe_icon_png) { |
+ TRACE_EVENT0("exo", "ShellSurface::SetIconChunk"); |
+ |
+ if (flags & kFirstIconChunkFlag) { |
+ unsafe_icon_png_builder_.clear(); |
+ } else if (unsafe_icon_png_builder_.empty()) { |
+ LOG(ERROR) << "Received shelf icon chunk withot first chunk."; |
+ return; |
+ } |
+ |
+ if (unsafe_icon_png.size() + unsafe_icon_png_builder_.size() > kMaxIconSize) { |
+ unsafe_icon_png_builder_.clear(); |
+ LOG(WARNING) << "Surface icon is too big " |
+ << (unsafe_icon_png.size() + unsafe_icon_png_builder_.size()) |
+ << "."; |
+ return; |
+ } |
+ |
+ unsafe_icon_png_builder_ += unsafe_icon_png; |
+ if (flags & kLastIconChunkFlag) { |
+ unsafe_icon_png_ = unsafe_icon_png_builder_; |
+ unsafe_icon_png_builder_.clear(); |
+ if (widget_ && widget_->GetNativeWindow()) |
+ SetUnsafeIconPngData(widget_->GetNativeWindow(), &unsafe_icon_png_); |
+ } |
+} |
+ |
+void ShellSurface::ResetIcon() { |
+ unsafe_icon_png_.clear(); |
+ unsafe_icon_png_builder_.clear(); |
+ if (widget_ && widget_->GetNativeWindow()) |
+ SetUnsafeIconPngData(widget_->GetNativeWindow(), nullptr); |
+} |
+ |
void ShellSurface::SetSystemModal(bool system_modal) { |
// System modal container is used by clients to implement client side |
// managed system modal dialogs using a single ShellSurface instance. |
@@ -708,6 +748,23 @@ Surface* ShellSurface::GetMainSurface(const aura::Window* window) { |
return window->GetProperty(kMainSurfaceKey); |
} |
+// static |
+bool ShellSurface::IsUnsafeIconPngDataKey(const void* key) { |
+ return key == kUnsafeIconPngDataKey; |
+} |
+ |
+// static |
+const std::string* ShellSurface::GetUnsafeIconPngData( |
+ const aura::Window* window) { |
+ return window->GetProperty(kUnsafeIconPngDataKey); |
+} |
+ |
+// static |
+void ShellSurface::SetUnsafeIconPngData(aura::Window* window, |
+ std::string* unsage_icon_png_data) { |
+ return window->SetProperty(kUnsafeIconPngDataKey, unsage_icon_png_data); |
+} |
+ |
std::unique_ptr<base::trace_event::TracedValue> ShellSurface::AsTracedValue() |
const { |
std::unique_ptr<base::trace_event::TracedValue> value( |
@@ -1200,6 +1257,8 @@ void ShellSurface::CreateShellSurfaceWidget(ui::WindowShowState show_state) { |
window->AddChild(surface_->window()); |
window->SetEventTargeter(base::WrapUnique(new CustomWindowTargeter(widget_))); |
SetApplicationId(window, application_id_); |
+ if (!unsafe_icon_png_.empty()) |
+ SetUnsafeIconPngData(window, &unsafe_icon_png_); |
SetMainSurface(window, surface_); |
// Start tracking changes to window bounds and window state. |