1 // Copyright (c) 2015 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.
5 #include "base/prefs/testing_pref_service.h"
6 #include "base/test/test_simple_task_runner.h"
7 #include "base/time/time.h"
8 #include "chrome/browser/chromeos/policy/device_local_account.h"
9 #include "chrome/browser/chromeos/policy/device_status_collector.h"
10 #include "chrome/browser/chromeos/policy/status_uploader.h"
11 #include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
12 #include "chromeos/settings/cros_settings_names.h"
13 #include "components/policy/core/common/cloud/cloud_policy_client.h"
14 #include "components/policy/core/common/cloud/mock_cloud_policy_client.h"
15 #include "components/policy/core/common/cloud/mock_device_management_service.h"
16 #include "content/public/test/test_browser_thread_bundle.h"
17 #include "content/public/test/test_utils.h"
18 #include "net/url_request/url_request_context_getter.h"
19 #include "testing/gmock/include/gmock/gmock.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21 #include "ui/base/user_activity/user_activity_detector.h"
22 #include "ui/events/platform/platform_event_source.h"
23 #include "ui/events/platform/platform_event_types.h"
26 #include "ui/events/devices/x11/device_data_manager_x11.h"
27 #include "ui/events/devices/x11/touch_factory_x11.h"
28 #include "ui/events/test/events_test_utils_x11.h"
31 #if defined(USE_OZONE)
32 #include "ui/events/event.h"
33 #include "ui/events/event_utils.h"
37 using ::testing::Invoke
;
38 using ::testing::Return
;
39 using ::testing::SaveArg
;
40 using ::testing::WithArgs
;
42 namespace em
= enterprise_management
;
46 // A test implementation of PlatformEventSource that we can instantiate to make
47 // sure that the PlatformEventSource has an instance while in unit tests (X11
48 // platforms don't have a PlatformEventSource by default, while Ozone tests do).
50 class TestPlatformEventSource
: public ui::PlatformEventSource
{
52 TestPlatformEventSource() {}
53 ~TestPlatformEventSource() override
{}
56 DISALLOW_COPY_AND_ASSIGN(TestPlatformEventSource
);
60 class MockDeviceStatusCollector
: public policy::DeviceStatusCollector
{
62 explicit MockDeviceStatusCollector(PrefService
* local_state
)
63 : DeviceStatusCollector(
66 policy::DeviceStatusCollector::LocationUpdateRequester(),
67 policy::DeviceStatusCollector::VolumeInfoFetcher(),
68 policy::DeviceStatusCollector::CPUStatisticsFetcher()) {}
70 MOCK_METHOD1(GetDeviceStatus
, bool(em::DeviceStatusReportRequest
*));
71 MOCK_METHOD1(GetDeviceSessionStatus
, bool(em::SessionStatusReportRequest
*));
73 // Explicit mock implementation declared here, since gmock::Invoke can't
74 // handle returning non-moveable types like scoped_ptr.
75 scoped_ptr
<policy::DeviceLocalAccount
> GetAutoLaunchedKioskSessionInfo()
77 return make_scoped_ptr(new policy::DeviceLocalAccount(
78 policy::DeviceLocalAccount::TYPE_KIOSK_APP
, "account_id", "app_id",
86 class StatusUploaderTest
: public testing::Test
{
88 StatusUploaderTest() : task_runner_(new base::TestSimpleTaskRunner()) {
89 DeviceStatusCollector::RegisterPrefs(prefs_
.registry());
92 void SetUp() override
{
94 ui::DeviceDataManagerX11::CreateInstance();
96 client_
.SetDMToken("dm_token");
97 collector_
.reset(new MockDeviceStatusCollector(&prefs_
));
98 settings_helper_
.ReplaceProvider(chromeos::kReportUploadFrequency
);
101 void TearDown() override
{
102 content::RunAllBlockingPoolTasksUntilIdle();
105 // Given a pending task to upload status, mocks out a server response.
106 void RunPendingUploadTaskAndCheckNext(const StatusUploader
& uploader
,
107 base::TimeDelta expected_delay
) {
108 EXPECT_FALSE(task_runner_
->GetPendingTasks().empty());
109 CloudPolicyClient::StatusCallback callback
;
110 EXPECT_CALL(client_
, UploadDeviceStatus(_
, _
, _
))
111 .WillOnce(SaveArg
<2>(&callback
));
112 task_runner_
->RunPendingTasks();
113 testing::Mock::VerifyAndClearExpectations(&device_management_service_
);
115 // Make sure no status upload is queued up yet (since an upload is in
117 EXPECT_TRUE(task_runner_
->GetPendingTasks().empty());
119 // Now invoke the response.
122 // Now that the previous request was satisfied, a task to do the next
123 // upload should be queued.
124 EXPECT_EQ(1U, task_runner_
->GetPendingTasks().size());
126 CheckPendingTaskDelay(uploader
, expected_delay
);
129 void CheckPendingTaskDelay(const StatusUploader
& uploader
,
130 base::TimeDelta expected_delay
) {
131 // The next task should be scheduled sometime between |last_upload| +
132 // |expected_delay| and |now| + |expected_delay|.
133 base::Time now
= base::Time::NowFromSystemTime();
134 base::Time next_task
= now
+ task_runner_
->NextPendingTaskDelay();
136 EXPECT_LE(next_task
, now
+ expected_delay
);
137 EXPECT_GE(next_task
, uploader
.last_upload() + expected_delay
);
140 content::TestBrowserThreadBundle thread_bundle_
;
141 scoped_refptr
<base::TestSimpleTaskRunner
> task_runner_
;
142 chromeos::ScopedCrosSettingsTestHelper settings_helper_
;
143 scoped_ptr
<MockDeviceStatusCollector
> collector_
;
145 TestPlatformEventSource platform_event_source_
;
147 ui::UserActivityDetector detector_
;
148 MockCloudPolicyClient client_
;
149 MockDeviceManagementService device_management_service_
;
150 TestingPrefServiceSimple prefs_
;
153 TEST_F(StatusUploaderTest
, BasicTest
) {
154 EXPECT_TRUE(task_runner_
->GetPendingTasks().empty());
155 StatusUploader
uploader(&client_
, collector_
.Pass(), task_runner_
);
156 EXPECT_EQ(1U, task_runner_
->GetPendingTasks().size());
157 // On startup, first update should happen immediately.
158 EXPECT_EQ(base::TimeDelta(), task_runner_
->NextPendingTaskDelay());
161 TEST_F(StatusUploaderTest
, DifferentFrequencyAtStart
) {
162 // Keep a pointer to the mock collector because collector_ gets cleared
163 // when it is passed to the StatusUploader constructor below.
164 MockDeviceStatusCollector
* const mock_collector
= collector_
.get();
165 const int new_delay
= StatusUploader::kDefaultUploadDelayMs
* 2;
166 settings_helper_
.SetInteger(chromeos::kReportUploadFrequency
, new_delay
);
167 const base::TimeDelta expected_delay
= base::TimeDelta::FromMilliseconds(
169 EXPECT_TRUE(task_runner_
->GetPendingTasks().empty());
170 StatusUploader
uploader(&client_
, collector_
.Pass(), task_runner_
);
171 ASSERT_EQ(1U, task_runner_
->GetPendingTasks().size());
172 // On startup, first update should happen immediately.
173 EXPECT_EQ(base::TimeDelta(), task_runner_
->NextPendingTaskDelay());
175 EXPECT_CALL(*mock_collector
, GetDeviceStatus(_
)).WillRepeatedly(Return(true));
176 EXPECT_CALL(*mock_collector
, GetDeviceSessionStatus(_
)).WillRepeatedly(
178 // Second update should use the delay specified in settings.
179 RunPendingUploadTaskAndCheckNext(uploader
, expected_delay
);
182 TEST_F(StatusUploaderTest
, ResetTimerAfterStatusCollection
) {
183 // Keep a pointer to the mock collector because collector_ gets cleared
184 // when it is passed to the StatusUploader constructor below.
185 MockDeviceStatusCollector
* const mock_collector
= collector_
.get();
186 StatusUploader
uploader(&client_
, collector_
.Pass(), task_runner_
);
187 EXPECT_CALL(*mock_collector
, GetDeviceStatus(_
)).WillRepeatedly(Return(true));
188 EXPECT_CALL(*mock_collector
, GetDeviceSessionStatus(_
)).WillRepeatedly(
190 const base::TimeDelta expected_delay
= base::TimeDelta::FromMilliseconds(
191 StatusUploader::kDefaultUploadDelayMs
);
192 RunPendingUploadTaskAndCheckNext(uploader
, expected_delay
);
194 // Handle this response also, and ensure new task is queued.
195 RunPendingUploadTaskAndCheckNext(uploader
, expected_delay
);
197 // Now that the previous request was satisfied, a task to do the next
198 // upload should be queued again.
199 EXPECT_EQ(1U, task_runner_
->GetPendingTasks().size());
202 TEST_F(StatusUploaderTest
, ResetTimerAfterFailedStatusCollection
) {
203 // Keep a pointer to the mock collector because collector_ gets cleared
204 // when it is passed to the StatusUploader constructor below.
205 MockDeviceStatusCollector
* mock_collector
= collector_
.get();
206 StatusUploader
uploader(&client_
, collector_
.Pass(), task_runner_
);
207 EXPECT_CALL(*mock_collector
, GetDeviceStatus(_
)).WillOnce(Return(false));
208 EXPECT_CALL(*mock_collector
, GetDeviceSessionStatus(_
)).WillOnce(
210 task_runner_
->RunPendingTasks();
212 // Make sure the next status upload is queued up.
213 EXPECT_EQ(1U, task_runner_
->GetPendingTasks().size());
214 const base::TimeDelta expected_delay
= base::TimeDelta::FromMilliseconds(
215 StatusUploader::kDefaultUploadDelayMs
);
216 CheckPendingTaskDelay(uploader
, expected_delay
);
219 TEST_F(StatusUploaderTest
, ChangeFrequency
) {
220 // Keep a pointer to the mock collector because collector_ gets cleared
221 // when it is passed to the StatusUploader constructor below.
222 MockDeviceStatusCollector
* const mock_collector
= collector_
.get();
223 StatusUploader
uploader(&client_
, collector_
.Pass(), task_runner_
);
224 EXPECT_CALL(*mock_collector
, GetDeviceStatus(_
)).WillRepeatedly(Return(true));
225 EXPECT_CALL(*mock_collector
, GetDeviceSessionStatus(_
)).WillRepeatedly(
227 // Change the frequency. The new frequency should be reflected in the timing
228 // used for the next callback.
229 const int new_delay
= StatusUploader::kDefaultUploadDelayMs
* 2;
230 settings_helper_
.SetInteger(chromeos::kReportUploadFrequency
, new_delay
);
231 const base::TimeDelta expected_delay
= base::TimeDelta::FromMilliseconds(
233 RunPendingUploadTaskAndCheckNext(uploader
, expected_delay
);
236 #if defined(USE_X11) || defined(USE_OZONE)
237 TEST_F(StatusUploaderTest
, NoUploadAfterUserInput
) {
238 StatusUploader
uploader(&client_
, collector_
.Pass(), task_runner_
);
239 // Should allow data upload before there is user input.
240 EXPECT_TRUE(uploader
.IsSessionDataUploadAllowed());
242 // Now mock user input, and no session data should be allowed.
244 ui::ScopedXI2Event native_event
;
245 const int kPointerDeviceId
= 10;
246 std::vector
<int> device_list
;
247 device_list
.push_back(kPointerDeviceId
);
248 ui::TouchFactory::GetInstance()->SetPointerDeviceForTest(device_list
);
249 native_event
.InitGenericButtonEvent(
250 kPointerDeviceId
, ui::ET_MOUSE_PRESSED
, gfx::Point(),
251 ui::EF_LEFT_MOUSE_BUTTON
| ui::EF_CONTROL_DOWN
);
252 #elif defined(USE_OZONE)
253 ui::MouseEvent
e(ui::ET_MOUSE_PRESSED
, gfx::Point(), gfx::Point(),
254 ui::EventTimeForNow(), 0, 0);
255 const ui::PlatformEvent
& native_event
= &e
;
257 ui::UserActivityDetector::Get()->DidProcessEvent(native_event
);
258 EXPECT_FALSE(uploader
.IsSessionDataUploadAllowed());
262 TEST_F(StatusUploaderTest
, NoUploadAfterVideoCapture
) {
263 StatusUploader
uploader(&client_
, collector_
.Pass(), task_runner_
);
264 // Should allow data upload before there is video capture.
265 EXPECT_TRUE(uploader
.IsSessionDataUploadAllowed());
267 // Now mock video capture, and no session data should be allowed.
268 MediaCaptureDevicesDispatcher::GetInstance()->OnMediaRequestStateChanged(
269 0, 0, 0, GURL("http://www.google.com"),
270 content::MEDIA_DEVICE_VIDEO_CAPTURE
,
271 content::MEDIA_REQUEST_STATE_OPENING
);
272 base::RunLoop().RunUntilIdle();
273 EXPECT_FALSE(uploader
.IsSessionDataUploadAllowed());
276 } // namespace policy