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

Commit 45ce9ddf authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Enable telephony fallback triggered by providers"

parents 39e4080c 7fbcae6e
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.app.time;
import static android.app.time.DetectorStatusTypes.DETECTION_ALGORITHM_STATUS_NOT_RUNNING;
import static android.app.time.DetectorStatusTypes.DETECTION_ALGORITHM_STATUS_NOT_SUPPORTED;
import static android.app.time.DetectorStatusTypes.DETECTION_ALGORITHM_STATUS_RUNNING;
import static android.app.time.DetectorStatusTypes.DETECTION_ALGORITHM_STATUS_UNKNOWN;
import static android.app.time.DetectorStatusTypes.detectionAlgorithmStatusFromString;
import static android.app.time.DetectorStatusTypes.detectionAlgorithmStatusToString;
import static android.app.time.DetectorStatusTypes.requireValidDetectionAlgorithmStatus;
@@ -319,6 +320,40 @@ public final class LocationTimeZoneAlgorithmStatus implements Parcelable {
                mSecondaryProviderStatus, mSecondaryProviderReportedStatus);
    }

    /**
     * Returns {@code true} if the algorithm status could allow the time zone detector to enter
     * telephony fallback mode.
     */
    public boolean couldEnableTelephonyFallback() {
        if (mStatus == DETECTION_ALGORITHM_STATUS_UNKNOWN
                || mStatus == DETECTION_ALGORITHM_STATUS_NOT_RUNNING
                || mStatus == DETECTION_ALGORITHM_STATUS_NOT_SUPPORTED) {
            // This method is not expected to be called on objects with these statuses. Fallback
            // should not be enabled if it is.
            return false;
        }

        // mStatus == DETECTOR_STATUS_RUNNING.

        boolean primarySuggestsFallback = false;
        if (mPrimaryProviderStatus == PROVIDER_STATUS_NOT_PRESENT) {
            primarySuggestsFallback = true;
        } else if (mPrimaryProviderStatus == PROVIDER_STATUS_IS_UNCERTAIN
                && mPrimaryProviderReportedStatus != null) {
            primarySuggestsFallback = mPrimaryProviderReportedStatus.couldEnableTelephonyFallback();
        }

        boolean secondarySuggestsFallback = false;
        if (mSecondaryProviderStatus == PROVIDER_STATUS_NOT_PRESENT) {
            secondarySuggestsFallback = true;
        } else if (mSecondaryProviderStatus == PROVIDER_STATUS_IS_UNCERTAIN
                && mSecondaryProviderReportedStatus != null) {
            secondarySuggestsFallback =
                    mSecondaryProviderReportedStatus.couldEnableTelephonyFallback();
        }
        return primarySuggestsFallback && secondarySuggestsFallback;
    }

    /** @hide */
    @VisibleForTesting
    @NonNull
