Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c84c4bc3 authored by Geoffrey Boullanger's avatar Geoffrey Boullanger Committed by Android (Google) Code Review
Browse files

Merge "Do not show time zone notifications if the time zone is first set" into main

parents 3740c6da 567ef76f
Loading
Loading
Loading
Loading
+16 −5
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import static com.android.server.timezonedetector.TimeZoneDetectorStrategy.ORIGI
import static com.android.server.timezonedetector.TimeZoneDetectorStrategy.ORIGIN_MANUAL;
import static com.android.server.timezonedetector.TimeZoneDetectorStrategy.ORIGIN_TELEPHONY;
import static com.android.server.timezonedetector.TimeZoneDetectorStrategy.ORIGIN_UNKNOWN;
import static com.android.server.SystemTimeZone.TIME_ZONE_CONFIDENCE_LOW;

import android.annotation.DurationMillisLong;
import android.annotation.IntDef;
@@ -398,7 +399,10 @@ public class NotifyingTimeZoneChangeListener implements TimeZoneChangeListener {
            if (changeEvent.getOrigin() == ORIGIN_MANUAL) {
                // Just clear any existing notification.
                clearNotificationForUser(currentUserId);
            } else {
            } else if (changeEvent.getOldConfidence() != TIME_ZONE_CONFIDENCE_LOW) {
                // b/421857844 Only notify if the old confidence is not 0. This
                // is to prevent notifying users when the time zone is first set
                // after setup wizard.
                notifyOfTimeZoneChange(currentUserId, trackedChangeEvent);
            }
        }
