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