+1 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ android_test {
        "androidx.test.ext.junit",
        "androidx.test.runner",
        "androidx.test.rules",
        "junit-params",
        "kotlin-test",
        "mockito-target-minus-junit4",
        "ub-uiautomator",
+117 −0
Original line number Diff line number Diff line
@@ -17,19 +17,26 @@
package android.app.time;

import static android.app.time.DetectorStatusTypes.DETECTION_ALGORITHM_STATUS_NOT_RUNNING;
import static android.app.time.DetectorStatusTypes.DETECTION_ALGORITHM_STATUS_NOT_SUPPORTED;
import static android.app.time.DetectorStatusTypes.DETECTION_ALGORITHM_STATUS_RUNNING;
import static android.app.time.DetectorStatusTypes.DETECTION_ALGORITHM_STATUS_UNKNOWN;
import static android.app.time.LocationTimeZoneAlgorithmStatus.PROVIDER_STATUS_IS_CERTAIN;
import static android.app.time.LocationTimeZoneAlgorithmStatus.PROVIDER_STATUS_IS_UNCERTAIN;
import static android.app.time.LocationTimeZoneAlgorithmStatus.PROVIDER_STATUS_NOT_PRESENT;
import static android.app.time.LocationTimeZoneAlgorithmStatus.PROVIDER_STATUS_NOT_READY;
import static android.app.time.ParcelableTestSupport.assertEqualsAndHashCode;
import static android.app.time.ParcelableTestSupport.assertRoundTripParcelable;
import static android.service.timezone.TimeZoneProviderStatus.DEPENDENCY_STATUS_BLOCKED_BY_ENVIRONMENT;
import static android.service.timezone.TimeZoneProviderStatus.DEPENDENCY_STATUS_NOT_APPLICABLE;
import static android.service.timezone.TimeZoneProviderStatus.DEPENDENCY_STATUS_OK;
import static android.service.timezone.TimeZoneProviderStatus.OPERATION_STATUS_NOT_APPLICABLE;
import static android.service.timezone.TimeZoneProviderStatus.OPERATION_STATUS_OK;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;

import android.app.time.LocationTimeZoneAlgorithmStatus.ProviderStatus;
import android.service.timezone.TimeZoneProviderStatus;
@@ -207,4 +214,114 @@ public class LocationTimeZoneAlgorithmStatusTest {
        assertEquals(status,
                LocationTimeZoneAlgorithmStatus.parseCommandlineArg(status.toString()));
    }

    @Test
    public void testCouldEnableTelephonyFallback_notRunning() {
        LocationTimeZoneAlgorithmStatus notRunning =
                new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_NOT_RUNNING,
                        PROVIDER_STATUS_NOT_READY, null, PROVIDER_STATUS_NOT_READY, null);
        assertFalse(notRunning.couldEnableTelephonyFallback());
    }

    @Test
    public void testCouldEnableTelephonyFallback_unknown() {
        // DETECTION_ALGORITHM_STATUS_UNKNOWN must never allow fallback
        LocationTimeZoneAlgorithmStatus unknown =
                new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_UNKNOWN,
                        PROVIDER_STATUS_NOT_READY, null, PROVIDER_STATUS_NOT_READY, null);
        assertFalse(unknown.couldEnableTelephonyFallback());
    }

    @Test
    public void testCouldEnableTelephonyFallback_notSupported() {
        // DETECTION_ALGORITHM_STATUS_NOT_SUPPORTED must never allow fallback
        LocationTimeZoneAlgorithmStatus notSupported =
                new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_NOT_SUPPORTED,
                        PROVIDER_STATUS_NOT_READY, null, PROVIDER_STATUS_NOT_READY, null);
        assertFalse(notSupported.couldEnableTelephonyFallback());
    }

    @Test
    public void testCouldEnableTelephonyFallback_running() {
        // DETECTION_ALGORITHM_STATUS_RUNNING may allow fallback

        // Sample provider-reported statuses that do / do not enable fallback.
        TimeZoneProviderStatus enableTelephonyFallbackProviderStatus =
                new TimeZoneProviderStatus.Builder()
                        .setLocationDetectionDependencyStatus(
                                DEPENDENCY_STATUS_BLOCKED_BY_ENVIRONMENT)
                        .setConnectivityDependencyStatus(DEPENDENCY_STATUS_NOT_APPLICABLE)
                        .setTimeZoneResolutionOperationStatus(OPERATION_STATUS_NOT_APPLICABLE)
                        .build();
        assertTrue(enableTelephonyFallbackProviderStatus.couldEnableTelephonyFallback());

        TimeZoneProviderStatus notEnableTelephonyFallbackProviderStatus =
                new TimeZoneProviderStatus.Builder()
                        .setLocationDetectionDependencyStatus(DEPENDENCY_STATUS_NOT_APPLICABLE)
                        .setConnectivityDependencyStatus(DEPENDENCY_STATUS_NOT_APPLICABLE)
                        .setTimeZoneResolutionOperationStatus(OPERATION_STATUS_NOT_APPLICABLE)
                        .build();
        assertFalse(notEnableTelephonyFallbackProviderStatus.couldEnableTelephonyFallback());

        // Provider not ready: Never enable fallback
        {
            LocationTimeZoneAlgorithmStatus status =
                    new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_RUNNING,
                            PROVIDER_STATUS_NOT_READY, null, PROVIDER_STATUS_NOT_READY, null);
            assertFalse(status.couldEnableTelephonyFallback());
        }

        // Provider uncertain without reported status: Never enable fallback
        {
            LocationTimeZoneAlgorithmStatus status =
                    new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_RUNNING,
                            PROVIDER_STATUS_IS_UNCERTAIN, null, PROVIDER_STATUS_NOT_READY, null);
            assertFalse(status.couldEnableTelephonyFallback());
        }
        {
            LocationTimeZoneAlgorithmStatus status =
                    new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_RUNNING,
                            PROVIDER_STATUS_IS_UNCERTAIN, null, PROVIDER_STATUS_NOT_PRESENT, null);
            assertFalse(status.couldEnableTelephonyFallback());
        }

        // Provider uncertain with reported status: Fallback is based on the status for present
        // providers that report their status. All present providers must have reported status and
        // agree that fallback is a good idea.
        {
            LocationTimeZoneAlgorithmStatus status =
                    new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_RUNNING,
                            PROVIDER_STATUS_IS_UNCERTAIN, enableTelephonyFallbackProviderStatus,
                            PROVIDER_STATUS_NOT_READY, null);
            assertFalse(status.couldEnableTelephonyFallback());
        }
        {
            LocationTimeZoneAlgorithmStatus status =
                    new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_RUNNING,
                            PROVIDER_STATUS_IS_UNCERTAIN, enableTelephonyFallbackProviderStatus,
                            PROVIDER_STATUS_NOT_PRESENT, null);
            assertTrue(status.couldEnableTelephonyFallback());
        }
        {
            LocationTimeZoneAlgorithmStatus status =
                    new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_RUNNING,
                            PROVIDER_STATUS_IS_UNCERTAIN, enableTelephonyFallbackProviderStatus,
                            PROVIDER_STATUS_IS_UNCERTAIN, enableTelephonyFallbackProviderStatus);
            assertTrue(status.couldEnableTelephonyFallback());
        }
        {
            LocationTimeZoneAlgorithmStatus status =
                    new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_RUNNING,
                            PROVIDER_STATUS_IS_UNCERTAIN, enableTelephonyFallbackProviderStatus,
                            PROVIDER_STATUS_IS_UNCERTAIN, notEnableTelephonyFallbackProviderStatus);
            assertFalse(status.couldEnableTelephonyFallback());
        }
        {
            LocationTimeZoneAlgorithmStatus status =
                    new LocationTimeZoneAlgorithmStatus(DETECTION_ALGORITHM_STATUS_RUNNING,
                            PROVIDER_STATUS_NOT_PRESENT, null,
                            PROVIDER_STATUS_IS_UNCERTAIN, enableTelephonyFallbackProviderStatus);
            assertTrue(status.couldEnableTelephonyFallback());
        }
    }
}
+63 −0
Original line number Diff line number Diff line
@@ -16,15 +16,31 @@

