ProfilePolicyConnectorFactory: Refactoring from Profile to BrowserContext.
[chromium-blink-merge.git] / ash / system / tray / tray_background_view.cc
blob9b4afd3be5d0b85bfd6c10e06e67b5256d9cd592
1 // Copyright (c) 2012 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.
5 #include "ash/system/tray/tray_background_view.h"
7 #include "ash/root_window_controller.h"
8 #include "ash/screen_util.h"
9 #include "ash/shelf/shelf_layout_manager.h"
10 #include "ash/shelf/shelf_widget.h"
11 #include "ash/shell.h"
12 #include "ash/shell_window_ids.h"
13 #include "ash/system/status_area_widget.h"
14 #include "ash/system/status_area_widget_delegate.h"
15 #include "ash/system/tray/system_tray.h"
16 #include "ash/system/tray/tray_constants.h"
17 #include "ash/system/tray/tray_event_filter.h"
18 #include "ash/wm/window_animations.h"
19 #include "base/command_line.h"
20 #include "grit/ash_resources.h"
21 #include "ui/accessibility/ax_view_state.h"
22 #include "ui/aura/window.h"
23 #include "ui/aura/window_event_dispatcher.h"
24 #include "ui/base/nine_image_painter_factory.h"
25 #include "ui/base/ui_base_switches_util.h"
26 #include "ui/compositor/layer.h"
27 #include "ui/compositor/layer_animation_element.h"
28 #include "ui/compositor/scoped_layer_animation_settings.h"
29 #include "ui/events/event_constants.h"
30 #include "ui/gfx/animation/tween.h"
31 #include "ui/gfx/canvas.h"
32 #include "ui/gfx/geometry/rect.h"
33 #include "ui/gfx/image/image_skia.h"
34 #include "ui/gfx/image/image_skia_operations.h"
35 #include "ui/gfx/nine_image_painter.h"
36 #include "ui/gfx/screen.h"
37 #include "ui/gfx/skia_util.h"
38 #include "ui/gfx/transform.h"
39 #include "ui/views/background.h"
40 #include "ui/views/layout/box_layout.h"
42 namespace {
44 const int kTrayBackgroundAlpha = 100;
45 const int kTrayBackgroundHoverAlpha = 150;
46 const SkColor kTrayBackgroundPressedColor = SkColorSetRGB(66, 129, 244);
48 const int kAnimationDurationForPopupMs = 200;
50 // Duration of opacity animation for visibility changes.
51 const int kAnimationDurationForVisibilityMs = 250;
53 // When becoming visible delay the animation so that StatusAreaWidgetDelegate
54 // can animate sibling views out of the position to be occuped by the
55 // TrayBackgroundView.
56 const int kShowAnimationDelayMs = 100;
58 } // namespace
60 using views::TrayBubbleView;
62 namespace ash {
64 // static
65 const char TrayBackgroundView::kViewClassName[] = "tray/TrayBackgroundView";
67 // Used to track when the anchor widget changes position on screen so that the
68 // bubble position can be updated.
69 class TrayBackgroundView::TrayWidgetObserver : public views::WidgetObserver {
70 public:
71 explicit TrayWidgetObserver(TrayBackgroundView* host)
72 : host_(host) {
75 void OnWidgetBoundsChanged(views::Widget* widget,
76 const gfx::Rect& new_bounds) override {
77 host_->AnchorUpdated();
80 void OnWidgetVisibilityChanged(views::Widget* widget, bool visible) override {
81 host_->AnchorUpdated();
84 private:
85 TrayBackgroundView* host_;
87 DISALLOW_COPY_AND_ASSIGN(TrayWidgetObserver);
90 class TrayBackground : public views::Background {
91 public:
92 const static int kImageTypeDefault = 0;
93 const static int kImageTypeOnBlack = 1;
94 const static int kImageTypePressed = 2;
95 const static int kNumStates = 3;
97 const static int kImageHorizontal = 0;
98 const static int kImageVertical = 1;
99 const static int kNumOrientations = 2;
101 explicit TrayBackground(TrayBackgroundView* tray_background_view) :
102 tray_background_view_(tray_background_view) {
103 set_alpha(kTrayBackgroundAlpha);
106 ~TrayBackground() override {}
108 SkColor color() { return color_; }
109 void set_color(SkColor color) { color_ = color; }
110 void set_alpha(int alpha) { color_ = SkColorSetARGB(alpha, 0, 0, 0); }
112 private:
113 ShelfWidget* GetShelfWidget() const {
114 return RootWindowController::ForWindow(tray_background_view_->
115 status_area_widget()->GetNativeWindow())->shelf();
118 // Overridden from views::Background.
119 void Paint(gfx::Canvas* canvas, views::View* view) const override {
120 const int kGridSizeForPainter = 9;
121 const int kImages[kNumOrientations][kNumStates][kGridSizeForPainter] = {
122 { // Horizontal
123 IMAGE_GRID_HORIZONTAL(IDR_AURA_TRAY_BG_HORIZ),
124 IMAGE_GRID_HORIZONTAL(IDR_AURA_TRAY_BG_HORIZ_ONBLACK),
125 IMAGE_GRID_HORIZONTAL(IDR_AURA_TRAY_BG_HORIZ_PRESSED),
127 { // Vertical
128 IMAGE_GRID_VERTICAL(IDR_AURA_TRAY_BG_VERTICAL),
129 IMAGE_GRID_VERTICAL(IDR_AURA_TRAY_BG_VERTICAL_ONBLACK),
130 IMAGE_GRID_VERTICAL(IDR_AURA_TRAY_BG_VERTICAL_PRESSED),
134 int orientation = kImageHorizontal;
135 ShelfWidget* shelf_widget = GetShelfWidget();
136 if (shelf_widget &&
137 !shelf_widget->shelf_layout_manager()->IsHorizontalAlignment())
138 orientation = kImageVertical;
140 int state = kImageTypeDefault;
141 if (tray_background_view_->draw_background_as_active())
142 state = kImageTypePressed;
143 else if (shelf_widget && shelf_widget->GetDimsShelf())
144 state = kImageTypeOnBlack;
145 else
146 state = kImageTypeDefault;
148 ui::CreateNineImagePainter(kImages[orientation][state])
149 ->Paint(canvas, view->GetLocalBounds());
152 SkColor color_;
153 // Reference to the TrayBackgroundView for which this is a background.
154 TrayBackgroundView* tray_background_view_;
156 DISALLOW_COPY_AND_ASSIGN(TrayBackground);
159 TrayBackgroundView::TrayContainer::TrayContainer(ShelfAlignment alignment)
160 : alignment_(alignment) {
161 UpdateLayout();
164 void TrayBackgroundView::TrayContainer::SetAlignment(ShelfAlignment alignment) {
165 if (alignment_ == alignment)
166 return;
167 alignment_ = alignment;
168 UpdateLayout();
171 gfx::Size TrayBackgroundView::TrayContainer::GetPreferredSize() const {
172 if (size_.IsEmpty())
173 return views::View::GetPreferredSize();
174 return size_;
177 void TrayBackgroundView::TrayContainer::ChildPreferredSizeChanged(
178 views::View* child) {
179 PreferredSizeChanged();
182 void TrayBackgroundView::TrayContainer::ChildVisibilityChanged(View* child) {
183 PreferredSizeChanged();
186 void TrayBackgroundView::TrayContainer::ViewHierarchyChanged(
187 const ViewHierarchyChangedDetails& details) {
188 if (details.parent == this)
189 PreferredSizeChanged();
192 void TrayBackgroundView::TrayContainer::UpdateLayout() {
193 // Adjust the size of status tray dark background by adding additional
194 // empty border.
195 if (alignment_ == SHELF_ALIGNMENT_BOTTOM ||
196 alignment_ == SHELF_ALIGNMENT_TOP) {
197 SetBorder(views::Border::CreateEmptyBorder(
198 kPaddingFromEdgeOfShelf,
199 kPaddingFromEdgeOfShelf,
200 kPaddingFromEdgeOfShelf,
201 kPaddingFromEdgeOfShelf));
203 views::BoxLayout* layout =
204 new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0);
205 layout->SetDefaultFlex(1);
206 views::View::SetLayoutManager(layout);
207 } else {
208 SetBorder(views::Border::CreateEmptyBorder(
209 kPaddingFromEdgeOfShelf,
210 kPaddingFromEdgeOfShelf,
211 kPaddingFromEdgeOfShelf,
212 kPaddingFromEdgeOfShelf));
214 views::BoxLayout* layout =
215 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0);
216 layout->SetDefaultFlex(1);
217 views::View::SetLayoutManager(layout);
219 PreferredSizeChanged();
222 ////////////////////////////////////////////////////////////////////////////////
223 // TrayBackgroundView
225 TrayBackgroundView::TrayBackgroundView(StatusAreaWidget* status_area_widget)
226 : status_area_widget_(status_area_widget),
227 tray_container_(NULL),
228 shelf_alignment_(SHELF_ALIGNMENT_BOTTOM),
229 background_(NULL),
230 hide_background_animator_(this, 0, kTrayBackgroundAlpha),
231 hover_background_animator_(
232 this,
234 kTrayBackgroundHoverAlpha - kTrayBackgroundAlpha),
235 hovered_(false),
236 draw_background_as_active_(false),
237 widget_observer_(new TrayWidgetObserver(this)) {
238 set_notify_enter_exit_on_child(true);
240 // Initially we want to paint the background, but without the hover effect.
241 hide_background_animator_.SetPaintsBackground(
242 true, BACKGROUND_CHANGE_IMMEDIATE);
243 hover_background_animator_.SetPaintsBackground(
244 false, BACKGROUND_CHANGE_IMMEDIATE);
246 tray_container_ = new TrayContainer(shelf_alignment_);
247 SetContents(tray_container_);
248 tray_event_filter_.reset(new TrayEventFilter);
250 SetPaintToLayer(true);
251 SetFillsBoundsOpaquely(false);
252 // Start the tray items not visible, because visibility changes are animated.
253 views::View::SetVisible(false);
256 TrayBackgroundView::~TrayBackgroundView() {
257 if (GetWidget())
258 GetWidget()->RemoveObserver(widget_observer_.get());
261 void TrayBackgroundView::Initialize() {
262 GetWidget()->AddObserver(widget_observer_.get());
263 SetTrayBorder();
266 void TrayBackgroundView::SetVisible(bool visible) {
267 if (visible == layer()->GetTargetVisibility())
268 return;
270 if (visible) {
271 // The alignment of the shelf can change while the TrayBackgroundView is
272 // hidden. Reset the offscreen transform so that the animation to becoming
273 // visible reflects the current layout.
274 HideTransformation();
275 // SetVisible(false) is defered until the animation for hiding is done.
276 // Otherwise the view is immediately hidden and the animation does not
277 // render.
278 views::View::SetVisible(true);
279 // If SetVisible(true) is called while animating to not visible, then
280 // views::View::SetVisible(true) is a no-op. When the previous animation
281 // ends layer->SetVisible(false) is called. To prevent this
282 // layer->SetVisible(true) immediately interrupts the animation of this
283 // property, and keeps the layer visible.
284 layer()->SetVisible(true);
287 ui::ScopedLayerAnimationSettings animation(layer()->GetAnimator());
288 animation.SetTransitionDuration(base::TimeDelta::FromMilliseconds(
289 kAnimationDurationForVisibilityMs));
290 animation.SetPreemptionStrategy(
291 ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
293 if (visible) {
294 animation.SetTweenType(gfx::Tween::EASE_OUT);
295 // Show is delayed so as to allow time for other children of
296 // StatusAreaWidget to begin animating to their new positions.
297 layer()->GetAnimator()->SchedulePauseForProperties(
298 base::TimeDelta::FromMilliseconds(kShowAnimationDelayMs),
299 ui::LayerAnimationElement::OPACITY |
300 ui::LayerAnimationElement::TRANSFORM);
301 layer()->SetOpacity(1.0f);
302 gfx::Transform transform;
303 transform.Translate(0.0f, 0.0f);
304 layer()->SetTransform(transform);
305 } else {
306 // Listen only to the hide animation. As we cannot turn off visibility
307 // until the animation is over.
308 animation.AddObserver(this);
309 animation.SetTweenType(gfx::Tween::EASE_IN);
310 layer()->SetOpacity(0.0f);
311 layer()->SetVisible(false);
312 HideTransformation();
316 const char* TrayBackgroundView::GetClassName() const {
317 return kViewClassName;
320 void TrayBackgroundView::OnMouseEntered(const ui::MouseEvent& event) {
321 hovered_ = true;
324 void TrayBackgroundView::OnMouseExited(const ui::MouseEvent& event) {
325 hovered_ = false;
328 void TrayBackgroundView::ChildPreferredSizeChanged(views::View* child) {
329 PreferredSizeChanged();
332 void TrayBackgroundView::GetAccessibleState(ui::AXViewState* state) {
333 state->role = ui::AX_ROLE_BUTTON;
334 state->name = GetAccessibleNameForTray();
337 void TrayBackgroundView::AboutToRequestFocusFromTabTraversal(bool reverse) {
338 // Return focus to the login view. See crbug.com/120500.
339 views::View* v = GetNextFocusableView();
340 if (v)
341 v->AboutToRequestFocusFromTabTraversal(reverse);
344 bool TrayBackgroundView::PerformAction(const ui::Event& event) {
345 return false;
348 gfx::Rect TrayBackgroundView::GetFocusBounds() {
349 // The tray itself expands to the right and bottom edge of the screen to make
350 // sure clicking on the edges brings up the popup. However, the focus border
351 // should be only around the container.
352 return GetContentsBounds();
355 void TrayBackgroundView::OnGestureEvent(ui::GestureEvent* event) {
356 if (switches::IsTouchFeedbackEnabled()) {
357 if (event->type() == ui::ET_GESTURE_TAP_DOWN) {
358 SetDrawBackgroundAsActive(true);
359 } else if (event->type() == ui::ET_GESTURE_SCROLL_BEGIN ||
360 event->type() == ui::ET_GESTURE_TAP_CANCEL) {
361 SetDrawBackgroundAsActive(false);
364 ActionableView::OnGestureEvent(event);
367 void TrayBackgroundView::UpdateBackground(int alpha) {
368 // The animator should never fire when the alternate shelf layout is used.
369 if (!background_ || draw_background_as_active_)
370 return;
371 background_->set_alpha(hide_background_animator_.alpha() +
372 hover_background_animator_.alpha());
373 SchedulePaint();
376 void TrayBackgroundView::SetContents(views::View* contents) {
377 SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0));
378 AddChildView(contents);
381 void TrayBackgroundView::SetPaintsBackground(
382 bool value, BackgroundAnimatorChangeType change_type) {
383 hide_background_animator_.SetPaintsBackground(value, change_type);
386 void TrayBackgroundView::SetContentsBackground() {
387 background_ = new TrayBackground(this);
388 tray_container_->set_background(background_);
391 ShelfLayoutManager* TrayBackgroundView::GetShelfLayoutManager() {
392 return ShelfLayoutManager::ForShelf(GetWidget()->GetNativeView());
395 void TrayBackgroundView::SetShelfAlignment(ShelfAlignment alignment) {
396 shelf_alignment_ = alignment;
397 SetTrayBorder();
398 tray_container_->SetAlignment(alignment);
401 void TrayBackgroundView::SetTrayBorder() {
402 views::View* parent = status_area_widget_->status_area_widget_delegate();
403 // Tray views are laid out right-to-left or bottom-to-top
404 bool on_edge = (this == parent->child_at(0));
405 int left_edge, top_edge, right_edge, bottom_edge;
406 if (shelf_alignment() == SHELF_ALIGNMENT_BOTTOM) {
407 top_edge = ShelfLayoutManager::kShelfItemInset;
408 left_edge = 0;
409 bottom_edge = kShelfSize -
410 ShelfLayoutManager::kShelfItemInset - kShelfItemHeight;
411 right_edge = on_edge ? kPaddingFromEdgeOfShelf : 0;
412 } else if (shelf_alignment() == SHELF_ALIGNMENT_LEFT) {
413 top_edge = 0;
414 left_edge = kShelfSize -
415 ShelfLayoutManager::kShelfItemInset - kShelfItemHeight;
416 bottom_edge = on_edge ? kPaddingFromEdgeOfShelf : 0;
417 right_edge = ShelfLayoutManager::kShelfItemInset;
418 } else { // SHELF_ALIGNMENT_RIGHT
419 top_edge = 0;
420 left_edge = ShelfLayoutManager::kShelfItemInset;
421 bottom_edge = on_edge ? kPaddingFromEdgeOfShelf : 0;
422 right_edge = kShelfSize -
423 ShelfLayoutManager::kShelfItemInset - kShelfItemHeight;
425 SetBorder(views::Border::CreateEmptyBorder(
426 top_edge, left_edge, bottom_edge, right_edge));
429 void TrayBackgroundView::OnImplicitAnimationsCompleted() {
430 // If there is another animation in the queue, the reverse animation was
431 // triggered before the completion of animating to invisible. Do not turn off
432 // the visibility so that the next animation may render. The value of
433 // layer()->GetTargetVisibility() can be incorrect if the hide animation was
434 // aborted to schedule an animation to become visible. As the new animation
435 // is not yet added to the queue. crbug.com/374236
436 if(layer()->GetAnimator()->is_animating() ||
437 layer()->GetTargetVisibility())
438 return;
439 views::View::SetVisible(false);
442 void TrayBackgroundView::HideTransformation() {
443 gfx::Transform transform;
444 if (shelf_alignment_ == SHELF_ALIGNMENT_BOTTOM ||
445 shelf_alignment_ == SHELF_ALIGNMENT_TOP)
446 transform.Translate(width(), 0.0f);
447 else
448 transform.Translate(0.0f, height());
449 layer()->SetTransform(transform);
452 void TrayBackgroundView::InitializeBubbleAnimations(
453 views::Widget* bubble_widget) {
454 wm::SetWindowVisibilityAnimationType(
455 bubble_widget->GetNativeWindow(),
456 wm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
457 wm::SetWindowVisibilityAnimationTransition(
458 bubble_widget->GetNativeWindow(),
459 wm::ANIMATE_HIDE);
460 wm::SetWindowVisibilityAnimationDuration(
461 bubble_widget->GetNativeWindow(),
462 base::TimeDelta::FromMilliseconds(kAnimationDurationForPopupMs));
465 aura::Window* TrayBackgroundView::GetBubbleWindowContainer() const {
466 return ash::Shell::GetContainer(
467 tray_container()->GetWidget()->GetNativeWindow()->GetRootWindow(),
468 ash::kShellWindowId_SettingBubbleContainer);
471 gfx::Rect TrayBackgroundView::GetBubbleAnchorRect(
472 views::Widget* anchor_widget,
473 TrayBubbleView::AnchorType anchor_type,
474 TrayBubbleView::AnchorAlignment anchor_alignment) const {
475 gfx::Rect rect;
476 if (anchor_widget && anchor_widget->IsVisible()) {
477 rect = anchor_widget->GetWindowBoundsInScreen();
478 if (anchor_type == TrayBubbleView::ANCHOR_TYPE_TRAY) {
479 if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM) {
480 bool rtl = base::i18n::IsRTL();
481 rect.Inset(
482 rtl ? kBubblePaddingHorizontalSide : 0,
483 kBubblePaddingHorizontalBottom,
484 rtl ? 0 : kBubblePaddingHorizontalSide,
486 } else if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_LEFT) {
487 rect.Inset(0, 0, kBubblePaddingVerticalSide + 4,
488 kBubblePaddingVerticalBottom);
489 } else if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT) {
490 rect.Inset(kBubblePaddingVerticalSide, 0, 0,
491 kBubblePaddingVerticalBottom);
492 } else {
493 // TODO(bruthig) May need to handle other ANCHOR_ALIGNMENT_ values.
494 // ie. ANCHOR_ALIGNMENT_TOP
495 DCHECK(false) << "Unhandled anchor alignment.";
497 } else if (anchor_type == TrayBubbleView::ANCHOR_TYPE_BUBBLE) {
498 // Invert the offsets to align with the bubble below.
499 // Note that with the alternate shelf layout the tips are not shown and
500 // the offsets for left and right alignment do not need to be applied.
501 int vertical_alignment = 0;
502 int horizontal_alignment = kBubblePaddingVerticalBottom;
503 if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_LEFT)
504 rect.Inset(vertical_alignment, 0, 0, horizontal_alignment);
505 else if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT)
506 rect.Inset(0, 0, vertical_alignment, horizontal_alignment);
507 } else {
508 DCHECK(false) << "Unhandled anchor type.";
510 } else {
511 aura::Window* target_root = anchor_widget ?
512 anchor_widget->GetNativeView()->GetRootWindow() :
513 Shell::GetPrimaryRootWindow();
514 rect = target_root->bounds();
515 if (anchor_type == TrayBubbleView::ANCHOR_TYPE_TRAY) {
516 if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM) {
517 rect = gfx::Rect(
518 base::i18n::IsRTL() ?
519 kPaddingFromRightEdgeOfScreenBottomAlignment :
520 rect.width() - kPaddingFromRightEdgeOfScreenBottomAlignment,
521 rect.height() - kPaddingFromBottomOfScreenBottomAlignment,
522 0, 0);
523 rect = ScreenUtil::ConvertRectToScreen(target_root, rect);
524 } else if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_LEFT) {
525 rect = gfx::Rect(
526 kPaddingFromRightEdgeOfScreenBottomAlignment,
527 rect.height() - kPaddingFromBottomOfScreenBottomAlignment,
528 1, 1);
529 rect = ScreenUtil::ConvertRectToScreen(target_root, rect);
530 } else if (anchor_alignment == TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT) {
531 rect = gfx::Rect(
532 rect.width() - kPaddingFromRightEdgeOfScreenBottomAlignment,
533 rect.height() - kPaddingFromBottomOfScreenBottomAlignment,
534 1, 1);
535 rect = ScreenUtil::ConvertRectToScreen(target_root, rect);
536 } else {
537 // TODO(bruthig) May need to handle other ANCHOR_ALIGNMENT_ values.
538 // ie. ANCHOR_ALIGNMENT_TOP
539 DCHECK(false) << "Unhandled anchor alignment.";
541 } else {
542 rect = gfx::Rect(
543 base::i18n::IsRTL() ?
544 kPaddingFromRightEdgeOfScreenBottomAlignment :
545 rect.width() - kPaddingFromRightEdgeOfScreenBottomAlignment,
546 rect.height() - kPaddingFromBottomOfScreenBottomAlignment,
547 0, 0);
550 return rect;
553 TrayBubbleView::AnchorAlignment TrayBackgroundView::GetAnchorAlignment() const {
554 switch (shelf_alignment_) {
555 case SHELF_ALIGNMENT_BOTTOM:
556 return TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM;
557 case SHELF_ALIGNMENT_LEFT:
558 return TrayBubbleView::ANCHOR_ALIGNMENT_LEFT;
559 case SHELF_ALIGNMENT_RIGHT:
560 return TrayBubbleView::ANCHOR_ALIGNMENT_RIGHT;
561 case SHELF_ALIGNMENT_TOP:
562 return TrayBubbleView::ANCHOR_ALIGNMENT_TOP;
564 NOTREACHED();
565 return TrayBubbleView::ANCHOR_ALIGNMENT_BOTTOM;
568 void TrayBackgroundView::SetDrawBackgroundAsActive(bool visible) {
569 if (draw_background_as_active_ == visible)
570 return;
571 draw_background_as_active_ = visible;
572 if (!background_)
573 return;
575 // Do not change gradually, changing color between grey and blue is weird.
576 if (draw_background_as_active_)
577 background_->set_color(kTrayBackgroundPressedColor);
578 else if (hovered_)
579 background_->set_alpha(kTrayBackgroundHoverAlpha);
580 else
581 background_->set_alpha(kTrayBackgroundAlpha);
582 SchedulePaint();
585 void TrayBackgroundView::UpdateBubbleViewArrow(
586 views::TrayBubbleView* bubble_view) {
587 // Nothing to do here.
590 } // namespace ash