1 // Copyright 2019 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/chromeos/bluetooth/debug_logs_manager.h"
6 
7 #include <memory>
8 
9 #include "base/test/scoped_feature_list.h"
10 #include "base/test/task_environment.h"
11 #include "chromeos/constants/chromeos_features.h"
12 #include "components/prefs/testing_pref_service.h"
13 #include "device/bluetooth/dbus/bluez_dbus_manager.h"
14 #include "device/bluetooth/dbus/fake_bluetooth_debug_manager_client.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 
17 namespace chromeos {
18 
19 namespace bluetooth {
20 
21 namespace {
22 
23 constexpr char kTestGooglerEmail[] = "user@google.com";
24 constexpr char kTestNonGooglerEmail[] = "user@gmail.com";
25 
26 }  // namespace
27 
28 class DebugLogsManagerTest : public testing::Test {
29  public:
30   DebugLogsManagerTest() = default;
31 
SetUp()32   void SetUp() override {
33     DebugLogsManager::RegisterPrefs(prefs_.registry());
34 
35     auto fake_bluetooth_debug_manager_client =
36         std::make_unique<bluez::FakeBluetoothDebugManagerClient>();
37     fake_bluetooth_debug_manager_client_ =
38         fake_bluetooth_debug_manager_client.get();
39 
40     std::unique_ptr<bluez::BluezDBusManagerSetter> dbus_setter =
41         bluez::BluezDBusManager::GetSetterForTesting();
42     dbus_setter->SetBluetoothDebugManagerClient(
43         std::unique_ptr<bluez::BluetoothDebugManagerClient>(
44             std::move(fake_bluetooth_debug_manager_client)));
45   }
46 
TearDown()47   void TearDown() override {
48     debug_logs_manager_.reset();
49     bluez::BluezDBusManager::Shutdown();
50   }
51 
SetDebugFlagState(bool debug_flag_enabled)52   void SetDebugFlagState(bool debug_flag_enabled) {
53     feature_list_.InitWithFeatureState(
54         chromeos::features::kShowBluetoothDebugLogToggle, debug_flag_enabled);
55   }
56 
InstantiateDebugManager(const char * email)57   void InstantiateDebugManager(const char* email) {
58     debug_logs_manager_ = std::make_unique<DebugLogsManager>(email, &prefs_);
59   }
60 
DestroyDebugManager()61   void DestroyDebugManager() { debug_logs_manager_.reset(); }
62 
debug_manager() const63   DebugLogsManager* debug_manager() const { return debug_logs_manager_.get(); }
64 
fake_bluetooth_debug_manager_client() const65   bluez::FakeBluetoothDebugManagerClient* fake_bluetooth_debug_manager_client()
66       const {
67     return fake_bluetooth_debug_manager_client_;
68   }
69 
70  private:
71   base::test::ScopedFeatureList feature_list_;
72   bluez::FakeBluetoothDebugManagerClient* fake_bluetooth_debug_manager_client_;
73   std::unique_ptr<DebugLogsManager> debug_logs_manager_;
74   TestingPrefServiceSimple prefs_;
75 
76   DISALLOW_COPY_AND_ASSIGN(DebugLogsManagerTest);
77 };
78 
TEST_F(DebugLogsManagerTest,FlagNotEnabled)79 TEST_F(DebugLogsManagerTest, FlagNotEnabled) {
80   SetDebugFlagState(false /* debug_flag_enabled */);
81   InstantiateDebugManager(kTestGooglerEmail);
82   EXPECT_EQ(debug_manager()->GetDebugLogsState(),
83             DebugLogsManager::DebugLogsState::kNotSupported);
84 }
85 
TEST_F(DebugLogsManagerTest,NonGoogler)86 TEST_F(DebugLogsManagerTest, NonGoogler) {
87   SetDebugFlagState(true /* debug_flag_enabled */);
88   InstantiateDebugManager(kTestNonGooglerEmail);
89   EXPECT_EQ(debug_manager()->GetDebugLogsState(),
90             DebugLogsManager::DebugLogsState::kNotSupported);
91 }
92 
TEST_F(DebugLogsManagerTest,ChangeDebugLogsState)93 TEST_F(DebugLogsManagerTest, ChangeDebugLogsState) {
94   SetDebugFlagState(true /* debug_flag_enabled */);
95   InstantiateDebugManager(kTestGooglerEmail);
96   EXPECT_EQ(debug_manager()->GetDebugLogsState(),
97             DebugLogsManager::DebugLogsState::kSupportedButDisabled);
98 
99   debug_manager()->ChangeDebugLogsState(
100       true /* should_debug_logs_be_enabled */);
101   EXPECT_EQ(debug_manager()->GetDebugLogsState(),
102             DebugLogsManager::DebugLogsState::kSupportedAndEnabled);
103 
104   // Despite DebugLogsManager is destroyed, the state of Debug logs is saved
105   DestroyDebugManager();
106   InstantiateDebugManager(kTestGooglerEmail);
107   EXPECT_EQ(debug_manager()->GetDebugLogsState(),
108             DebugLogsManager::DebugLogsState::kSupportedAndEnabled);
109 
110   debug_manager()->ChangeDebugLogsState(
111       false /* should_debug_logs_be_enabled */);
112   EXPECT_EQ(debug_manager()->GetDebugLogsState(),
113             DebugLogsManager::DebugLogsState::kSupportedButDisabled);
114 
115   DestroyDebugManager();
116   InstantiateDebugManager(kTestGooglerEmail);
117   EXPECT_EQ(debug_manager()->GetDebugLogsState(),
118             DebugLogsManager::DebugLogsState::kSupportedButDisabled);
119 }
120 
TEST_F(DebugLogsManagerTest,SendVerboseLogsRequestUponLoginAndLogout)121 TEST_F(DebugLogsManagerTest, SendVerboseLogsRequestUponLoginAndLogout) {
122   SetDebugFlagState(true /* debug_flag_enabled */);
123   InstantiateDebugManager(kTestGooglerEmail);
124   EXPECT_EQ(fake_bluetooth_debug_manager_client()->dispatcher_level(), 0);
125   debug_manager()->ChangeDebugLogsState(
126       true /* should_debug_logs_be_enabled */);
127   // Dispatcher level is updated only on login/logout, so now it stays the same.
128   EXPECT_EQ(fake_bluetooth_debug_manager_client()->dispatcher_level(), 0);
129 
130   // Deletion and Recreation of DebugManager simulates logout-login event
131   DestroyDebugManager();
132   InstantiateDebugManager(kTestGooglerEmail);
133   // After login, dispatcher level should change
134   EXPECT_EQ(fake_bluetooth_debug_manager_client()->dispatcher_level(), 1);
135 
136   DestroyDebugManager();
137   // After logout, dispatcher level should reset to 0
138   EXPECT_EQ(fake_bluetooth_debug_manager_client()->dispatcher_level(), 0);
139 
140   InstantiateDebugManager(kTestGooglerEmail);
141   EXPECT_EQ(fake_bluetooth_debug_manager_client()->dispatcher_level(), 1);
142 
143   debug_manager()->ChangeDebugLogsState(
144       false /* should_debug_logs_be_enabled */);
145   // Dispatcher level is updated only on login/logout, so now it stays the same.
146   EXPECT_EQ(fake_bluetooth_debug_manager_client()->dispatcher_level(), 1);
147   DestroyDebugManager();
148   EXPECT_EQ(fake_bluetooth_debug_manager_client()->dispatcher_level(), 0);
149 
150   InstantiateDebugManager(kTestGooglerEmail);
151   // dispatcher level should still be 0 because logging is disabled
152   EXPECT_EQ(fake_bluetooth_debug_manager_client()->dispatcher_level(), 0);
153 }
154 
TEST_F(DebugLogsManagerTest,RetryUponSetVerboseLogsFailure)155 TEST_F(DebugLogsManagerTest, RetryUponSetVerboseLogsFailure) {
156   base::test::TaskEnvironment task_environment{
157       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
158 
159   SetDebugFlagState(true /* debug_flag_enabled */);
160   InstantiateDebugManager(kTestGooglerEmail);
161   EXPECT_EQ(fake_bluetooth_debug_manager_client()->dispatcher_level(), 0);
162   debug_manager()->ChangeDebugLogsState(
163       true /* should_debug_logs_be_enabled */);
164 
165   DestroyDebugManager();
166   fake_bluetooth_debug_manager_client()->MakeNextSetLogLevelsFail();
167   InstantiateDebugManager(kTestGooglerEmail);
168   task_environment.FastForwardUntilNoTasksRemain();
169 
170   EXPECT_EQ(fake_bluetooth_debug_manager_client()->set_log_levels_fail_count(),
171             1);
172   // Message is re-sent upon failing, eventually dispatcher level should change.
173   EXPECT_EQ(fake_bluetooth_debug_manager_client()->dispatcher_level(), 1);
174 }
175 
176 }  // namespace bluetooth
177 
178 }  // namespace chromeos
179