blob: 913402e8ee558113df9e59aeb8062ac923fcaaa1 [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
Michael Giuffrida2dbce0d12017-09-02 03:30:595#include "components/keep_alive_registry/keep_alive_registry.h"
dgn3d351ad12016-02-26 17:36:456
Michael Giuffrida2dbce0d12017-09-02 03:30:597#include "base/logging.h"
manzagopba8991e2017-05-08 21:05:218#include "build/build_config.h"
Michael Giuffrida2dbce0d12017-09-02 03:30:599#include "components/keep_alive_registry/keep_alive_state_observer.h"
10#include "components/keep_alive_registry/keep_alive_types.h"
dgn3d351ad12016-02-26 17:36:4511
manzagopba8991e2017-05-08 21:05:2112#if defined(OS_WIN)
Sigurdur Asgeirssona0ecc772020-02-06 18:02:2713#include "components/browser_watcher/activity_data_names.h"
14#include "components/browser_watcher/extended_crash_reporting.h"
manzagopba8991e2017-05-08 21:05:2115#endif
16
dgn3d351ad12016-02-26 17:36:4517////////////////////////////////////////////////////////////////////////////////
18// Public methods
19
20// static
21KeepAliveRegistry* KeepAliveRegistry::GetInstance() {
22 return base::Singleton<KeepAliveRegistry>::get();
23}
24
dgn3563ecaf2016-03-09 19:28:2625bool KeepAliveRegistry::IsKeepingAlive() const {
dgn3d351ad12016-02-26 17:36:4526 return registered_count_ > 0;
27}
28
Aleksei Seren121533e2017-11-28 20:11:1829bool KeepAliveRegistry::IsKeepingAliveOnlyByBrowserOrigin() const {
30 for (const auto& value : registered_keep_alives_) {
31 if (value.first != KeepAliveOrigin::BROWSER)
32 return false;
33 }
34 return true;
35}
36
dgn3563ecaf2016-03-09 19:28:2637bool KeepAliveRegistry::IsRestartAllowed() const {
38 return registered_count_ == restart_allowed_count_;
39}
40
dgnfe075c82016-03-18 11:25:3541bool KeepAliveRegistry::IsOriginRegistered(KeepAliveOrigin origin) const {
42 return registered_keep_alives_.find(origin) != registered_keep_alives_.end();
43}
44
dgn3563ecaf2016-03-09 19:28:2645void KeepAliveRegistry::AddObserver(KeepAliveStateObserver* observer) {
46 observers_.AddObserver(observer);
47}
48
49void KeepAliveRegistry::RemoveObserver(KeepAliveStateObserver* observer) {
50 observers_.RemoveObserver(observer);
51}
52
dgnaf6e8612016-08-12 12:24:0953bool KeepAliveRegistry::WouldRestartWithout(
54 const std::vector<KeepAliveOrigin>& origins) const {
55 int registered_count = 0;
56 int restart_allowed_count = 0;
57
58 for (auto origin : origins) {
59 auto counts_it = registered_keep_alives_.find(origin);
60 if (counts_it != registered_keep_alives_.end()) {
61 registered_count += counts_it->second;
62
63 counts_it = restart_allowed_keep_alives_.find(origin);
64 if (counts_it != restart_allowed_keep_alives_.end())
65 restart_allowed_count += counts_it->second;
66 } else {
67 // |registered_keep_alives_| is supposed to be a superset of
68 // |restart_allowed_keep_alives_|
69 DCHECK(restart_allowed_keep_alives_.find(origin) ==
70 restart_allowed_keep_alives_.end());
71 }
72 }
73
74 registered_count = registered_count_ - registered_count;
75 restart_allowed_count = restart_allowed_count_ - restart_allowed_count;
76
77 DCHECK_GE(registered_count, 0);
78 DCHECK_GE(restart_allowed_count, 0);
79
80 return registered_count == restart_allowed_count;
81}
82
Vladislav Kaznacheeveb65ea12019-05-14 00:30:0583bool KeepAliveRegistry::IsShuttingDown() const {
84 return is_shutting_down_;
85}
86
Michael Giuffrida2dbce0d12017-09-02 03:30:5987void KeepAliveRegistry::SetIsShuttingDown(bool value) {
Michael Giuffrida2dbce0d12017-09-02 03:30:5988 is_shutting_down_ = value;
Michael Giuffrida2dbce0d12017-09-02 03:30:5989}
90
dgn3d351ad12016-02-26 17:36:4591////////////////////////////////////////////////////////////////////////////////
92// Private methods
93
dgn3563ecaf2016-03-09 19:28:2694KeepAliveRegistry::KeepAliveRegistry()
95 : registered_count_(0), restart_allowed_count_(0) {}
dgn3d351ad12016-02-26 17:36:4596
97KeepAliveRegistry::~KeepAliveRegistry() {
Wez2f88261b2018-04-16 18:03:0998 DCHECK_LE(registered_count_, 0) << "KeepAliveRegistry state:" << *this;
99 DCHECK_EQ(registered_keep_alives_.size(), 0u)
100 << "KeepAliveRegistry state:" << *this;
dgn3d351ad12016-02-26 17:36:45101}
102
dgn3563ecaf2016-03-09 19:28:26103void KeepAliveRegistry::Register(KeepAliveOrigin origin,
104 KeepAliveRestartOption restart) {
Wez2f88261b2018-04-16 18:03:09105 CHECK(!is_shutting_down_);
dgn1e50dd22016-04-22 22:16:56106
dgn3563ecaf2016-03-09 19:28:26107 bool old_keeping_alive = IsKeepingAlive();
108 bool old_restart_allowed = IsRestartAllowed();
dgn3d351ad12016-02-26 17:36:45109
110 ++registered_keep_alives_[origin];
111 ++registered_count_;
dgn3563ecaf2016-03-09 19:28:26112
dgnaf6e8612016-08-12 12:24:09113 if (restart == KeepAliveRestartOption::ENABLED) {
114 ++restart_allowed_keep_alives_[origin];
dgn3563ecaf2016-03-09 19:28:26115 ++restart_allowed_count_;
dgnaf6e8612016-08-12 12:24:09116 }
dgn3563ecaf2016-03-09 19:28:26117
118 bool new_keeping_alive = IsKeepingAlive();
119 bool new_restart_allowed = IsRestartAllowed();
120
121 if (new_keeping_alive != old_keeping_alive)
dgnfe075c82016-03-18 11:25:35122 OnKeepAliveStateChanged(new_keeping_alive);
dgn3563ecaf2016-03-09 19:28:26123
124 if (new_restart_allowed != old_restart_allowed)
125 OnRestartAllowedChanged(new_restart_allowed);
126
dgn1e50dd22016-04-22 22:16:56127 DVLOG(1) << "New state of the KeepAliveRegistry: " << *this;
dgn3d351ad12016-02-26 17:36:45128}
129
dgn3563ecaf2016-03-09 19:28:26130void KeepAliveRegistry::Unregister(KeepAliveOrigin origin,
131 KeepAliveRestartOption restart) {
132 bool old_keeping_alive = IsKeepingAlive();
133 bool old_restart_allowed = IsRestartAllowed();
134
dgn3d351ad12016-02-26 17:36:45135 --registered_count_;
136 DCHECK_GE(registered_count_, 0);
dgnaf6e8612016-08-12 12:24:09137 DecrementCount(origin, &registered_keep_alives_);
dgn3d351ad12016-02-26 17:36:45138
dgnaf6e8612016-08-12 12:24:09139 if (restart == KeepAliveRestartOption::ENABLED) {
dgn3563ecaf2016-03-09 19:28:26140 --restart_allowed_count_;
dgnaf6e8612016-08-12 12:24:09141 DecrementCount(origin, &restart_allowed_keep_alives_);
142 }
dgn3563ecaf2016-03-09 19:28:26143
144 bool new_keeping_alive = IsKeepingAlive();
145 bool new_restart_allowed = IsRestartAllowed();
146
dgn3eaf67e2016-07-26 09:01:12147 // Update the KeepAlive state first, so that listeners can check if we are
148 // trying to shutdown.
dgn3563ecaf2016-03-09 19:28:26149 if (new_keeping_alive != old_keeping_alive)
dgnfe075c82016-03-18 11:25:35150 OnKeepAliveStateChanged(new_keeping_alive);
dgn3563ecaf2016-03-09 19:28:26151
dgn3eaf67e2016-07-26 09:01:12152 if (new_restart_allowed != old_restart_allowed)
153 OnRestartAllowedChanged(new_restart_allowed);
154
dgn1e50dd22016-04-22 22:16:56155 DVLOG(1) << "New state of the KeepAliveRegistry:" << *this;
dgn3d351ad12016-02-26 17:36:45156}
dgn3563ecaf2016-03-09 19:28:26157
dgnfe075c82016-03-18 11:25:35158void KeepAliveRegistry::OnKeepAliveStateChanged(bool new_keeping_alive) {
159 DVLOG(1) << "Notifying KeepAliveStateObservers: KeepingAlive changed to: "
160 << new_keeping_alive;
manzagopba8991e2017-05-08 21:05:21161#if defined(OS_WIN)
Sigurdur Asgeirssona0ecc772020-02-06 18:02:27162 browser_watcher::ExtendedCrashReporting::SetDataBool(
163 browser_watcher::kActivityKeepAlive, new_keeping_alive);
manzagopba8991e2017-05-08 21:05:21164#endif
ericwilligers58b0e162016-10-21 07:15:56165 for (KeepAliveStateObserver& observer : observers_)
166 observer.OnKeepAliveStateChanged(new_keeping_alive);
dgn3563ecaf2016-03-09 19:28:26167}
168
169void KeepAliveRegistry::OnRestartAllowedChanged(bool new_restart_allowed) {
170 DVLOG(1) << "Notifying KeepAliveStateObservers: Restart changed to: "
171 << new_restart_allowed;
manzagopba8991e2017-05-08 21:05:21172#if defined(OS_WIN)
Sigurdur Asgeirssona0ecc772020-02-06 18:02:27173 browser_watcher::ExtendedCrashReporting::SetDataBool(
174 browser_watcher::kActivityRestartAllowed, new_restart_allowed);
manzagopba8991e2017-05-08 21:05:21175#endif
ericwilligers58b0e162016-10-21 07:15:56176 for (KeepAliveStateObserver& observer : observers_)
177 observer.OnKeepAliveRestartStateChanged(new_restart_allowed);
dgn3563ecaf2016-03-09 19:28:26178}
179
dgnaf6e8612016-08-12 12:24:09180void KeepAliveRegistry::DecrementCount(KeepAliveOrigin origin,
181 OriginMap* keep_alive_map) {
182 int new_count = --keep_alive_map->at(origin);
183 DCHECK_GE(keep_alive_map->at(origin), 0);
184 if (new_count == 0)
185 keep_alive_map->erase(origin);
186}
187
dgn3563ecaf2016-03-09 19:28:26188std::ostream& operator<<(std::ostream& out, const KeepAliveRegistry& registry) {
dgn02377782016-03-12 00:58:38189 out << "{registered_count_=" << registry.registered_count_
190 << ", restart_allowed_count_=" << registry.restart_allowed_count_
191 << ", KeepAlives=[";
dgn3563ecaf2016-03-09 19:28:26192 for (auto counts_per_origin_it : registry.registered_keep_alives_) {
193 if (counts_per_origin_it != *registry.registered_keep_alives_.begin())
194 out << ", ";
195 out << counts_per_origin_it.first << " (" << counts_per_origin_it.second
196 << ")";
197 }
198 out << "]}";
199 return out;
200}