1 // 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 "chromeos/services/multidevice_setup/eligible_host_devices_provider_impl.h"
6
7 #include <memory>
8
9 #include "base/containers/flat_set.h"
10 #include "base/macros.h"
11 #include "base/stl_util.h"
12 #include "base/test/scoped_feature_list.h"
13 #include "chromeos/components/multidevice/remote_device_test_util.h"
14 #include "chromeos/components/multidevice/software_feature.h"
15 #include "chromeos/components/multidevice/software_feature_state.h"
16 #include "chromeos/constants/chromeos_features.h"
17 #include "chromeos/services/device_sync/proto/cryptauth_api.pb.h"
18 #include "chromeos/services/device_sync/public/cpp/fake_device_sync_client.h"
19 #include "chromeos/services/device_sync/public/mojom/device_sync.mojom.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace chromeos {
23
24 namespace multidevice_setup {
25
26 namespace {
27
28 const size_t kNumTestDevices = 5;
29
30 } // namespace
31
32 class MultiDeviceSetupEligibleHostDevicesProviderImplTest
33 : public testing::TestWithParam<bool> {
34 protected:
MultiDeviceSetupEligibleHostDevicesProviderImplTest()35 MultiDeviceSetupEligibleHostDevicesProviderImplTest()
36 : test_devices_(
37 multidevice::CreateRemoteDeviceRefListForTest(kNumTestDevices)) {}
38 ~MultiDeviceSetupEligibleHostDevicesProviderImplTest() override = default;
39
40 // testing::Test:
SetUp()41 void SetUp() override {
42 use_get_devices_activity_status_ = GetParam();
43 scoped_feature_list_.InitWithFeatureState(
44 chromeos::features::kCryptAuthV2DeviceActivityStatus,
45 use_get_devices_activity_status_);
46
47 fake_device_sync_client_ =
48 std::make_unique<device_sync::FakeDeviceSyncClient>();
49 fake_device_sync_client_->set_synced_devices(test_devices_);
50
51 provider_ = EligibleHostDevicesProviderImpl::Factory::Create(
52 fake_device_sync_client_.get());
53 }
54
fake_device_sync_client()55 device_sync::FakeDeviceSyncClient* fake_device_sync_client() {
56 return fake_device_sync_client_.get();
57 }
58
test_devices()59 multidevice::RemoteDeviceRefList& test_devices() { return test_devices_; }
60
provider()61 EligibleHostDevicesProvider* provider() { return provider_.get(); }
62
SetBitsOnTestDevices()63 void SetBitsOnTestDevices() {
64 // Devices 0, 1, and 2 are supported.
65 GetMutableRemoteDevice(test_devices()[0])
66 ->software_features[multidevice::SoftwareFeature::kBetterTogetherHost] =
67 multidevice::SoftwareFeatureState::kSupported;
68 GetMutableRemoteDevice(test_devices()[1])
69 ->software_features[multidevice::SoftwareFeature::kBetterTogetherHost] =
70 multidevice::SoftwareFeatureState::kSupported;
71 GetMutableRemoteDevice(test_devices()[2])
72 ->software_features[multidevice::SoftwareFeature::kBetterTogetherHost] =
73 multidevice::SoftwareFeatureState::kSupported;
74
75 // Device 3 is enabled.
76 GetMutableRemoteDevice(test_devices()[3])
77 ->software_features[multidevice::SoftwareFeature::kBetterTogetherHost] =
78 multidevice::SoftwareFeatureState::kEnabled;
79
80 // Device 4 is not supported.
81 GetMutableRemoteDevice(test_devices()[4])
82 ->software_features[multidevice::SoftwareFeature::kBetterTogetherHost] =
83 multidevice::SoftwareFeatureState::kNotSupported;
84 }
85
use_get_devices_activity_status()86 bool use_get_devices_activity_status() {
87 return use_get_devices_activity_status_;
88 }
89
90 private:
91 multidevice::RemoteDeviceRefList test_devices_;
92
93 std::unique_ptr<device_sync::FakeDeviceSyncClient> fake_device_sync_client_;
94
95 std::unique_ptr<EligibleHostDevicesProvider> provider_;
96
97 bool use_get_devices_activity_status_;
98
99 base::test::ScopedFeatureList scoped_feature_list_;
100
101 DISALLOW_COPY_AND_ASSIGN(MultiDeviceSetupEligibleHostDevicesProviderImplTest);
102 };
103
TEST_P(MultiDeviceSetupEligibleHostDevicesProviderImplTest,Empty)104 TEST_P(MultiDeviceSetupEligibleHostDevicesProviderImplTest, Empty) {
105 EXPECT_TRUE(provider()->GetEligibleHostDevices().empty());
106 }
107
TEST_P(MultiDeviceSetupEligibleHostDevicesProviderImplTest,NoEligibleDevices)108 TEST_P(MultiDeviceSetupEligibleHostDevicesProviderImplTest, NoEligibleDevices) {
109 GetMutableRemoteDevice(test_devices()[0])
110 ->software_features[multidevice::SoftwareFeature::kBetterTogetherHost] =
111 multidevice::SoftwareFeatureState::kNotSupported;
112 GetMutableRemoteDevice(test_devices()[1])
113 ->software_features[multidevice::SoftwareFeature::kBetterTogetherHost] =
114 multidevice::SoftwareFeatureState::kNotSupported;
115
116 multidevice::RemoteDeviceRefList devices{test_devices()[0],
117 test_devices()[1]};
118 fake_device_sync_client()->set_synced_devices(devices);
119 fake_device_sync_client()->NotifyNewDevicesSynced();
120
121 EXPECT_TRUE(provider()->GetEligibleHostDevices().empty());
122 }
123
TEST_P(MultiDeviceSetupEligibleHostDevicesProviderImplTest,SupportedAndEnabled)124 TEST_P(MultiDeviceSetupEligibleHostDevicesProviderImplTest,
125 SupportedAndEnabled) {
126 SetBitsOnTestDevices();
127
128 GetMutableRemoteDevice(test_devices()[0])->last_update_time_millis = 1999;
129 GetMutableRemoteDevice(test_devices()[1])->last_update_time_millis = 25;
130 GetMutableRemoteDevice(test_devices()[2])->last_update_time_millis = 2525;
131 GetMutableRemoteDevice(test_devices()[3])->last_update_time_millis = 500;
132 GetMutableRemoteDevice(test_devices()[4])->last_update_time_millis = 1000;
133
134 multidevice::RemoteDeviceRefList devices{test_devices()[0], test_devices()[1],
135 test_devices()[2], test_devices()[3],
136 test_devices()[4]};
137 fake_device_sync_client()->set_synced_devices(devices);
138 fake_device_sync_client()->NotifyNewDevicesSynced();
139
140 multidevice::RemoteDeviceRefList eligible_devices =
141 provider()->GetEligibleHostDevices();
142 EXPECT_EQ(4u, eligible_devices.size());
143 EXPECT_EQ(test_devices()[2], eligible_devices[0]);
144 EXPECT_EQ(test_devices()[0], eligible_devices[1]);
145 EXPECT_EQ(test_devices()[3], eligible_devices[2]);
146 EXPECT_EQ(test_devices()[1], eligible_devices[3]);
147 }
148
TEST_P(MultiDeviceSetupEligibleHostDevicesProviderImplTest,GetDevicesActivityStatus)149 TEST_P(MultiDeviceSetupEligibleHostDevicesProviderImplTest,
150 GetDevicesActivityStatus) {
151 SetBitsOnTestDevices();
152
153 GetMutableRemoteDevice(test_devices()[0])->last_update_time_millis = 1;
154 GetMutableRemoteDevice(test_devices()[1])->last_update_time_millis = 25;
155 GetMutableRemoteDevice(test_devices()[2])->last_update_time_millis = 10;
156 GetMutableRemoteDevice(test_devices()[3])->last_update_time_millis = 100;
157 GetMutableRemoteDevice(test_devices()[4])->last_update_time_millis = 10000;
158
159 multidevice::RemoteDeviceRefList devices{test_devices()[0], test_devices()[1],
160 test_devices()[2], test_devices()[3],
161 test_devices()[4]};
162 fake_device_sync_client()->set_synced_devices(devices);
163 fake_device_sync_client()->NotifyNewDevicesSynced();
164
165 std::vector<device_sync::mojom::DeviceActivityStatusPtr>
166 device_activity_statuses;
167 device_activity_statuses.emplace_back(
168 device_sync::mojom::DeviceActivityStatus::New(
169 test_devices()[0].instance_id(), base::Time::FromTimeT(50),
170 cryptauthv2::ConnectivityStatus::ONLINE));
171 device_activity_statuses.emplace_back(
172 device_sync::mojom::DeviceActivityStatus::New(
173 test_devices()[1].instance_id(), base::Time::FromTimeT(100),
174 cryptauthv2::ConnectivityStatus::OFFLINE));
175 device_activity_statuses.emplace_back(
176 device_sync::mojom::DeviceActivityStatus::New(
177 test_devices()[2].instance_id(), base::Time::FromTimeT(200),
178 cryptauthv2::ConnectivityStatus::ONLINE));
179 device_activity_statuses.emplace_back(
180 device_sync::mojom::DeviceActivityStatus::New(
181 test_devices()[3].instance_id(), base::Time::FromTimeT(50),
182 cryptauthv2::ConnectivityStatus::ONLINE));
183 if (use_get_devices_activity_status()) {
184 fake_device_sync_client()->InvokePendingGetDevicesActivityStatusCallback(
185 device_sync::mojom::NetworkRequestResult::kSuccess,
186 std::move(device_activity_statuses));
187 }
188
189 multidevice::DeviceWithConnectivityStatusList eligible_active_devices =
190 provider()->GetEligibleActiveHostDevices();
191 EXPECT_EQ(4u, eligible_active_devices.size());
192
193 if (use_get_devices_activity_status()) {
194 EXPECT_EQ(test_devices()[2], eligible_active_devices[0].remote_device);
195 EXPECT_EQ(test_devices()[3], eligible_active_devices[1].remote_device);
196 EXPECT_EQ(test_devices()[0], eligible_active_devices[2].remote_device);
197 EXPECT_EQ(test_devices()[1], eligible_active_devices[3].remote_device);
198 EXPECT_EQ(cryptauthv2::ConnectivityStatus::ONLINE,
199 eligible_active_devices[0].connectivity_status);
200 EXPECT_EQ(cryptauthv2::ConnectivityStatus::ONLINE,
201 eligible_active_devices[1].connectivity_status);
202 EXPECT_EQ(cryptauthv2::ConnectivityStatus::ONLINE,
203 eligible_active_devices[2].connectivity_status);
204 EXPECT_EQ(cryptauthv2::ConnectivityStatus::OFFLINE,
205 eligible_active_devices[3].connectivity_status);
206 } else {
207 multidevice::RemoteDeviceRefList eligible_devices =
208 provider()->GetEligibleHostDevices();
209 EXPECT_EQ(4u, eligible_devices.size());
210 EXPECT_EQ(test_devices()[3], eligible_devices[0]);
211 EXPECT_EQ(test_devices()[1], eligible_devices[1]);
212 EXPECT_EQ(test_devices()[2], eligible_devices[2]);
213 EXPECT_EQ(test_devices()[0], eligible_devices[3]);
214
215 for (size_t i = 0; i < 4; i++) {
216 EXPECT_EQ(eligible_devices[i], eligible_active_devices[i].remote_device);
217 }
218 for (size_t i = 0; i < 4; i++) {
219 EXPECT_EQ(cryptauthv2::ConnectivityStatus::UNKNOWN_CONNECTIVITY,
220 eligible_active_devices[i].connectivity_status);
221 }
222 }
223 }
224
TEST_P(MultiDeviceSetupEligibleHostDevicesProviderImplTest,GetDevicesActivityStatusFailedRequest)225 TEST_P(MultiDeviceSetupEligibleHostDevicesProviderImplTest,
226 GetDevicesActivityStatusFailedRequest) {
227 if (!use_get_devices_activity_status()) {
228 return;
229 }
230
231 SetBitsOnTestDevices();
232 GetMutableRemoteDevice(test_devices()[0])->last_update_time_millis = 5;
233 GetMutableRemoteDevice(test_devices()[1])->last_update_time_millis = 4;
234 GetMutableRemoteDevice(test_devices()[2])->last_update_time_millis = 3;
235 GetMutableRemoteDevice(test_devices()[3])->last_update_time_millis = 2;
236 GetMutableRemoteDevice(test_devices()[4])->last_update_time_millis = 1;
237
238 multidevice::RemoteDeviceRefList devices{test_devices()[0], test_devices()[1],
239 test_devices()[2], test_devices()[3],
240 test_devices()[4]};
241 fake_device_sync_client()->set_synced_devices(devices);
242 fake_device_sync_client()->NotifyNewDevicesSynced();
243 fake_device_sync_client()->InvokePendingGetDevicesActivityStatusCallback(
244 device_sync::mojom::NetworkRequestResult::kInternalServerError,
245 base::nullopt);
246
247 multidevice::DeviceWithConnectivityStatusList eligible_active_devices =
248 provider()->GetEligibleActiveHostDevices();
249 multidevice::RemoteDeviceRefList eligible_devices =
250 provider()->GetEligibleHostDevices();
251 EXPECT_EQ(test_devices()[0], eligible_active_devices[0].remote_device);
252 EXPECT_EQ(test_devices()[1], eligible_active_devices[1].remote_device);
253 EXPECT_EQ(test_devices()[2], eligible_active_devices[2].remote_device);
254 EXPECT_EQ(test_devices()[3], eligible_active_devices[3].remote_device);
255 EXPECT_EQ(test_devices()[0], eligible_devices[0]);
256 EXPECT_EQ(test_devices()[1], eligible_devices[1]);
257 EXPECT_EQ(test_devices()[2], eligible_devices[2]);
258 EXPECT_EQ(test_devices()[3], eligible_devices[3]);
259 }
260
261 INSTANTIATE_TEST_SUITE_P(All,
262 MultiDeviceSetupEligibleHostDevicesProviderImplTest,
263 testing::Bool());
264
265 } // namespace multidevice_setup
266
267 } // namespace chromeos
268