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

Commit 61ea56e6 authored by Jack Yu's avatar Jack Yu Committed by Android (Google) Code Review
Browse files

Merge "Satellite Internet Support" into main

parents e129e095 73049250
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -1435,6 +1435,18 @@ public class DataConfigManager extends Handler {
                com.android.internal.R.bool.config_honor_data_retry_timer_for_emergency_network);
    }

    /**
     * @return The capabilities that network will be forced to mark as cellular transport.
     */
    public @NetCapability Set<Integer> getForcedCellularTransportCapabilities() {
        String[] forcedCellularTransportCapabilities = mResources.getStringArray(
                com.android.internal.R.array.config_force_cellular_transport_capabilities);

        return Arrays.stream(forcedCellularTransportCapabilities)
                .map(DataUtils::getNetworkCapabilityFromString)
                .collect(Collectors.toSet());
    }

    /**
     * Log debug messages.
     * @param s debug messages
@@ -1543,6 +1555,9 @@ public class DataConfigManager extends Handler {
        pw.println("isTetheringProfileDisabledForRoaming="
                + isTetheringProfileDisabledForRoaming());
        pw.println("allowClearInitialAttachDataProfile=" + allowClearInitialAttachDataProfile());
        pw.println("forcedCellularTransportCapabilities=" + getForcedCellularTransportCapabilities()
                .stream().map(DataUtils::networkCapabilityToString)
                .collect(Collectors.joining(",")));
        pw.decreaseIndent();
    }
}
+3 −1
Original line number Diff line number Diff line
@@ -346,7 +346,9 @@ public class DataEvaluation {
        /** Handover max retry stopped but network is not on the preferred transport. */
        HANDOVER_RETRY_STOPPED(true),
        /** BootStrap sim data limit reached. */
        DATA_LIMIT_REACHED(true);
        DATA_LIMIT_REACHED(true),
        /** Data network connectivity transport not allowed. */
        DATA_NETWORK_TRANSPORT_NOT_ALLOWED(true);

        private final boolean mIsHardReason;

+36 −3
Original line number Diff line number Diff line
@@ -314,6 +314,7 @@ public class DataNetwork extends StateMachine {
                    TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK,
                    TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED,
                    TEAR_DOWN_REASON_DATA_LIMIT_REACHED,
                    TEAR_DOWN_REASON_DATA_NETWORK_TRANSPORT_NOT_ALLOWED,
            })
    public @interface TearDownReason {}

