blob: e2377de054ebd965e31bbc9b8dd336a739f702a2 [file] [log] [blame]
Stephen Lanham366d988e2018-04-14 00:25:411// Copyright 2018 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 "chromecast/browser/bluetooth/cast_bluetooth_chooser.h"
6
7#include "base/test/mock_callback.h"
8#include "base/test/scoped_task_environment.h"
9#include "testing/gmock/include/gmock/gmock.h"
10#include "testing/gtest/include/gtest/gtest.h"
11
12namespace chromecast {
13namespace {
14
15class SimpleDeviceAccessProvider : public mojom::BluetoothDeviceAccessProvider {
16 public:
17 SimpleDeviceAccessProvider() = default;
18 ~SimpleDeviceAccessProvider() override = default;
19
20 // mojom::BluetoothDeviceAccessProvider implementation:
21 void RequestDeviceAccess(
22 mojom::BluetoothDeviceAccessProviderClientPtr client) override {
23 DCHECK(!client_);
24 client.set_connection_error_handler(connection_closed_.Get());
25 for (const auto& address : approved_devices_)
26 client->GrantAccess(address);
27 client_ = std::move(client);
28 }
29
30 mojom::BluetoothDeviceAccessProviderClientPtr& client() { return client_; }
31 base::MockCallback<base::OnceClosure>& connection_closed() {
32 return connection_closed_;
33 }
34 std::vector<std::string>& approved_devices() { return approved_devices_; }
35
36 private:
37 mojom::BluetoothDeviceAccessProviderClientPtr client_;
38 base::MockCallback<base::OnceClosure> connection_closed_;
39 std::vector<std::string> approved_devices_;
40
41 DISALLOW_COPY_AND_ASSIGN(SimpleDeviceAccessProvider);
42};
43
44} // namespace
45
46using testing::AnyOf;
47
48class CastBluetoothChooserTest : public testing::Test {
49 public:
50 CastBluetoothChooserTest() : provider_binding_(&provider_) {
51 mojom::BluetoothDeviceAccessProviderPtr provider;
52 provider_binding_.Bind(mojo::MakeRequest(&provider));
53 cast_bluetooth_chooser_ = std::make_unique<CastBluetoothChooser>(
54 handler_.Get(), std::move(provider));
Gabriel Charette694c3c332019-08-19 14:53:0555 task_environment_.RunUntilIdle();
Stephen Lanham366d988e2018-04-14 00:25:4156 }
57
58 ~CastBluetoothChooserTest() override = default;
59
60 void AddDeviceToChooser(const std::string& address) {
61 chooser().AddOrUpdateDevice(address, false, base::string16(), false, false,
62 0);
63 }
64
65 SimpleDeviceAccessProvider& provider() { return provider_; }
66 content::BluetoothChooser& chooser() { return *cast_bluetooth_chooser_; }
67
68 protected:
Gabriel Charette694c3c332019-08-19 14:53:0569 base::test::TaskEnvironment task_environment_;
Stephen Lanham366d988e2018-04-14 00:25:4170 base::MockCallback<content::BluetoothChooser::EventHandler> handler_;
71
72 private:
73 SimpleDeviceAccessProvider provider_;
74 mojo::Binding<mojom::BluetoothDeviceAccessProvider> provider_binding_;
75 std::unique_ptr<CastBluetoothChooser> cast_bluetooth_chooser_;
76
77 DISALLOW_COPY_AND_ASSIGN(CastBluetoothChooserTest);
78};
79
80TEST_F(CastBluetoothChooserTest, GrantAccessBeforeDeviceAvailable) {
81 // No devices have been made available to |chooser| yet. Grant it access to a
82 // device. |handler| should not run yet.
83 EXPECT_TRUE(provider().client());
84 provider().client()->GrantAccess("aa:bb:cc:dd:ee:ff");
Gabriel Charette694c3c332019-08-19 14:53:0585 task_environment_.RunUntilIdle();
Stephen Lanham366d988e2018-04-14 00:25:4186
87 // Make some unapproved devices available. |handler| should not run yet.
88 AddDeviceToChooser("11:22:33:44:55:66");
89 AddDeviceToChooser("99:88:77:66:55:44");
90
91 // Now make the approved device available. |handler| should be called.
92 EXPECT_CALL(handler_, Run(content::BluetoothChooser::Event::SELECTED,
93 "aa:bb:cc:dd:ee:ff"));
94 EXPECT_CALL(provider().connection_closed(), Run());
95 AddDeviceToChooser("aa:bb:cc:dd:ee:ff");
Gabriel Charette694c3c332019-08-19 14:53:0596 task_environment_.RunUntilIdle();
Stephen Lanham366d988e2018-04-14 00:25:4197}
98
99TEST_F(CastBluetoothChooserTest, DiscoverDeviceBeforeAccessGranted) {
100 // Make some devices available before access is granted. |handler| should not
101 // run yet.
102 AddDeviceToChooser("11:22:33:44:55:66");
103 AddDeviceToChooser("aa:bb:cc:dd:ee:ff");
104 AddDeviceToChooser("00:00:00:11:00:00");
105 AddDeviceToChooser("99:88:77:66:55:44");
106
107 // Now approve one of those devices. |handler| should run.
108 EXPECT_CALL(handler_, Run(content::BluetoothChooser::Event::SELECTED,
109 "00:00:00:11:00:00"));
110 EXPECT_CALL(provider().connection_closed(), Run());
111 provider().client()->GrantAccess("00:00:00:11:00:00");
Gabriel Charette694c3c332019-08-19 14:53:05112 task_environment_.RunUntilIdle();
Stephen Lanham366d988e2018-04-14 00:25:41113}
114
115TEST_F(CastBluetoothChooserTest, GrantAccessToAllDevicesBeforeDiscovery) {
116 // Grant access to all devices. |handler| should not run until the first
117 // device is made available.
118 provider().client()->GrantAccessToAllDevices();
Gabriel Charette694c3c332019-08-19 14:53:05119 task_environment_.RunUntilIdle();
Stephen Lanham366d988e2018-04-14 00:25:41120
121 // Now make the some device available. |handler| should be called.
122 EXPECT_CALL(handler_, Run(content::BluetoothChooser::Event::SELECTED,
123 "aa:bb:cc:dd:ee:ff"));
124 EXPECT_CALL(provider().connection_closed(), Run());
125 AddDeviceToChooser("aa:bb:cc:dd:ee:ff");
Gabriel Charette694c3c332019-08-19 14:53:05126 task_environment_.RunUntilIdle();
Stephen Lanham366d988e2018-04-14 00:25:41127}
128
129TEST_F(CastBluetoothChooserTest, GrantAccessToAllDevicesAfterDiscovery) {
130 // Make some devices available before access is granted. |handler| should not
131 // run yet.
132 AddDeviceToChooser("11:22:33:44:55:66");
133 AddDeviceToChooser("aa:bb:cc:dd:ee:ff");
134 AddDeviceToChooser("00:00:00:11:00:00");
135
136 // Now grant access to all devices. |handler| should be called with one of the
137 // available devices.
138 EXPECT_CALL(handler_, Run(content::BluetoothChooser::Event::SELECTED,
139 AnyOf("11:22:33:44:55:66", "aa:bb:cc:dd:ee:ff",
140 "00:00:00:11:00:00")));
141 EXPECT_CALL(provider().connection_closed(), Run());
142 provider().client()->GrantAccessToAllDevices();
Gabriel Charette694c3c332019-08-19 14:53:05143 task_environment_.RunUntilIdle();
Stephen Lanham366d988e2018-04-14 00:25:41144}
145
146TEST_F(CastBluetoothChooserTest, TearDownClientAfterAllAccessGranted) {
147 // Grant access to all devices. |handler| should not run until the first
148 // device is made available.
149 provider().client()->GrantAccessToAllDevices();
Gabriel Charette694c3c332019-08-19 14:53:05150 task_environment_.RunUntilIdle();
Stephen Lanham366d988e2018-04-14 00:25:41151
152 // Tear down the client. Now that it has granted access to the client, it does
153 // not need to keep a reference to it. However, the chooser should stay alive
154 // and wait for devices to be made available.
155 provider().client().reset();
156 EXPECT_FALSE(provider().client());
Gabriel Charette694c3c332019-08-19 14:53:05157 task_environment_.RunUntilIdle();
Stephen Lanham366d988e2018-04-14 00:25:41158
159 // As soon as a device is available, run the handler.
160 EXPECT_CALL(handler_, Run(content::BluetoothChooser::Event::SELECTED,
161 "aa:bb:cc:dd:ee:ff"));
162 AddDeviceToChooser("aa:bb:cc:dd:ee:ff");
163}
164
165TEST_F(CastBluetoothChooserTest, TearDownClientBeforeApprovedDeviceDiscovered) {
166 // Make some devices available before access is granted. |handler| should not
167 // run yet.
168 AddDeviceToChooser("11:22:33:44:55:66");
169 AddDeviceToChooser("aa:bb:cc:dd:ee:ff");
170
171 // Tear the client down before any access is granted. |handler| should run,
172 // but with Event::CANCELLED.
173 EXPECT_CALL(handler_, Run(content::BluetoothChooser::Event::CANCELLED, ""));
174 provider().client().reset();
175 EXPECT_FALSE(provider().client());
Gabriel Charette694c3c332019-08-19 14:53:05176 task_environment_.RunUntilIdle();
Stephen Lanham366d988e2018-04-14 00:25:41177}
178
Gabriel Charette694c3c332019-08-19 14:53:05179} // namespace chromecast