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 
5 #include "components/keep_alive_registry/keep_alive_registry.h"
6 
7 #include <memory>
8 
9 #include "components/keep_alive_registry/keep_alive_state_observer.h"
10 #include "components/keep_alive_registry/keep_alive_types.h"
11 #include "components/keep_alive_registry/scoped_keep_alive.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 
14 class KeepAliveRegistryTest : public testing::Test,
15                               public KeepAliveStateObserver {
16  public:
KeepAliveRegistryTest()17   KeepAliveRegistryTest()
18       : on_restart_allowed_call_count_(0),
19         on_restart_forbidden_call_count_(0),
20         start_keep_alive_call_count_(0),
21         stop_keep_alive_call_count_(0),
22         registry_(KeepAliveRegistry::GetInstance()) {
23     registry_->AddObserver(this);
24 
25     EXPECT_FALSE(registry_->IsKeepingAlive());
26   }
27 
~KeepAliveRegistryTest()28   ~KeepAliveRegistryTest() override {
29     registry_->RemoveObserver(this);
30 
31     EXPECT_FALSE(registry_->IsKeepingAlive());
32   }
33 
OnKeepAliveStateChanged(bool is_keeping_alive)34   void OnKeepAliveStateChanged(bool is_keeping_alive) override {
35     if (is_keeping_alive)
36       ++start_keep_alive_call_count_;
37     else
38       ++stop_keep_alive_call_count_;
39   }
40 
OnKeepAliveRestartStateChanged(bool can_restart)41   void OnKeepAliveRestartStateChanged(bool can_restart) override {
42     if (can_restart)
43       ++on_restart_allowed_call_count_;
44     else
45       ++on_restart_forbidden_call_count_;
46   }
47 
48  protected:
49   int on_restart_allowed_call_count_;
50   int on_restart_forbidden_call_count_;
51   int start_keep_alive_call_count_;
52   int stop_keep_alive_call_count_;
53   KeepAliveRegistry* registry_;
54 };
55 
56 // Test the IsKeepingAlive state and when we interact with the browser with
57 // a KeepAlive registered.
TEST_F(KeepAliveRegistryTest,BasicKeepAliveTest)58 TEST_F(KeepAliveRegistryTest, BasicKeepAliveTest) {
59   EXPECT_EQ(0, start_keep_alive_call_count_);
60   EXPECT_EQ(0, stop_keep_alive_call_count_);
61 
62   {
63     // Arbitrarily chosen Origin
64     ScopedKeepAlive test_keep_alive(KeepAliveOrigin::CHROME_APP_DELEGATE,
65                                     KeepAliveRestartOption::DISABLED);
66 
67     // We should require the browser to stay alive
68     ASSERT_EQ(1, start_keep_alive_call_count_--);  // decrement to ack
69     EXPECT_TRUE(registry_->IsKeepingAlive());
70   }
71 
72   // We should be back to normal now, notifying of the state change.
73   ASSERT_EQ(1, stop_keep_alive_call_count_--);
74   EXPECT_FALSE(registry_->IsKeepingAlive());
75 
76   // This should not have changed.
77   ASSERT_EQ(0, start_keep_alive_call_count_);
78 }
79 
80 // Test the IsKeepingAlive state and when we interact with the browser with
81 // more than one KeepAlive registered.
TEST_F(KeepAliveRegistryTest,DoubleKeepAliveTest)82 TEST_F(KeepAliveRegistryTest, DoubleKeepAliveTest) {
83   EXPECT_EQ(0, start_keep_alive_call_count_);
84   EXPECT_EQ(0, stop_keep_alive_call_count_);
85   std::unique_ptr<ScopedKeepAlive> keep_alive_1, keep_alive_2;
86 
87   keep_alive_1.reset(new ScopedKeepAlive(KeepAliveOrigin::CHROME_APP_DELEGATE,
88                                          KeepAliveRestartOption::DISABLED));
89   ASSERT_EQ(1, start_keep_alive_call_count_--);  // decrement to ack
90   EXPECT_TRUE(registry_->IsKeepingAlive());
91 
92   keep_alive_2.reset(new ScopedKeepAlive(KeepAliveOrigin::CHROME_APP_DELEGATE,
93                                          KeepAliveRestartOption::DISABLED));
94   // We should not increment the count twice
95   EXPECT_EQ(0, start_keep_alive_call_count_);
96   EXPECT_TRUE(registry_->IsKeepingAlive());
97 
98   keep_alive_1.reset();
99   // We should not decrement the count before the last keep alive is released.
100   EXPECT_EQ(0, stop_keep_alive_call_count_);
101   EXPECT_TRUE(registry_->IsKeepingAlive());
102 
103   keep_alive_2.reset();
104   ASSERT_EQ(1, stop_keep_alive_call_count_--);
105   EXPECT_EQ(0, start_keep_alive_call_count_);
106   EXPECT_FALSE(registry_->IsKeepingAlive());
107 }
108 
109 // Test the IsKeepingAlive state and when we interact with the browser with
110 // more than one KeepAlive registered.
TEST_F(KeepAliveRegistryTest,RestartOptionTest)111 TEST_F(KeepAliveRegistryTest, RestartOptionTest) {
112   std::unique_ptr<ScopedKeepAlive> keep_alive, keep_alive_restart;
113 
114   EXPECT_EQ(0, on_restart_allowed_call_count_);
115   EXPECT_EQ(0, on_restart_forbidden_call_count_);
116 
117   // With a normal keep alive, restart should not be allowed
118   keep_alive.reset(new ScopedKeepAlive(KeepAliveOrigin::CHROME_APP_DELEGATE,
119                                        KeepAliveRestartOption::DISABLED));
120   ASSERT_EQ(1, on_restart_forbidden_call_count_--);  // decrement to ack
121 
122   // Restart should not be allowed if all KA don't allow it.
123   keep_alive_restart.reset(new ScopedKeepAlive(
124       KeepAliveOrigin::CHROME_APP_DELEGATE, KeepAliveRestartOption::ENABLED));
125   EXPECT_EQ(0, on_restart_allowed_call_count_);
126 
127   // Now restart should be allowed, the only one left allows it.
128   keep_alive.reset();
129   ASSERT_EQ(1, on_restart_allowed_call_count_--);
130 
131   // No keep alive, we should no prevent restarts.
132   keep_alive.reset();
133   EXPECT_EQ(0, on_restart_forbidden_call_count_);
134 
135   // Make sure all calls were checked.
136   EXPECT_EQ(0, on_restart_allowed_call_count_);
137   EXPECT_EQ(0, on_restart_forbidden_call_count_);
138 }
139 
TEST_F(KeepAliveRegistryTest,WouldRestartWithoutTest)140 TEST_F(KeepAliveRegistryTest, WouldRestartWithoutTest) {
141   // WouldRestartWithout() should have the same results as IsRestartAllowed()
142   // when called with an empty vector.
143   std::vector<KeepAliveOrigin> empty_vector;
144 
145   // Init and sanity checks.
146   ScopedKeepAlive kar(KeepAliveOrigin::BACKGROUND_MODE_MANAGER,
147                       KeepAliveRestartOption::ENABLED);
148   ASSERT_TRUE(registry_->IsRestartAllowed());
149   EXPECT_EQ(registry_->IsRestartAllowed(),
150             registry_->WouldRestartWithout(empty_vector));
151   ScopedKeepAlive ka1(KeepAliveOrigin::CHROME_APP_DELEGATE,
152                       KeepAliveRestartOption::DISABLED);
153   ASSERT_FALSE(registry_->IsRestartAllowed());
154 
155   // Basic case: exclude one KeepAlive.
156   EXPECT_TRUE(
157       registry_->WouldRestartWithout({KeepAliveOrigin::CHROME_APP_DELEGATE}));
158   EXPECT_FALSE(registry_->WouldRestartWithout(
159       {KeepAliveOrigin::BACKGROUND_MODE_MANAGER}));
160 
161   // Check it works properly with multiple KeepAlives of the same type
162   ScopedKeepAlive ka2(KeepAliveOrigin::CHROME_APP_DELEGATE,
163                       KeepAliveRestartOption::DISABLED);
164   EXPECT_TRUE(
165       registry_->WouldRestartWithout({KeepAliveOrigin::CHROME_APP_DELEGATE}));
166 
167   // Check it works properly with different KeepAlive types
168   ScopedKeepAlive ka3(KeepAliveOrigin::PANEL, KeepAliveRestartOption::DISABLED);
169   EXPECT_FALSE(
170       registry_->WouldRestartWithout({KeepAliveOrigin::CHROME_APP_DELEGATE}));
171   EXPECT_FALSE(registry_->WouldRestartWithout(
172       {KeepAliveOrigin::BACKGROUND_MODE_MANAGER}));
173   EXPECT_TRUE(registry_->WouldRestartWithout(
174       {KeepAliveOrigin::CHROME_APP_DELEGATE, KeepAliveOrigin::PANEL}));
175   EXPECT_EQ(registry_->IsRestartAllowed(),
176             registry_->WouldRestartWithout(empty_vector));
177 }
178