@@ -425,10 +429,17 @@ public class NotifyingTimeZoneChangeListener implements TimeZoneChangeListener {
            TimeZoneChangeEvent lastChangeEvent = lastTimeZoneChangeRecord.getEvent();
            if (!changeEvent.getOldZoneId().equals(lastChangeEvent.getNewZoneId())) {
                int changeEventId = mNextChangeEventId.getAndIncrement();
                TimeZoneChangeEvent syntheticChangeEvent = new TimeZoneChangeEvent(
                        mEnvironment.elapsedRealtimeMillis(), mEnvironment.currentTimeMillis(),
                        ORIGIN_UNKNOWN, UserHandle.USER_NULL, lastChangeEvent.getNewZoneId(),
                        changeEvent.getOldZoneId(), 0, "Synthetic");
                TimeZoneChangeEvent syntheticChangeEvent =
                        new TimeZoneChangeEvent(
                                mEnvironment.elapsedRealtimeMillis(),
                                mEnvironment.currentTimeMillis(),
                                ORIGIN_UNKNOWN,
                                UserHandle.USER_NULL,
                                /* oldZoneId= */ lastChangeEvent.getNewZoneId(),
                                /* newZoneId= */ changeEvent.getOldZoneId(),
                                /* oldConfidence= */ lastChangeEvent.getNewConfidence(),
                                /* newConfidence= */ TIME_ZONE_CONFIDENCE_LOW,
                                "Synthetic");
                TimeZoneChangeRecord syntheticTrackedChangeEvent =
                        new TimeZoneChangeRecord(changeEventId, syntheticChangeEvent);
                syntheticTrackedChangeEvent.setStatus(STATUS_SUPERSEDED, SIGNAL_TYPE_NONE);
+51 −13
Original line number Diff line number Diff line
@@ -43,19 +43,27 @@ public interface TimeZoneChangeListener {
        private final @UserIdInt int mUserId;
        private final String mOldZoneId;
        private final String mNewZoneId;
        private final @TimeZoneConfidence int mOldConfidence;
        private final @TimeZoneConfidence int mNewConfidence;
        private final String mCause;

        public TimeZoneChangeEvent(@ElapsedRealtimeLong long elapsedRealtimeMillis,
        public TimeZoneChangeEvent(
                @ElapsedRealtimeLong long elapsedRealtimeMillis,
                @CurrentTimeMillisLong long unixEpochTimeMillis,
                @Origin int origin, @UserIdInt int userId, @NonNull String oldZoneId,
                @NonNull String newZoneId, int newConfidence, @NonNull String cause) {
                @Origin int origin,
                @UserIdInt int userId,
                @NonNull String oldZoneId,
                @NonNull String newZoneId,
                @TimeZoneConfidence int oldConfidence,
                @TimeZoneConfidence int newConfidence,
                @NonNull String cause) {
            mElapsedRealtimeMillis = elapsedRealtimeMillis;
            mUnixEpochTimeMillis = unixEpochTimeMillis;
            mOrigin = origin;
            mUserId = userId;
            mOldZoneId = Objects.requireNonNull(oldZoneId);
            mNewZoneId = Objects.requireNonNull(newZoneId);
            mOldConfidence = oldConfidence;
            mNewConfidence = newConfidence;
            mCause = Objects.requireNonNull(cause);
        }
@@ -89,17 +97,38 @@ public interface TimeZoneChangeListener {
            return mNewZoneId;
        }

        public @TimeZoneConfidence int getOldConfidence() {
            return mOldConfidence;
        }

        public @TimeZoneConfidence int getNewConfidence() {
            return mNewConfidence;
        }

        @Override
        public String toString() {
            return "TimeZoneChangeEvent{"
                    + "mElapsedRealtimeMillis=" + mElapsedRealtimeMillis
                    + ", mUnixEpochTimeMillis=" + mUnixEpochTimeMillis
                    + ", mOrigin=" + mOrigin
                    + ", mUserId=" + mUserId
                    + ", mOldZoneId='" + mOldZoneId + '\''
                    + ", mNewZoneId='" + mNewZoneId + '\''
                    + ", mNewConfidence=" + mNewConfidence
                    + ", mCause='" + mCause + '\''
                    + "mElapsedRealtimeMillis="
                    + mElapsedRealtimeMillis
                    + ", mUnixEpochTimeMillis="
                    + mUnixEpochTimeMillis
                    + ", mOrigin="
                    + mOrigin
                    + ", mUserId="
                    + mUserId
                    + ", mOldZoneId='"
                    + mOldZoneId
                    + '\''
                    + ", mNewZoneId='"
                    + mNewZoneId
                    + '\''
                    + ", mOldConfidence="
                    + mOldConfidence
                    + ", mNewConfidence="
                    + mNewConfidence
                    + ", mCause='"
                    + mCause
                    + '\''
                    + '}';
        }

@@ -115,6 +144,7 @@ public interface TimeZoneChangeListener {
                        && mUserId == that.mUserId
                        && Objects.equals(mOldZoneId, that.mOldZoneId)
                        && Objects.equals(mNewZoneId, that.mNewZoneId)
                        && mOldConfidence == that.mOldConfidence
                        && mNewConfidence == that.mNewConfidence
                        && Objects.equals(mCause, that.mCause);
            }
@@ -123,8 +153,16 @@ public interface TimeZoneChangeListener {

        @Override
        public int hashCode() {
            return Objects.hash(mElapsedRealtimeMillis, mUnixEpochTimeMillis, mOrigin, mUserId,
                    mOldZoneId, mNewZoneId, mNewConfidence, mCause);
            return Objects.hash(
                    mElapsedRealtimeMillis,
                    mUnixEpochTimeMillis,
                    mOrigin,
                    mUserId,
                    mOldZoneId,
                    mNewZoneId,
                    mOldConfidence,
                    mNewConfidence,
                    mCause);
        }
    }
}
+8 −2
Original line number Diff line number Diff line
@@ -802,9 +802,15 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
            // whether the device / user sticks with it.
            TimeZoneChangeListener.TimeZoneChangeEvent changeEvent =
                    new TimeZoneChangeListener.TimeZoneChangeEvent(
                            SystemClock.elapsedRealtime(), System.currentTimeMillis(), origin,
                            SystemClock.elapsedRealtime(),
                            System.currentTimeMillis(),
                            origin,
                            userId,
                            currentZoneId, newZoneId, newConfidence, cause);
                            currentZoneId,
                            newZoneId,
                            currentConfidence,
                            newConfidence,
                            cause);
            mChangeTracker.process(changeEvent);
        }
    }
