| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/policy/device_status_collector.h" | 5 #include "chrome/browser/policy/device_status_collector.h" |
| 6 | 6 |
| 7 #include "base/message_loop.h" | 7 #include "base/message_loop.h" |
| 8 #include "base/time.h" | 8 #include "base/time.h" |
| 9 #include "chrome/browser/idle.h" | 9 #include "chrome/browser/idle.h" |
| 10 #include "chrome/browser/chromeos/cros_settings.h" |
| 11 #include "chrome/browser/chromeos/cros_settings_names.h" |
| 12 #include "chrome/browser/chromeos/cros_settings_provider.h" |
| 13 #include "chrome/browser/chromeos/stub_cros_settings_provider.h" |
| 10 #include "chrome/browser/chromeos/system/mock_statistics_provider.h" | 14 #include "chrome/browser/chromeos/system/mock_statistics_provider.h" |
| 11 #include "chrome/browser/policy/proto/device_management_backend.pb.h" | 15 #include "chrome/browser/policy/proto/device_management_backend.pb.h" |
| 12 #include "chrome/browser/prefs/pref_service.h" | 16 #include "chrome/browser/prefs/pref_service.h" |
| 13 #include "chrome/test/base/testing_pref_service.h" | 17 #include "chrome/test/base/testing_pref_service.h" |
| 18 #include "content/test/test_browser_thread.h" |
| 14 #include "testing/gmock/include/gmock/gmock.h" | 19 #include "testing/gmock/include/gmock/gmock.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 20 #include "testing/gtest/include/gtest/gtest.h" |
| 16 | 21 |
| 17 using base::TimeDelta; | 22 using base::TimeDelta; |
| 18 using base::Time; | 23 using base::Time; |
| 19 | 24 |
| 20 namespace em = enterprise_management; | 25 namespace em = enterprise_management; |
| 21 | 26 |
| 22 namespace { | 27 namespace { |
| 23 | 28 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 namespace policy { | 89 namespace policy { |
| 85 | 90 |
| 86 using ::testing::_; | 91 using ::testing::_; |
| 87 using ::testing::NotNull; | 92 using ::testing::NotNull; |
| 88 using ::testing::Return; | 93 using ::testing::Return; |
| 89 using ::testing::SetArgPointee; | 94 using ::testing::SetArgPointee; |
| 90 | 95 |
| 91 class DeviceStatusCollectorTest : public testing::Test { | 96 class DeviceStatusCollectorTest : public testing::Test { |
| 92 public: | 97 public: |
| 93 DeviceStatusCollectorTest() | 98 DeviceStatusCollectorTest() |
| 94 : prefs_(), | 99 : message_loop_(MessageLoop::TYPE_UI), |
| 95 status_collector_(&prefs_, &statistics_provider_) { | 100 ui_thread_(content::BrowserThread::UI, &message_loop_), |
| 101 file_thread_(content::BrowserThread::FILE, &message_loop_), |
| 102 status_collector_(&prefs_, &statistics_provider_) { |
| 103 |
| 96 DeviceStatusCollector::RegisterPrefs(&prefs_); | 104 DeviceStatusCollector::RegisterPrefs(&prefs_); |
| 97 EXPECT_CALL(statistics_provider_, GetMachineStatistic(_, NotNull())) | 105 EXPECT_CALL(statistics_provider_, GetMachineStatistic(_, NotNull())) |
| 98 .WillRepeatedly(Return(false)); | 106 .WillRepeatedly(Return(false)); |
| 107 |
| 108 cros_settings_ = chromeos::CrosSettings::Get(); |
| 109 |
| 110 // Remove the real DeviceSettingsProvider and replace it with a stub. |
| 111 device_settings_provider_ = |
| 112 cros_settings_->GetProvider(chromeos::kReportDeviceVersionInfo); |
| 113 EXPECT_TRUE(device_settings_provider_ != NULL); |
| 114 EXPECT_TRUE( |
| 115 cros_settings_->RemoveSettingsProvider(device_settings_provider_)); |
| 116 cros_settings_->AddSettingsProvider(&stub_settings_provider_); |
| 117 } |
| 118 |
| 119 ~DeviceStatusCollectorTest() { |
| 120 // Restore the real DeviceSettingsProvider. |
| 121 EXPECT_TRUE( |
| 122 cros_settings_->RemoveSettingsProvider(&stub_settings_provider_)); |
| 123 cros_settings_->AddSettingsProvider(device_settings_provider_); |
| 99 } | 124 } |
| 100 | 125 |
| 101 protected: | 126 protected: |
| 102 // Convenience method. | 127 // Convenience method. |
| 103 int64 ActivePeriodMilliseconds() { | 128 int64 ActivePeriodMilliseconds() { |
| 104 return policy::DeviceStatusCollector::kPollIntervalSeconds * 1000; | 129 return policy::DeviceStatusCollector::kPollIntervalSeconds * 1000; |
| 105 } | 130 } |
| 106 | 131 |
| 107 MessageLoop message_loop_; | 132 MessageLoop message_loop_; |
| 133 content::TestBrowserThread ui_thread_; |
| 134 content::TestBrowserThread file_thread_; |
| 135 |
| 108 TestingPrefService prefs_; | 136 TestingPrefService prefs_; |
| 109 chromeos::system::MockStatisticsProvider statistics_provider_; | 137 chromeos::system::MockStatisticsProvider statistics_provider_; |
| 110 TestingDeviceStatusCollector status_collector_; | 138 TestingDeviceStatusCollector status_collector_; |
| 111 em::DeviceStatusReportRequest status_; | 139 em::DeviceStatusReportRequest status_; |
| 140 chromeos::CrosSettings* cros_settings_; |
| 141 chromeos::CrosSettingsProvider* device_settings_provider_; |
| 142 chromeos::StubCrosSettingsProvider stub_settings_provider_; |
| 112 }; | 143 }; |
| 113 | 144 |
| 114 TEST_F(DeviceStatusCollectorTest, AllIdle) { | 145 TEST_F(DeviceStatusCollectorTest, AllIdle) { |
| 115 IdleState test_states[] = { | 146 IdleState test_states[] = { |
| 116 IDLE_STATE_IDLE, | 147 IDLE_STATE_IDLE, |
| 117 IDLE_STATE_IDLE, | 148 IDLE_STATE_IDLE, |
| 118 IDLE_STATE_IDLE | 149 IDLE_STATE_IDLE |
| 119 }; | 150 }; |
| 151 cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true); |
| 152 |
| 120 // Test reporting with no data. | 153 // Test reporting with no data. |
| 121 status_collector_.GetStatus(&status_); | 154 status_collector_.GetStatus(&status_); |
| 122 EXPECT_EQ(0, status_.active_time_size()); | 155 EXPECT_EQ(0, status_.active_time_size()); |
| 123 EXPECT_EQ(0, GetActiveMilliseconds(status_)); | 156 EXPECT_EQ(0, GetActiveMilliseconds(status_)); |
| 124 | 157 |
| 125 // Test reporting with a single idle sample. | 158 // Test reporting with a single idle sample. |
| 126 status_collector_.Simulate(test_states, 1); | 159 status_collector_.Simulate(test_states, 1); |
| 127 status_collector_.GetStatus(&status_); | 160 status_collector_.GetStatus(&status_); |
| 128 EXPECT_EQ(0, status_.active_time_size()); | 161 EXPECT_EQ(0, status_.active_time_size()); |
| 129 EXPECT_EQ(0, GetActiveMilliseconds(status_)); | 162 EXPECT_EQ(0, GetActiveMilliseconds(status_)); |
| 130 | 163 |
| 131 // Test reporting with multiple consecutive idle samples. | 164 // Test reporting with multiple consecutive idle samples. |
| 132 status_collector_.Simulate(test_states, | 165 status_collector_.Simulate(test_states, |
| 133 sizeof(test_states) / sizeof(IdleState)); | 166 sizeof(test_states) / sizeof(IdleState)); |
| 134 status_collector_.GetStatus(&status_); | 167 status_collector_.GetStatus(&status_); |
| 135 EXPECT_EQ(0, status_.active_time_size()); | 168 EXPECT_EQ(0, status_.active_time_size()); |
| 136 EXPECT_EQ(0, GetActiveMilliseconds(status_)); | 169 EXPECT_EQ(0, GetActiveMilliseconds(status_)); |
| 137 } | 170 } |
| 138 | 171 |
| 139 TEST_F(DeviceStatusCollectorTest, AllActive) { | 172 TEST_F(DeviceStatusCollectorTest, AllActive) { |
| 140 IdleState test_states[] = { | 173 IdleState test_states[] = { |
| 141 IDLE_STATE_ACTIVE, | 174 IDLE_STATE_ACTIVE, |
| 142 IDLE_STATE_ACTIVE, | 175 IDLE_STATE_ACTIVE, |
| 143 IDLE_STATE_ACTIVE | 176 IDLE_STATE_ACTIVE |
| 144 }; | 177 }; |
| 178 cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true); |
| 179 |
| 145 // Test a single active sample. | 180 // Test a single active sample. |
| 146 status_collector_.Simulate(test_states, 1); | 181 status_collector_.Simulate(test_states, 1); |
| 147 status_collector_.GetStatus(&status_); | 182 status_collector_.GetStatus(&status_); |
| 148 EXPECT_EQ(1, status_.active_time_size()); | 183 EXPECT_EQ(1, status_.active_time_size()); |
| 149 EXPECT_EQ(1 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_)); | 184 EXPECT_EQ(1 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_)); |
| 150 status_.clear_active_time(); // Clear the result protobuf. | 185 status_.clear_active_time(); // Clear the result protobuf. |
| 151 | 186 |
| 152 // Test multiple consecutive active samples -- they should be coalesced | 187 // Test multiple consecutive active samples -- they should be coalesced |
| 153 // into a single active period. | 188 // into a single active period. |
| 154 status_collector_.Simulate(test_states, | 189 status_collector_.Simulate(test_states, |
| 155 sizeof(test_states) / sizeof(IdleState)); | 190 sizeof(test_states) / sizeof(IdleState)); |
| 156 status_collector_.GetStatus(&status_); | 191 status_collector_.GetStatus(&status_); |
| 157 EXPECT_EQ(1, status_.active_time_size()); | 192 EXPECT_EQ(1, status_.active_time_size()); |
| 158 EXPECT_EQ(3 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_)); | 193 EXPECT_EQ(3 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_)); |
| 159 } | 194 } |
| 160 | 195 |
| 161 TEST_F(DeviceStatusCollectorTest, MixedStates) { | 196 TEST_F(DeviceStatusCollectorTest, MixedStates) { |
| 162 IdleState test_states[] = { | 197 IdleState test_states[] = { |
| 163 IDLE_STATE_ACTIVE, | 198 IDLE_STATE_ACTIVE, |
| 164 IDLE_STATE_IDLE, | 199 IDLE_STATE_IDLE, |
| 165 IDLE_STATE_ACTIVE, | 200 IDLE_STATE_ACTIVE, |
| 166 IDLE_STATE_ACTIVE, | 201 IDLE_STATE_ACTIVE, |
| 167 IDLE_STATE_IDLE, | 202 IDLE_STATE_IDLE, |
| 168 IDLE_STATE_IDLE, | 203 IDLE_STATE_IDLE, |
| 169 IDLE_STATE_ACTIVE | 204 IDLE_STATE_ACTIVE |
| 170 }; | 205 }; |
| 206 cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true); |
| 171 status_collector_.Simulate(test_states, | 207 status_collector_.Simulate(test_states, |
| 172 sizeof(test_states) / sizeof(IdleState)); | 208 sizeof(test_states) / sizeof(IdleState)); |
| 173 status_collector_.GetStatus(&status_); | 209 status_collector_.GetStatus(&status_); |
| 174 EXPECT_EQ(3, status_.active_time_size()); | 210 EXPECT_EQ(3, status_.active_time_size()); |
| 175 EXPECT_EQ(4 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_)); | 211 EXPECT_EQ(4 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_)); |
| 176 } | 212 } |
| 177 | 213 |
| 178 TEST_F(DeviceStatusCollectorTest, StateKeptInPref) { | 214 TEST_F(DeviceStatusCollectorTest, StateKeptInPref) { |
| 179 IdleState test_states[] = { | 215 IdleState test_states[] = { |
| 180 IDLE_STATE_ACTIVE, | 216 IDLE_STATE_ACTIVE, |
| 181 IDLE_STATE_IDLE, | 217 IDLE_STATE_IDLE, |
| 182 IDLE_STATE_ACTIVE, | 218 IDLE_STATE_ACTIVE, |
| 183 IDLE_STATE_ACTIVE, | 219 IDLE_STATE_ACTIVE, |
| 184 IDLE_STATE_IDLE, | 220 IDLE_STATE_IDLE, |
| 185 IDLE_STATE_IDLE | 221 IDLE_STATE_IDLE |
| 186 }; | 222 }; |
| 223 cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true); |
| 187 status_collector_.Simulate(test_states, | 224 status_collector_.Simulate(test_states, |
| 188 sizeof(test_states) / sizeof(IdleState)); | 225 sizeof(test_states) / sizeof(IdleState)); |
| 189 | 226 |
| 190 // Process the list a second time with a different collector. | 227 // Process the list a second time with a different collector. |
| 191 // It should be able to count the active periods found by the first | 228 // It should be able to count the active periods found by the first |
| 192 // collector, because the results are stored in a pref. | 229 // collector, because the results are stored in a pref. |
| 193 TestingDeviceStatusCollector second_collector(&prefs_, | 230 TestingDeviceStatusCollector second_collector(&prefs_, |
| 194 &statistics_provider_); | 231 &statistics_provider_); |
| 195 second_collector.Simulate(test_states, | 232 second_collector.Simulate(test_states, |
| 196 sizeof(test_states) / sizeof(IdleState)); | 233 sizeof(test_states) / sizeof(IdleState)); |
| 197 | 234 |
| 198 second_collector.GetStatus(&status_); | 235 second_collector.GetStatus(&status_); |
| 199 EXPECT_EQ(4, status_.active_time_size()); | 236 EXPECT_EQ(4, status_.active_time_size()); |
| 200 EXPECT_EQ(6 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_)); | 237 EXPECT_EQ(6 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_)); |
| 201 } | 238 } |
| 202 | 239 |
| 203 TEST_F(DeviceStatusCollectorTest, Times) { | 240 TEST_F(DeviceStatusCollectorTest, Times) { |
| 204 IdleState test_states[] = { | 241 IdleState test_states[] = { |
| 205 IDLE_STATE_ACTIVE, | 242 IDLE_STATE_ACTIVE, |
| 206 IDLE_STATE_IDLE, | 243 IDLE_STATE_IDLE, |
| 207 IDLE_STATE_ACTIVE, | 244 IDLE_STATE_ACTIVE, |
| 208 IDLE_STATE_ACTIVE, | 245 IDLE_STATE_ACTIVE, |
| 209 IDLE_STATE_IDLE, | 246 IDLE_STATE_IDLE, |
| 210 IDLE_STATE_IDLE | 247 IDLE_STATE_IDLE |
| 211 }; | 248 }; |
| 249 cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true); |
| 212 status_collector_.Simulate(test_states, | 250 status_collector_.Simulate(test_states, |
| 213 sizeof(test_states) / sizeof(IdleState)); | 251 sizeof(test_states) / sizeof(IdleState)); |
| 214 status_collector_.GetStatus(&status_); | 252 status_collector_.GetStatus(&status_); |
| 215 EXPECT_EQ(2, status_.active_time_size()); | 253 EXPECT_EQ(2, status_.active_time_size()); |
| 216 | 254 |
| 217 EXPECT_EQ(3 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_)); | 255 EXPECT_EQ(3 * ActivePeriodMilliseconds(), GetActiveMilliseconds(status_)); |
| 218 } | 256 } |
| 219 | 257 |
| 220 TEST_F(DeviceStatusCollectorTest, MaxStoredPeriods) { | 258 TEST_F(DeviceStatusCollectorTest, MaxStoredPeriods) { |
| 221 IdleState test_states[] = { | 259 IdleState test_states[] = { |
| 222 IDLE_STATE_ACTIVE, | 260 IDLE_STATE_ACTIVE, |
| 223 IDLE_STATE_IDLE | 261 IDLE_STATE_IDLE |
| 224 }; | 262 }; |
| 225 unsigned int max_periods = 10; | 263 unsigned int max_periods = 10; |
| 226 | 264 |
| 265 cros_settings_->SetBoolean(chromeos::kReportDeviceActivityTimes, true); |
| 227 status_collector_.set_max_stored_active_periods(max_periods); | 266 status_collector_.set_max_stored_active_periods(max_periods); |
| 228 | 267 |
| 229 // Simulate 12 active periods. | 268 // Simulate 12 active periods. |
| 230 for (int i = 0; i < 12; i++) { | 269 for (int i = 0; i < 12; i++) { |
| 231 status_collector_.Simulate(test_states, | 270 status_collector_.Simulate(test_states, |
| 232 sizeof(test_states) / sizeof(IdleState)); | 271 sizeof(test_states) / sizeof(IdleState)); |
| 233 } | 272 } |
| 234 | 273 |
| 235 // Check that we don't exceed the max number of periods. | 274 // Check that we don't exceed the max number of periods. |
| 236 status_collector_.GetStatus(&status_); | 275 status_collector_.GetStatus(&status_); |
| 237 EXPECT_EQ(static_cast<int>(max_periods), status_.active_time_size()); | 276 EXPECT_EQ(static_cast<int>(max_periods), status_.active_time_size()); |
| 238 } | 277 } |
| 239 | 278 |
| 279 TEST_F(DeviceStatusCollectorTest, ActivityTimesDisabledByDefault) { |
| 280 // If the pref for collecting device activity times isn't explicitly turned |
| 281 // on, no data on activity times should be reported. |
| 282 |
| 283 IdleState test_states[] = { |
| 284 IDLE_STATE_ACTIVE, |
| 285 IDLE_STATE_ACTIVE, |
| 286 IDLE_STATE_ACTIVE |
| 287 }; |
| 288 status_collector_.Simulate(test_states, |
| 289 sizeof(test_states) / sizeof(IdleState)); |
| 290 status_collector_.GetStatus(&status_); |
| 291 EXPECT_EQ(0, status_.active_time_size()); |
| 292 EXPECT_EQ(0, GetActiveMilliseconds(status_)); |
| 293 } |
| 294 |
| 240 TEST_F(DeviceStatusCollectorTest, DevSwitchBootMode) { | 295 TEST_F(DeviceStatusCollectorTest, DevSwitchBootMode) { |
| 296 // Test that boot mode data is not reported if the pref is not turned on. |
| 241 status_collector_.GetStatus(&status_); | 297 status_collector_.GetStatus(&status_); |
| 242 EXPECT_EQ(false, status_.has_boot_mode()); | 298 EXPECT_EQ(false, status_.has_boot_mode()); |
| 243 | 299 |
| 244 EXPECT_CALL(statistics_provider_, | 300 EXPECT_CALL(statistics_provider_, |
| 245 GetMachineStatistic("devsw_boot", NotNull())) | 301 GetMachineStatistic("devsw_boot", NotNull())) |
| 302 .WillRepeatedly(DoAll(SetArgPointee<1>("0"), Return(true))); |
| 303 EXPECT_EQ(false, status_.has_boot_mode()); |
| 304 |
| 305 // Turn the pref on, and check that the status is reported iff the |
| 306 // statistics provider returns valid data. |
| 307 cros_settings_->SetBoolean(chromeos::kReportDeviceBootMode, true); |
| 308 |
| 309 EXPECT_CALL(statistics_provider_, |
| 310 GetMachineStatistic("devsw_boot", NotNull())) |
| 246 .WillOnce(DoAll(SetArgPointee<1>("(error)"), Return(true))); | 311 .WillOnce(DoAll(SetArgPointee<1>("(error)"), Return(true))); |
| 247 status_collector_.GetStatus(&status_); | 312 status_collector_.GetStatus(&status_); |
| 248 EXPECT_EQ(false, status_.has_boot_mode()); | 313 EXPECT_EQ(false, status_.has_boot_mode()); |
| 249 | 314 |
| 250 EXPECT_CALL(statistics_provider_, | 315 EXPECT_CALL(statistics_provider_, |
| 251 GetMachineStatistic("devsw_boot", NotNull())) | 316 GetMachineStatistic("devsw_boot", NotNull())) |
| 252 .WillOnce(DoAll(SetArgPointee<1>(" "), Return(true))); | 317 .WillOnce(DoAll(SetArgPointee<1>(" "), Return(true))); |
| 253 status_collector_.GetStatus(&status_); | 318 status_collector_.GetStatus(&status_); |
| 254 EXPECT_EQ(false, status_.has_boot_mode()); | 319 EXPECT_EQ(false, status_.has_boot_mode()); |
| 255 | 320 |
| 256 EXPECT_CALL(statistics_provider_, | 321 EXPECT_CALL(statistics_provider_, |
| 257 GetMachineStatistic("devsw_boot", NotNull())) | 322 GetMachineStatistic("devsw_boot", NotNull())) |
| 258 .WillOnce(DoAll(SetArgPointee<1>("0"), Return(true))); | 323 .WillOnce(DoAll(SetArgPointee<1>("0"), Return(true))); |
| 259 status_collector_.GetStatus(&status_); | 324 status_collector_.GetStatus(&status_); |
| 260 EXPECT_EQ("Verified", status_.boot_mode()); | 325 EXPECT_EQ("Verified", status_.boot_mode()); |
| 261 | 326 |
| 262 EXPECT_CALL(statistics_provider_, | 327 EXPECT_CALL(statistics_provider_, |
| 263 GetMachineStatistic("devsw_boot", NotNull())) | 328 GetMachineStatistic("devsw_boot", NotNull())) |
| 264 .WillOnce(DoAll(SetArgPointee<1>("1"), Return(true))); | 329 .WillOnce(DoAll(SetArgPointee<1>("1"), Return(true))); |
| 265 status_collector_.GetStatus(&status_); | 330 status_collector_.GetStatus(&status_); |
| 266 EXPECT_EQ("Dev", status_.boot_mode()); | 331 EXPECT_EQ("Dev", status_.boot_mode()); |
| 267 } | 332 } |
| 268 | 333 |
| 334 TEST_F(DeviceStatusCollectorTest, VersionInfo) { |
| 335 // When the pref to collect this data is not enabled, expect that none of |
| 336 // the fields are present in the protobuf. |
| 337 status_collector_.GetStatus(&status_); |
| 338 EXPECT_EQ(false, status_.has_browser_version()); |
| 339 EXPECT_EQ(false, status_.has_os_version()); |
| 340 EXPECT_EQ(false, status_.has_firmware_version()); |
| 341 |
| 342 cros_settings_->SetBoolean(chromeos::kReportDeviceVersionInfo, true); |
| 343 status_collector_.GetStatus(&status_); |
| 344 EXPECT_EQ(true, status_.has_browser_version()); |
| 345 EXPECT_EQ(true, status_.has_os_version()); |
| 346 EXPECT_EQ(true, status_.has_firmware_version()); |
| 347 |
| 348 // Check that the browser version is not empty. OS version & firmware |
| 349 // don't have any reasonable values inside the unit test, so those |
| 350 // aren't checked. |
| 351 EXPECT_NE("", status_.browser_version()); |
| 352 } |
| 353 |
| 269 } // namespace policy | 354 } // namespace policy |
| OLD | NEW |