From ea6b34da8d4291390649f1ced7bd39c199ec6f9e Mon Sep 17 00:00:00 2001 From: Neil Fuller Date: Fri, 13 Mar 2020 13:27:52 +0000 Subject: [PATCH] Raise tz standards for uninitialized devices Removes the lowering of standards applied for tz detection on uninitialized devices. Before this change, the device would accept any telephony tz suggestion, which could include lower-quality answers; i.e. those where the zone was chosen based on a country's default zone, even when there are multiple different zones to choose from. Unfortunately, the stock device setup wizard assumes any time zone change made while it is running is a high quality answer and so it then doesn't ask the user to confirm the choice. Without an API it has no way of telling whether the time zone chosen was a high or low quality answer. This should eventually be resolved with improved system APIs. Bug: 143721631 Test: atest services/tests/servicestests/src/com/android/server/timezonedetector Change-Id: I1dbd1046f0e641e609ecc8809cf86b7ddb6111b3 --- .../TimeZoneDetectorStrategyImpl.java | 13 +-- .../TimeZoneDetectorStrategyImplTest.java | 82 ++++++++++++------- 2 files changed, 55 insertions(+), 40 deletions(-) diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java index cc33fb0f50084..d318b1a4732cd 100644 --- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java +++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java @@ -276,18 +276,6 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat return; } - // Special case handling for uninitialized devices. This should only happen once. - String newZoneId = bestTelephonySuggestion.suggestion.getZoneId(); - if (newZoneId != null && !mCallback.isDeviceTimeZoneInitialized()) { - String cause = "Device has no time zone set. Attempting to set the device to the best" - + " available suggestion." - + " bestTelephonySuggestion=" + bestTelephonySuggestion - + ", detectionReason=" + detectionReason; - Slog.i(LOG_TAG, cause); - setDeviceTimeZoneIfRequired(ORIGIN_TELEPHONY, newZoneId, cause); - return; - } - boolean suggestionGoodEnough = bestTelephonySuggestion.score >= TELEPHONY_SCORE_USAGE_THRESHOLD; if (!suggestionGoodEnough) { @@ -301,6 +289,7 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat // Paranoia: Every suggestion above the SCORE_USAGE_THRESHOLD should have a non-null time // zone ID. + String newZoneId = bestTelephonySuggestion.suggestion.getZoneId(); if (newZoneId == null) { Slog.w(LOG_TAG, "Empty zone suggestion scored higher than expected. This is an error:" + " bestTelephonySuggestion=" + bestTelephonySuggestion diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java index ba309679e47a0..30bb12e3e6169 100644 --- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java +++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java @@ -128,43 +128,69 @@ public class TimeZoneDetectorStrategyImplTest { } @Test - public void testFirstPlausibleTelephonySuggestionAcceptedWhenTimeZoneUninitialized() { + public void testTelephonySuggestionsWhenTimeZoneUninitialized() { + assertTrue(TELEPHONY_SCORE_LOW < TELEPHONY_SCORE_USAGE_THRESHOLD); + assertTrue(TELEPHONY_SCORE_HIGH >= TELEPHONY_SCORE_USAGE_THRESHOLD); SuggestionTestCase testCase = newTestCase(MATCH_TYPE_NETWORK_COUNTRY_ONLY, QUALITY_MULTIPLE_ZONES_WITH_DIFFERENT_OFFSETS, TELEPHONY_SCORE_LOW); - TelephonyTimeZoneSuggestion lowQualitySuggestion = - testCase.createSuggestion(SLOT_INDEX1, "America/New_York"); + SuggestionTestCase testCase2 = newTestCase(MATCH_TYPE_NETWORK_COUNTRY_ONLY, + QUALITY_SINGLE_ZONE, TELEPHONY_SCORE_HIGH); - // The device time zone setting is left uninitialized. Script script = new Script() .initializeAutoTimeZoneDetection(true); - // The very first suggestion will be taken. - script.suggestTelephonyTimeZone(lowQualitySuggestion) - .verifyTimeZoneSetAndReset(lowQualitySuggestion); + // A low quality suggestions will not be taken: The device time zone setting is left + // uninitialized. + { + TelephonyTimeZoneSuggestion lowQualitySuggestion = + testCase.createSuggestion(SLOT_INDEX1, "America/New_York"); - // Assert internal service state. - QualifiedTelephonyTimeZoneSuggestion expectedScoredSuggestion = - new QualifiedTelephonyTimeZoneSuggestion( - lowQualitySuggestion, testCase.expectedScore); - assertEquals(expectedScoredSuggestion, - mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1)); - assertEquals(expectedScoredSuggestion, - mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests()); + script.suggestTelephonyTimeZone(lowQualitySuggestion) + .verifyTimeZoneNotSet(); - // Another low quality suggestion will be ignored now that the setting is initialized. - TelephonyTimeZoneSuggestion lowQualitySuggestion2 = - testCase.createSuggestion(SLOT_INDEX1, "America/Los_Angeles"); - script.suggestTelephonyTimeZone(lowQualitySuggestion2) - .verifyTimeZoneNotSet(); + // Assert internal service state. + QualifiedTelephonyTimeZoneSuggestion expectedScoredSuggestion = + new QualifiedTelephonyTimeZoneSuggestion( + lowQualitySuggestion, testCase.expectedScore); + assertEquals(expectedScoredSuggestion, + mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1)); + assertEquals(expectedScoredSuggestion, + mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests()); + } - // Assert internal service state. - QualifiedTelephonyTimeZoneSuggestion expectedScoredSuggestion2 = - new QualifiedTelephonyTimeZoneSuggestion( - lowQualitySuggestion2, testCase.expectedScore); - assertEquals(expectedScoredSuggestion2, - mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1)); - assertEquals(expectedScoredSuggestion2, - mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests()); + // A good quality suggestion will be used. + { + TelephonyTimeZoneSuggestion goodQualitySuggestion = + testCase2.createSuggestion(SLOT_INDEX1, "Europe/London"); + script.suggestTelephonyTimeZone(goodQualitySuggestion) + .verifyTimeZoneSetAndReset(goodQualitySuggestion); + + // Assert internal service state. + QualifiedTelephonyTimeZoneSuggestion expectedScoredSuggestion = + new QualifiedTelephonyTimeZoneSuggestion( + goodQualitySuggestion, testCase2.expectedScore); + assertEquals(expectedScoredSuggestion, + mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1)); + assertEquals(expectedScoredSuggestion, + mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests()); + } + + // A low quality suggestion will be accepted, but not used to set the device time zone. + { + TelephonyTimeZoneSuggestion lowQualitySuggestion2 = + testCase.createSuggestion(SLOT_INDEX1, "America/Los_Angeles"); + script.suggestTelephonyTimeZone(lowQualitySuggestion2) + .verifyTimeZoneNotSet(); + + // Assert internal service state. + QualifiedTelephonyTimeZoneSuggestion expectedScoredSuggestion = + new QualifiedTelephonyTimeZoneSuggestion( + lowQualitySuggestion2, testCase.expectedScore); + assertEquals(expectedScoredSuggestion, + mTimeZoneDetectorStrategy.getLatestTelephonySuggestion(SLOT_INDEX1)); + assertEquals(expectedScoredSuggestion, + mTimeZoneDetectorStrategy.findBestTelephonySuggestionForTests()); + } } /**