blob: e98006163fa60231d934be3a3c624f78dbe4fff7 [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
28void KeepAliveRegistry::AddObserver(KeepAliveStateObserver* observer) {
29 observers_.AddObserver(observer);
30}
31
32void KeepAliveRegistry::RemoveObserver(KeepAliveStateObserver* observer) {
33 observers_.RemoveObserver(observer);
34}
35
dgn3d351ad12016-02-26 17:36:4536////////////////////////////////////////////////////////////////////////////////
37// Private methods
38
dgn3563ecaf2016-03-09 19:28:2639KeepAliveRegistry::KeepAliveRegistry()
40 : registered_count_(0), restart_allowed_count_(0) {}
dgn3d351ad12016-02-26 17:36:4541
42KeepAliveRegistry::~KeepAliveRegistry() {
dgn02377782016-03-12 00:58:3843 DLOG_IF(ERROR, registered_count_ > 0 || registered_keep_alives_.size() > 0)
44 << "KeepAliveRegistry not empty at destruction time. State: " << *this;
dgn3d351ad12016-02-26 17:36:4545}
46
dgn3563ecaf2016-03-09 19:28:2647void KeepAliveRegistry::Register(KeepAliveOrigin origin,
48 KeepAliveRestartOption restart) {
49 bool old_keeping_alive = IsKeepingAlive();
50 bool old_restart_allowed = IsRestartAllowed();
dgn3d351ad12016-02-26 17:36:4551
52 ++registered_keep_alives_[origin];
53 ++registered_count_;
dgn3563ecaf2016-03-09 19:28:2654
55 if (restart == KeepAliveRestartOption::ENABLED)
56 ++restart_allowed_count_;
57
58 bool new_keeping_alive = IsKeepingAlive();
59 bool new_restart_allowed = IsRestartAllowed();
60
61 if (new_keeping_alive != old_keeping_alive)
62 OnKeepingAliveChanged(new_keeping_alive);
63
64 if (new_restart_allowed != old_restart_allowed)
65 OnRestartAllowedChanged(new_restart_allowed);
66
67 DVLOG(1) << "New state of the KeepAliveRegistry: " << *this;
dgn3d351ad12016-02-26 17:36:4568}
69
dgn3563ecaf2016-03-09 19:28:2670void KeepAliveRegistry::Unregister(KeepAliveOrigin origin,
71 KeepAliveRestartOption restart) {
72 bool old_keeping_alive = IsKeepingAlive();
73 bool old_restart_allowed = IsRestartAllowed();
74
dgn3d351ad12016-02-26 17:36:4575 --registered_count_;
76 DCHECK_GE(registered_count_, 0);
77
78 int new_count = --registered_keep_alives_[origin];
79 DCHECK_GE(registered_keep_alives_[origin], 0);
80 if (new_count == 0)
81 registered_keep_alives_.erase(origin);
82
dgn3563ecaf2016-03-09 19:28:2683 if (restart == KeepAliveRestartOption::ENABLED)
84 --restart_allowed_count_;
85
86 bool new_keeping_alive = IsKeepingAlive();
87 bool new_restart_allowed = IsRestartAllowed();
88
89 if (new_restart_allowed != old_restart_allowed)
90 OnRestartAllowedChanged(new_restart_allowed);
91
92 if (new_keeping_alive != old_keeping_alive)
93 OnKeepingAliveChanged(new_keeping_alive);
94
95 DVLOG(1) << "New state of the KeepAliveRegistry: " << *this;
dgn3d351ad12016-02-26 17:36:4596}
dgn3563ecaf2016-03-09 19:28:2697
98void KeepAliveRegistry::OnKeepingAliveChanged(bool new_keeping_alive) {
dgn02377782016-03-12 00:58:3899 // Although we should have a browser process, if there is none,
100 // there is nothing to do.
101 if (!g_browser_process)
102 return;
103
dgn3563ecaf2016-03-09 19:28:26104 if (new_keeping_alive) {
105 DVLOG(1) << "KeepAliveRegistry is now keeping the browser alive.";
dgn02377782016-03-12 00:58:38106 g_browser_process->AddRefModule();
dgn3563ecaf2016-03-09 19:28:26107 } else {
108 DVLOG(1) << "KeepAliveRegistry stopped keeping the browser alive.";
dgn02377782016-03-12 00:58:38109 g_browser_process->ReleaseModule();
110 chrome::CloseAllBrowsersIfNeeded();
dgn3563ecaf2016-03-09 19:28:26111 }
112}
113
114void KeepAliveRegistry::OnRestartAllowedChanged(bool new_restart_allowed) {
115 DVLOG(1) << "Notifying KeepAliveStateObservers: Restart changed to: "
116 << new_restart_allowed;
117 FOR_EACH_OBSERVER(KeepAliveStateObserver, observers_,
118 OnKeepAliveRestartStateChanged(new_restart_allowed));
119}
120
121#ifndef NDEBUG
122std::ostream& operator<<(std::ostream& out, const KeepAliveRegistry& registry) {
dgn02377782016-03-12 00:58:38123 out << "{registered_count_=" << registry.registered_count_
124 << ", restart_allowed_count_=" << registry.restart_allowed_count_
125 << ", KeepAlives=[";
dgn3563ecaf2016-03-09 19:28:26126 for (auto counts_per_origin_it : registry.registered_keep_alives_) {
127 if (counts_per_origin_it != *registry.registered_keep_alives_.begin())
128 out << ", ";
129 out << counts_per_origin_it.first << " (" << counts_per_origin_it.second
130 << ")";
131 }
132 out << "]}";
133 return out;
134}
135#endif // ndef NDEBUG