@@ -413,6 +414,9 @@ public class DataNetwork extends StateMachine {
    /** Data network tear down due to bootstrap sim data limit reached. */
    public static final int TEAR_DOWN_REASON_DATA_LIMIT_REACHED = 31;

    /** Data network tear down due to current data network transport mismatch. */
    public static final int TEAR_DOWN_REASON_DATA_NETWORK_TRANSPORT_NOT_ALLOWED = 32;

    //********************************************************************************************//
    // WHENEVER ADD A NEW TEAR DOWN REASON, PLEASE UPDATE DataDeactivateReasonEnum in enums.proto //
    //********************************************************************************************//
@@ -698,6 +702,11 @@ public class DataNetwork extends StateMachine {
     */
    private boolean mLastKnownRoamingState;

    /**
     * The non-terrestrial status
     */
    private final boolean mIsSatellite;

    /** The reason that why setting up this data network is allowed. */
    private @NonNull DataAllowedReason mDataAllowedReason;

@@ -988,6 +997,8 @@ public class DataNetwork extends StateMachine {
        mTransport = transport;
        mLastKnownDataNetworkType = getDataNetworkType();
        mLastKnownRoamingState = mPhone.getServiceState().getDataRoamingFromRegistration();
        mIsSatellite = mPhone.getServiceState().isUsingNonTerrestrialNetwork()
                && transport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
        mDataAllowedReason = dataAllowedReason;
        dataProfile.setLastSetupTimestamp(SystemClock.elapsedRealtime());
        mAttachedNetworkRequestList.addAll(networkRequestList);
@@ -2213,12 +2224,27 @@ public class DataNetwork extends StateMachine {
        }
    }

    /**
     * @return {@code true} if this is a satellite data network.
     */
    public boolean isSatellite() {
        return mIsSatellite;
    }

    /**
     * Update the network capabilities.
     */
    private void updateNetworkCapabilities() {
        final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder()
                .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
        final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder();

        if (mFlags.carrierEnabledSatelliteFlag() && mIsSatellite
                && mDataConfigManager.getForcedCellularTransportCapabilities().stream()
                .noneMatch(this::hasNetworkCapabilityInNetworkRequests)) {
            builder.addTransportType(NetworkCapabilities.TRANSPORT_SATELLITE);
        } else {
            builder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
        }

        boolean roaming = mPhone.getServiceState().getDataRoaming();

        builder.setNetworkSpecifier(new TelephonyNetworkSpecifier.Builder()
@@ -2385,6 +2411,11 @@ public class DataNetwork extends StateMachine {
            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
        }

        // mark the network as restricted when service state is non-terrestrial(satellite network)
        if (mFlags.carrierEnabledSatelliteFlag() && mIsSatellite) {
            builder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
        }

        // Check if the feature force MMS on IWLAN is enabled. When the feature is enabled, MMS
        // will be attempted on IWLAN if possible, even if existing cellular networks already
        // supports IWLAN.
@@ -2401,7 +2432,7 @@ public class DataNetwork extends StateMachine {
                DataProfile dataProfile = mDataNetworkController.getDataProfileManager()
                        .getDataProfileForNetworkRequest(new TelephonyNetworkRequest(
                                new NetworkRequest.Builder().addCapability(
                                NetworkCapabilities.NET_CAPABILITY_MMS).build(), mPhone),
                                NetworkCapabilities.NET_CAPABILITY_MMS).build(), mPhone, mFlags),
                        TelephonyManager.NETWORK_TYPE_IWLAN, false, false, false);
                // If we find another data data profile that can support MMS on IWLAN, then remove
                // the MMS capability from this cellular network. This will allow IWLAN to be
@@ -3790,6 +3821,8 @@ public class DataNetwork extends StateMachine {
                return "TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED";
            case TEAR_DOWN_REASON_DATA_LIMIT_REACHED:
                return "TEAR_DOWN_REASON_DATA_LIMIT_REACHED";
            case TEAR_DOWN_REASON_DATA_NETWORK_TRANSPORT_NOT_ALLOWED:
                return "TEAR_DOWN_REASON_DATA_NETWORK_TRANSPORT_NOT_ALLOWED";
            default:
                return "UNKNOWN(" + reason + ")";
        }
+98 −55
Original line number Diff line number Diff line
@@ -1455,7 +1455,7 @@ public class DataNetworkController extends Handler {
                new NetworkRequest.Builder()
                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                        .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                        .build(), mPhone);
                        .build(), mPhone, mFeatureFlags);
        // If we don't skip checking existing network, then we should check If one of the
        // existing networks can satisfy the internet request, then internet is allowed.
        if ((!mFeatureFlags.ignoreExistingNetworksForInternetAllowedChecking()
@@ -1515,7 +1515,7 @@ public class DataNetworkController extends Handler {
                new NetworkRequest.Builder()
                        .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                        .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
                        .build(), mPhone);
                        .build(), mPhone, mFeatureFlags);
        DataEvaluation evaluation = evaluateNetworkRequest(internetRequest,
                DataEvaluationReason.EXTERNAL_QUERY);
        return evaluation.getDataDisallowedReasons();
@@ -1535,6 +1535,13 @@ public class DataNetworkController extends Handler {
        int transport = mAccessNetworksManager.getPreferredTransportByNetworkCapability(
                networkRequest.getApnTypeNetworkCapability());

        // Check if the request can be satisfied by cellular network or satellite network.
        if (mFeatureFlags.carrierEnabledSatelliteFlag()
                && !canConnectivityTransportSatisfyNetworkRequest(networkRequest, transport)) {
            evaluation.addDataDisallowedReason(
                    DataDisallowedReason.DATA_NETWORK_TRANSPORT_NOT_ALLOWED);
        }

        // Bypass all checks for emergency network request.
        if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_EIMS)) {
            DataProfile emergencyProfile = mDataProfileManager.getDataProfileForNetworkRequest(
@@ -1549,15 +1556,14 @@ public class DataNetworkController extends Handler {
                evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_THROTTLED);
                log("Emergency network request is throttled by the previous setup data "
                            + "call response.");
                log(evaluation.toString());
                networkRequest.setEvaluation(evaluation);
                return evaluation;
            }

            if (!evaluation.containsDisallowedReasons()) {
                evaluation.addDataAllowedReason(DataAllowedReason.EMERGENCY_REQUEST);
                if (emergencyProfile != null) {
                    evaluation.setCandidateDataProfile(emergencyProfile);
                }
            }
            networkRequest.setEvaluation(evaluation);
            log(evaluation.toString());
            return evaluation;
@@ -1645,11 +1651,6 @@ public class DataNetworkController extends Handler {
            evaluation.addDataDisallowedReason(DataDisallowedReason.CDMA_EMERGENCY_CALLBACK_MODE);
        }

        // Check whether data is disallowed while using satellite
        if (isDataDisallowedDueToSatellite(networkRequest.getCapabilities())) {
            evaluation.addDataDisallowedReason(DataDisallowedReason.SERVICE_OPTION_NOT_SUPPORTED);
        }

        // Check if only one data network is allowed.
        if (isOnlySingleDataNetworkAllowed(transport)
                && !hasCapabilityExemptsFromSinglePdnRule(networkRequest.getCapabilities())) {
@@ -1822,7 +1823,7 @@ public class DataNetworkController extends Handler {
                networkRequestList.add(networkRequest);
            }
        }
        return DataUtils.getGroupedNetworkRequestList(networkRequestList);
        return DataUtils.getGroupedNetworkRequestList(networkRequestList, mFeatureFlags);
    }

    /**
@@ -1891,10 +1892,26 @@ public class DataNetworkController extends Handler {
            evaluation.addDataDisallowedReason(DataDisallowedReason.CDMA_EMERGENCY_CALLBACK_MODE);
        }

        // Check whether data is disallowed while using satellite
        if (isDataDisallowedDueToSatellite(dataNetwork.getNetworkCapabilities()
                .getCapabilities())) {
            evaluation.addDataDisallowedReason(DataDisallowedReason.SERVICE_OPTION_NOT_SUPPORTED);
        // If the network is satellite, then the network must be restricted.
        if (mFeatureFlags.carrierEnabledSatelliteFlag()) {
            // The IWLAN data network should remain intact even when satellite is connected.
            if (dataNetwork.getTransport() != AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
                // On satellite, every data network needs to be restricted.
                if (mServiceState.isUsingNonTerrestrialNetwork()
                        && dataNetwork.getNetworkCapabilities()
                        .hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)) {
                    evaluation.addDataDisallowedReason(
                            DataDisallowedReason.DATA_NETWORK_TRANSPORT_NOT_ALLOWED);
                }

                // Check if the transport is compatible with the network
                if (mServiceState.isUsingNonTerrestrialNetwork() != dataNetwork.isSatellite()) {
                    // Since we don't support satellite/cellular network handover, we should always
                    // tear down the network when transport changes.
                    evaluation.addDataDisallowedReason(
                            DataDisallowedReason.DATA_NETWORK_TRANSPORT_NOT_ALLOWED);
                }
            }
        }

        // Check whether data limit reached for bootstrap sim, else re-evaluate based on the timer
@@ -2081,6 +2098,65 @@ public class DataNetworkController extends Handler {
        return evaluation;
    }

    /**
     * Check if the transport from connectivity service can satisfy the network request. Note the
     * transport here is connectivity service's transport (Wifi, cellular, satellite, etc..), not
     * the widely used {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN WLAN},
     * {@link AccessNetworkConstants#TRANSPORT_TYPE_WWAN WWAN} transport in telephony.
     *
     * @param networkRequest Network request
     * @param transport The preferred transport type for the request. The transport here is
     * WWAN/WLAN.
     * @return {@code true} if the connectivity transport can satisfy the network request, otherwise
     * {@code false}.
     */
    private boolean canConnectivityTransportSatisfyNetworkRequest(
            @NonNull TelephonyNetworkRequest networkRequest, @TransportType int transport) {
        // When the device is on satellite, only restricted network request can request network.
        if (mServiceState.isUsingNonTerrestrialNetwork()
                && networkRequest.getNativeNetworkRequest().hasCapability(
                        NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)) {
            return false;
        }

        // If the network request does not specify cellular or satellite, then it can be
        // satisfied when the device is either on cellular ot satellite.
        if (!networkRequest.getNativeNetworkRequest().hasTransport(
                NetworkCapabilities.TRANSPORT_CELLULAR)
                && !networkRequest.getNativeNetworkRequest().hasTransport(
                        NetworkCapabilities.TRANSPORT_SATELLITE)) {
            return true;
        }

        // Check if this is a IWLAN network request.
        if (networkRequest.getNativeNetworkRequest().hasTransport(
                NetworkCapabilities.TRANSPORT_CELLULAR)
                && transport == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
            // If the cellular request would result in bringing up network on IWLAN, then no
            // need to check if the device is using satellite network.
            return true;
        }

        // As a short term solution, allowing some networks to be always marked as cellular
        // transport if certain capabilities are in the network request.
        if (networkRequest.getNativeNetworkRequest().hasTransport(
                NetworkCapabilities.TRANSPORT_CELLULAR) && Arrays.stream(
                        networkRequest.getCapabilities())
                .anyMatch(mDataConfigManager.getForcedCellularTransportCapabilities()::contains)) {
            return true;
        }

        // If the network is cellular, then the request must specify cellular transport. Or if the
        // the network is satellite, then the request must specify satellite transport and
        // restricted.
        return (mServiceState.isUsingNonTerrestrialNetwork()
                && networkRequest.getNativeNetworkRequest().hasTransport(
                        NetworkCapabilities.TRANSPORT_SATELLITE))
                || (!mServiceState.isUsingNonTerrestrialNetwork()
                        && networkRequest.getNativeNetworkRequest().hasTransport(
                        NetworkCapabilities.TRANSPORT_CELLULAR));
    }

    /**
     * tethering and enterprise capabilities are not respected as restricted requests. For a request
     * with these capabilities, any soft disallowed reasons are honored.
@@ -2300,6 +2376,8 @@ public class DataNetworkController extends Handler {
                    return DataNetwork.TEAR_DOWN_REASON_HANDOVER_FAILED;
                case DATA_LIMIT_REACHED:
                    return DataNetwork.TEAR_DOWN_REASON_DATA_LIMIT_REACHED;
                case DATA_NETWORK_TRANSPORT_NOT_ALLOWED:
                    return DataNetwork.TEAR_DOWN_REASON_DATA_NETWORK_TRANSPORT_NOT_ALLOWED;
            }
        }
        return DataNetwork.TEAR_DOWN_REASON_NONE;
@@ -3590,7 +3668,7 @@ public class DataNetworkController extends Handler {
            return true;
        }

        if (!oldNri.isNonTerrestrialNetwork() && newNri.isNonTerrestrialNetwork()) {
        if (oldNri.isNonTerrestrialNetwork() != newNri.isNonTerrestrialNetwork()) {
            return true;
        }

@@ -3647,7 +3725,7 @@ public class DataNetworkController extends Handler {
            return true;
        }

        if (oldSS.isUsingNonTerrestrialNetwork() && !newSS.isUsingNonTerrestrialNetwork()) {
        if (oldSS.isUsingNonTerrestrialNetwork() != newSS.isUsingNonTerrestrialNetwork()) {
            return true;
        }

@@ -4022,41 +4100,6 @@ public class DataNetworkController extends Handler {
        return packages;
    }

    /**
     * Check whether data is disallowed while using satellite
     * @param capabilities An array of the NetworkCapabilities to be checked
     * @return {@code true} if the capabilities contain any capability that are restricted
     * while using satellite else {@code false}
     */
    private boolean isDataDisallowedDueToSatellite(@NetCapability int[] capabilities) {
        if (!mFeatureFlags.carrierEnabledSatelliteFlag()) {
            return false;
        }

        if (!mServiceState.isUsingNonTerrestrialNetwork()) {
            // Device is not connected to satellite
            return false;
        }

        Set<Integer> restrictedCapabilities = Set.of(NetworkCapabilities.NET_CAPABILITY_INTERNET);
        if (Arrays.stream(capabilities).noneMatch(restrictedCapabilities::contains)) {
            // Only internet data disallowed while using satellite
            return false;
        }

        for (NetworkRegistrationInfo nri : mServiceState.getNetworkRegistrationInfoList()) {
            if (nri.isNonTerrestrialNetwork()
                    && nri.getAvailableServices().contains(
                            NetworkRegistrationInfo.SERVICE_TYPE_DATA)) {
                // Data is supported while using satellite
                return false;
            }
        }

        // Data is disallowed while using satellite
        return true;
    }

    /**
     * Request network validation.
     *
+1 −1
Original line number Diff line number Diff line
@@ -899,7 +899,7 @@ public class DataProfileManager extends Handler {
        TelephonyNetworkRequest networkRequest = new TelephonyNetworkRequest(
                new NetworkRequest.Builder()
                        .addCapability(NetworkCapabilities.NET_CAPABILITY_DUN)
                        .build(), mPhone);
                        .build(), mPhone, mFeatureFlags);
        return getDataProfileForNetworkRequest(networkRequest, networkType,
                mPhone.getServiceState().isUsingNonTerrestrialNetwork(),
                mDataNetworkController.isEsimBootStrapProvisioningActivated(),
Loading