keep_alive_registry.cc 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. // 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. #include "components/keep_alive_registry/keep_alive_registry.h"
  5. #include "base/logging.h"
  6. #include "base/observer_list.h"
  7. #include "build/build_config.h"
  8. #include "components/keep_alive_registry/keep_alive_state_observer.h"
  9. #include "components/keep_alive_registry/keep_alive_types.h"
  10. #if BUILDFLAG(IS_WIN)
  11. #include "components/browser_watcher/activity_data_names.h"
  12. #include "components/browser_watcher/extended_crash_reporting.h"
  13. #endif
  14. ////////////////////////////////////////////////////////////////////////////////
  15. // Public methods
  16. // static
  17. KeepAliveRegistry* KeepAliveRegistry::GetInstance() {
  18. return base::Singleton<KeepAliveRegistry>::get();
  19. }
  20. bool KeepAliveRegistry::IsKeepingAlive() const {
  21. return registered_count_ > 0 && !(IsRestartAllowed() && is_restarting_);
  22. }
  23. bool KeepAliveRegistry::IsKeepingAliveOnlyByBrowserOrigin() const {
  24. for (const auto& value : registered_keep_alives_) {
  25. if (value.first != KeepAliveOrigin::BROWSER)
  26. return false;
  27. }
  28. return true;
  29. }
  30. bool KeepAliveRegistry::IsRestartAllowed() const {
  31. return registered_count_ == restart_allowed_count_;
  32. }
  33. bool KeepAliveRegistry::IsOriginRegistered(KeepAliveOrigin origin) const {
  34. return registered_keep_alives_.find(origin) != registered_keep_alives_.end();
  35. }
  36. void KeepAliveRegistry::AddObserver(KeepAliveStateObserver* observer) {
  37. observers_.AddObserver(observer);
  38. }
  39. void KeepAliveRegistry::RemoveObserver(KeepAliveStateObserver* observer) {
  40. observers_.RemoveObserver(observer);
  41. }
  42. bool KeepAliveRegistry::WouldRestartWithout(
  43. const std::vector<KeepAliveOrigin>& origins) const {
  44. int registered_count = 0;
  45. int restart_allowed_count = 0;
  46. for (auto origin : origins) {
  47. auto counts_it = registered_keep_alives_.find(origin);
  48. if (counts_it != registered_keep_alives_.end()) {
  49. registered_count += counts_it->second;
  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. registered_count = registered_count_ - registered_count;
  61. restart_allowed_count = restart_allowed_count_ - restart_allowed_count;
  62. DCHECK_GE(registered_count, 0);
  63. DCHECK_GE(restart_allowed_count, 0);
  64. return registered_count == restart_allowed_count;
  65. }
  66. bool KeepAliveRegistry::IsShuttingDown() const {
  67. return is_shutting_down_;
  68. }
  69. void KeepAliveRegistry::SetIsShuttingDown(bool value) {
  70. is_shutting_down_ = value;
  71. }
  72. bool KeepAliveRegistry::IsRestarting() const {
  73. return is_restarting_;
  74. }
  75. void KeepAliveRegistry::SetRestarting() {
  76. bool old_keeping_alive = IsKeepingAlive();
  77. is_restarting_ = true;
  78. bool new_keeping_alive = IsKeepingAlive();
  79. // keep alive state can be updated by |is_restarting_| change.
  80. // If that happens, notify observers.
  81. if (old_keeping_alive != new_keeping_alive)
  82. OnKeepAliveStateChanged(new_keeping_alive);
  83. }
  84. ////////////////////////////////////////////////////////////////////////////////
  85. // Private methods
  86. KeepAliveRegistry::KeepAliveRegistry()
  87. : registered_count_(0), restart_allowed_count_(0) {}
  88. KeepAliveRegistry::~KeepAliveRegistry() {
  89. DCHECK_LE(registered_count_, 0) << "KeepAliveRegistry state:" << *this;
  90. DCHECK_EQ(registered_keep_alives_.size(), 0u)
  91. << "KeepAliveRegistry state:" << *this;
  92. }
  93. void KeepAliveRegistry::Register(KeepAliveOrigin origin,
  94. KeepAliveRestartOption restart) {
  95. CHECK(!is_shutting_down_);
  96. bool old_keeping_alive = IsKeepingAlive();
  97. bool old_restart_allowed = IsRestartAllowed();
  98. ++registered_keep_alives_[origin];
  99. ++registered_count_;
  100. if (restart == KeepAliveRestartOption::ENABLED) {
  101. ++restart_allowed_keep_alives_[origin];
  102. ++restart_allowed_count_;
  103. }
  104. bool new_keeping_alive = IsKeepingAlive();
  105. bool new_restart_allowed = IsRestartAllowed();
  106. if (new_keeping_alive != old_keeping_alive)
  107. OnKeepAliveStateChanged(new_keeping_alive);
  108. if (new_restart_allowed != old_restart_allowed)
  109. OnRestartAllowedChanged(new_restart_allowed);
  110. DVLOG(1) << "New state of the KeepAliveRegistry: " << *this;
  111. }
  112. void KeepAliveRegistry::Unregister(KeepAliveOrigin origin,
  113. KeepAliveRestartOption restart) {
  114. bool old_keeping_alive = IsKeepingAlive();
  115. bool old_restart_allowed = IsRestartAllowed();
  116. --registered_count_;
  117. DCHECK_GE(registered_count_, 0);
  118. DecrementCount(origin, &registered_keep_alives_);
  119. if (restart == KeepAliveRestartOption::ENABLED) {
  120. --restart_allowed_count_;
  121. DecrementCount(origin, &restart_allowed_keep_alives_);
  122. }
  123. bool new_keeping_alive = IsKeepingAlive();
  124. bool new_restart_allowed = IsRestartAllowed();
  125. // Update the KeepAlive state first, so that listeners can check if we are
  126. // trying to shutdown.
  127. if (new_keeping_alive != old_keeping_alive)
  128. OnKeepAliveStateChanged(new_keeping_alive);
  129. if (new_restart_allowed != old_restart_allowed)
  130. OnRestartAllowedChanged(new_restart_allowed);
  131. DVLOG(1) << "New state of the KeepAliveRegistry:" << *this;
  132. }
  133. void KeepAliveRegistry::OnKeepAliveStateChanged(bool new_keeping_alive) {
  134. DVLOG(1) << "Notifying KeepAliveStateObservers: KeepingAlive changed to: "
  135. << new_keeping_alive;
  136. #if BUILDFLAG(IS_WIN)
  137. browser_watcher::ExtendedCrashReporting::SetDataBool(
  138. browser_watcher::kActivityKeepAlive, new_keeping_alive);
  139. #endif
  140. for (KeepAliveStateObserver& observer : observers_)
  141. observer.OnKeepAliveStateChanged(new_keeping_alive);
  142. }
  143. void KeepAliveRegistry::OnRestartAllowedChanged(bool new_restart_allowed) {
  144. DVLOG(1) << "Notifying KeepAliveStateObservers: Restart changed to: "
  145. << new_restart_allowed;
  146. #if BUILDFLAG(IS_WIN)
  147. browser_watcher::ExtendedCrashReporting::SetDataBool(
  148. browser_watcher::kActivityRestartAllowed, new_restart_allowed);
  149. #endif
  150. for (KeepAliveStateObserver& observer : observers_)
  151. observer.OnKeepAliveRestartStateChanged(new_restart_allowed);
  152. }
  153. void KeepAliveRegistry::DecrementCount(KeepAliveOrigin origin,
  154. OriginMap* keep_alive_map) {
  155. int new_count = --keep_alive_map->at(origin);
  156. DCHECK_GE(keep_alive_map->at(origin), 0);
  157. if (new_count == 0)
  158. keep_alive_map->erase(origin);
  159. }
  160. std::ostream& operator<<(std::ostream& out, const KeepAliveRegistry& registry) {
  161. out << "{registered_count_=" << registry.registered_count_
  162. << ", restart_allowed_count_=" << registry.restart_allowed_count_
  163. << ", KeepAlives=[";
  164. for (auto counts_per_origin_it : registry.registered_keep_alives_) {
  165. if (counts_per_origin_it != *registry.registered_keep_alives_.begin())
  166. out << ", ";
  167. out << counts_per_origin_it.first << " (" << counts_per_origin_it.second
  168. << ")";
  169. }
  170. out << "]}";
  171. return out;
  172. }