blob: f61ef82706df2cd271f97e0e78fa3266f35d7a13 [file] [log] [blame]
dgn3d351ad12016-02-26 17:36:451// Copyright 2016 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.
4
5#include "chrome/browser/lifetime/keep_alive_registry.h"
6
dgn02377782016-03-12 00:58:387#include "chrome/browser/browser_process.h"
dgn3d351ad12016-02-26 17:36:458#include "chrome/browser/lifetime/application_lifetime.h"
dgn3563ecaf2016-03-09 19:28:269#include "chrome/browser/lifetime/keep_alive_state_observer.h"
dgn3d351ad12016-02-26 17:36:4510#include "chrome/browser/lifetime/keep_alive_types.h"
11
12////////////////////////////////////////////////////////////////////////////////
13// Public methods
14
15// static
16KeepAliveRegistry* KeepAliveRegistry::GetInstance() {
17 return base::Singleton<KeepAliveRegistry>::get();
18}
19
dgn3563ecaf2016-03-09 19:28:2620bool KeepAliveRegistry::IsKeepingAlive() const {
dgn3d351ad12016-02-26 17:36:4521 return registered_count_ > 0;
22}
23
dgn3563ecaf2016-03-09 19:28:2624bool KeepAliveRegistry::IsRestartAllowed() const {
25 return registered_count_ == restart_allowed_count_;
26}
27
dgnfe075c82016-03-18 11:25:3528bool KeepAliveRegistry::IsOriginRegistered(KeepAliveOrigin origin) const {
29 return registered_keep_alives_.find(origin) != registered_keep_alives_.end();
30}
31
dgn3563ecaf2016-03-09 19:28:2632void KeepAliveRegistry::AddObserver(KeepAliveStateObserver* observer) {
33 observers_.AddObserver(observer);
34}
35
36void KeepAliveRegistry::RemoveObserver(KeepAliveStateObserver* observer) {
37 observers_.RemoveObserver(observer);
38}
39
dgnaf6e8612016-08-12 12:24:0940bool KeepAliveRegistry::WouldRestartWithout(
41 const std::vector<KeepAliveOrigin>& origins) const {
42 int registered_count = 0;
43 int restart_allowed_count = 0;
44
45 for (auto origin : origins) {
46 auto counts_it = registered_keep_alives_.find(origin);
47 if (counts_it != registered_keep_alives_.end()) {
48 registered_count += counts_it->second;
49
50 counts_it = restart_allowed_keep_alives_.find(origin);
51 if (counts_it != restart_allowed_keep_alives_.end())
52 restart_allowed_count += counts_it->second;
53 } else {
54 // |registered_keep_alives_| is supposed to be a superset of
55 // |restart_allowed_keep_alives_|
56 DCHECK(restart_allowed_keep_alives_.find(origin) ==
57 restart_allowed_keep_alives_.end());
58 }
59 }
60
61 registered_count = registered_count_ - registered_count;
62 restart_allowed_count = restart_allowed_count_ - restart_allowed_count;
63
64 DCHECK_GE(registered_count, 0);
65 DCHECK_GE(restart_allowed_count, 0);
66
67 return registered_count == restart_allowed_count;
68}
69
dgn3d351ad12016-02-26 17:36:4570////////////////////////////////////////////////////////////////////////////////
71// Private methods
72
dgn3563ecaf2016-03-09 19:28:2673KeepAliveRegistry::KeepAliveRegistry()
74 : registered_count_(0), restart_allowed_count_(0) {}
dgn3d351ad12016-02-26 17:36:4575
76KeepAliveRegistry::~KeepAliveRegistry() {
dgn02377782016-03-12 00:58:3877 DLOG_IF(ERROR, registered_count_ > 0 || registered_keep_alives_.size() > 0)
dgn1e50dd22016-04-22 22:16:5678 << "KeepAliveRegistry not empty at destruction time. State:" << *this;
dgn3d351ad12016-02-26 17:36:4579}
80
dgn3563ecaf2016-03-09 19:28:2681void KeepAliveRegistry::Register(KeepAliveOrigin origin,
82 KeepAliveRestartOption restart) {
dgn1e50dd22016-04-22 22:16:5683 DCHECK(!g_browser_process->IsShuttingDown());
84
dgn3563ecaf2016-03-09 19:28:2685 bool old_keeping_alive = IsKeepingAlive();
86 bool old_restart_allowed = IsRestartAllowed();
dgn3d351ad12016-02-26 17:36:4587
88 ++registered_keep_alives_[origin];
89 ++registered_count_;
dgn3563ecaf2016-03-09 19:28:2690
dgnaf6e8612016-08-12 12:24:0991 if (restart == KeepAliveRestartOption::ENABLED) {
92 ++restart_allowed_keep_alives_[origin];
dgn3563ecaf2016-03-09 19:28:2693 ++restart_allowed_count_;
dgnaf6e8612016-08-12 12:24:0994 }
dgn3563ecaf2016-03-09 19:28:2695
96 bool new_keeping_alive = IsKeepingAlive();
97 bool new_restart_allowed = IsRestartAllowed();
98
99 if (new_keeping_alive != old_keeping_alive)
dgnfe075c82016-03-18 11:25:35100 OnKeepAliveStateChanged(new_keeping_alive);
dgn3563ecaf2016-03-09 19:28:26101
102 if (new_restart_allowed != old_restart_allowed)
103 OnRestartAllowedChanged(new_restart_allowed);
104
dgn1e50dd22016-04-22 22:16:56105 DVLOG(1) << "New state of the KeepAliveRegistry: " << *this;
dgn3d351ad12016-02-26 17:36:45106}
107
dgn3563ecaf2016-03-09 19:28:26108void KeepAliveRegistry::Unregister(KeepAliveOrigin origin,
109 KeepAliveRestartOption restart) {
110 bool old_keeping_alive = IsKeepingAlive();
111 bool old_restart_allowed = IsRestartAllowed();
112
dgn3d351ad12016-02-26 17:36:45113 --registered_count_;
114 DCHECK_GE(registered_count_, 0);
dgnaf6e8612016-08-12 12:24:09115 DecrementCount(origin, &registered_keep_alives_);
dgn3d351ad12016-02-26 17:36:45116
dgnaf6e8612016-08-12 12:24:09117 if (restart == KeepAliveRestartOption::ENABLED) {
dgn3563ecaf2016-03-09 19:28:26118 --restart_allowed_count_;
dgnaf6e8612016-08-12 12:24:09119 DecrementCount(origin, &restart_allowed_keep_alives_);
120 }
dgn3563ecaf2016-03-09 19:28:26121
122 bool new_keeping_alive = IsKeepingAlive();
123 bool new_restart_allowed = IsRestartAllowed();
124
dgn3eaf67e2016-07-26 09:01:12125 // Update the KeepAlive state first, so that listeners can check if we are
126 // trying to shutdown.
dgn3563ecaf2016-03-09 19:28:26127 if (new_keeping_alive != old_keeping_alive)
dgnfe075c82016-03-18 11:25:35128 OnKeepAliveStateChanged(new_keeping_alive);
dgn3563ecaf2016-03-09 19:28:26129
dgn3eaf67e2016-07-26 09:01:12130 if (new_restart_allowed != old_restart_allowed)
131 OnRestartAllowedChanged(new_restart_allowed);
132
dgn1e50dd22016-04-22 22:16:56133 DVLOG(1) << "New state of the KeepAliveRegistry:" << *this;
dgn3d351ad12016-02-26 17:36:45134}
dgn3563ecaf2016-03-09 19:28:26135
dgnfe075c82016-03-18 11:25:35136void KeepAliveRegistry::OnKeepAliveStateChanged(bool new_keeping_alive) {
137 DVLOG(1) << "Notifying KeepAliveStateObservers: KeepingAlive changed to: "
138 << new_keeping_alive;
ericwilligers58b0e162016-10-21 07:15:56139 for (KeepAliveStateObserver& observer : observers_)
140 observer.OnKeepAliveStateChanged(new_keeping_alive);
dgn3563ecaf2016-03-09 19:28:26141}
142
143void KeepAliveRegistry::OnRestartAllowedChanged(bool new_restart_allowed) {
144 DVLOG(1) << "Notifying KeepAliveStateObservers: Restart changed to: "
145 << new_restart_allowed;
ericwilligers58b0e162016-10-21 07:15:56146 for (KeepAliveStateObserver& observer : observers_)
147 observer.OnKeepAliveRestartStateChanged(new_restart_allowed);
dgn3563ecaf2016-03-09 19:28:26148}
149
dgnaf6e8612016-08-12 12:24:09150void KeepAliveRegistry::DecrementCount(KeepAliveOrigin origin,
151 OriginMap* keep_alive_map) {
152 int new_count = --keep_alive_map->at(origin);
153 DCHECK_GE(keep_alive_map->at(origin), 0);
154 if (new_count == 0)
155 keep_alive_map->erase(origin);
156}
157
dgn3563ecaf2016-03-09 19:28:26158std::ostream& operator<<(std::ostream& out, const KeepAliveRegistry& registry) {
dgn02377782016-03-12 00:58:38159 out << "{registered_count_=" << registry.registered_count_
160 << ", restart_allowed_count_=" << registry.restart_allowed_count_
161 << ", KeepAlives=[";
dgn3563ecaf2016-03-09 19:28:26162 for (auto counts_per_origin_it : registry.registered_keep_alives_) {
163 if (counts_per_origin_it != *registry.registered_keep_alives_.begin())
164 out << ", ";
165 out << counts_per_origin_it.first << " (" << counts_per_origin_it.second
166 << ")";
167 }
168 out << "]}";
169 return out;
170}