package android.service.timezone;

import static android.service.timezone.TimeZoneProviderStatus.DEPENDENCY_STATUS_BLOCKED_BY_ENVIRONMENT;
import static android.service.timezone.TimeZoneProviderStatus.DEPENDENCY_STATUS_BLOCKED_BY_SETTINGS;
import static android.service.timezone.TimeZoneProviderStatus.DEPENDENCY_STATUS_OK;
import static android.service.timezone.TimeZoneProviderStatus.DEPENDENCY_STATUS_UNKNOWN;
import static android.service.timezone.TimeZoneProviderStatus.OPERATION_STATUS_FAILED;
import static android.service.timezone.TimeZoneProviderStatus.OPERATION_STATUS_OK;
import static android.service.timezone.TimeZoneProviderStatus.OPERATION_STATUS_UNKNOWN;

import static org.junit.Assert.assertEquals;

import android.service.timezone.TimeZoneProviderStatus.DependencyStatus;
import android.service.timezone.TimeZoneProviderStatus.OperationStatus;

import org.junit.Test;
import org.junit.runner.RunWith;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;

import junitparams.JUnitParamsRunner;
import junitparams.Parameters;

/** Non-SDK tests. See CTS for SDK API tests. */
@RunWith(JUnitParamsRunner.class)
public class TimeZoneProviderStatusTest {

