blob: 0ea8d4f5e3537a42aa0dbe7c67e1af1ad2c0eee8 [file] [log] [blame]
Neil Fuller68f66662017-03-16 18:32:21 +00001/*
2 * Copyright (C) 2017 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 */
16
17package com.android.server.timezone;
18
19import org.hamcrest.BaseMatcher;
20import org.hamcrest.Description;
21import org.hamcrest.Matcher;
22import org.junit.After;
23import org.junit.Before;
24import org.junit.Test;
25
26import android.app.timezone.RulesUpdaterContract;
27import android.content.Context;
28import android.content.Intent;
29import android.provider.TimeZoneRulesDataContract;
30import android.support.test.InstrumentationRegistry;
31import android.support.test.filters.SmallTest;
32
Neil Fuller87b11282017-06-23 16:43:45 +010033import java.io.PrintWriter;
34import java.io.StringWriter;
35
Neil Fuller68f66662017-03-16 18:32:21 +000036import static org.junit.Assert.assertEquals;
37import static org.junit.Assert.assertFalse;
38import static org.junit.Assert.assertNotNull;
39import static org.junit.Assert.assertNull;
40import static org.junit.Assert.assertTrue;
41import static org.junit.Assert.fail;
42import static org.mockito.Mockito.eq;
43import static org.mockito.Mockito.mock;
44import static org.mockito.Mockito.when;
45import static org.mockito.hamcrest.MockitoHamcrest.argThat;
46
47/**
48 * White box interaction / unit testing of the {@link PackageTracker}.
49 */
50@SmallTest
51public class PackageTrackerTest {
52 private static final String UPDATE_APP_PACKAGE_NAME = "updateAppPackageName";
53 private static final String DATA_APP_PACKAGE_NAME = "dataAppPackageName";
54 private static final PackageVersions INITIAL_APP_PACKAGE_VERSIONS =
55 new PackageVersions(2 /* updateAppVersion */, 2 /* dataAppVersion */);
56
57 private ConfigHelper mMockConfigHelper;
58 private PackageManagerHelper mMockPackageManagerHelper;
59
60 private FakeClockHelper mFakeClock;
61 private FakeIntentHelper mFakeIntentHelper;
62 private PackageStatusStorage mPackageStatusStorage;
63 private PackageTracker mPackageTracker;
64
65 @Before
66 public void setUp() throws Exception {
67 Context context = InstrumentationRegistry.getContext();
68
69 mFakeClock = new FakeClockHelper();
70
71 // Read-only interfaces so are easy to mock.
72 mMockConfigHelper = mock(ConfigHelper.class);
73 mMockPackageManagerHelper = mock(PackageManagerHelper.class);
74
75 // Using the instrumentation context means the database is created in a test app-specific
76 // directory. We can use the real thing for this test.
Neil Fuller5f6750f2017-05-17 04:43:12 +010077 mPackageStatusStorage = new PackageStatusStorage(context.getFilesDir());
Neil Fuller68f66662017-03-16 18:32:21 +000078
79 // For other interactions with the Android framework we create a fake object.
80 mFakeIntentHelper = new FakeIntentHelper();
81
82 // Create the PackageTracker to use in tests.
83 mPackageTracker = new PackageTracker(
84 mFakeClock,
85 mMockConfigHelper,
86 mMockPackageManagerHelper,
87 mPackageStatusStorage,
88 mFakeIntentHelper);
89 }
90
91 @After
92 public void tearDown() throws Exception {
93 if (mPackageStatusStorage != null) {
Neil Fuller5f6750f2017-05-17 04:43:12 +010094 mPackageStatusStorage.deleteFileForTests();
Neil Fuller68f66662017-03-16 18:32:21 +000095 }
96 }
97
98 @Test
99 public void trackingDisabled_intentHelperNotUsed() {
100 // Set up device configuration.
101 configureTrackingDisabled();
102
103 // Initialize the tracker.
104 mPackageTracker.start();
105
106 // Check the IntentHelper was not initialized.
107 mFakeIntentHelper.assertNotInitialized();
108
109 // Check reliability triggering state.
Neil Fullercd1a1092017-09-13 21:59:59 +0100110 mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +0000111 }
112
113 @Test
114 public void trackingDisabled_triggerUpdateIfNeededNotAllowed() {
115 // Set up device configuration.
116 configureTrackingDisabled();
117
118 // Initialize the tracker.
119 mPackageTracker.start();
120
121 // Check reliability triggering state.
Neil Fullercd1a1092017-09-13 21:59:59 +0100122 mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +0000123
124 try {
125 // This call should also not be allowed and will throw an exception if tracking is
126 // disabled.
127 mPackageTracker.triggerUpdateIfNeeded(true);
128 fail();
129 } catch (IllegalStateException expected) {}
130
131 // Check reliability triggering state.
Neil Fullercd1a1092017-09-13 21:59:59 +0100132 mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +0000133 }
134
135 @Test
136 public void trackingDisabled_unsolicitedResultsIgnored_withoutToken() {
137 // Set up device configuration.
138 configureTrackingDisabled();
139
140 // Initialize the tracker.
141 mPackageTracker.start();
142
143 // Check reliability triggering state.
Neil Fullercd1a1092017-09-13 21:59:59 +0100144 mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +0000145
146 // Receiving a check result when tracking is disabled should cause the storage to be
147 // reset.
148 mPackageTracker.recordCheckResult(null /* checkToken */, true /* success */);
149
150 // Check reliability triggering state.
Neil Fullercd1a1092017-09-13 21:59:59 +0100151 mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +0000152
153 // Assert the storage was reset.
154 checkPackageStorageStatusIsInitialOrReset();
155 }
156
157 @Test
158 public void trackingDisabled_unsolicitedResultsIgnored_withToken() {
159 // Set up device configuration.
160 configureTrackingDisabled();
161
162 // Set the storage into an arbitrary state so we can detect a reset.
163 mPackageStatusStorage.generateCheckToken(INITIAL_APP_PACKAGE_VERSIONS);
164
165 // Initialize the tracker.
166 mPackageTracker.start();
167
168 // Check reliability triggering state.
Neil Fullercd1a1092017-09-13 21:59:59 +0100169 mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +0000170
171 // Receiving a check result when tracking is disabled should cause the storage to be reset.
172 mPackageTracker.recordCheckResult(createArbitraryCheckToken(), true /* success */);
173
174 // Check reliability triggering state.
Neil Fullercd1a1092017-09-13 21:59:59 +0100175 mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +0000176
177 // Assert the storage was reset.
178 checkPackageStorageStatusIsInitialOrReset();
179 }
180
181 @Test
182 public void trackingEnabled_updateAppConfigMissing() throws Exception {
183 // Set up device configuration.
184 configureTrackingEnabled();
185 configureReliabilityConfigSettingsOk();
186 configureUpdateAppPackageNameMissing();
187 configureDataAppPackageOk(DATA_APP_PACKAGE_NAME);
188
189 try {
190 // Initialize the tracker.
191 mPackageTracker.start();
192 fail();
193 } catch (RuntimeException expected) {}
194
195 mFakeIntentHelper.assertNotInitialized();
196
197 // Check reliability triggering state.
Neil Fullercd1a1092017-09-13 21:59:59 +0100198 mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +0000199 }
200
Neil Fuller29ff71b2017-07-18 10:30:53 +0100201 @Test
202 public void trackingEnabled_updateAppNotPrivileged() throws Exception {
203 // Set up device configuration.
204 configureTrackingEnabled();
205 configureReliabilityConfigSettingsOk();
206 configureUpdateAppPackageNotPrivileged(UPDATE_APP_PACKAGE_NAME);
207 configureDataAppPackageOk(DATA_APP_PACKAGE_NAME);
208
209 try {
210 // Initialize the tracker.
211 mPackageTracker.start();
212 fail();
213 } catch (RuntimeException expected) {}
214
215 mFakeIntentHelper.assertNotInitialized();
216
217 // Check reliability triggering state.
Neil Fullercd1a1092017-09-13 21:59:59 +0100218 mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
Neil Fuller29ff71b2017-07-18 10:30:53 +0100219 }
Neil Fuller68f66662017-03-16 18:32:21 +0000220
221 @Test
222 public void trackingEnabled_dataAppConfigMissing() throws Exception {
223 // Set up device configuration.
224 configureTrackingEnabled();
225 configureReliabilityConfigSettingsOk();
226 configureUpdateAppPackageOk(UPDATE_APP_PACKAGE_NAME);
227 configureDataAppPackageNameMissing();
228
229 try {
230 // Initialize the tracker.
231 mPackageTracker.start();
232 fail();
233 } catch (RuntimeException expected) {}
234
235 mFakeIntentHelper.assertNotInitialized();
236
237 // Check reliability triggering state.
Neil Fullercd1a1092017-09-13 21:59:59 +0100238 mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +0000239 }
240
Neil Fuller29ff71b2017-07-18 10:30:53 +0100241 @Test
242 public void trackingEnabled_dataAppNotPrivileged() throws Exception {
243 // Set up device configuration.
244 configureTrackingEnabled();
245 configureReliabilityConfigSettingsOk();
246 configureUpdateAppPackageOk(UPDATE_APP_PACKAGE_NAME);
247 configureDataAppPackageNotPrivileged(DATA_APP_PACKAGE_NAME);
248
249 try {
250 // Initialize the tracker.
251 mPackageTracker.start();
252 fail();
253 } catch (RuntimeException expected) {}
254
255 mFakeIntentHelper.assertNotInitialized();
256
257 // Check reliability triggering state.
Neil Fullercd1a1092017-09-13 21:59:59 +0100258 mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
Neil Fuller29ff71b2017-07-18 10:30:53 +0100259 }
Neil Fuller68f66662017-03-16 18:32:21 +0000260
261 @Test
262 public void trackingEnabled_packageUpdate_badUpdateAppManifestEntry() throws Exception {
263 // Set up device configuration.
264 configureTrackingEnabled();
265 configureReliabilityConfigSettingsOk();
266 configureValidApplications();
267
268 // Initialize the tracker.
269 mPackageTracker.start();
270
271 // Check the intent helper is properly configured.
272 checkIntentHelperInitializedAndReliabilityTrackingEnabled();
273
274 // Check the initial storage state.
275 checkPackageStorageStatusIsInitialOrReset();
276
277 // Configure a bad manifest for the update app. Should effectively turn off tracking.
278 PackageVersions packageVersions =
279 new PackageVersions(2 /* updateAppPackageVersion */, 3 /* dataAppPackageVersion */);
280 configureUpdateAppManifestBad(UPDATE_APP_PACKAGE_NAME);
281 configureDataAppManifestOk(DATA_APP_PACKAGE_NAME);
282 configureUpdateAppPackageVersion(
283 UPDATE_APP_PACKAGE_NAME, packageVersions.mUpdateAppVersion);
284 configureDataAppPackageVersion(DATA_APP_PACKAGE_NAME, packageVersions.mDataAppVersion);
285 // Simulate a tracked package being updated.
286 mFakeIntentHelper.simulatePackageUpdatedEvent();
287
288 // Assert the PackageTracker did not attempt to trigger an update.
289 mFakeIntentHelper.assertUpdateNotTriggered();
290
291 // Check reliability triggering state.
Neil Fullercd1a1092017-09-13 21:59:59 +0100292 mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +0000293
294 // Assert the storage was not touched.
295 checkPackageStorageStatusIsInitialOrReset();
296 }
297
298 @Test
299 public void trackingEnabled_packageUpdate_badDataAppManifestEntry() throws Exception {
300 // Set up device configuration.
301 configureTrackingEnabled();
302 configureReliabilityConfigSettingsOk();
303 configureValidApplications();
304
305 // Initialize the tracker.
306 mPackageTracker.start();
307
308 // Check the intent helper is properly configured.
309 checkIntentHelperInitializedAndReliabilityTrackingEnabled();
310
311 // Check the initial storage state.
312 checkPackageStorageStatusIsInitialOrReset();
313
314 // Configure a bad manifest for the data app. Should effectively turn off tracking.
315 PackageVersions packageVersions =
316 new PackageVersions(2 /* updateAppPackageVersion */, 3 /* dataAppPackageVersion */);
317 configureUpdateAppManifestOk(UPDATE_APP_PACKAGE_NAME);
318 configureDataAppManifestBad(DATA_APP_PACKAGE_NAME);
319 configureUpdateAppPackageVersion(
320 UPDATE_APP_PACKAGE_NAME, packageVersions.mUpdateAppVersion);
321 configureDataAppPackageVersion(DATA_APP_PACKAGE_NAME, packageVersions.mDataAppVersion);
322 mFakeIntentHelper.simulatePackageUpdatedEvent();
323
324 // Assert the PackageTracker did not attempt to trigger an update.
325 mFakeIntentHelper.assertUpdateNotTriggered();
326
327 // Check reliability triggering state.
Neil Fullercd1a1092017-09-13 21:59:59 +0100328 mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +0000329
330 // Assert the storage was not touched.
331 checkPackageStorageStatusIsInitialOrReset();
332 }
333
334 @Test
335 public void trackingEnabled_packageUpdate_responseWithToken_success() throws Exception {
336 trackingEnabled_packageUpdate_responseWithToken(true);
337 }
338
339 @Test
340 public void trackingEnabled_packageUpdate_responseWithToken_failed() throws Exception {
341 trackingEnabled_packageUpdate_responseWithToken(false);
342 }
343
344 private void trackingEnabled_packageUpdate_responseWithToken(boolean success) throws Exception {
345 // Set up device configuration.
346 configureTrackingEnabled();
347 configureReliabilityConfigSettingsOk();
348 configureValidApplications();
349
350 // Initialize the tracker.
351 mPackageTracker.start();
352
353 // Check the intent helper is properly configured.
354 checkIntentHelperInitializedAndReliabilityTrackingEnabled();
355
356 // Check the initial storage state.
357 checkPackageStorageStatusIsInitialOrReset();
358
359 // Simulate a tracked package being updated.
360 PackageVersions packageVersions =
361 new PackageVersions(2 /* updateAppPackageVersion */, 3 /* dataAppPackageVersion */);
362 simulatePackageInstallation(packageVersions);
363
364 // Confirm an update was triggered.
365 checkUpdateCheckTriggered(packageVersions);
366
367 // Get the token that was passed to the intent helper, and pass it back.
368 CheckToken token = mFakeIntentHelper.captureAndResetLastToken();
369 mPackageTracker.recordCheckResult(token, success);
370
371 // Check storage and reliability triggering state.
372 if (success) {
373 checkUpdateCheckSuccessful(packageVersions);
374 } else {
375 checkUpdateCheckFailed(packageVersions);
376 }
377 }
378
379 @Test
380 public void trackingEnabled_packageUpdate_responseWithoutTokenCausesStorageReset_success()
381 throws Exception {
382 trackingEnabled_packageUpdate_responseWithoutTokenCausesStorageReset(true);
383 }
384
385 @Test
386 public void trackingEnabled_packageUpdate_responseWithoutTokenCausesStorageReset_failed()
387 throws Exception {
388 trackingEnabled_packageUpdate_responseWithoutTokenCausesStorageReset(false);
389 }
390
391 private void trackingEnabled_packageUpdate_responseWithoutTokenCausesStorageReset(
392 boolean success) throws Exception {
393 // Set up device configuration.
394 configureTrackingEnabled();
395 configureReliabilityConfigSettingsOk();
396 configureValidApplications();
397
398 // Initialize the tracker.
399 mPackageTracker.start();
400
401 // Check the intent helper is properly configured.
402 checkIntentHelperInitializedAndReliabilityTrackingEnabled();
403
404 // Check the initial storage state.
405 checkPackageStorageStatusIsInitialOrReset();
406
407 // Set up installed app versions / manifests.
408 PackageVersions packageVersions =
409 new PackageVersions(2 /* updateAppPackageVersion */, 3 /* dataAppPackageVersion */);
410 simulatePackageInstallation(packageVersions);
411
412 // Confirm an update was triggered.
413 checkUpdateCheckTriggered(packageVersions);
414
415 // Ignore the token that was given to the intent helper, just pass null.
416 mPackageTracker.recordCheckResult(null /* checkToken */, success);
417
418 // Check reliability triggering state.
Neil Fullercd1a1092017-09-13 21:59:59 +0100419 mFakeIntentHelper.assertReliabilityTriggerScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +0000420
421 // Assert the storage was reset.
422 checkPackageStorageStatusIsInitialOrReset();
423 }
424
425 /**
426 * Two package updates triggered for the same package versions. The second is triggered while
427 * the first is still happening.
428 */
429 @Test
430 public void trackingEnabled_packageUpdate_twoChecksNoPackageChange_secondWhileFirstInProgress()
431 throws Exception {
432 // Set up device configuration.
433 configureTrackingEnabled();
434 configureReliabilityConfigSettingsOk();
435 configureValidApplications();
436
437 // Initialize the tracker.
438 mPackageTracker.start();
439
440 // Check the intent helper is properly configured.
441 checkIntentHelperInitializedAndReliabilityTrackingEnabled();
442
443 // Check the initial storage state.
444 checkPackageStorageStatusIsInitialOrReset();
445
446 // Simulate package installation.
447 PackageVersions packageVersions =
448 new PackageVersions(2 /* updateAppPackageVersion */, 3 /* dataAppPackageVersion */);
449 simulatePackageInstallation(packageVersions);
450
451 // Confirm an update was triggered.
452 checkUpdateCheckTriggered(packageVersions);
453
454 // Get the first token.
455 CheckToken token1 = mFakeIntentHelper.captureAndResetLastToken();
456 assertEquals(packageVersions, token1.mPackageVersions);
457
458 // Now attempt to generate another check while the first is in progress and without having
459 // updated the package versions. The PackageTracker should trigger again for safety.
460 simulatePackageInstallation(packageVersions);
461
462 // Confirm an update was triggered.
463 checkUpdateCheckTriggered(packageVersions);
464
465 CheckToken token2 = mFakeIntentHelper.captureAndResetLastToken();
466 assertEquals(packageVersions, token2.mPackageVersions);
467 assertEquals(token1.mPackageVersions, token2.mPackageVersions);
468 assertTrue(token1.mOptimisticLockId != token2.mOptimisticLockId);
469 }
470
471 /**
472 * Two package updates triggered for the same package versions. The second happens after
473 * the first has succeeded.
474 */
475 @Test
476 public void trackingEnabled_packageUpdate_twoChecksNoPackageChange_sequential()
477 throws Exception {
478 // Set up device configuration.
479 configureTrackingEnabled();
480 configureReliabilityConfigSettingsOk();
481 configureValidApplications();
482
483 // Initialize the tracker.
484 mPackageTracker.start();
485
486 // Check the intent helper is properly configured.
487 checkIntentHelperInitializedAndReliabilityTrackingEnabled();
488
489 // Check the initial storage state.
490 checkPackageStorageStatusIsInitialOrReset();
491
492 // Simulate package installation.
493 PackageVersions packageVersions =
494 new PackageVersions(2 /* updateAppPackageVersion */, 3 /* dataAppPackageVersion */);
495 simulatePackageInstallation(packageVersions);
496
497 // Confirm an update was triggered.
498 checkUpdateCheckTriggered(packageVersions);
499
500 // Get the token.
501 CheckToken token = mFakeIntentHelper.captureAndResetLastToken();
502 assertEquals(packageVersions, token.mPackageVersions);
503
504 // Simulate a successful check.
505 mPackageTracker.recordCheckResult(token, true /* success */);
506
507 // Check storage and reliability triggering state.
508 checkUpdateCheckSuccessful(packageVersions);
509
510 // Now attempt to generate another check, but without having updated the package. The
511 // PackageTracker should be smart enough to recognize there's nothing to do here.
512 simulatePackageInstallation(packageVersions);
513
514 // Assert the PackageTracker did not attempt to trigger an update.
515 mFakeIntentHelper.assertUpdateNotTriggered();
516
517 // Check storage and reliability triggering state.
518 checkUpdateCheckSuccessful(packageVersions);
519 }
520
521 /**
522 * Two package updates triggered for the same package versions. The second is triggered after
523 * the first has failed.
524 */
525 @Test
526 public void trackingEnabled_packageUpdate_afterFailure() throws Exception {
527 // Set up device configuration.
528 configureTrackingEnabled();
529 configureReliabilityConfigSettingsOk();
530 configureValidApplications();
531
532 // Initialize the tracker.
533 mPackageTracker.start();
534
535 // Check the intent helper is properly configured.
536 checkIntentHelperInitializedAndReliabilityTrackingEnabled();
537
538 // Check the initial storage state.
539 checkPackageStorageStatusIsInitialOrReset();
540
541 // Simulate package installation.
542 PackageVersions packageVersions =
543 new PackageVersions(2 /* updateAppPackageVersion */, 3 /* dataAppPackageVersion */);
544 simulatePackageInstallation(packageVersions);
545
546 // Confirm an update was triggered.
547 checkUpdateCheckTriggered(packageVersions);
548
549 // Get the first token.
550 CheckToken token1 = mFakeIntentHelper.captureAndResetLastToken();
551 assertEquals(packageVersions, token1.mPackageVersions);
552
553 // Simulate an *unsuccessful* check.
554 mPackageTracker.recordCheckResult(token1, false /* success */);
555
556 // Check storage and reliability triggering state.
557 checkUpdateCheckFailed(packageVersions);
558
559 // Now generate another check, but without having updated the package. The
560 // PackageTracker should recognize the last check failed and trigger again.
561 simulatePackageInstallation(packageVersions);
562
563 // Confirm an update was triggered.
564 checkUpdateCheckTriggered(packageVersions);
565
566 // Get the second token.
567 CheckToken token2 = mFakeIntentHelper.captureAndResetLastToken();
568
569 // Assert some things about the tokens.
570 assertEquals(packageVersions, token2.mPackageVersions);
571 assertTrue(token1.mOptimisticLockId != token2.mOptimisticLockId);
572
573 // For completeness, now simulate this check was successful.
574 mPackageTracker.recordCheckResult(token2, true /* success */);
575
576 // Check storage and reliability triggering state.
577 checkUpdateCheckSuccessful(packageVersions);
578 }
579
580 /**
581 * Two package updates triggered for different package versions. The second is triggered while
582 * the first is still happening.
583 */
584 @Test
585 public void trackingEnabled_packageUpdate_twoChecksWithPackageChange_firstCheckInProcess()
586 throws Exception {
587 // Set up device configuration.
588 configureTrackingEnabled();
589 configureReliabilityConfigSettingsOk();
590 configureValidApplications();
591
592 // Initialize the package tracker.
593 mPackageTracker.start();
594
595 // Check the intent helper is properly configured.
596 checkIntentHelperInitializedAndReliabilityTrackingEnabled();
597
598 // Check the initial storage state.
599 checkPackageStorageStatusIsInitialOrReset();
600
601 // Simulate package installation.
602 PackageVersions packageVersions1 =
603 new PackageVersions(2 /* updateAppPackageVersion */, 3 /* dataAppPackageVersion */);
604 simulatePackageInstallation(packageVersions1);
605
606 // Confirm an update was triggered.
607 checkUpdateCheckTriggered(packageVersions1);
608
609 // Get the first token.
610 CheckToken token1 = mFakeIntentHelper.captureAndResetLastToken();
611 assertEquals(packageVersions1, token1.mPackageVersions);
612
613 // Simulate a tracked package being updated a second time (before the response for the
614 // first has been received).
615 PackageVersions packageVersions2 =
616 new PackageVersions(3 /* updateAppPackageVersion */, 4 /* dataAppPackageVersion */);
617 simulatePackageInstallation(packageVersions2);
618
619 // Confirm an update was triggered.
620 checkUpdateCheckTriggered(packageVersions2);
621
622 // Get the second token.
623 CheckToken token2 = mFakeIntentHelper.captureAndResetLastToken();
624 assertEquals(packageVersions2, token2.mPackageVersions);
625
626 // token1 should be invalid because the token2 was generated.
627 mPackageTracker.recordCheckResult(token1, true /* success */);
628
629 // Reliability triggering should still be enabled.
Neil Fullercd1a1092017-09-13 21:59:59 +0100630 mFakeIntentHelper.assertReliabilityTriggerScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +0000631
632 // Check the expected storage state.
633 checkPackageStorageStatus(PackageStatus.CHECK_STARTED, packageVersions2);
634
635 // token2 should still be accepted.
636 mPackageTracker.recordCheckResult(token2, true /* success */);
637
638 // Check storage and reliability triggering state.
639 checkUpdateCheckSuccessful(packageVersions2);
640 }
641
642 /**
643 * Two package updates triggered for different package versions. The second is triggered after
644 * the first has completed successfully.
645 */
646 @Test
647 public void trackingEnabled_packageUpdate_twoChecksWithPackageChange_sequential()
648 throws Exception {
649 // Set up device configuration.
650 configureTrackingEnabled();
651 configureReliabilityConfigSettingsOk();
652 configureValidApplications();
653
654 // Initialize the package tracker.
655 mPackageTracker.start();
656
657 // Check the intent helper is properly configured.
658 checkIntentHelperInitializedAndReliabilityTrackingEnabled();
659
660 // Check the initial storage state.
661 checkPackageStorageStatusIsInitialOrReset();
662
663 // Simulate package installation.
664 PackageVersions packageVersions1 =
665 new PackageVersions(2 /* updateAppPackageVersion */, 3 /* dataAppPackageVersion */);
666 simulatePackageInstallation(packageVersions1);
667
668 // Confirm an update was triggered.
669 checkUpdateCheckTriggered(packageVersions1);
670
671 // Get the first token.
672 CheckToken token1 = mFakeIntentHelper.captureAndResetLastToken();
673 assertEquals(packageVersions1, token1.mPackageVersions);
674
675 // token1 should be accepted.
676 mPackageTracker.recordCheckResult(token1, true /* success */);
677
678 // Check storage and reliability triggering state.
679 checkUpdateCheckSuccessful(packageVersions1);
680
681 // Simulate a tracked package being updated a second time.
682 PackageVersions packageVersions2 =
683 new PackageVersions(3 /* updateAppPackageVersion */, 4 /* dataAppPackageVersion */);
684 simulatePackageInstallation(packageVersions2);
685
686 // Confirm an update was triggered.
687 checkUpdateCheckTriggered(packageVersions2);
688
689 // Get the second token.
690 CheckToken token2 = mFakeIntentHelper.captureAndResetLastToken();
691 assertEquals(packageVersions2, token2.mPackageVersions);
692
693 // token2 should still be accepted.
694 mPackageTracker.recordCheckResult(token2, true /* success */);
695
696 // Check storage and reliability triggering state.
697 checkUpdateCheckSuccessful(packageVersions2);
698 }
699
700 /**
701 * Replaying the same token twice.
702 */
703 @Test
704 public void trackingEnabled_packageUpdate_sameTokenReplayFails() throws Exception {
705 // Set up device configuration.
706 configureTrackingEnabled();
707 configureReliabilityConfigSettingsOk();
708 configureValidApplications();
709
710 // Initialize the package tracker.
711 mPackageTracker.start();
712
713 // Check the intent helper is properly configured.
714 checkIntentHelperInitializedAndReliabilityTrackingEnabled();
715
716 // Check the initial storage state.
717 checkPackageStorageStatusIsInitialOrReset();
718
719 // Simulate package installation.
720 PackageVersions packageVersions1 =
721 new PackageVersions(2 /* updateAppPackageVersion */, 3 /* dataAppPackageVersion */);
722 simulatePackageInstallation(packageVersions1);
723
724 // Confirm an update was triggered.
725 checkUpdateCheckTriggered(packageVersions1);
726
727 // Get the first token.
728 CheckToken token1 = mFakeIntentHelper.captureAndResetLastToken();
729 assertEquals(packageVersions1, token1.mPackageVersions);
730
731 // token1 should be accepted.
732 mPackageTracker.recordCheckResult(token1, true /* success */);
733
734 // Check storage and reliability triggering state.
735 checkUpdateCheckSuccessful(packageVersions1);
736
737 // Apply token1 again.
738 mPackageTracker.recordCheckResult(token1, true /* success */);
739
740 // Check the expected storage state. No real way to tell if it has been updated, but
741 // we can check the final state is still what it should be.
742 checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_SUCCESS, packageVersions1);
743
744 // Under the covers we expect it to fail to update because the storage should recognize that
745 // the token is no longer valid.
Neil Fullercd1a1092017-09-13 21:59:59 +0100746 mFakeIntentHelper.assertReliabilityTriggerScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +0000747
748 // Peek inside the package tracker to make sure it is tracking failure counts properly.
749 assertEquals(1, mPackageTracker.getCheckFailureCountForTests());
750 }
751
752 @Test
753 public void trackingEnabled_reliabilityTrigger_firstTime_initialStorage() throws Exception {
754 // Set up device configuration.
755 configureTrackingEnabled();
756 configureReliabilityConfigSettingsOk();
757 PackageVersions packageVersions = configureValidApplications();
758
759 // Initialize the package tracker.
760 mPackageTracker.start();
761
762 // Check the intent helper is properly configured.
763 checkIntentHelperInitializedAndReliabilityTrackingEnabled();
764
765 // Check the initial storage state.
766 checkPackageStorageStatusIsInitialOrReset();
767
768 // Simulate a reliability trigger.
Neil Fullercd1a1092017-09-13 21:59:59 +0100769 mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
Neil Fuller68f66662017-03-16 18:32:21 +0000770
771 // Assert the PackageTracker did trigger an update.
772 checkUpdateCheckTriggered(packageVersions);
773
774 // Confirm the token was correct.
775 CheckToken token1 = mFakeIntentHelper.captureAndResetLastToken();
776 assertEquals(packageVersions, token1.mPackageVersions);
777
778 // token1 should be accepted.
779 mPackageTracker.recordCheckResult(token1, true /* success */);
780
781 // Check storage and reliability triggering state.
782 checkUpdateCheckSuccessful(packageVersions);
783 }
784
785 @Test
786 public void trackingEnabled_reliabilityTrigger_afterRebootNoTriggerNeeded() throws Exception {
787 // Set up device configuration.
788 configureTrackingEnabled();
789 configureReliabilityConfigSettingsOk();
790 PackageVersions packageVersions = configureValidApplications();
791
792 // Force the storage into a state we want.
793 mPackageStatusStorage.forceCheckStateForTests(
794 PackageStatus.CHECK_COMPLETED_SUCCESS, packageVersions);
795
796 // Initialize the package tracker.
797 mPackageTracker.start();
798
799 // Check the intent helper is properly configured.
800 checkIntentHelperInitializedAndReliabilityTrackingEnabled();
801
802 // Check the initial storage state.
803 checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_SUCCESS, packageVersions);
804
805 // Simulate a reliability trigger.
Neil Fullercd1a1092017-09-13 21:59:59 +0100806 mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
Neil Fuller68f66662017-03-16 18:32:21 +0000807
808 // Assert the PackageTracker did not attempt to trigger an update.
809 mFakeIntentHelper.assertUpdateNotTriggered();
810
811 // Check storage and reliability triggering state.
812 checkUpdateCheckSuccessful(packageVersions);
813 }
814
815 /**
816 * Simulates the device starting where the storage records do not match the installed app
817 * versions. The reliability trigger should cause the package tracker to perform a check.
818 */
819 @Test
820 public void trackingEnabled_reliabilityTrigger_afterRebootTriggerNeededBecausePreviousFailed()
821 throws Exception {
822 // Set up device configuration.
823 configureTrackingEnabled();
824 configureReliabilityConfigSettingsOk();
825
826 PackageVersions oldPackageVersions = new PackageVersions(1, 1);
827 PackageVersions currentPackageVersions = new PackageVersions(2, 2);
828
829 // Simulate there being a newer version installed than the one recorded in storage.
830 configureValidApplications(currentPackageVersions);
831
832 // Force the storage into a state we want.
833 mPackageStatusStorage.forceCheckStateForTests(
834 PackageStatus.CHECK_COMPLETED_FAILURE, oldPackageVersions);
835
836 // Initialize the package tracker.
837 mPackageTracker.start();
838
839 // Check the intent helper is properly configured.
840 checkIntentHelperInitializedAndReliabilityTrackingEnabled();
841
842 // Check the initial storage state.
843 checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_FAILURE, oldPackageVersions);
844
845 // Simulate a reliability trigger.
Neil Fullercd1a1092017-09-13 21:59:59 +0100846 mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
Neil Fuller68f66662017-03-16 18:32:21 +0000847
848 // Assert the PackageTracker did trigger an update.
849 checkUpdateCheckTriggered(currentPackageVersions);
850
851 // Simulate the update check completing successfully.
852 CheckToken checkToken = mFakeIntentHelper.captureAndResetLastToken();
853 mPackageTracker.recordCheckResult(checkToken, true /* success */);
854
855 // Check storage and reliability triggering state.
856 checkUpdateCheckSuccessful(currentPackageVersions);
857 }
858
859 /**
860 * Simulates persistent failures of the reliability check. It should stop after the configured
861 * number of checks.
862 */
863 @Test
864 public void trackingEnabled_reliabilityTrigger_repeatedFailures() throws Exception {
865 // Set up device configuration.
866 configureTrackingEnabled();
867
868 int retriesAllowed = 3;
869 int checkDelayMillis = 5 * 60 * 1000;
870 configureReliabilityConfigSettings(retriesAllowed, checkDelayMillis);
871
872 PackageVersions oldPackageVersions = new PackageVersions(1, 1);
873 PackageVersions currentPackageVersions = new PackageVersions(2, 2);
874
875 // Simulate there being a newer version installed than the one recorded in storage.
876 configureValidApplications(currentPackageVersions);
877
878 // Force the storage into a state we want.
879 mPackageStatusStorage.forceCheckStateForTests(
880 PackageStatus.CHECK_COMPLETED_FAILURE, oldPackageVersions);
881
882 // Initialize the package tracker.
883 mPackageTracker.start();
884
885 // Check the intent helper is properly configured.
886 checkIntentHelperInitializedAndReliabilityTrackingEnabled();
887
888 // Check the initial storage state.
889 checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_FAILURE, oldPackageVersions);
890
891 for (int i = 0; i < retriesAllowed + 1; i++) {
892 // Simulate a reliability trigger.
Neil Fullercd1a1092017-09-13 21:59:59 +0100893 mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
Neil Fuller68f66662017-03-16 18:32:21 +0000894
895 // Assert the PackageTracker did trigger an update.
896 checkUpdateCheckTriggered(currentPackageVersions);
897
898 // Check the PackageTracker failure count before calling recordCheckResult.
899 assertEquals(i, mPackageTracker.getCheckFailureCountForTests());
900
901 // Simulate a check failure.
902 CheckToken checkToken = mFakeIntentHelper.captureAndResetLastToken();
903 mPackageTracker.recordCheckResult(checkToken, false /* success */);
904
905 // Peek inside the package tracker to make sure it is tracking failure counts properly.
906 assertEquals(i + 1, mPackageTracker.getCheckFailureCountForTests());
907
908 // Confirm nothing has changed.
909 mFakeIntentHelper.assertUpdateNotTriggered();
910 checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_FAILURE,
911 currentPackageVersions);
912
913 // Check reliability triggering is in the correct state.
914 if (i <= retriesAllowed) {
Neil Fullercd1a1092017-09-13 21:59:59 +0100915 mFakeIntentHelper.assertReliabilityTriggerScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +0000916 } else {
Neil Fullercd1a1092017-09-13 21:59:59 +0100917 mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +0000918 }
919 }
920 }
921
922 @Test
923 public void trackingEnabled_reliabilityTrigger_failureCountIsReset() throws Exception {
924 // Set up device configuration.
925 configureTrackingEnabled();
926
927 int retriesAllowed = 3;
928 int checkDelayMillis = 5 * 60 * 1000;
929 configureReliabilityConfigSettings(retriesAllowed, checkDelayMillis);
930
931 PackageVersions oldPackageVersions = new PackageVersions(1, 1);
932 PackageVersions currentPackageVersions = new PackageVersions(2, 2);
933
934 // Simulate there being a newer version installed than the one recorded in storage.
935 configureValidApplications(currentPackageVersions);
936
937 // Force the storage into a state we want.
938 mPackageStatusStorage.forceCheckStateForTests(
939 PackageStatus.CHECK_COMPLETED_FAILURE, oldPackageVersions);
940
941 // Initialize the package tracker.
942 mPackageTracker.start();
943
944 // Check the intent helper is properly configured.
945 checkIntentHelperInitializedAndReliabilityTrackingEnabled();
946
947 // Check the initial storage state.
948 checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_FAILURE, oldPackageVersions);
949
950 // Fail (retries - 1) times.
951 for (int i = 0; i < retriesAllowed - 1; i++) {
952 // Simulate a reliability trigger.
Neil Fullercd1a1092017-09-13 21:59:59 +0100953 mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
Neil Fuller68f66662017-03-16 18:32:21 +0000954
955 // Assert the PackageTracker did trigger an update.
956 checkUpdateCheckTriggered(currentPackageVersions);
957
958 // Check the PackageTracker failure count before calling recordCheckResult.
959 assertEquals(i, mPackageTracker.getCheckFailureCountForTests());
960
961 // Simulate a check failure.
962 CheckToken checkToken = mFakeIntentHelper.captureAndResetLastToken();
963 mPackageTracker.recordCheckResult(checkToken, false /* success */);
964
965 // Peek inside the package tracker to make sure it is tracking failure counts properly.
966 assertEquals(i + 1, mPackageTracker.getCheckFailureCountForTests());
967
968 // Confirm nothing has changed.
969 mFakeIntentHelper.assertUpdateNotTriggered();
970 checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_FAILURE,
971 currentPackageVersions);
972
973 // Check reliability triggering is still enabled.
Neil Fullercd1a1092017-09-13 21:59:59 +0100974 mFakeIntentHelper.assertReliabilityTriggerScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +0000975 }
976
977 // Simulate a reliability trigger.
Neil Fullercd1a1092017-09-13 21:59:59 +0100978 mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
Neil Fuller68f66662017-03-16 18:32:21 +0000979
980 // Assert the PackageTracker did trigger an update.
981 checkUpdateCheckTriggered(currentPackageVersions);
982
983 // Check the PackageTracker failure count before calling recordCheckResult.
984 assertEquals(retriesAllowed - 1, mPackageTracker.getCheckFailureCountForTests());
985
986 // On the last possible try, succeed.
987 CheckToken checkToken = mFakeIntentHelper.captureAndResetLastToken();
988 mPackageTracker.recordCheckResult(checkToken, true /* success */);
989
990 checkUpdateCheckSuccessful(currentPackageVersions);
991 }
992
993 /**
994 * Simulates reliability triggers happening too close together. Package tracker should ignore
995 * the ones it doesn't need.
996 */
997 @Test
998 public void trackingEnabled_reliabilityTrigger_tooSoon() throws Exception {
999 // Set up device configuration.
1000 configureTrackingEnabled();
1001
1002 int retriesAllowed = 5;
1003 int checkDelayMillis = 5 * 60 * 1000;
1004 configureReliabilityConfigSettings(retriesAllowed, checkDelayMillis);
1005
1006 PackageVersions oldPackageVersions = new PackageVersions(1, 1);
1007 PackageVersions currentPackageVersions = new PackageVersions(2, 2);
1008
1009 // Simulate there being a newer version installed than the one recorded in storage.
1010 configureValidApplications(currentPackageVersions);
1011
1012 // Force the storage into a state we want.
1013 mPackageStatusStorage.forceCheckStateForTests(
1014 PackageStatus.CHECK_COMPLETED_FAILURE, oldPackageVersions);
1015
1016 // Initialize the package tracker.
1017 mPackageTracker.start();
1018
1019 // Check the intent helper is properly configured.
1020 checkIntentHelperInitializedAndReliabilityTrackingEnabled();
1021
1022 // Check the initial storage state.
1023 checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_FAILURE, oldPackageVersions);
1024
1025 // Simulate a reliability trigger.
Neil Fullercd1a1092017-09-13 21:59:59 +01001026 mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
Neil Fuller68f66662017-03-16 18:32:21 +00001027
1028 // Assert the PackageTracker did trigger an update.
1029 checkUpdateCheckTriggered(currentPackageVersions);
1030 CheckToken token1 = mFakeIntentHelper.captureAndResetLastToken();
1031
1032 // Increment the clock, but not enough.
1033 mFakeClock.incrementClock(checkDelayMillis - 1);
1034
1035 // Simulate a reliability trigger.
Neil Fullercd1a1092017-09-13 21:59:59 +01001036 mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
Neil Fuller68f66662017-03-16 18:32:21 +00001037
1038 // Assert the PackageTracker did not trigger an update.
1039 mFakeIntentHelper.assertUpdateNotTriggered();
1040 checkPackageStorageStatus(PackageStatus.CHECK_STARTED, currentPackageVersions);
Neil Fullercd1a1092017-09-13 21:59:59 +01001041 mFakeIntentHelper.assertReliabilityTriggerScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +00001042
1043 // Increment the clock slightly more. Should now consider the response overdue.
1044 mFakeClock.incrementClock(2);
1045
1046 // Simulate a reliability trigger.
Neil Fullercd1a1092017-09-13 21:59:59 +01001047 mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
Neil Fuller68f66662017-03-16 18:32:21 +00001048
1049 // Triggering should have happened.
1050 checkUpdateCheckTriggered(currentPackageVersions);
1051 CheckToken token2 = mFakeIntentHelper.captureAndResetLastToken();
1052
1053 // Check a new token was generated.
1054 assertFalse(token1.equals(token2));
1055 }
1056
1057 /**
1058 * Tests what happens when a package update doesn't complete and a reliability trigger cleans
1059 * up for it.
1060 */
1061 @Test
1062 public void trackingEnabled_reliabilityTrigger_afterPackageUpdateDidNotComplete()
1063 throws Exception {
1064
1065 // Set up device configuration.
1066 configureTrackingEnabled();
1067
1068 int retriesAllowed = 5;
1069 int checkDelayMillis = 5 * 60 * 1000;
1070 configureReliabilityConfigSettings(retriesAllowed, checkDelayMillis);
1071
1072 PackageVersions currentPackageVersions = new PackageVersions(1, 1);
1073 PackageVersions newPackageVersions = new PackageVersions(2, 2);
1074
1075 // Simulate there being a newer version installed than the one recorded in storage.
1076 configureValidApplications(currentPackageVersions);
1077
1078 // Force the storage into a state we want.
1079 mPackageStatusStorage.forceCheckStateForTests(
1080 PackageStatus.CHECK_COMPLETED_SUCCESS, currentPackageVersions);
1081
1082 // Initialize the package tracker.
1083 mPackageTracker.start();
1084
1085 // Check the intent helper is properly configured.
1086 checkIntentHelperInitializedAndReliabilityTrackingEnabled();
1087
1088 // Simulate a reliability trigger.
1089 simulatePackageInstallation(newPackageVersions);
1090
1091 // Assert the PackageTracker did trigger an update.
1092 checkUpdateCheckTriggered(newPackageVersions);
1093 CheckToken token1 = mFakeIntentHelper.captureAndResetLastToken();
1094
1095 // Increment the clock, but not enough.
1096 mFakeClock.incrementClock(checkDelayMillis + 1);
1097
1098 // Simulate a reliability trigger.
Neil Fullercd1a1092017-09-13 21:59:59 +01001099 mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
Neil Fuller68f66662017-03-16 18:32:21 +00001100
1101 // Assert the PackageTracker triggered an update.
1102 checkUpdateCheckTriggered(newPackageVersions);
1103 CheckToken token2 = mFakeIntentHelper.captureAndResetLastToken();
1104
1105 // Check a new token was generated.
1106 assertFalse(token1.equals(token2));
1107
1108 // Simulate the reliability check completing.
1109 mPackageTracker.recordCheckResult(token2, true /* success */);
1110
1111 // Check everything is now as it should be.
1112 checkUpdateCheckSuccessful(newPackageVersions);
1113 }
1114
1115 /**
1116 * Simulates a reliability trigger happening too soon after a package update trigger occurred.
1117 */
1118 @Test
1119 public void trackingEnabled_reliabilityTriggerAfterUpdate_tooSoon() throws Exception {
1120 // Set up device configuration.
1121 configureTrackingEnabled();
1122
1123 int retriesAllowed = 5;
1124 int checkDelayMillis = 5 * 60 * 1000;
1125 configureReliabilityConfigSettings(retriesAllowed, checkDelayMillis);
1126
1127 PackageVersions currentPackageVersions = new PackageVersions(1, 1);
1128 PackageVersions newPackageVersions = new PackageVersions(2, 2);
1129
1130 // Simulate there being a newer version installed than the one recorded in storage.
1131 configureValidApplications(currentPackageVersions);
1132
1133 // Force the storage into a state we want.
1134 mPackageStatusStorage.forceCheckStateForTests(
1135 PackageStatus.CHECK_COMPLETED_SUCCESS, currentPackageVersions);
1136
1137 // Initialize the package tracker.
1138 mPackageTracker.start();
1139
1140 // Check the intent helper is properly configured.
1141 checkIntentHelperInitializedAndReliabilityTrackingEnabled();
1142
1143 // Check the initial storage state.
1144 checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_SUCCESS, currentPackageVersions);
1145
1146 // Simulate a package update trigger.
1147 simulatePackageInstallation(newPackageVersions);
1148
1149 // Assert the PackageTracker did trigger an update.
1150 checkUpdateCheckTriggered(newPackageVersions);
1151 CheckToken token1 = mFakeIntentHelper.captureAndResetLastToken();
1152
1153 // Increment the clock, but not enough.
1154 mFakeClock.incrementClock(checkDelayMillis - 1);
1155
1156 // Simulate a reliability trigger.
Neil Fullercd1a1092017-09-13 21:59:59 +01001157 mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
Neil Fuller68f66662017-03-16 18:32:21 +00001158
1159 // Assert the PackageTracker did not trigger an update.
1160 mFakeIntentHelper.assertUpdateNotTriggered();
1161 checkPackageStorageStatus(PackageStatus.CHECK_STARTED, newPackageVersions);
Neil Fullercd1a1092017-09-13 21:59:59 +01001162 mFakeIntentHelper.assertReliabilityTriggerScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +00001163
1164 // Increment the clock slightly more. Should now consider the response overdue.
1165 mFakeClock.incrementClock(2);
1166
1167 // Simulate a reliability trigger.
Neil Fullercd1a1092017-09-13 21:59:59 +01001168 mPackageTracker.triggerUpdateIfNeeded(false /* packageChanged */);
Neil Fuller68f66662017-03-16 18:32:21 +00001169
1170 // Triggering should have happened.
1171 checkUpdateCheckTriggered(newPackageVersions);
1172 CheckToken token2 = mFakeIntentHelper.captureAndResetLastToken();
1173
1174 // Check a new token was generated.
1175 assertFalse(token1.equals(token2));
1176 }
1177
Neil Fuller87b11282017-06-23 16:43:45 +01001178 @Test
1179 public void dump() {
1180 StringWriter stringWriter = new StringWriter();
1181 PrintWriter printWriter = new PrintWriter(stringWriter);
1182
1183 mPackageTracker.dump(printWriter);
1184
1185 assertFalse(stringWriter.toString().isEmpty());
1186 }
1187
Neil Fuller68f66662017-03-16 18:32:21 +00001188 private void simulatePackageInstallation(PackageVersions packageVersions) throws Exception {
1189 configureApplicationsValidManifests(packageVersions);
1190
1191 // Simulate a tracked package being updated.
1192 mFakeIntentHelper.simulatePackageUpdatedEvent();
1193 }
1194
1195 /**
1196 * Checks an update check was triggered, reliability triggering is therefore enabled and the
1197 * storage state reflects that there is a check in progress.
1198 */
1199 private void checkUpdateCheckTriggered(PackageVersions packageVersions) {
1200 // Assert the PackageTracker attempted to trigger an update.
1201 mFakeIntentHelper.assertUpdateTriggered();
1202
1203 // If an update check was triggered reliability triggering should always be enabled to
1204 // ensure that it can be completed if it fails.
Neil Fullercd1a1092017-09-13 21:59:59 +01001205 mFakeIntentHelper.assertReliabilityTriggerScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +00001206
1207 // Check the expected storage state.
1208 checkPackageStorageStatus(PackageStatus.CHECK_STARTED, packageVersions);
1209 }
1210
1211 private void checkUpdateCheckFailed(PackageVersions packageVersions) {
1212 // Check reliability triggering state.
Neil Fullercd1a1092017-09-13 21:59:59 +01001213 mFakeIntentHelper.assertReliabilityTriggerScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +00001214
1215 // Assert the storage was updated.
1216 checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_FAILURE, packageVersions);
1217 }
1218
1219 private void checkUpdateCheckSuccessful(PackageVersions packageVersions) {
1220 // Check reliability triggering state.
Neil Fullercd1a1092017-09-13 21:59:59 +01001221 mFakeIntentHelper.assertReliabilityTriggerNotScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +00001222
1223 // Assert the storage was updated.
1224 checkPackageStorageStatus(PackageStatus.CHECK_COMPLETED_SUCCESS, packageVersions);
1225
1226 // Peek inside the package tracker to make sure it is tracking failure counts properly.
1227 assertEquals(0, mPackageTracker.getCheckFailureCountForTests());
1228 }
1229
1230 private PackageVersions configureValidApplications() throws Exception {
1231 configureValidApplications(INITIAL_APP_PACKAGE_VERSIONS);
1232 return INITIAL_APP_PACKAGE_VERSIONS;
1233 }
1234
1235 private void configureValidApplications(PackageVersions versions) throws Exception {
1236 configureUpdateAppPackageOk(UPDATE_APP_PACKAGE_NAME);
1237 configureDataAppPackageOk(DATA_APP_PACKAGE_NAME);
1238 configureApplicationsValidManifests(versions);
1239 }
1240
1241 private void configureApplicationsValidManifests(PackageVersions versions) throws Exception {
1242 configureUpdateAppManifestOk(UPDATE_APP_PACKAGE_NAME);
1243 configureDataAppManifestOk(DATA_APP_PACKAGE_NAME);
1244 configureUpdateAppPackageVersion(UPDATE_APP_PACKAGE_NAME, versions.mUpdateAppVersion);
1245 configureDataAppPackageVersion(DATA_APP_PACKAGE_NAME, versions.mDataAppVersion);
1246 }
1247
1248 private void configureUpdateAppPackageVersion(String updateAppPackageName,
Dianne Hackborn3accca02013-09-20 09:32:11 -07001249 long updataAppPackageVersion) throws Exception {
Neil Fuller68f66662017-03-16 18:32:21 +00001250 when(mMockPackageManagerHelper.getInstalledPackageVersion(updateAppPackageName))
1251 .thenReturn(updataAppPackageVersion);
1252 }
1253
1254 private void configureDataAppPackageVersion(String dataAppPackageName,
Dianne Hackborn3accca02013-09-20 09:32:11 -07001255 long dataAppPackageVersion) throws Exception {
Neil Fuller68f66662017-03-16 18:32:21 +00001256 when(mMockPackageManagerHelper.getInstalledPackageVersion(dataAppPackageName))
1257 .thenReturn(dataAppPackageVersion);
1258 }
1259
1260 private void configureUpdateAppManifestOk(String updateAppPackageName) throws Exception {
1261 Intent expectedIntent = RulesUpdaterContract.createUpdaterIntent(updateAppPackageName);
1262 when(mMockPackageManagerHelper.receiverRegistered(
1263 filterEquals(expectedIntent),
1264 eq(RulesUpdaterContract.TRIGGER_TIME_ZONE_RULES_CHECK_PERMISSION)))
1265 .thenReturn(true);
1266 when(mMockPackageManagerHelper.usesPermission(
1267 updateAppPackageName, RulesUpdaterContract.UPDATE_TIME_ZONE_RULES_PERMISSION))
1268 .thenReturn(true);
1269 }
1270
1271 private void configureUpdateAppManifestBad(String updateAppPackageName) throws Exception {
1272 Intent expectedIntent = RulesUpdaterContract.createUpdaterIntent(updateAppPackageName);
1273 when(mMockPackageManagerHelper.receiverRegistered(
1274 filterEquals(expectedIntent),
1275 eq(RulesUpdaterContract.TRIGGER_TIME_ZONE_RULES_CHECK_PERMISSION)))
1276 .thenReturn(false);
1277 // Has permission, but that shouldn't matter if the check above is false.
1278 when(mMockPackageManagerHelper.usesPermission(
1279 updateAppPackageName, RulesUpdaterContract.UPDATE_TIME_ZONE_RULES_PERMISSION))
1280 .thenReturn(true);
1281 }
1282
1283 private void configureDataAppManifestOk(String dataAppPackageName) throws Exception {
1284 when(mMockPackageManagerHelper.contentProviderRegistered(
1285 TimeZoneRulesDataContract.AUTHORITY, dataAppPackageName))
1286 .thenReturn(true);
1287 }
1288
1289 private void configureDataAppManifestBad(String dataAppPackageName) throws Exception {
1290 // Simulate the data app not exposing the content provider we require.
1291 when(mMockPackageManagerHelper.contentProviderRegistered(
1292 TimeZoneRulesDataContract.AUTHORITY, dataAppPackageName))
1293 .thenReturn(false);
1294 }
1295
1296 private void configureTrackingEnabled() {
1297 when(mMockConfigHelper.isTrackingEnabled()).thenReturn(true);
1298 }
1299
1300 private void configureTrackingDisabled() {
1301 when(mMockConfigHelper.isTrackingEnabled()).thenReturn(false);
1302 }
1303
1304 private void configureReliabilityConfigSettings(int retriesAllowed, int checkDelayMillis) {
1305 when(mMockConfigHelper.getFailedCheckRetryCount()).thenReturn(retriesAllowed);
1306 when(mMockConfigHelper.getCheckTimeAllowedMillis()).thenReturn(checkDelayMillis);
1307 }
1308
1309 private void configureReliabilityConfigSettingsOk() {
1310 configureReliabilityConfigSettings(5, 5 * 60 * 1000);
1311 }
1312
1313 private void configureUpdateAppPackageOk(String updateAppPackageName) throws Exception {
1314 when(mMockConfigHelper.getUpdateAppPackageName()).thenReturn(updateAppPackageName);
1315 when(mMockPackageManagerHelper.isPrivilegedApp(updateAppPackageName)).thenReturn(true);
1316 }
1317
1318 private void configureUpdateAppPackageNotPrivileged(String updateAppPackageName)
1319 throws Exception {
1320 when(mMockConfigHelper.getUpdateAppPackageName()).thenReturn(updateAppPackageName);
1321 when(mMockPackageManagerHelper.isPrivilegedApp(updateAppPackageName)).thenReturn(false);
1322 }
1323
1324 private void configureUpdateAppPackageNameMissing() {
1325 when(mMockConfigHelper.getUpdateAppPackageName()).thenReturn(null);
1326 }
1327
1328 private void configureDataAppPackageOk(String dataAppPackageName) throws Exception {
1329 when(mMockConfigHelper.getDataAppPackageName()).thenReturn(dataAppPackageName);
1330 when(mMockPackageManagerHelper.isPrivilegedApp(dataAppPackageName)).thenReturn(true);
1331 }
1332
1333 private void configureDataAppPackageNotPrivileged(String dataAppPackageName)
1334 throws Exception {
1335 when(mMockConfigHelper.getUpdateAppPackageName()).thenReturn(dataAppPackageName);
1336 when(mMockPackageManagerHelper.isPrivilegedApp(dataAppPackageName)).thenReturn(false);
1337 }
1338
1339 private void configureDataAppPackageNameMissing() {
1340 when(mMockConfigHelper.getDataAppPackageName()).thenThrow(new RuntimeException());
1341 }
1342
1343 private void checkIntentHelperInitializedAndReliabilityTrackingEnabled() {
1344 // Verify that calling start initialized the IntentHelper as well.
1345 mFakeIntentHelper.assertInitialized(UPDATE_APP_PACKAGE_NAME, DATA_APP_PACKAGE_NAME);
1346
1347 // Assert that reliability tracking is always enabled after initialization.
Neil Fullercd1a1092017-09-13 21:59:59 +01001348 mFakeIntentHelper.assertReliabilityTriggerScheduled();
Neil Fuller68f66662017-03-16 18:32:21 +00001349 }
1350
1351 private void checkPackageStorageStatus(
1352 int expectedCheckStatus, PackageVersions expectedPackageVersions) {
1353 PackageStatus packageStatus = mPackageStatusStorage.getPackageStatus();
1354 assertEquals(expectedCheckStatus, packageStatus.mCheckStatus);
1355 assertEquals(expectedPackageVersions, packageStatus.mVersions);
1356 }
1357
1358 private void checkPackageStorageStatusIsInitialOrReset() {
1359 assertNull(mPackageStatusStorage.getPackageStatus());
1360 }
1361
1362 private static CheckToken createArbitraryCheckToken() {
1363 return new CheckToken(1, INITIAL_APP_PACKAGE_VERSIONS);
1364 }
1365
1366 /**
1367 * A fake IntentHelper implementation for use in tests.
1368 */
1369 private static class FakeIntentHelper implements IntentHelper {
1370
Neil Fullercd1a1092017-09-13 21:59:59 +01001371 private PackageTracker mPackageTracker;
Neil Fuller68f66662017-03-16 18:32:21 +00001372 private String mUpdateAppPackageName;
1373 private String mDataAppPackageName;
1374
1375 private CheckToken mLastToken;
1376
Neil Fullercd1a1092017-09-13 21:59:59 +01001377 private boolean mReliabilityTriggerScheduled;
Neil Fuller68f66662017-03-16 18:32:21 +00001378
1379 @Override
1380 public void initialize(String updateAppPackageName, String dataAppPackageName,
Neil Fullercd1a1092017-09-13 21:59:59 +01001381 PackageTracker packageTracker) {
Neil Fuller68f66662017-03-16 18:32:21 +00001382 assertNotNull(updateAppPackageName);
1383 assertNotNull(dataAppPackageName);
Neil Fullercd1a1092017-09-13 21:59:59 +01001384 assertNotNull(packageTracker);
1385 mPackageTracker = packageTracker;
Neil Fuller68f66662017-03-16 18:32:21 +00001386 mUpdateAppPackageName = updateAppPackageName;
1387 mDataAppPackageName = dataAppPackageName;
1388 }
1389
1390 public void assertInitialized(
1391 String expectedUpdateAppPackageName, String expectedDataAppPackageName) {
Neil Fullercd1a1092017-09-13 21:59:59 +01001392 assertNotNull(mPackageTracker);
Neil Fuller68f66662017-03-16 18:32:21 +00001393 assertEquals(expectedUpdateAppPackageName, mUpdateAppPackageName);
1394 assertEquals(expectedDataAppPackageName, mDataAppPackageName);
1395 }
1396
1397 public void assertNotInitialized() {
Neil Fullercd1a1092017-09-13 21:59:59 +01001398 assertNull(mPackageTracker);
Neil Fuller68f66662017-03-16 18:32:21 +00001399 }
1400
1401 @Override
1402 public void sendTriggerUpdateCheck(CheckToken checkToken) {
1403 if (mLastToken != null) {
1404 fail("lastToken already set");
1405 }
1406 mLastToken = checkToken;
1407 }
1408
1409 @Override
Neil Fullercd1a1092017-09-13 21:59:59 +01001410 public void scheduleReliabilityTrigger(long minimumDelayMillis) {
1411 mReliabilityTriggerScheduled = true;
Neil Fuller68f66662017-03-16 18:32:21 +00001412 }
1413
1414 @Override
Neil Fullercd1a1092017-09-13 21:59:59 +01001415 public void unscheduleReliabilityTrigger() {
1416 mReliabilityTriggerScheduled = false;
Neil Fuller68f66662017-03-16 18:32:21 +00001417 }
1418
Neil Fullercd1a1092017-09-13 21:59:59 +01001419 public void assertReliabilityTriggerScheduled() {
1420 assertTrue(mReliabilityTriggerScheduled);
Neil Fuller68f66662017-03-16 18:32:21 +00001421 }
1422
Neil Fullercd1a1092017-09-13 21:59:59 +01001423 public void assertReliabilityTriggerNotScheduled() {
1424 assertFalse(mReliabilityTriggerScheduled);
Neil Fuller68f66662017-03-16 18:32:21 +00001425 }
1426
1427 public void assertUpdateTriggered() {
1428 assertNotNull(mLastToken);
1429 }
1430
1431 public void assertUpdateNotTriggered() {
1432 assertNull(mLastToken);
1433 }
1434
1435 public CheckToken captureAndResetLastToken() {
1436 CheckToken toReturn = mLastToken;
1437 assertNotNull("No update triggered", toReturn);
1438 mLastToken = null;
1439 return toReturn;
1440 }
1441
1442 public void simulatePackageUpdatedEvent() {
Neil Fullercd1a1092017-09-13 21:59:59 +01001443 mPackageTracker.triggerUpdateIfNeeded(true /* packageChanged */);
Neil Fuller68f66662017-03-16 18:32:21 +00001444 }
1445 }
1446
1447 private static class FakeClockHelper implements ClockHelper {
1448
1449 private long currentTime = 1000;
1450
1451 @Override
1452 public long currentTimestamp() {
1453 return currentTime;
1454 }
1455
1456 public void incrementClock(long millis) {
1457 currentTime += millis;
1458 }
1459 }
1460
1461 /**
1462 * Registers a mockito parameter matcher that uses {@link Intent#filterEquals(Intent)}. to
1463 * check the parameter against the intent supplied.
1464 */
1465 private static Intent filterEquals(final Intent expected) {
1466 final Matcher<Intent> m = new BaseMatcher<Intent>() {
1467 @Override
1468 public boolean matches(Object actual) {
1469 return actual != null && expected.filterEquals((Intent) actual);
1470 }
1471 @Override
1472 public void describeTo(Description description) {
1473 description.appendText(expected.toString());
1474 }
1475 };
1476 return argThat(m);
1477 }
1478}