Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(710)

Side by Side Diff: ui/arc/notification/arc_custom_notification_view.cc

Issue 2269403004: arc: Defer notification surface creation (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase and fix compile Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/arc/notification/arc_custom_notification_view.h" 5 #include "ui/arc/notification/arc_custom_notification_view.h"
6 6
7 #include "components/exo/notification_surface.h" 7 #include "components/exo/notification_surface.h"
8 #include "components/exo/surface.h" 8 #include "components/exo/surface.h"
9 #include "third_party/skia/include/core/SkColor.h" 9 #include "third_party/skia/include/core/SkColor.h"
10 #include "ui/base/l10n/l10n_util.h" 10 #include "ui/base/l10n/l10n_util.h"
11 #include "ui/base/resource/resource_bundle.h" 11 #include "ui/base/resource/resource_bundle.h"
12 #include "ui/compositor/layer_animation_observer.h" 12 #include "ui/compositor/layer_animation_observer.h"
13 #include "ui/display/screen.h" 13 #include "ui/display/screen.h"
14 #include "ui/events/event_handler.h" 14 #include "ui/events/event_handler.h"
15 #include "ui/gfx/canvas.h"
16 #include "ui/gfx/image/image_skia.h"
15 #include "ui/gfx/transform.h" 17 #include "ui/gfx/transform.h"
16 #include "ui/message_center/message_center_style.h" 18 #include "ui/message_center/message_center_style.h"
17 #include "ui/resources/grit/ui_resources.h" 19 #include "ui/resources/grit/ui_resources.h"
18 #include "ui/strings/grit/ui_strings.h" 20 #include "ui/strings/grit/ui_strings.h"
19 #include "ui/views/background.h" 21 #include "ui/views/background.h"
20 #include "ui/views/border.h" 22 #include "ui/views/border.h"
21 #include "ui/views/controls/button/image_button.h" 23 #include "ui/views/controls/button/image_button.h"
22 #include "ui/views/widget/widget.h" 24 #include "ui/views/widget/widget.h"
23 #include "ui/wm/core/window_util.h" 25 #include "ui/wm/core/window_util.h"
24 26
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 void OnLayerAnimationScheduled(ui::LayerAnimationSequence* seq) override {} 109 void OnLayerAnimationScheduled(ui::LayerAnimationSequence* seq) override {}
108 110
109 ArcCustomNotificationView* const owner_; 111 ArcCustomNotificationView* const owner_;
110 bool sliding_ = false; 112 bool sliding_ = false;
111 std::unique_ptr<ui::LayerTreeOwner> surface_copy_; 113 std::unique_ptr<ui::LayerTreeOwner> surface_copy_;
112 114
113 DISALLOW_COPY_AND_ASSIGN(SlideHelper); 115 DISALLOW_COPY_AND_ASSIGN(SlideHelper);
114 }; 116 };
115 117
116 ArcCustomNotificationView::ArcCustomNotificationView( 118 ArcCustomNotificationView::ArcCustomNotificationView(
117 ArcCustomNotificationItem* item, 119 ArcCustomNotificationItem* item)
118 exo::NotificationSurface* surface) 120 : item_(item),
119 : item_(item), event_forwarder_(new EventForwarder(this)) { 121 notification_key_(item->notification_key()),
120 SetSurface(surface); 122 event_forwarder_(new EventForwarder(this)) {
123 item_->IncrementWindowRefCount();
121 item_->AddObserver(this); 124 item_->AddObserver(this);
122 OnItemPinnedChanged(); 125
126 ArcNotificationSurfaceManager::Get()->AddObserver(this);
127 exo::NotificationSurface* surface =
128 ArcNotificationSurfaceManager::Get()->GetSurface(notification_key_);
129 if (surface)
130 OnNotificationSurfaceAdded(surface);
123 131
124 // Create a layer as an anchor to insert surface copy during a slide. 132 // Create a layer as an anchor to insert surface copy during a slide.
125 SetPaintToLayer(true); 133 SetPaintToLayer(true);
134 UpdatePreferredSize();
126 } 135 }
127 136
128 ArcCustomNotificationView::~ArcCustomNotificationView() { 137 ArcCustomNotificationView::~ArcCustomNotificationView() {
129 SetSurface(nullptr); 138 SetSurface(nullptr);
130 if (item_) 139 if (item_) {
140 item_->DecrementWindowRefCount();
131 item_->RemoveObserver(this); 141 item_->RemoveObserver(this);
142 }
143
144 if (ArcNotificationSurfaceManager::Get())
145 ArcNotificationSurfaceManager::Get()->RemoveObserver(this);
132 } 146 }
133 147
134 void ArcCustomNotificationView::CreateFloatingCloseButton() { 148 void ArcCustomNotificationView::CreateFloatingCloseButton() {
149 if (!surface_)
150 return;
151
135 floating_close_button_ = new views::ImageButton(this); 152 floating_close_button_ = new views::ImageButton(this);
136 floating_close_button_->set_background( 153 floating_close_button_->set_background(
137 views::Background::CreateSolidBackground(SK_ColorTRANSPARENT)); 154 views::Background::CreateSolidBackground(SK_ColorTRANSPARENT));
138 155
139 // The sizes below are in DIPs. 156 // The sizes below are in DIPs.
140 constexpr int kPaddingFromBorder = 4; 157 constexpr int kPaddingFromBorder = 4;
141 constexpr int kImageSize = 16; 158 constexpr int kImageSize = 16;
142 constexpr int kTouchExtendedPadding = 159 constexpr int kTouchExtendedPadding =
143 message_center::kControlButtonSize - kImageSize - kPaddingFromBorder; 160 message_center::kControlButtonSize - kImageSize - kPaddingFromBorder;
144 floating_close_button_->SetBorder(views::Border::CreateEmptyBorder( 161 floating_close_button_->SetBorder(views::Border::CreateEmptyBorder(
(...skipping 27 matching lines...) Expand all
172 if (surface_ && surface_->window()) { 189 if (surface_ && surface_->window()) {
173 surface_->window()->RemoveObserver(this); 190 surface_->window()->RemoveObserver(this);
174 surface_->window()->RemovePreTargetHandler(event_forwarder_.get()); 191 surface_->window()->RemovePreTargetHandler(event_forwarder_.get());
175 } 192 }
176 193
177 surface_ = surface; 194 surface_ = surface;
178 195
179 if (surface_ && surface_->window()) { 196 if (surface_ && surface_->window()) {
180 surface_->window()->AddObserver(this); 197 surface_->window()->AddObserver(this);
181 surface_->window()->AddPreTargetHandler(event_forwarder_.get()); 198 surface_->window()->AddPreTargetHandler(event_forwarder_.get());
199
200 if (GetWidget())
201 AttachSurface();
202
203 UpdatePinnedState();
182 } 204 }
183 } 205 }
184 206
185 void ArcCustomNotificationView::UpdatePreferredSize() { 207 void ArcCustomNotificationView::UpdatePreferredSize() {
186 gfx::Size preferred_size = surface_->GetSize(); 208 gfx::Size preferred_size =
209 surface_ ? surface_->GetSize() : item_ ? item_->snapshot().size()
210 : gfx::Size();
211 if (preferred_size.IsEmpty())
212 return;
213
187 if (preferred_size.width() != message_center::kNotificationWidth) { 214 if (preferred_size.width() != message_center::kNotificationWidth) {
188 const float scale = static_cast<float>(message_center::kNotificationWidth) / 215 const float scale = static_cast<float>(message_center::kNotificationWidth) /
189 preferred_size.width(); 216 preferred_size.width();
190 preferred_size.SetSize(message_center::kNotificationWidth, 217 preferred_size.SetSize(message_center::kNotificationWidth,
191 preferred_size.height() * scale); 218 preferred_size.height() * scale);
192 } 219 }
193 220
194 SetPreferredSize(preferred_size); 221 SetPreferredSize(preferred_size);
195 } 222 }
196 223
197 void ArcCustomNotificationView::UpdateCloseButtonVisiblity() { 224 void ArcCustomNotificationView::UpdateCloseButtonVisiblity() {
198 if (!surface_ || !floating_close_button_widget_) 225 if (!surface_ || !floating_close_button_widget_)
199 return; 226 return;
200 227
201 const bool target_visiblity = 228 const bool target_visiblity =
202 surface_->window()->GetBoundsInScreen().Contains( 229 surface_->window()->GetBoundsInScreen().Contains(
203 display::Screen::GetScreen()->GetCursorScreenPoint()); 230 display::Screen::GetScreen()->GetCursorScreenPoint());
204 if (target_visiblity == floating_close_button_widget_->IsVisible()) 231 if (target_visiblity == floating_close_button_widget_->IsVisible())
205 return; 232 return;
206 233
207 if (target_visiblity) 234 if (target_visiblity)
208 floating_close_button_widget_->Show(); 235 floating_close_button_widget_->Show();
209 else 236 else
210 floating_close_button_widget_->Hide(); 237 floating_close_button_widget_->Hide();
211 } 238 }
212 239
240 void ArcCustomNotificationView::UpdatePinnedState() {
241 if (item_->pinned() && floating_close_button_widget_) {
242 floating_close_button_widget_.reset();
243 } else if (!item_->pinned() && !floating_close_button_widget_) {
244 CreateFloatingCloseButton();
245 }
246 }
247
248 void ArcCustomNotificationView::UpdateSnapshot() {
249 // Bail if we have a |surface_| because it controls the sizes and paints UI.
250 if (surface_)
251 return;
252
253 UpdatePreferredSize();
254 SchedulePaint();
255 }
256
257 void ArcCustomNotificationView::AttachSurface() {
258 if (!GetWidget())
259 return;
260
261 UpdatePreferredSize();
262 Attach(surface_->window());
263
264 // Creates slide helper after this view is added to its parent.
265 slide_helper_.reset(new SlideHelper(this));
266 }
267
213 void ArcCustomNotificationView::ViewHierarchyChanged( 268 void ArcCustomNotificationView::ViewHierarchyChanged(
214 const views::View::ViewHierarchyChangedDetails& details) { 269 const views::View::ViewHierarchyChangedDetails& details) {
215 views::Widget* widget = GetWidget(); 270 views::Widget* widget = GetWidget();
216 271
217 if (!details.is_add) { 272 if (!details.is_add) {
218 // Resets slide helper when this view is removed from its parent. 273 // Resets slide helper when this view is removed from its parent.
219 slide_helper_.reset(); 274 slide_helper_.reset();
220 } 275 }
221 276
222 // Bail if native_view() has attached to a different widget. 277 // Bail if native_view() has attached to a different widget.
223 if (widget && native_view() && 278 if (widget && native_view() &&
224 views::Widget::GetTopLevelWidgetForNativeView(native_view()) != widget) { 279 views::Widget::GetTopLevelWidgetForNativeView(native_view()) != widget) {
225 return; 280 return;
226 } 281 }
227 282
228 views::NativeViewHost::ViewHierarchyChanged(details); 283 views::NativeViewHost::ViewHierarchyChanged(details);
229 284
230 if (!widget || !surface_ || !details.is_add) 285 if (!widget || !surface_ || !details.is_add)
231 return; 286 return;
232 287
233 UpdatePreferredSize(); 288 AttachSurface();
234 Attach(surface_->window());
235
236 // Creates slide helper after this view is added to its parent.
237 slide_helper_.reset(new SlideHelper(this));
238 } 289 }
239 290
240 void ArcCustomNotificationView::Layout() { 291 void ArcCustomNotificationView::Layout() {
241 views::NativeViewHost::Layout(); 292 views::NativeViewHost::Layout();
242 293
243 if (!surface_ || !GetWidget()) 294 if (!surface_ || !GetWidget())
244 return; 295 return;
245 296
246 // Scale notification surface if necessary. 297 // Scale notification surface if necessary.
247 gfx::Transform transform; 298 gfx::Transform transform;
(...skipping 12 matching lines...) Expand all
260 gfx::Rect surface_local_bounds(surface_->GetSize()); 311 gfx::Rect surface_local_bounds(surface_->GetSize());
261 gfx::Rect close_button_bounds(floating_close_button_->GetPreferredSize()); 312 gfx::Rect close_button_bounds(floating_close_button_->GetPreferredSize());
262 close_button_bounds.set_x(surface_local_bounds.right() - 313 close_button_bounds.set_x(surface_local_bounds.right() -
263 close_button_bounds.width()); 314 close_button_bounds.width());
264 close_button_bounds.set_y(surface_local_bounds.y()); 315 close_button_bounds.set_y(surface_local_bounds.y());
265 floating_close_button_widget_->SetBounds(close_button_bounds); 316 floating_close_button_widget_->SetBounds(close_button_bounds);
266 317
267 UpdateCloseButtonVisiblity(); 318 UpdateCloseButtonVisiblity();
268 } 319 }
269 320
321 void ArcCustomNotificationView::OnPaint(gfx::Canvas* canvas) {
322 views::NativeViewHost::OnPaint(canvas);
323
324 // Bail if there is a |surface_| or no item or no snapshot image.
325 if (surface_ || !item_ || item_->snapshot().isNull())
326 return;
327 const gfx::Rect contents_bounds = GetContentsBounds();
328 canvas->DrawImageInt(item_->snapshot(), 0, 0, item_->snapshot().width(),
329 item_->snapshot().height(), contents_bounds.x(),
330 contents_bounds.y(), contents_bounds.width(),
331 contents_bounds.height(), false);
332 }
333
270 void ArcCustomNotificationView::OnKeyEvent(ui::KeyEvent* event) { 334 void ArcCustomNotificationView::OnKeyEvent(ui::KeyEvent* event) {
271 // Forward to parent CustomNotificationView to handle keyboard dismissal. 335 // Forward to parent CustomNotificationView to handle keyboard dismissal.
272 parent()->OnKeyEvent(event); 336 parent()->OnKeyEvent(event);
273 } 337 }
274 338
275 void ArcCustomNotificationView::OnGestureEvent(ui::GestureEvent* event) { 339 void ArcCustomNotificationView::OnGestureEvent(ui::GestureEvent* event) {
276 // Forward to parent CustomNotificationView to handle sliding out. 340 // Forward to parent CustomNotificationView to handle sliding out.
277 parent()->OnGestureEvent(event); 341 parent()->OnGestureEvent(event);
278 slide_helper_->Update(); 342 slide_helper_->Update();
279 } 343 }
(...skipping 14 matching lines...) Expand all
294 } 358 }
295 359
296 void ArcCustomNotificationView::OnWindowBoundsChanged( 360 void ArcCustomNotificationView::OnWindowBoundsChanged(
297 aura::Window* window, 361 aura::Window* window,
298 const gfx::Rect& old_bounds, 362 const gfx::Rect& old_bounds,
299 const gfx::Rect& new_bounds) { 363 const gfx::Rect& new_bounds) {
300 UpdatePreferredSize(); 364 UpdatePreferredSize();
301 } 365 }
302 366
303 void ArcCustomNotificationView::OnWindowDestroying(aura::Window* window) { 367 void ArcCustomNotificationView::OnWindowDestroying(aura::Window* window) {
304 window->RemoveObserver(this); 368 SetSurface(nullptr);
305 } 369 }
306 370
307 void ArcCustomNotificationView::OnItemDestroying() { 371 void ArcCustomNotificationView::OnItemDestroying() {
308 item_->RemoveObserver(this); 372 item_->RemoveObserver(this);
309 item_ = nullptr; 373 item_ = nullptr;
310 374
311 // Reset |surface_| with |item_| since no one is observing the |surface_| 375 // Reset |surface_| with |item_| since no one is observing the |surface_|
312 // after |item_| is gone and this view should be removed soon. 376 // after |item_| is gone and this view should be removed soon.
313 SetSurface(nullptr); 377 SetSurface(nullptr);
314 } 378 }
315 379
316 void ArcCustomNotificationView::OnItemPinnedChanged() { 380 void ArcCustomNotificationView::OnItemUpdated() {
317 if (item_->pinned() && floating_close_button_widget_) { 381 UpdatePinnedState();
318 floating_close_button_widget_.reset(); 382 UpdateSnapshot();
319 } else if (!item_->pinned() && !floating_close_button_widget_) {
320 CreateFloatingCloseButton();
321 }
322 } 383 }
323 384
324 void ArcCustomNotificationView::OnItemNotificationSurfaceRemoved() { 385 void ArcCustomNotificationView::OnNotificationSurfaceAdded(
386 exo::NotificationSurface* surface) {
387 if (surface->notification_id() != notification_key_)
388 return;
389
390 SetSurface(surface);
391 }
392
393 void ArcCustomNotificationView::OnNotificationSurfaceRemoved(
394 exo::NotificationSurface* surface) {
395 if (surface->notification_id() != notification_key_)
396 return;
397
325 SetSurface(nullptr); 398 SetSurface(nullptr);
326 } 399 }
327 400
328 } // namespace arc 401 } // namespace arc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698