SystemUpdatePolicyTest.java revision 1b2f37401818b04cf4908d5aa9017eab44fe5662
1/* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package com.android.server.devicepolicy; 17 18import static android.app.admin.SystemUpdatePolicy.ValidationFailedException.ERROR_COMBINED_FREEZE_PERIOD_TOO_CLOSE; 19import static android.app.admin.SystemUpdatePolicy.ValidationFailedException.ERROR_COMBINED_FREEZE_PERIOD_TOO_LONG; 20import static android.app.admin.SystemUpdatePolicy.ValidationFailedException.ERROR_DUPLICATE_OR_OVERLAP; 21import static android.app.admin.SystemUpdatePolicy.ValidationFailedException.ERROR_NEW_FREEZE_PERIOD_TOO_CLOSE; 22import static android.app.admin.SystemUpdatePolicy.ValidationFailedException.ERROR_NEW_FREEZE_PERIOD_TOO_LONG; 23import static org.junit.Assert.assertEquals; 24import static org.junit.Assert.assertTrue; 25import static org.junit.Assert.fail; 26 27import android.app.admin.FreezePeriod; 28import android.app.admin.SystemUpdatePolicy; 29import android.os.Parcel; 30import android.support.test.runner.AndroidJUnit4; 31import android.util.Pair; 32import android.util.Xml; 33 34import com.android.internal.util.FastXmlSerializer; 35 36import org.junit.Test; 37import org.junit.runner.RunWith; 38import org.xmlpull.v1.XmlPullParser; 39import org.xmlpull.v1.XmlSerializer; 40 41import java.io.ByteArrayInputStream; 42import java.io.ByteArrayOutputStream; 43import java.io.InputStreamReader; 44import java.nio.charset.StandardCharsets; 45import java.time.LocalDate; 46import java.time.LocalDateTime; 47import java.time.MonthDay; 48import java.time.ZoneId; 49import java.util.ArrayList; 50import java.util.List; 51import java.util.concurrent.TimeUnit; 52 53 54/** 55 * Unit tests for {@link android.app.admin.SystemUpdatePolicy}. 56 * Throughout this test, we use "MM-DD" format to denote dates without year. 57 * 58 * atest com.android.server.devicepolicy.SystemUpdatePolicyTest 59 * runtest -c com.android.server.devicepolicy.SystemUpdatePolicyTest frameworks-services 60 */ 61@RunWith(AndroidJUnit4.class) 62public final class SystemUpdatePolicyTest { 63 64 private static final int DUPLICATE_OR_OVERLAP = ERROR_DUPLICATE_OR_OVERLAP; 65 private static final int TOO_LONG = ERROR_NEW_FREEZE_PERIOD_TOO_LONG; 66 private static final int TOO_CLOSE = ERROR_NEW_FREEZE_PERIOD_TOO_CLOSE; 67 private static final int COMBINED_TOO_LONG = ERROR_COMBINED_FREEZE_PERIOD_TOO_LONG; 68 private static final int COMBINED_TOO_CLOSE = ERROR_COMBINED_FREEZE_PERIOD_TOO_CLOSE; 69 70 @Test 71 public void testSimplePeriod() throws Exception { 72 testFreezePeriodsSucceeds("01-01", "01-02"); 73 testFreezePeriodsSucceeds("01-31", "01-31"); 74 testFreezePeriodsSucceeds("11-01", "01-15"); 75 testFreezePeriodsSucceeds("02-01", "02-29"); // Leap year 76 testFreezePeriodsSucceeds("02-01", "03-01"); 77 testFreezePeriodsSucceeds("12-01", "01-30"); // Wrapped Period 78 testFreezePeriodsSucceeds("11-02", "01-30", "04-01", "04-30"); // Wrapped Period 79 } 80 81 @Test 82 public void testCanonicalizationValidation() throws Exception { 83 testFreezePeriodsSucceeds("03-01", "03-31", "09-01", "09-30"); 84 testFreezePeriodsSucceeds("06-01", "07-01", "09-01", "09-30"); 85 testFreezePeriodsSucceeds("10-01", "10-31", "12-31", "01-31"); 86 testFreezePeriodsSucceeds("01-01", "01-30", "04-01", "04-30"); 87 testFreezePeriodsSucceeds("01-01", "02-28", "05-01", "06-30", "09-01", "10-31"); 88 89 // One interval fully covers the other 90 testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "03-01", "03-31", "03-15", "03-31"); 91 testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "03-01", "03-31", "03-15", "03-16"); 92 testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "11-15", "01-31", "12-01", "12-31"); 93 testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "12-01", "01-31", "01-01", "01-15"); 94 95 // Partial overlap 96 testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "03-01", "03-31", "03-15", "01-01"); 97 testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "11-15", "01-31", "12-01", "02-28"); 98 99 // No gap between two intervals 100 testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "01-31", "01-31", "02-01", "02-01"); 101 testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "12-01", "12-15", "12-15", "02-01"); 102 testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "12-01", "12-15", "12-16", "02-01"); 103 testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "12-01", "01-15", "01-15", "02-01"); 104 testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "12-01", "01-15", "01-16", "02-01"); 105 testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "01-01", "01-30", "12-01", "12-31"); 106 testFreezePeriodsFails(DUPLICATE_OR_OVERLAP, "12-01", "12-31", "04-01", "04-01", 107 "01-01", "01-30"); 108 } 109 110 @Test 111 public void testLengthValidation() throws Exception { 112 testFreezePeriodsSucceeds("03-01", "03-31"); 113 testFreezePeriodsSucceeds("03-03", "03-03", "12-31", "01-01"); 114 testFreezePeriodsSucceeds("01-01", "03-31", "06-01", "08-29"); 115 // entire year 116 testFreezePeriodsFails(TOO_LONG, "01-01", "12-31"); 117 // long period spanning across year end 118 testFreezePeriodsSucceeds("11-01", "01-29"); 119 testFreezePeriodsFails(TOO_LONG, "11-01", "01-30"); 120 // Leap year handling 121 testFreezePeriodsSucceeds("12-01", "02-28"); 122 testFreezePeriodsSucceeds("12-01", "02-29"); 123 testFreezePeriodsFails(TOO_LONG, "12-01", "03-01"); 124 // Regular long period 125 testFreezePeriodsSucceeds("01-01", "03-31", "06-01", "08-29"); 126 testFreezePeriodsFails(TOO_LONG, "01-01", "03-31", "06-01", "08-30"); 127 } 128 129 @Test 130 public void testSeparationValidation() throws Exception { 131 testFreezePeriodsSucceeds("01-01", "03-31", "06-01", "08-29"); 132 testFreezePeriodsFails(TOO_CLOSE, "01-01", "01-01", "01-03", "01-03"); 133 testFreezePeriodsFails(TOO_CLOSE, "03-01", "03-31", "05-01", "05-31"); 134 // Short interval spans across end of year 135 testFreezePeriodsSucceeds("01-31", "03-01", "11-01", "12-01"); 136 testFreezePeriodsFails(TOO_CLOSE, "01-30", "03-01", "11-01", "12-01"); 137 // Short separation is after wrapped period 138 testFreezePeriodsSucceeds("03-03", "03-31", "12-31", "01-01"); 139 testFreezePeriodsFails(TOO_CLOSE, "03-02", "03-31", "12-31", "01-01"); 140 // Short separation including Feb 29 141 testFreezePeriodsSucceeds("12-01", "01-15", "03-17", "04-01"); 142 testFreezePeriodsFails(TOO_CLOSE, "12-01", "01-15", "03-16", "04-01"); 143 // Short separation including Feb 29 144 testFreezePeriodsSucceeds("01-01", "02-28", "04-30", "06-01"); 145 testFreezePeriodsSucceeds("01-01", "02-29", "04-30", "06-01"); 146 testFreezePeriodsFails(TOO_CLOSE, "01-01", "03-01", "04-30", "06-01"); 147 } 148 149 @Test 150 public void testValidateTotalLengthWithPreviousPeriods() throws Exception { 151 testPrevFreezePeriodSucceeds("2018-01-19", "2018-01-19", /* now */"2018-01-19", 152 "07-01", "07-31", "10-01", "11-30"); 153 testPrevFreezePeriodSucceeds("2018-01-01", "2018-01-19", /* now */"2018-01-19", 154 "01-01", "03-30"); 155 testPrevFreezePeriodSucceeds("2018-01-01", "2018-02-01", /* now */"2018-02-01", 156 "11-01", "12-31"); 157 158 testPrevFreezePeriodSucceeds("2017-11-01", "2018-01-02", /* now */"2018-01-02", 159 "01-01", "01-29"); 160 testPrevFreezePeriodFails(COMBINED_TOO_LONG, "2017-11-01", "2018-01-02", "2018-01-02", 161 "01-01", "01-30"); 162 testPrevFreezePeriodSucceeds("2017-11-01", "2018-01-02", /* now */"2018-01-01", 163 "01-02", "01-29"); 164 testPrevFreezePeriodFails(COMBINED_TOO_LONG, "2017-11-01", "2018-01-02", "2018-01-01", 165 "01-02", "01-30"); 166 167 testPrevFreezePeriodSucceeds("2017-11-01", "2017-12-01", /* now */"2017-12-01", 168 "11-15", "01-29"); 169 testPrevFreezePeriodFails(COMBINED_TOO_LONG, "2017-11-01", "2017-12-01", "2017-12-01", 170 "11-15", "01-30"); 171 172 testPrevFreezePeriodSucceeds("2017-11-01", "2018-01-01", /* now */"2018-01-01", 173 "11-15", "01-29"); 174 testPrevFreezePeriodFails(COMBINED_TOO_LONG, "2017-11-01", "2018-01-01", "2018-01-01", 175 "11-15", "01-30"); 176 177 testPrevFreezePeriodSucceeds("2018-03-01", "2018-03-31", /* now */"2018-03-31", 178 "04-01", "05-29"); 179 testPrevFreezePeriodFails(COMBINED_TOO_LONG, "2018-03-01", "2018-03-31", "2018-03-31", 180 "04-01", "05-30"); 181 182 // Leap year handing 183 testPrevFreezePeriodSucceeds("2017-12-01", "2018-01-02", /* now */"2018-01-02", 184 "01-01", "02-28"); 185 testPrevFreezePeriodSucceeds("2017-12-01", "2018-01-02", /* now */"2018-01-02", 186 "01-01", "02-29"); 187 testPrevFreezePeriodFails(COMBINED_TOO_LONG, "2017-12-01", "2018-01-02", "2018-01-02", 188 "01-01", "03-01"); 189 190 testPrevFreezePeriodSucceeds("2016-01-01", "2016-02-28", /* now */"2016-02-28", 191 "02-01", "03-31"); 192 testPrevFreezePeriodSucceeds("2016-01-01", "2016-02-28", /* now */"2016-02-29", 193 "02-01", "03-31"); 194 testPrevFreezePeriodFails(COMBINED_TOO_LONG, "2016-01-01", "2016-02-28", "2016-02-29", 195 "02-01", "04-01"); 196 197 } 198 199 @Test 200 public void testValidateSeparationWithPreviousPeriods() throws Exception { 201 testPrevFreezePeriodSucceeds("2018-01-01", "2018-01-02", /* now */"2018-03-04", 202 "01-01", "03-30"); 203 testPrevFreezePeriodSucceeds("2018-01-01", "2018-01-02", /* now */"2018-01-19", 204 "04-01", "06-29"); 205 testPrevFreezePeriodSucceeds("2017-01-01", "2017-03-30", /* now */"2018-12-01", 206 "01-01", "03-30"); 207 208 testPrevFreezePeriodSucceeds("2018-01-01", "2018-02-01", "2018-02-01", 209 "04-03", "06-01"); 210 testPrevFreezePeriodFails(COMBINED_TOO_CLOSE, "2018-01-01", "2018-02-01", "2018-02-01", 211 "04-02", "06-01"); 212 213 testPrevFreezePeriodSucceeds("2018-04-01", "2018-06-01", "2018-08-01", 214 "07-01", "08-30"); 215 testPrevFreezePeriodFails(COMBINED_TOO_CLOSE, "2018-04-01", "2018-06-01", "2018-07-30", 216 "07-01", "08-30"); 217 218 219 testPrevFreezePeriodSucceeds("2018-03-01", "2018-04-01", "2018-06-01", 220 "05-01", "07-01"); 221 testPrevFreezePeriodFails(COMBINED_TOO_CLOSE, "2018-03-01", "2018-04-01", "2018-05-31", 222 "05-01", "07-01"); 223 } 224 225 @Test 226 public void testDistanceWithoutLeapYear() { 227 assertEquals(364, FreezePeriod.distanceWithoutLeapYear( 228 LocalDate.of(2016, 12, 31), LocalDate.of(2016, 1, 1))); 229 assertEquals(365, FreezePeriod.distanceWithoutLeapYear( 230 LocalDate.of(2017, 1, 1), LocalDate.of(2016, 1, 1))); 231 assertEquals(365, FreezePeriod.distanceWithoutLeapYear( 232 LocalDate.of(2017, 2, 28), LocalDate.of(2016, 2, 29))); 233 assertEquals(-365, FreezePeriod.distanceWithoutLeapYear( 234 LocalDate.of(2016, 1, 1), LocalDate.of(2017, 1, 1))); 235 assertEquals(1, FreezePeriod.distanceWithoutLeapYear( 236 LocalDate.of(2016, 3, 1), LocalDate.of(2016, 2, 29))); 237 assertEquals(1, FreezePeriod.distanceWithoutLeapYear( 238 LocalDate.of(2016, 3, 1), LocalDate.of(2016, 2, 28))); 239 assertEquals(0, FreezePeriod.distanceWithoutLeapYear( 240 LocalDate.of(2016, 2, 29), LocalDate.of(2016, 2, 28))); 241 assertEquals(0, FreezePeriod.distanceWithoutLeapYear( 242 LocalDate.of(2016, 2, 28), LocalDate.of(2016, 2, 28))); 243 244 assertEquals(59, FreezePeriod.distanceWithoutLeapYear( 245 LocalDate.of(2016, 3, 1), LocalDate.of(2016, 1, 1))); 246 assertEquals(59, FreezePeriod.distanceWithoutLeapYear( 247 LocalDate.of(2017, 3, 1), LocalDate.of(2017, 1, 1))); 248 249 assertEquals(365 * 40, FreezePeriod.distanceWithoutLeapYear( 250 LocalDate.of(2040, 1, 1), LocalDate.of(2000, 1, 1))); 251 252 assertEquals(365 * 2, FreezePeriod.distanceWithoutLeapYear( 253 LocalDate.of(2019, 3, 1), LocalDate.of(2017, 3, 1))); 254 assertEquals(365 * 2, FreezePeriod.distanceWithoutLeapYear( 255 LocalDate.of(2018, 3, 1), LocalDate.of(2016, 3, 1))); 256 assertEquals(365 * 2, FreezePeriod.distanceWithoutLeapYear( 257 LocalDate.of(2017, 3, 1), LocalDate.of(2015, 3, 1))); 258 259 } 260 261 @Test 262 public void testInstallationOptionWithoutFreeze() { 263 // Also duplicated at com.google.android.gts.deviceowner.SystemUpdatePolicyTest 264 final long millis_2018_01_01 = toMillis(2018, 1, 1); 265 266 SystemUpdatePolicy p = SystemUpdatePolicy.createAutomaticInstallPolicy(); 267 assertInstallationOption(SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, Long.MAX_VALUE, 268 millis_2018_01_01, p); 269 270 p = SystemUpdatePolicy.createPostponeInstallPolicy(); 271 assertInstallationOption(SystemUpdatePolicy.TYPE_POSTPONE, Long.MAX_VALUE, 272 millis_2018_01_01, p); 273 274 p = SystemUpdatePolicy.createWindowedInstallPolicy(120, 180); // 2:00 - 3:00 275 // 00:00 is two hours before the next window 276 assertInstallationOption(SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.HOURS.toMillis(2), 277 millis_2018_01_01, p); 278 // 02:00 is within the current maintenance window, and one hour until the window ends 279 assertInstallationOption( 280 SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, TimeUnit.HOURS.toMillis(1), 281 millis_2018_01_01 + TimeUnit.HOURS.toMillis(2), p); 282 // 04:00 is 22 hours from the window next day 283 assertInstallationOption(SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.HOURS.toMillis(22), 284 millis_2018_01_01 + TimeUnit.HOURS.toMillis(4), p); 285 286 p = SystemUpdatePolicy.createWindowedInstallPolicy(22 * 60, 2 * 60); // 22:00 - 2:00 287 // 21:00 is one hour from the next window 288 assertInstallationOption(SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.HOURS.toMillis(1), 289 millis_2018_01_01 + TimeUnit.HOURS.toMillis(21), p); 290 // 00:00 is two hours from the end of current window 291 assertInstallationOption( 292 SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, TimeUnit.HOURS.toMillis(2), 293 millis_2018_01_01, p); 294 // 03:00 is 22 hours from the window today 295 assertInstallationOption(SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.HOURS.toMillis(19), 296 millis_2018_01_01 + TimeUnit.HOURS.toMillis(3), p); 297 } 298 299 @Test 300 public void testInstallationOptionWithFreeze() throws Exception { 301 final long millis_2016_02_29 = toMillis(2016, 2, 29); 302 final long millis_2017_01_31 = toMillis(2017, 1, 31); 303 final long millis_2017_02_28 = toMillis(2017, 2, 28); 304 final long millis_2018_01_01 = toMillis(2018, 1, 1); 305 final long millis_2018_08_01 = toMillis(2018, 8, 1); 306 307 SystemUpdatePolicy p = SystemUpdatePolicy.createAutomaticInstallPolicy(); 308 setFreezePeriods(p, "01-01", "01-31"); 309 // Inside a freeze period 310 assertInstallationOption( 311 SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.DAYS.toMillis(31), 312 millis_2018_01_01, p); 313 // Device is outside freeze between 2/28 to 12/31 inclusive 314 assertInstallationOption( 315 SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, TimeUnit.DAYS.toMillis(307), 316 millis_2017_02_28, p); 317 318 // Freeze period contains leap day Feb 29 319 p = SystemUpdatePolicy.createPostponeInstallPolicy(); 320 setFreezePeriods(p, "02-01", "03-05"); 321 // Freezed until 3/5, note 2016 is a leap year 322 assertInstallationOption(SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.DAYS.toMillis(6), 323 millis_2016_02_29, p); 324 // Freezed until 3/5, note 2017 is not a leap year 325 assertInstallationOption(SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.DAYS.toMillis(6), 326 millis_2017_02_28, p); 327 // Next freeze is 2018/2/1 328 assertInstallationOption(SystemUpdatePolicy.TYPE_POSTPONE, TimeUnit.DAYS.toMillis(31), 329 millis_2018_01_01, p); 330 331 // Freeze period start on or right after leap day 332 p = SystemUpdatePolicy.createAutomaticInstallPolicy(); 333 setFreezePeriods(p, "03-01", "03-31"); 334 assertInstallationOption( 335 SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, TimeUnit.DAYS.toMillis(1), 336 millis_2016_02_29, p); 337 assertInstallationOption( 338 SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, TimeUnit.DAYS.toMillis(1), 339 millis_2017_02_28, p); 340 setFreezePeriods(p, "02-28", "03-05"); 341 assertInstallationOption( 342 SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.DAYS.toMillis(6), 343 millis_2016_02_29, p); 344 assertInstallationOption( 345 SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.DAYS.toMillis(6), 346 millis_2017_02_28, p); 347 348 // Freeze period end on or right after leap day 349 p = SystemUpdatePolicy.createAutomaticInstallPolicy(); 350 setFreezePeriods(p, "02-01", "02-28"); 351 assertInstallationOption( 352 SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.DAYS.toMillis(1), 353 millis_2016_02_29, p); 354 assertInstallationOption( 355 SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.DAYS.toMillis(1), 356 millis_2017_02_28, p); 357 p = SystemUpdatePolicy.createAutomaticInstallPolicy(); 358 setFreezePeriods(p, "02-01", "03-01"); 359 assertInstallationOption( 360 SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.DAYS.toMillis(2), 361 millis_2016_02_29, p); 362 assertInstallationOption( 363 SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.DAYS.toMillis(2), 364 millis_2017_02_28, p); 365 366 // Freeze period with maintenance window 367 p = SystemUpdatePolicy.createWindowedInstallPolicy(23 * 60, 1 * 60); // 23:00 - 1:00 368 setFreezePeriods(p, "02-01", "02-28"); 369 // 00:00 is within the current window, outside freeze period 370 assertInstallationOption( 371 SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, TimeUnit.HOURS.toMillis(1), 372 millis_2018_01_01, p); 373 // Last day of feeze period, which ends in 22 hours 374 assertInstallationOption( 375 SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.HOURS.toMillis(22), 376 millis_2017_02_28 + TimeUnit.HOURS.toMillis(2), p); 377 // Last day before the next freeze, and within window 378 assertInstallationOption( 379 SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, TimeUnit.HOURS.toMillis(1), 380 millis_2017_01_31, p); 381 // Last day before the next freeze, and there is still a partial maintenance window before 382 // the freeze. 383 assertInstallationOption( 384 SystemUpdatePolicy.TYPE_PAUSE, TimeUnit.HOURS.toMillis(19), 385 millis_2017_01_31 + TimeUnit.HOURS.toMillis(4), p); 386 387 // Two freeze periods 388 p = SystemUpdatePolicy.createAutomaticInstallPolicy(); 389 setFreezePeriods(p, "05-01", "06-01", "10-15", "01-10"); 390 // automatic policy for July, August, September and October until 15th 391 assertInstallationOption( 392 SystemUpdatePolicy.TYPE_INSTALL_AUTOMATIC, TimeUnit.DAYS.toMillis(31 + 30 + 14), 393 millis_2018_08_01, p); 394 } 395 396 private void assertInstallationOption(int expectedType, long expectedTime, long now, 397 SystemUpdatePolicy p) { 398 assertEquals(expectedType, p.getInstallationOptionAt(now).getType()); 399 assertEquals(expectedTime, p.getInstallationOptionAt(now).getEffectiveTime()); 400 } 401 402 private void testFreezePeriodsSucceeds(String...dates) throws Exception { 403 SystemUpdatePolicy p = SystemUpdatePolicy.createPostponeInstallPolicy(); 404 setFreezePeriods(p, dates); 405 } 406 407 private void testFreezePeriodsFails(int expectedError, String... dates) throws Exception { 408 SystemUpdatePolicy p = SystemUpdatePolicy.createPostponeInstallPolicy(); 409 try { 410 setFreezePeriods(p, dates); 411 fail("Invalid periods (" + expectedError + ") not flagged: " + String.join(" ", dates)); 412 } catch (SystemUpdatePolicy.ValidationFailedException e) { 413 assertTrue("Exception not expected: " + e.getMessage(), 414 e.getErrorCode() == expectedError); 415 } 416 } 417 418 private void testPrevFreezePeriodSucceeds(String prevStart, String prevEnd, String now, 419 String... dates) throws Exception { 420 createPrevFreezePeriod(prevStart, prevEnd, now, dates); 421 } 422 423 private void testPrevFreezePeriodFails(int expectedError, String prevStart, String prevEnd, 424 String now, String... dates) throws Exception { 425 try { 426 createPrevFreezePeriod(prevStart, prevEnd, now, dates); 427 fail("Invalid period (" + expectedError + ") not flagged: " + String.join(" ", dates)); 428 } catch (SystemUpdatePolicy.ValidationFailedException e) { 429 assertTrue("Exception not expected: " + e.getMessage(), 430 e.getErrorCode() == expectedError); 431 } 432 } 433 434 private void createPrevFreezePeriod(String prevStart, String prevEnd, String now, 435 String... dates) throws Exception { 436 SystemUpdatePolicy p = SystemUpdatePolicy.createPostponeInstallPolicy(); 437 setFreezePeriods(p, dates); 438 p.validateAgainstPreviousFreezePeriod(parseLocalDate(prevStart), 439 parseLocalDate(prevEnd), parseLocalDate(now)); 440 } 441 442 // "MM-DD" format for date 443 private void setFreezePeriods(SystemUpdatePolicy policy, String... dates) throws Exception { 444 List<FreezePeriod> periods = new ArrayList<>(); 445 MonthDay lastDate = null; 446 for (String date : dates) { 447 MonthDay currentDate = parseMonthDay(date); 448 if (lastDate != null) { 449 periods.add(new FreezePeriod(lastDate, currentDate)); 450 lastDate = null; 451 } else { 452 lastDate = currentDate; 453 } 454 } 455 policy.setFreezePeriods(periods); 456 testSerialization(policy, periods); 457 } 458 459 private void testSerialization(SystemUpdatePolicy policy, 460 List<FreezePeriod> expectedPeriods) throws Exception { 461 // Test parcel / unparcel 462 Parcel parcel = Parcel.obtain(); 463 policy.writeToParcel(parcel, 0); 464 parcel.setDataPosition(0); 465 SystemUpdatePolicy q = SystemUpdatePolicy.CREATOR.createFromParcel(parcel); 466 checkFreezePeriods(q, expectedPeriods); 467 parcel.recycle(); 468 469 // Test XML serialization 470 ByteArrayOutputStream outStream = new ByteArrayOutputStream(); 471 final XmlSerializer outXml = new FastXmlSerializer(); 472 outXml.setOutput(outStream, StandardCharsets.UTF_8.name()); 473 outXml.startDocument(null, true); 474 outXml.startTag(null, "ota"); 475 policy.saveToXml(outXml); 476 outXml.endTag(null, "ota"); 477 outXml.endDocument(); 478 outXml.flush(); 479 480 ByteArrayInputStream inStream = new ByteArrayInputStream(outStream.toByteArray()); 481 XmlPullParser parser = Xml.newPullParser(); 482 parser.setInput(new InputStreamReader(inStream)); 483 assertEquals(XmlPullParser.START_TAG, parser.next()); 484 checkFreezePeriods(SystemUpdatePolicy.restoreFromXml(parser), expectedPeriods); 485 } 486 487 private void checkFreezePeriods(SystemUpdatePolicy policy, 488 List<FreezePeriod> expectedPeriods) { 489 int i = 0; 490 for (FreezePeriod period : policy.getFreezePeriods()) { 491 assertEquals(expectedPeriods.get(i).getStart(), period.getStart()); 492 assertEquals(expectedPeriods.get(i).getEnd(), period.getEnd()); 493 i++; 494 } 495 } 496 497 // MonthDay is of format MM-dd 498 private MonthDay parseMonthDay(String date) { 499 return MonthDay.of(Integer.parseInt(date.substring(0, 2)), 500 Integer.parseInt(date.substring(3, 5))); 501 } 502 503 // LocalDat is of format YYYY-MM-dd 504 private LocalDate parseLocalDate(String date) { 505 return parseMonthDay(date.substring(5)).atYear(Integer.parseInt(date.substring(0, 4))); 506 } 507 508 509 private long toMillis(int year, int month, int day) { 510 return LocalDateTime.of(year, month, day, 0, 0, 0).atZone(ZoneId.systemDefault()) 511 .toInstant().toEpochMilli(); 512 } 513} 514