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"
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());
22 scoped_ptr
<BubbleController
> controller(
23 new BubbleController(this, bubble
.Pass()));
25 BubbleReference bubble_ref
= controller
->AsWeakPtr();
27 switch (manager_state_
) {
30 controllers_
.push_back(controller
.Pass());
33 show_queue_
.push_back(controller
.Pass());
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.
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
);
56 iter
= controllers_
.erase(iter
);
62 // Attempting to close a bubble that is already closed or that this manager
63 // doesn't own is a bug.
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;
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_
)
98 controllers_
.insert(controllers_
.end(), show_queue_
.begin(),
101 show_queue_
.weak_clear();
103 // Clear the queue if bubbles can't be shown.