Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / components / bubble / bubble_manager.cc
blob8bbed4614bcbc9c4d532b4eb9f85102b0581a917
1 // Copyright 2015 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 "components/bubble/bubble_manager.h"
7 #include <vector>
9 #include "components/bubble/bubble_controller.h"
10 #include "components/bubble/bubble_delegate.h"
12 BubbleManager::BubbleManager() : manager_state_(SHOW_BUBBLES) {}
14 BubbleManager::~BubbleManager() {
15 manager_state_ = NO_MORE_BUBBLES;
16 CloseAllBubbles(BUBBLE_CLOSE_FORCED);
19 BubbleReference BubbleManager::ShowBubble(scoped_ptr<BubbleDelegate> bubble) {
20 DCHECK(thread_checker_.CalledOnValidThread());
21 DCHECK(bubble);
22 scoped_ptr<BubbleController> controller(
23 new BubbleController(this, bubble.Pass()));
25 BubbleReference bubble_ref = controller->AsWeakPtr();
27 switch (manager_state_) {
28 case SHOW_BUBBLES:
29 controller->Show();
30 controllers_.push_back(controller.Pass());
31 break;
32 case QUEUE_BUBBLES:
33 show_queue_.push_back(controller.Pass());
34 break;
35 case NO_MORE_BUBBLES:
36 // The controller will be cleaned up and |bubble_ref| will be invalidated.
37 // It's important that the controller is created even though it's
38 // destroyed immediately because it will collect metrics about the bubble.
39 break;
42 return bubble_ref;
45 bool BubbleManager::CloseBubble(BubbleReference bubble,
46 BubbleCloseReason reason) {
47 DCHECK(thread_checker_.CalledOnValidThread());
48 DCHECK_NE(manager_state_, QUEUE_BUBBLES);
49 if (manager_state_ == SHOW_BUBBLES)
50 manager_state_ = QUEUE_BUBBLES;
52 for (auto iter = controllers_.begin(); iter != controllers_.end(); ++iter) {
53 if (*iter == bubble.get()) {
54 bool closed = (*iter)->ShouldClose(reason);
55 if (closed)
56 iter = controllers_.erase(iter);
57 ShowPendingBubbles();
58 return closed;
62 // Attempting to close a bubble that is already closed or that this manager
63 // doesn't own is a bug.
64 NOTREACHED();
65 return false;
68 void BubbleManager::CloseAllBubbles(BubbleCloseReason reason) {
69 // The following close reasons don't make sense for multiple bubbles:
70 DCHECK_NE(reason, BUBBLE_CLOSE_ACCEPTED);
71 DCHECK_NE(reason, BUBBLE_CLOSE_CANCELED);
73 DCHECK(thread_checker_.CalledOnValidThread());
74 DCHECK_NE(manager_state_, QUEUE_BUBBLES);
75 if (manager_state_ == SHOW_BUBBLES)
76 manager_state_ = QUEUE_BUBBLES;
78 for (auto iter = controllers_.begin(); iter != controllers_.end();)
79 iter = (*iter)->ShouldClose(reason) ? controllers_.erase(iter) : iter + 1;
81 ShowPendingBubbles();
84 void BubbleManager::UpdateAllBubbleAnchors() {
85 DCHECK(thread_checker_.CalledOnValidThread());
86 for (auto controller : controllers_)
87 controller->UpdateAnchorPosition();
90 void BubbleManager::ShowPendingBubbles() {
91 if (manager_state_ == QUEUE_BUBBLES)
92 manager_state_ = SHOW_BUBBLES;
94 if (manager_state_ == SHOW_BUBBLES) {
95 for (auto controller : show_queue_)
96 controller->Show();
98 controllers_.insert(controllers_.end(), show_queue_.begin(),
99 show_queue_.end());
101 show_queue_.weak_clear();
102 } else {
103 // Clear the queue if bubbles can't be shown.
104 show_queue_.clear();