+185 −101
Original line number Diff line number Diff line
@@ -26,11 +26,15 @@ import static com.android.server.timezonedetector.NotifyingTimeZoneChangeListene
import static com.android.server.timezonedetector.TimeZoneDetectorStrategy.ORIGIN_LOCATION;
import static com.android.server.timezonedetector.TimeZoneDetectorStrategy.ORIGIN_MANUAL;
import static com.android.server.timezonedetector.TimeZoneDetectorStrategy.ORIGIN_TELEPHONY;
import static com.android.server.SystemTimeZone.TIME_ZONE_CONFIDENCE_HIGH;
import static com.android.server.SystemTimeZone.TIME_ZONE_CONFIDENCE_LOW;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.spy;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Notification;
import android.app.NotificationManager;
@@ -152,7 +156,8 @@ public class NotifyingTimeZoneChangeListenerTest {
    public void process_autoDetectionOff_noManualTracking_shouldTrackWithoutNotifying() {
        enableTimeZoneNotifications();

        TimeZoneChangeRecord expectedTimeZoneChangeRecord = new TimeZoneChangeRecord(
        TimeZoneChangeRecord expectedTimeZoneChangeRecord =
                new TimeZoneChangeRecord(
                        /* id= */ 1,
                        new TimeZoneChangeEvent(
                                /* elapsedRealtimeMillis= */ 0,
@@ -161,7 +166,8 @@ public class NotifyingTimeZoneChangeListenerTest {
                                /* userId= */ mUid,
                                /* oldZoneId= */ "Europe/Paris",
                                /* newZoneId= */ "Europe/London",
                        /* newConfidence= */ 1,
                                /* oldConfidence= */ TIME_ZONE_CONFIDENCE_HIGH,
                                /* newConfidence= */ TIME_ZONE_CONFIDENCE_HIGH,
                                /* cause= */ "NO_REASON"));
        expectedTimeZoneChangeRecord.setStatus(STATUS_UNTRACKED, SIGNAL_TYPE_NONE);

@@ -179,7 +185,8 @@ public class NotifyingTimeZoneChangeListenerTest {
    public void process_autoDetectionOff_shouldTrackWithoutNotifying() {
        enableNotificationsWithManualChangeTracking();

        TimeZoneChangeRecord expectedTimeZoneChangeRecord = new TimeZoneChangeRecord(
        TimeZoneChangeRecord expectedTimeZoneChangeRecord =
                new TimeZoneChangeRecord(
                        /* id= */ 1,
                        new TimeZoneChangeEvent(
                                /* elapsedRealtimeMillis= */ 0,
@@ -188,7 +195,8 @@ public class NotifyingTimeZoneChangeListenerTest {
                                /* userId= */ mUid,
                                /* oldZoneId= */ "Europe/Paris",
                                /* newZoneId= */ "Europe/London",
                        /* newConfidence= */ 1,
                                /* oldConfidence= */ TIME_ZONE_CONFIDENCE_HIGH,
                                /* newConfidence= */ TIME_ZONE_CONFIDENCE_HIGH,
                                /* cause= */ "NO_REASON"));
        expectedTimeZoneChangeRecord.setStatus(STATUS_UNTRACKED, SIGNAL_TYPE_NONE);

@@ -217,7 +225,8 @@ public class NotifyingTimeZoneChangeListenerTest {

        enableNotificationsWithManualChangeTracking();

        TimeZoneChangeRecord expectedTimeZoneChangeRecord = new TimeZoneChangeRecord(
        TimeZoneChangeRecord expectedTimeZoneChangeRecord =
                new TimeZoneChangeRecord(
                        /* id= */ 1,
                        new TimeZoneChangeEvent(
                                /* elapsedRealtimeMillis= */ 0,
@@ -226,7 +235,8 @@ public class NotifyingTimeZoneChangeListenerTest {
                                /* userId= */ mUid,
                                /* oldZoneId= */ "Europe/Paris",
                                /* newZoneId= */ "Europe/London",
                        /* newConfidence= */ 1,
                                /* oldConfidence= */ TIME_ZONE_CONFIDENCE_HIGH,
                                /* newConfidence= */ TIME_ZONE_CONFIDENCE_HIGH,
                                /* cause= */ "NO_REASON"));
        expectedTimeZoneChangeRecord.setStatus(STATUS_UNKNOWN, SIGNAL_TYPE_UNKNOWN);

@@ -241,7 +251,8 @@ public class NotifyingTimeZoneChangeListenerTest {
        assertEquals(1, mNotificationManager.getNotifications().size());
        mHandler.assertTotalMessagesEnqueued(1);

        expectedTimeZoneChangeRecord = new TimeZoneChangeRecord(
        expectedTimeZoneChangeRecord =
                new TimeZoneChangeRecord(
                        /* id= */ 2,
                        new TimeZoneChangeEvent(
                                /* elapsedRealtimeMillis= */ 1000L,
@@ -250,7 +261,8 @@ public class NotifyingTimeZoneChangeListenerTest {
                                /* userId= */ mUid,
                                /* oldZoneId= */ "Europe/London",
                                /* newZoneId= */ "Europe/Paris",
                        /* newConfidence= */ 1,
                                /* oldConfidence= */ TIME_ZONE_CONFIDENCE_HIGH,
                                /* newConfidence= */ TIME_ZONE_CONFIDENCE_HIGH,
                                /* cause= */ "NO_REASON"));
        expectedTimeZoneChangeRecord.setStatus(STATUS_UNKNOWN, SIGNAL_TYPE_UNKNOWN);

@@ -268,17 +280,20 @@ public class NotifyingTimeZoneChangeListenerTest {

        // Test manual change within revert threshold
        {
            expectedTimeZoneChangeRecord = new TimeZoneChangeRecord(
            expectedTimeZoneChangeRecord =
                    new TimeZoneChangeRecord(
                            /* id= */ 3,
                            new TimeZoneChangeEvent(
                                    /* elapsedRealtimeMillis= */ 999L + AUTO_REVERT_THRESHOLD,
                            /* unixEpochTimeMillis= */
                            1726597800000L + 999L + AUTO_REVERT_THRESHOLD,
                                    /* unixEpochTimeMillis= */ 1726597800000L
                                            + 999L
                                            + AUTO_REVERT_THRESHOLD,
                                    /* origin= */ ORIGIN_MANUAL,
                                    /* userId= */ mUid,
                                    /* oldZoneId= */ "Europe/Paris",
                                    /* newZoneId= */ "Europe/London",
                            /* newConfidence= */ 1,
                                    /* oldConfidence= */ TIME_ZONE_CONFIDENCE_HIGH,
                                    /* newConfidence= */ TIME_ZONE_CONFIDENCE_HIGH,
                                    /* cause= */ "NO_REASON"));
            expectedTimeZoneChangeRecord.setStatus(STATUS_UNTRACKED, SIGNAL_TYPE_NONE);

@@ -303,17 +318,20 @@ public class NotifyingTimeZoneChangeListenerTest {
            disableTimeZoneAutoDetection();
            // [END] Reset previous event

            expectedTimeZoneChangeRecord = new TimeZoneChangeRecord(
            expectedTimeZoneChangeRecord =
                    new TimeZoneChangeRecord(
                            /* id= */ 5,
                            new TimeZoneChangeEvent(
                                    /* elapsedRealtimeMillis= */ 1001L + AUTO_REVERT_THRESHOLD,
                            /* unixEpochTimeMillis= */
                            1726597800000L + 1001L + AUTO_REVERT_THRESHOLD,
                                    /* unixEpochTimeMillis= */ 1726597800000L
                                            + 1001L
                                            + AUTO_REVERT_THRESHOLD,
                                    /* origin= */ ORIGIN_MANUAL,
                                    /* userId= */ mUid,
                                    /* oldZoneId= */ "Europe/Paris",
                                    /* newZoneId= */ "Europe/London",
                            /* newConfidence= */ 1,
                                    /* oldConfidence= */ TIME_ZONE_CONFIDENCE_HIGH,
                                    /* newConfidence= */ TIME_ZONE_CONFIDENCE_HIGH,
                                    /* cause= */ "NO_REASON"));
            expectedTimeZoneChangeRecord.setStatus(STATUS_UNTRACKED, SIGNAL_TYPE_NONE);

@@ -344,7 +362,8 @@ public class NotifyingTimeZoneChangeListenerTest {

        enableNotificationsWithManualChangeTracking();

        TimeZoneChangeRecord expectedTimeZoneChangeRecord = new TimeZoneChangeRecord(
        TimeZoneChangeRecord expectedTimeZoneChangeRecord =
                new TimeZoneChangeRecord(
                        /* id= */ 1,
                        new TimeZoneChangeEvent(
                                /* elapsedRealtimeMillis= */ 0,
@@ -353,7 +372,8 @@ public class NotifyingTimeZoneChangeListenerTest {
                                /* userId= */ mUid,
                                /* oldZoneId= */ "Europe/Paris",
                                /* newZoneId= */ "Europe/London",
                        /* newConfidence= */ 1,
                                /* oldConfidence= */ TIME_ZONE_CONFIDENCE_HIGH,
                                /* newConfidence= */ TIME_ZONE_CONFIDENCE_HIGH,
                                /* cause= */ "NO_REASON"));
        expectedTimeZoneChangeRecord.setStatus(STATUS_UNKNOWN, SIGNAL_TYPE_UNKNOWN);

@@ -368,7 +388,8 @@ public class NotifyingTimeZoneChangeListenerTest {
        assertEquals(1, mNotificationManager.getNotifications().size());
        mHandler.assertTotalMessagesEnqueued(1);

        expectedTimeZoneChangeRecord = new TimeZoneChangeRecord(
        expectedTimeZoneChangeRecord =
                new TimeZoneChangeRecord(
                        /* id= */ 3,
                        new TimeZoneChangeEvent(
                                /* elapsedRealtimeMillis= */ 1000L,
@@ -377,7 +398,8 @@ public class NotifyingTimeZoneChangeListenerTest {
                                /* userId= */ mUid,
                                /* oldZoneId= */ "Europe/Athens",
                                /* newZoneId= */ "Europe/Paris",
                        /* newConfidence= */ 1,
                                /* oldConfidence= */ TIME_ZONE_CONFIDENCE_HIGH,
                                /* newConfidence= */ TIME_ZONE_CONFIDENCE_HIGH,
                                /* cause= */ "NO_REASON"));
        expectedTimeZoneChangeRecord.setStatus(STATUS_UNKNOWN, SIGNAL_TYPE_UNKNOWN);

@@ -407,7 +429,8 @@ public class NotifyingTimeZoneChangeListenerTest {

        enableNotificationsWithManualChangeTracking();

        TimeZoneChangeRecord expectedTimeZoneChangeRecord = new TimeZoneChangeRecord(
        TimeZoneChangeRecord expectedTimeZoneChangeRecord =
                new TimeZoneChangeRecord(
                        /* id= */ 1,
                        new TimeZoneChangeEvent(
                                /* elapsedRealtimeMillis= */ 0,
@@ -416,7 +439,8 @@ public class NotifyingTimeZoneChangeListenerTest {
                                /* userId= */ mUid,
                                /* oldZoneId= */ "Europe/Paris",
                                /* newZoneId= */ "Europe/Rome",
                        /* newConfidence= */ 1,
                                /* oldConfidence= */ TIME_ZONE_CONFIDENCE_HIGH,
                                /* newConfidence= */ TIME_ZONE_CONFIDENCE_HIGH,
                                /* cause= */ "NO_REASON"));
        expectedTimeZoneChangeRecord.setStatus(STATUS_UNKNOWN, SIGNAL_TYPE_UNKNOWN);

@@ -433,6 +457,66 @@ public class NotifyingTimeZoneChangeListenerTest {
        mHandler.assertTotalMessagesEnqueued(1);
    }

    @Test
    @Parameters(method = "getDetectionOrigins")
    public void process_oldConfidenceIsZero_noNotificationSent(
            @TimeZoneDetectorStrategy.Origin int origin) {
        if (origin == ORIGIN_LOCATION) {
            enableLocationTimeZoneDetection();
        } else if (origin == ORIGIN_TELEPHONY) {
            enableTelephonyTimeZoneDetection();
        } else {
            throw new IllegalStateException(
                    "The given origin has not been implemented for this test: " + origin);
        }

        enableNotificationsWithManualChangeTracking();

        // Process a first event with zero confidence.
        // We expect this to be tracked but not to generate a notification.
        TimeZoneChangeEvent firstEvent =
                new TimeZoneChangeEvent(
                        /* elapsedRealtimeMillis= */ 0,
                        /* unixEpochTimeMillis= */ 1726597800000L,
                        /* origin= */ origin,
                        /* userId= */ mUid,
                        /* oldZoneId= */ "Europe/Paris",
                        /* newZoneId= */ "Europe/London",
                        /* oldConfidence= */ TIME_ZONE_CONFIDENCE_LOW,
                        /* newConfidence= */ TIME_ZONE_CONFIDENCE_LOW, // Zero confidence
                        /* cause= */ "NO_REASON");

        mTimeZoneChangeTracker.process(firstEvent);

        // Verify the first event was tracked but did not trigger a notification.
        TimeZoneChangeRecord firstRecord = mTimeZoneChangeTracker.getLastTimeZoneChangeRecord();
        assertEquals(firstEvent, firstRecord.getEvent());
        assertEquals(0, mNotificationManager.getNotifications().size());
        mHandler.assertTotalMessagesEnqueued(1);

        // Process a second event with non-zero confidence.
        TimeZoneChangeEvent secondEvent =
                new TimeZoneChangeEvent(
                        /* elapsedRealtimeMillis= */ 1000L,
                        /* unixEpochTimeMillis= */ 1726597800000L + 1000L,
                        /* origin= */ origin,
                        /* userId= */ mUid,
                        /* oldZoneId= */ "Europe/London",
                        /* newZoneId= */ "America/New_York",
                        /* oldConfidence= */ TIME_ZONE_CONFIDENCE_LOW,
                        /* newConfidence= */ TIME_ZONE_CONFIDENCE_HIGH,
                        /* cause= */ "NO_REASON");

        mTimeZoneChangeTracker.process(secondEvent);

        // Verify the second event was tracked but did not trigger a notification.
        TimeZoneChangeRecord secondRecord = mTimeZoneChangeTracker.getLastTimeZoneChangeRecord();
        assertEquals(secondEvent, secondRecord.getEvent());
        // No notification sent as the previous event had zero confidence.
        assertEquals(0, mNotificationManager.getNotifications().size());
        mHandler.assertTotalMessagesEnqueued(2);
    }

    private void enableLocationTimeZoneDetection() {
        ConfigurationInternal oldConfiguration =
                mServiceConfigAccessor.getCurrentUserConfigurationInternal();