Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / policy / device_status_collector_browsertest.cc
1 // Copyright (c) 2012 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/policy/device_status_collector.h"
6
7 #include "base/environment.h"
8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/prefs/pref_service.h"
12 #include "base/prefs/testing_pref_service.h"
13 #include "base/run_loop.h"
14 #include "base/threading/sequenced_worker_pool.h"
15 #include "chrome/browser/chromeos/login/users/mock_user_manager.h"
16 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
17 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
18 #include "chrome/browser/chromeos/policy/stub_enterprise_install_attributes.h"
19 #include "chrome/browser/chromeos/settings/cros_settings.h"
20 #include "chrome/browser/chromeos/settings/device_settings_service.h"
21 #include "chrome/browser/chromeos/settings/stub_cros_settings_provider.h"
22 #include "chrome/common/pref_names.h"
23 #include "chrome/test/base/testing_browser_process.h"
24 #include "chromeos/dbus/dbus_thread_manager.h"
25 #include "chromeos/dbus/shill_device_client.h"
26 #include "chromeos/network/network_handler.h"
27 #include "chromeos/settings/cros_settings_names.h"
28 #include "chromeos/settings/cros_settings_provider.h"
29 #include "chromeos/system/mock_statistics_provider.h"
30 #include "content/public/browser/browser_thread.h"
31 #include "content/public/browser/geolocation_provider.h"
32 #include "content/public/test/test_browser_thread.h"
33 #include "content/public/test/test_utils.h"
34 #include "policy/proto/device_management_backend.pb.h"
35 #include "testing/gmock/include/gmock/gmock.h"
36 #include "testing/gtest/include/gtest/gtest.h"
37 #include "third_party/cros_system_api/dbus/service_constants.h"
38
39 using ::testing::DoAll;
40 using ::testing::NotNull;
41 using ::testing::Return;
42 using ::testing::SetArgPointee;
43 using ::testing::_;
44 using base::Time;
45 using base::TimeDelta;
46
47 namespace em = enterprise_management;
48
49 namespace {
50
51 const int64 kMillisecondsPerDay = Time::kMicrosecondsPerDay / 1000;
52
53 scoped_ptr<content::Geoposition> mock_position_to_return_next;
54
55 void SetMockPositionToReturnNext(const content::Geoposition &position) {
56   mock_position_to_return_next.reset(new content::Geoposition(position));
57 }
58
59 void MockPositionUpdateRequester(
60     const content::GeolocationProvider::LocationUpdateCallback& callback) {
61   if (!mock_position_to_return_next.get())
62     return;
63
64   // If the fix is invalid, the DeviceStatusCollector will immediately request
65   // another update when it receives the callback. This is desirable and safe in
66   // real life where geolocation updates arrive asynchronously. In this testing
67   // harness, the callback is invoked synchronously upon request, leading to a
68   // request-callback loop. The loop is broken by returning the mock position
69   // only once.
70   scoped_ptr<content::Geoposition> position(
71       mock_position_to_return_next.release());
72   callback.Run(*position);
73 }
74
75 class TestingDeviceStatusCollector : public policy::DeviceStatusCollector {
76  public:
77   TestingDeviceStatusCollector(
78       PrefService* local_state,
79       chromeos::system::StatisticsProvider* provider,
80       policy::DeviceStatusCollector::LocationUpdateRequester*
81           location_update_requester)
82       : policy::DeviceStatusCollector(
83           local_state,
84           provider,
85           location_update_requester) {
86     // Set the baseline time to a fixed value (1 AM) to prevent test flakiness
87     // due to a single activity period spanning two days.
88     SetBaselineTime(Time::Now().LocalMidnight() + TimeDelta::FromHours(1));
89   }
90
91   void Simulate(IdleState* states, int len) {
92     for (int i = 0; i < len; i++)
93       IdleStateCallback(states[i]);
94   }
95
96   void set_max_stored_past_activity_days(unsigned int value) {
97     max_stored_past_activity_days_ = value;
98   }
99
100   void set_max_stored_future_activity_days(unsigned int value) {
101     max_stored_future_activity_days_ = value;
102   }
103
104   // Reset the baseline time.
105   void SetBaselineTime(Time time) {
106     baseline_time_ = time;
107     baseline_offset_periods_ = 0;
108   }
109
110  protected:
111   virtual void CheckIdleState() OVERRIDE {
112     // This should never be called in testing, as it results in a dbus call.
113     ADD_FAILURE();
114   }
115
116   // Each time this is called, returns a time that is a fixed increment
117   // later than the previous time.
118   virtual Time GetCurrentTime() OVERRIDE {
119     int poll_interval = policy::DeviceStatusCollector::kIdlePollIntervalSeconds;
120     return baseline_time_ +
121         TimeDelta::FromSeconds(poll_interval * baseline_offset_periods_++);
122   }
123
124  private:
125   // Baseline time for the fake times returned from GetCurrentTime().
126   Time baseline_time_;
127
128   // The number of simulated periods since the baseline time.
129   int baseline_offset_periods_;
130 };
131
132 // Return the total number of active milliseconds contained in a device
133 // status report.
134 int64 GetActiveMilliseconds(em::DeviceStatusReportRequest& status) {
135   int64 active_milliseconds = 0;
136   for (int i = 0; i < status.active_period_size(); i++) {
137     active_milliseconds += status.active_period(i).active_duration();
138   }
139   return active_milliseconds;
140 }
141
142 }  // namespace
143
144 namespace policy {
145
146 // Though it is a unit test, this test is linked with browser_tests so that it
147 // runs in a separate process. The intention is to avoid overriding the timezone
148 // environment variable for other tests.
149 class DeviceStatusCollectorTest : public testing::Test {
150  public:
151   DeviceStatusCollectorTest()
152     : ui_thread_(content::BrowserThread::UI, &message_loop_),
153       file_thread_(content::BrowserThread::FILE, &message_loop_),
154       io_thread_(content::BrowserThread::IO, &message_loop_),
155       install_attributes_("managed.com",
156                           "user@managed.com",
157                           "device_id",
158                           DEVICE_MODE_ENTERPRISE),
159       user_manager_(new chromeos::MockUserManager()),
160       user_manager_enabler_(user_manager_) {
161     // Run this test with a well-known timezone so that Time::LocalMidnight()
162     // returns the same values on all machines.
163     scoped_ptr<base::Environment> env(base::Environment::Create());
164     env->SetVar("TZ", "UTC");
165
166     TestingDeviceStatusCollector::RegisterPrefs(prefs_.registry());
167
168     EXPECT_CALL(statistics_provider_, GetMachineStatistic(_, NotNull()))
169         .WillRepeatedly(Return(false));
170
171     // Remove the real DeviceSettingsProvider and replace it with a stub.
172     cros_settings_ = chromeos::CrosSettings::Get();
173     device_settings_provider_ =
174         cros_settings_->GetProvider(chromeos::kReportDeviceVersionInfo);
175     EXPECT_TRUE(device_settings_provider_ != NULL);
176     EXPECT_TRUE(
177         cros_settings_->RemoveSettingsProvider(device_settings_provider_));
178     cros_settings_->AddSettingsProvider(&stub_settings_provider_);
179
180     RestartStatusCollector();
181   }
182
183   virtual ~DeviceStatusCollectorTest() {
184     // Finish pending tasks.
185     content::BrowserThread::GetBlockingPool()->FlushForTesting();
186     message_loop_.RunUntilIdle();
187
188     // Restore the real DeviceSettingsProvider.
189     EXPECT_TRUE(
190       cros_settings_->RemoveSettingsProvider(&stub_settings_provider_));
191     cros_settings_->AddSettingsProvider(device_settings_provider_);
192   }
193
194   virtual void SetUp() OVERRIDE {
195     // Disable network interface reporting since it requires additional setup.
196     cros_settings_->SetBoolean(chromeos::kReportDeviceNetworkInterfaces, false);
197   }
198
199   void RestartStatusCollector() {
200     policy::DeviceStatusCollector::LocationUpdateRequester callback =
201         base::Bind(&MockPositionUpdateRequester);
202     status_collector_.reset(
203         new TestingDeviceStatusCollector(&prefs_,
204                                          &statistics_provider_,
205                                          &callback));
206   }
207
208   void GetStatus() {
209     status_.Clear();
210     status_collector_->GetDeviceStatus(&status_);
211   }
212
213   void CheckThatNoLocationIsReported() {
214     GetStatus();
215     EXPECT_FALSE(status_.has_device_location());
216   }
217
218   void CheckThatAValidLocationIsReported() {
219     // Checks that a location is being reported which matches the valid fix
220     // set using SetMockPositionToReturnNext().
221     GetStatus();
222     EXPECT_TRUE(status_.has_device_location());
223     em::DeviceLocation location = status_.device_location();
224     if (location.has_error_code())
225       EXPECT_EQ(em::DeviceLocation::ERROR_CODE_NONE, location.error_code());
226     EXPECT_TRUE(location.has_latitude());
227     EXPECT_TRUE(location.has_longitude());
228     EXPECT_TRUE(location.has_accuracy());
229     EXPECT_TRUE(location.has_timestamp());
230     EXPECT_FALSE(location.has_altitude());
231     EXPECT_FALSE(location.has_altitude_accuracy());
232     EXPECT_FALSE(location.has_heading());
233     EXPECT_FALSE(location.has_speed());
234     EXPECT_FALSE(location.has_error_message());
235     EXPECT_DOUBLE_EQ(4.3, location.latitude());
236     EXPECT_DOUBLE_EQ(-7.8, location.longitude());
237     EXPECT_DOUBLE_EQ(3., location.accuracy());
238     // Check that the timestamp is not older than ten minutes.
239     EXPECT_TRUE(Time::Now() - Time::FromDoubleT(location.timestamp() / 1000.) <
240                 TimeDelta::FromMinutes(10));
241   }
242
243   void CheckThatALocationErrorIsReported() {
244     GetStatus();
245     EXPECT_TRUE(status_.has_device_location());
246     em::DeviceLocation location = status_.device_location();
247     EXPECT_TRUE(location.has_error_code());
248     EXPECT_EQ(em::DeviceLocation::ERROR_CODE_POSITION_UNAVAILABLE,
249               location.error_code());
250   }
251
252  protected:
253   // Convenience method.
254   int64 ActivePeriodMilliseconds() {
255     return policy::DeviceStatusCollector::kIdlePollIntervalSeconds * 1000;
256   }
257
258   // Since this is a unit test running in browser_tests we must do additional
259   // unit test setup and make a TestingBrowserProcess. Must be first member.
260   TestingBrowserProcessInitializer initializer_;
261   base::MessageLoopForUI message_loop_;
262   content::TestBrowserThread ui_thread_;
263   content::TestBrowserThread file_thread_;
264   content::TestBrowserThread io_thread_;
265
266   ScopedStubEnterpriseInstallAttributes install_attributes_;
267   TestingPrefServiceSimple prefs_;
268   chromeos::system::MockStatisticsProvider statistics_provider_;
269   chromeos::ScopedTestDeviceSettingsService test_device_settings_service_;
270   chromeos::ScopedTestCrosSettings test_cros_settings_;
271   chromeos::CrosSettings* cros_settings_;
272   chromeos::CrosSettingsProvider* device_settings_provider_;
273   chromeos::StubCrosSettingsProvider stub_settings_provider_;
274   chromeos::MockUserManager* user_manager_;
275   chromeos::ScopedUserManagerEnabler user_manager_enabler_;
276   em::DeviceStatusReportRequest status_;
277   scoped_ptr<TestingDeviceStatusCollector> status_collector_;
278 };
279
280 TEST_F(DeviceStatusCollectorTest, AllIdle) {
281   IdleState test_states[] = {
282     IDLE_STATE_IDLE,
283     IDLE_STATE_IDLE,
284     IDLE_STATE_IDLE
285   };
286   cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
287
288   // Test reporting with no data.
289   GetStatus();
290   EXPECT_EQ(0, status_.active_period_size());
291   EXPECT_EQ(0, GetActiveMilliseconds(status_));
292
293   // Test reporting with a single idle sample.
294   status_collector_->Simulate(test_states, 1);
295   GetStatus();
296   EXPECT_EQ(0, status_.active_period_size());
297   EXPECT_EQ(0, GetActiveMilliseconds(status_));
298
299   // Test reporting with multiple consecutive idle samples.
300   status_collector_->Simulate(test_states,
301                               sizeof(test_states) / sizeof(IdleState));
302   GetStatus();
303   EXPECT_EQ(0, status_.active_period_size());
304   EXPECT_EQ(0, GetActiveMilliseconds(status_));
305 }
306
307 TEST_F(DeviceStatusCollectorTest, AllActive) {
308   IdleState test_states[] = {
309     IDLE_STATE_ACTIVE,
310     IDLE_STATE_ACTIVE,
311     IDLE_STATE_ACTIVE
312   };
313   cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
314
315   // Test a single active sample.
316   status_collector_->Simulate(test_states, 1);
317   GetStatus();
318   EXPECT_EQ(1, status_.active_period_size());
319   EXPECT_EQ(1 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
320   status_.clear_active_period(); // Clear the result protobuf.
321
322   // Test multiple consecutive active samples.
323   status_collector_->Simulate(test_states,
324                               sizeof(test_states) / sizeof(IdleState));
325   GetStatus();
326   EXPECT_EQ(1, status_.active_period_size());
327   EXPECT_EQ(4 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
328 }
329
330 TEST_F(DeviceStatusCollectorTest, MixedStates) {
331   IdleState test_states[] = {
332     IDLE_STATE_ACTIVE,
333     IDLE_STATE_IDLE,
334     IDLE_STATE_ACTIVE,
335     IDLE_STATE_ACTIVE,
336     IDLE_STATE_IDLE,
337     IDLE_STATE_IDLE,
338     IDLE_STATE_ACTIVE
339   };
340   cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
341   status_collector_->Simulate(test_states,
342                               sizeof(test_states) / sizeof(IdleState));
343   GetStatus();
344   EXPECT_EQ(4 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
345 }
346
347 TEST_F(DeviceStatusCollectorTest, StateKeptInPref) {
348   IdleState test_states[] = {
349     IDLE_STATE_ACTIVE,
350     IDLE_STATE_IDLE,
351     IDLE_STATE_ACTIVE,
352     IDLE_STATE_ACTIVE,
353     IDLE_STATE_IDLE,
354     IDLE_STATE_IDLE
355   };
356   cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
357   status_collector_->Simulate(test_states,
358                               sizeof(test_states) / sizeof(IdleState));
359
360   // Process the list a second time after restarting the collector. It should be
361   // able to count the active periods found by the original collector, because
362   // the results are stored in a pref.
363   RestartStatusCollector();
364   status_collector_->Simulate(test_states,
365                               sizeof(test_states) / sizeof(IdleState));
366
367   GetStatus();
368   EXPECT_EQ(6 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
369 }
370
371 TEST_F(DeviceStatusCollectorTest, Times) {
372   IdleState test_states[] = {
373     IDLE_STATE_ACTIVE,
374     IDLE_STATE_IDLE,
375     IDLE_STATE_ACTIVE,
376     IDLE_STATE_ACTIVE,
377     IDLE_STATE_IDLE,
378     IDLE_STATE_IDLE
379   };
380   cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
381   status_collector_->Simulate(test_states,
382                               sizeof(test_states) / sizeof(IdleState));
383   GetStatus();
384   EXPECT_EQ(3 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
385 }
386
387 TEST_F(DeviceStatusCollectorTest, MaxStoredPeriods) {
388   IdleState test_states[] = {
389     IDLE_STATE_ACTIVE,
390     IDLE_STATE_IDLE
391   };
392   const int kMaxDays = 10;
393
394   cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
395   status_collector_->set_max_stored_past_activity_days(kMaxDays - 1);
396   status_collector_->set_max_stored_future_activity_days(1);
397   Time baseline = Time::Now().LocalMidnight();
398
399   // Simulate 12 active periods.
400   for (int i = 0; i < kMaxDays + 2; i++) {
401     status_collector_->Simulate(test_states,
402                                 sizeof(test_states) / sizeof(IdleState));
403     // Advance the simulated clock by a day.
404     baseline += TimeDelta::FromDays(1);
405     status_collector_->SetBaselineTime(baseline);
406   }
407
408   // Check that we don't exceed the max number of periods.
409   GetStatus();
410   EXPECT_EQ(kMaxDays - 1, status_.active_period_size());
411
412   // Simulate some future times.
413   for (int i = 0; i < kMaxDays + 2; i++) {
414     status_collector_->Simulate(test_states,
415                                 sizeof(test_states) / sizeof(IdleState));
416     // Advance the simulated clock by a day.
417     baseline += TimeDelta::FromDays(1);
418     status_collector_->SetBaselineTime(baseline);
419   }
420   // Set the clock back so the previous simulated times are in the future.
421   baseline -= TimeDelta::FromDays(20);
422   status_collector_->SetBaselineTime(baseline);
423
424   // Collect one more data point to trigger pruning.
425   status_collector_->Simulate(test_states, 1);
426
427   // Check that we don't exceed the max number of periods.
428   status_.clear_active_period();
429   GetStatus();
430   EXPECT_LT(status_.active_period_size(), kMaxDays);
431 }
432
433 TEST_F(DeviceStatusCollectorTest, ActivityTimesEnabledByDefault) {
434   // Device activity times should be reported by default.
435   IdleState test_states[] = {
436     IDLE_STATE_ACTIVE,
437     IDLE_STATE_ACTIVE,
438     IDLE_STATE_ACTIVE
439   };
440   status_collector_->Simulate(test_states,
441                               sizeof(test_states) / sizeof(IdleState));
442   GetStatus();
443   EXPECT_EQ(1, status_.active_period_size());
444   EXPECT_EQ(3 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
445 }
446
447 TEST_F(DeviceStatusCollectorTest, ActivityTimesOff) {
448   // Device activity times should not be reported if explicitly disabled.
449   cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, false);
450
451   IdleState test_states[] = {
452     IDLE_STATE_ACTIVE,
453     IDLE_STATE_ACTIVE,
454     IDLE_STATE_ACTIVE
455   };
456   status_collector_->Simulate(test_states,
457                               sizeof(test_states) / sizeof(IdleState));
458   GetStatus();
459   EXPECT_EQ(0, status_.active_period_size());
460   EXPECT_EQ(0, GetActiveMilliseconds(status_));
461 }
462
463 TEST_F(DeviceStatusCollectorTest, ActivityCrossingMidnight) {
464   IdleState test_states[] = {
465     IDLE_STATE_ACTIVE
466   };
467   cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
468
469   // Set the baseline time to 10 seconds after midnight.
470   status_collector_->SetBaselineTime(
471       Time::Now().LocalMidnight() + TimeDelta::FromSeconds(10));
472
473   status_collector_->Simulate(test_states, 1);
474   GetStatus();
475   ASSERT_EQ(2, status_.active_period_size());
476
477   em::ActiveTimePeriod period0 = status_.active_period(0);
478   em::ActiveTimePeriod period1 = status_.active_period(1);
479   EXPECT_EQ(ActivePeriodMilliseconds() - 10000, period0.active_duration());
480   EXPECT_EQ(10000, period1.active_duration());
481
482   em::TimePeriod time_period0 = period0.time_period();
483   em::TimePeriod time_period1 = period1.time_period();
484
485   EXPECT_EQ(time_period0.end_timestamp(), time_period1.start_timestamp());
486
487   // Ensure that the start and end times for the period are a day apart.
488   EXPECT_EQ(time_period0.end_timestamp() - time_period0.start_timestamp(),
489             kMillisecondsPerDay);
490   EXPECT_EQ(time_period1.end_timestamp() - time_period1.start_timestamp(),
491             kMillisecondsPerDay);
492 }
493
494 TEST_F(DeviceStatusCollectorTest, ActivityTimesKeptUntilSubmittedSuccessfully) {
495   IdleState test_states[] = {
496     IDLE_STATE_ACTIVE,
497     IDLE_STATE_ACTIVE,
498   };
499   cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true);
500
501   status_collector_->Simulate(test_states, 2);
502   GetStatus();
503   EXPECT_EQ(2 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
504   em::DeviceStatusReportRequest first_status(status_);
505
506   // The collector returns the same status again.
507   GetStatus();
508   EXPECT_EQ(first_status.SerializeAsString(), status_.SerializeAsString());
509
510   // After indicating a successful submit, the submitted status gets cleared,
511   // but what got collected meanwhile sticks around.
512   status_collector_->Simulate(test_states, 1);
513   status_collector_->OnSubmittedSuccessfully();
514   GetStatus();
515   EXPECT_EQ(ActivePeriodMilliseconds(), GetActiveMilliseconds(status_));
516 }
517
518 TEST_F(DeviceStatusCollectorTest, DevSwitchBootMode) {
519   // Test that boot mode data is reported by default.
520   EXPECT_CALL(statistics_provider_,
521               GetMachineStatistic("devsw_boot", NotNull()))
522       .WillOnce(DoAll(SetArgPointee<1>("0"), Return(true)));
523   GetStatus();
524   EXPECT_EQ("Verified", status_.boot_mode());
525
526   // Test that boot mode data is not reported if the pref turned off.
527   cros_settings_->SetBoolean(chromeos::kReportDeviceBootMode, false);
528
529   EXPECT_CALL(statistics_provider_,
530               GetMachineStatistic("devsw_boot", NotNull()))
531       .WillRepeatedly(DoAll(SetArgPointee<1>("0"), Return(true)));
532   GetStatus();
533   EXPECT_FALSE(status_.has_boot_mode());
534
535   // Turn the pref on, and check that the status is reported iff the
536   // statistics provider returns valid data.
537   cros_settings_->SetBoolean(chromeos::kReportDeviceBootMode, true);
538
539   EXPECT_CALL(statistics_provider_,
540               GetMachineStatistic("devsw_boot", NotNull()))
541       .WillOnce(DoAll(SetArgPointee<1>("(error)"), Return(true)));
542   GetStatus();
543   EXPECT_FALSE(status_.has_boot_mode());
544
545   EXPECT_CALL(statistics_provider_,
546               GetMachineStatistic("devsw_boot", NotNull()))
547       .WillOnce(DoAll(SetArgPointee<1>(" "), Return(true)));
548   GetStatus();
549   EXPECT_FALSE(status_.has_boot_mode());
550
551   EXPECT_CALL(statistics_provider_,
552               GetMachineStatistic("devsw_boot", NotNull()))
553       .WillOnce(DoAll(SetArgPointee<1>("0"), Return(true)));
554   GetStatus();
555   EXPECT_EQ("Verified", status_.boot_mode());
556
557   EXPECT_CALL(statistics_provider_,
558               GetMachineStatistic("devsw_boot", NotNull()))
559       .WillOnce(DoAll(SetArgPointee<1>("1"), Return(true)));
560   GetStatus();
561   EXPECT_EQ("Dev", status_.boot_mode());
562 }
563
564 TEST_F(DeviceStatusCollectorTest, VersionInfo) {
565   // Expect the version info to be reported by default.
566   GetStatus();
567   EXPECT_TRUE(status_.has_browser_version());
568   EXPECT_TRUE(status_.has_os_version());
569   EXPECT_TRUE(status_.has_firmware_version());
570
571   // When the pref to collect this data is not enabled, expect that none of
572   // the fields are present in the protobuf.
573   cros_settings_->SetBoolean(chromeos::kReportDeviceVersionInfo, false);
574   GetStatus();
575   EXPECT_FALSE(status_.has_browser_version());
576   EXPECT_FALSE(status_.has_os_version());
577   EXPECT_FALSE(status_.has_firmware_version());
578
579   cros_settings_->SetBoolean(chromeos::kReportDeviceVersionInfo, true);
580   GetStatus();
581   EXPECT_TRUE(status_.has_browser_version());
582   EXPECT_TRUE(status_.has_os_version());
583   EXPECT_TRUE(status_.has_firmware_version());
584
585   // Check that the browser version is not empty. OS version & firmware
586   // don't have any reasonable values inside the unit test, so those
587   // aren't checked.
588   EXPECT_NE("", status_.browser_version());
589 }
590
591 TEST_F(DeviceStatusCollectorTest, Location) {
592   content::Geoposition valid_fix;
593   valid_fix.latitude = 4.3;
594   valid_fix.longitude = -7.8;
595   valid_fix.accuracy = 3.;
596   valid_fix.timestamp = Time::Now();
597
598   content::Geoposition invalid_fix;
599   invalid_fix.error_code =
600       content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
601   invalid_fix.timestamp = Time::Now();
602
603   // Check that when device location reporting is disabled, no location is
604   // reported.
605   SetMockPositionToReturnNext(valid_fix);
606   CheckThatNoLocationIsReported();
607
608   // Check that when device location reporting is enabled and a valid fix is
609   // available, the location is reported and is stored in local state.
610   SetMockPositionToReturnNext(valid_fix);
611   cros_settings_->SetBoolean(chromeos::kReportDeviceLocation, true);
612   EXPECT_FALSE(prefs_.GetDictionary(prefs::kDeviceLocation)->empty());
613   CheckThatAValidLocationIsReported();
614
615   // Restart the status collector. Check that the last known location has been
616   // retrieved from local state without requesting a geolocation update.
617   SetMockPositionToReturnNext(valid_fix);
618   RestartStatusCollector();
619   CheckThatAValidLocationIsReported();
620   EXPECT_TRUE(mock_position_to_return_next.get());
621
622   // Check that after disabling location reporting again, the last known
623   // location has been cleared from local state and is no longer reported.
624   SetMockPositionToReturnNext(valid_fix);
625   cros_settings_->SetBoolean(chromeos::kReportDeviceLocation, false);
626   // Allow the new pref to propagate to the status collector.
627   message_loop_.RunUntilIdle();
628   EXPECT_TRUE(prefs_.GetDictionary(prefs::kDeviceLocation)->empty());
629   CheckThatNoLocationIsReported();
630
631   // Check that after enabling location reporting again, an error is reported
632   // if no valid fix is available.
633   SetMockPositionToReturnNext(invalid_fix);
634   cros_settings_->SetBoolean(chromeos::kReportDeviceLocation, true);
635   // Allow the new pref to propagate to the status collector.
636   message_loop_.RunUntilIdle();
637   CheckThatALocationErrorIsReported();
638 }
639
640 TEST_F(DeviceStatusCollectorTest, ReportUsers) {
641   user_manager_->CreatePublicAccountUser("public@localhost");
642   user_manager_->AddUser("user0@managed.com");
643   user_manager_->AddUser("user1@managed.com");
644   user_manager_->AddUser("user2@managed.com");
645   user_manager_->AddUser("user3@unmanaged.com");
646   user_manager_->AddUser("user4@managed.com");
647   user_manager_->AddUser("user5@managed.com");
648
649   // Verify that users are reported by default.
650   GetStatus();
651   EXPECT_EQ(6, status_.user_size());
652
653   // Verify that users are reported after enabling the setting.
654   cros_settings_->SetBoolean(chromeos::kReportDeviceUsers, true);
655   GetStatus();
656   EXPECT_EQ(6, status_.user_size());
657   EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(0).type());
658   EXPECT_EQ("user0@managed.com", status_.user(0).email());
659   EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(1).type());
660   EXPECT_EQ("user1@managed.com", status_.user(1).email());
661   EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(2).type());
662   EXPECT_EQ("user2@managed.com", status_.user(2).email());
663   EXPECT_EQ(em::DeviceUser::USER_TYPE_UNMANAGED, status_.user(3).type());
664   EXPECT_FALSE(status_.user(3).has_email());
665   EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(4).type());
666   EXPECT_EQ("user4@managed.com", status_.user(4).email());
667   EXPECT_EQ(em::DeviceUser::USER_TYPE_MANAGED, status_.user(5).type());
668   EXPECT_EQ("user5@managed.com", status_.user(5).email());
669
670   // Verify that users are no longer reported if setting is disabled.
671   cros_settings_->SetBoolean(chromeos::kReportDeviceUsers, false);
672   GetStatus();
673   EXPECT_EQ(0, status_.user_size());
674 }
675
676 // Fake device state.
677 struct FakeDeviceData {
678   const char* device_path;
679   const char* type;
680   const char* object_path;
681   const char* mac_address;
682   const char* meid;
683   const char* imei;
684   int expected_type; // proto enum type value, -1 for not present.
685 };
686
687 static const FakeDeviceData kFakeDevices[] = {
688   { "/device/ethernet", shill::kTypeEthernet, "ethernet",
689     "112233445566", "", "",
690     em::NetworkInterface::TYPE_ETHERNET },
691   { "/device/cellular1", shill::kTypeCellular, "cellular1",
692     "abcdefabcdef", "A10000009296F2", "",
693     em::NetworkInterface::TYPE_CELLULAR },
694   { "/device/cellular2", shill::kTypeCellular, "cellular2",
695     "abcdefabcdef", "", "352099001761481",
696     em::NetworkInterface::TYPE_CELLULAR },
697   { "/device/wifi", shill::kTypeWifi, "wifi",
698     "aabbccddeeff", "", "",
699     em::NetworkInterface::TYPE_WIFI },
700   { "/device/bluetooth", shill::kTypeBluetooth, "bluetooth",
701     "", "", "",
702     em::NetworkInterface::TYPE_BLUETOOTH },
703   { "/device/vpn", shill::kTypeVPN, "vpn",
704     "", "", "",
705     -1 },
706 };
707
708 class DeviceStatusCollectorNetworkInterfacesTest
709     : public DeviceStatusCollectorTest {
710  protected:
711   virtual void SetUp() OVERRIDE {
712     chromeos::DBusThreadManager::InitializeWithStub();
713     chromeos::NetworkHandler::Initialize();
714     chromeos::ShillDeviceClient::TestInterface* test_device_client =
715         chromeos::DBusThreadManager::Get()->GetShillDeviceClient()->
716             GetTestInterface();
717     test_device_client->ClearDevices();
718     for (size_t i = 0; i < arraysize(kFakeDevices); ++i) {
719       const FakeDeviceData& dev = kFakeDevices[i];
720       test_device_client->AddDevice(dev.device_path, dev.type,
721                                     dev.object_path);
722       if (*dev.mac_address) {
723         test_device_client->SetDeviceProperty(
724             dev.device_path, shill::kAddressProperty,
725             base::StringValue(dev.mac_address));
726       }
727       if (*dev.meid) {
728         test_device_client->SetDeviceProperty(
729             dev.device_path, shill::kMeidProperty,
730             base::StringValue(dev.meid));
731       }
732       if (*dev.imei) {
733         test_device_client->SetDeviceProperty(
734             dev.device_path, shill::kImeiProperty,
735             base::StringValue(dev.imei));
736       }
737     }
738
739     // Flush out pending state updates.
740     base::RunLoop().RunUntilIdle();
741   }
742
743   virtual void TearDown() OVERRIDE {
744     chromeos::NetworkHandler::Shutdown();
745     chromeos::DBusThreadManager::Shutdown();
746   }
747 };
748
749 TEST_F(DeviceStatusCollectorNetworkInterfacesTest, NetworkInterfaces) {
750   // Interfaces should be reported by default.
751   GetStatus();
752   EXPECT_TRUE(status_.network_interface_size() > 0);
753
754   // No interfaces should be reported if the policy is off.
755   cros_settings_->SetBoolean(chromeos::kReportDeviceNetworkInterfaces, false);
756   GetStatus();
757   EXPECT_EQ(0, status_.network_interface_size());
758
759   // Switch the policy on and verify the interface list is present.
760   cros_settings_->SetBoolean(chromeos::kReportDeviceNetworkInterfaces, true);
761   GetStatus();
762
763   int count = 0;
764   for (size_t i = 0; i < arraysize(kFakeDevices); ++i) {
765     const FakeDeviceData& dev = kFakeDevices[i];
766     if (dev.expected_type == -1)
767       continue;
768
769     // Find the corresponding entry in reporting data.
770     bool found_match = false;
771     google::protobuf::RepeatedPtrField<em::NetworkInterface>::const_iterator
772         iface;
773     for (iface = status_.network_interface().begin();
774          iface != status_.network_interface().end();
775          ++iface) {
776       // Check whether type, field presence and field values match.
777       if (dev.expected_type == iface->type() &&
778           iface->has_mac_address() == !!*dev.mac_address &&
779           iface->has_meid() == !!*dev.meid &&
780           iface->has_imei() == !!*dev.imei &&
781           iface->mac_address() == dev.mac_address &&
782           iface->meid() == dev.meid &&
783           iface->imei() == dev.imei) {
784         found_match = true;
785         break;
786       }
787     }
788
789     EXPECT_TRUE(found_match) << "No matching interface for fake device " << i;
790     count++;
791   }
792
793   EXPECT_EQ(count, status_.network_interface_size());
794 }
795
796 }  // namespace policy