    @Test
@@ -37,4 +53,51 @@ public class TimeZoneProviderStatusTest {

        assertEquals(status, TimeZoneProviderStatus.parseProviderStatus(status.toString()));
    }

    @Test
    @Parameters(method = "couldEnableTelephonyFallbackParams")
    public void couldEnableTelephonyFallback(@DependencyStatus int locationDetectionStatus,
            @DependencyStatus int connectivityStatus, @OperationStatus int tzResolutionStatus) {
        TimeZoneProviderStatus providerStatus =
                new TimeZoneProviderStatus.Builder()
                        .setLocationDetectionDependencyStatus(locationDetectionStatus)
                        .setConnectivityDependencyStatus(connectivityStatus)
                        .setTimeZoneResolutionOperationStatus(tzResolutionStatus)
                        .build();
        boolean locationDetectionStatusCouldEnableFallback =
                (locationDetectionStatus == DEPENDENCY_STATUS_BLOCKED_BY_ENVIRONMENT
                        || locationDetectionStatus == DEPENDENCY_STATUS_BLOCKED_BY_SETTINGS);
        boolean connectivityStatusCouldEnableFallback =
                (connectivityStatus == DEPENDENCY_STATUS_BLOCKED_BY_ENVIRONMENT
                        || connectivityStatus == DEPENDENCY_STATUS_BLOCKED_BY_SETTINGS);
        boolean tzResolutionStatusCouldEnableFallback = false;

        assertEquals(locationDetectionStatusCouldEnableFallback
                        || connectivityStatusCouldEnableFallback
                        || tzResolutionStatusCouldEnableFallback,
                providerStatus.couldEnableTelephonyFallback());
    }

    public static Integer[][] couldEnableTelephonyFallbackParams() {
        List<Integer[]> params = new ArrayList<>();
        @DependencyStatus int[] dependencyStatuses =
                IntStream.rangeClosed(
                        DEPENDENCY_STATUS_UNKNOWN, DEPENDENCY_STATUS_BLOCKED_BY_SETTINGS).toArray();
        @OperationStatus int[] operationStatuses =
                IntStream.rangeClosed(OPERATION_STATUS_UNKNOWN, OPERATION_STATUS_FAILED).toArray();

        // Cartesian product: dependencyStatus x dependencyStatus x operationStatus
        for (@DependencyStatus int locationDetectionStatus : dependencyStatuses) {
            for (@DependencyStatus int connectivityStatus : dependencyStatuses) {
                for (@OperationStatus int tzResolutionStatus : operationStatuses) {
                    params.add(new Integer[] {
                            locationDetectionStatus,
                            connectivityStatus,
                            tzResolutionStatus
                    });
                }
            }
        }
        return params.toArray(new Integer[0][0]);
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
            deviceActivityMonitor.addListener(new DeviceActivityMonitor.Listener() {
                @Override
                public void onFlightComplete() {
                    timeZoneDetectorStrategy.enableTelephonyTimeZoneFallback();
                    timeZoneDetectorStrategy.enableTelephonyTimeZoneFallback("onFlightComplete()");
                }
            });

@@ -402,9 +402,9 @@ public final class TimeZoneDetectorService extends ITimeZoneDetectorService.Stub
     * Sends a signal to enable telephony fallback. Provided for command-line access for use
     * during tests. This is not exposed as a binder API.
     */
    void enableTelephonyFallback() {
    void enableTelephonyFallback(@NonNull String reason) {
        enforceManageTimeZoneDetectorPermission();
        mTimeZoneDetectorStrategy.enableTelephonyTimeZoneFallback();
        mTimeZoneDetectorStrategy.enableTelephonyTimeZoneFallback(reason);
    }

    /**
Loading