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

Commit a88393db authored by Jack Yu's avatar Jack Yu
Browse files

Separate AccessNetworkManager from TransportManager

Moved partial TransportManager logic into AccessNetworksManager.
This is the preliminary step to remove TransportManager in data
redesign.

Bug: 196597630
Test: atest FrameworksTelephonyTests & manual test
Merged-In: I679368636b97a49814bbfec362c06b419a27af37
Change-Id: I679368636b97a49814bbfec362c06b419a27af37
parent a68a4914
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.cdma.CdmaMmiCode;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
import com.android.internal.telephony.data.DataNetworkController;
import com.android.internal.telephony.dataconnection.AccessNetworksManager;
import com.android.internal.telephony.dataconnection.DataEnabledSettings;
import com.android.internal.telephony.dataconnection.DcTracker;
import com.android.internal.telephony.dataconnection.LinkBandwidthEstimator;
@@ -307,6 +308,9 @@ public class GsmCdmaPhone extends Phone {
                .makeCarrierActionAgent(this);
        mCarrierSignalAgent = mTelephonyComponentFactory.inject(CarrierSignalAgent.class.getName())
                .makeCarrierSignalAgent(this);
        mAccessNetworksManager = mTelephonyComponentFactory
                .inject(AccessNetworksManager.class.getName())
                .makeAccessNetworksManager(this);
        mTransportManager = mTelephonyComponentFactory.inject(TransportManager.class.getName())
                .makeTransportManager(this);
        // SST/DSM depends on SSC, so SSC is instanced before SST/DSM
@@ -654,6 +658,11 @@ public class GsmCdmaPhone extends Phone {
        return mTransportManager;
    }

    @Override
    public AccessNetworksManager getAccessNetworksManager() {
        return mAccessNetworksManager;
    }

    @Override
    public DeviceStateMonitor getDeviceStateMonitor() {
        return mDeviceStateMonitor;
+10 −1
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ import com.android.ims.ImsManager;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.data.DataNetworkController;
import com.android.internal.telephony.dataconnection.AccessNetworksManager;
import com.android.internal.telephony.dataconnection.DataConnectionReasons;
import com.android.internal.telephony.dataconnection.DataEnabledSettings;
import com.android.internal.telephony.dataconnection.DcTracker;
@@ -345,6 +346,7 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
    protected DeviceStateMonitor mDeviceStateMonitor;
    protected DisplayInfoController mDisplayInfoController;
    protected TransportManager mTransportManager;
    protected AccessNetworksManager mAccessNetworksManager;
    protected DataEnabledSettings mDataEnabledSettings;
    // Used for identify the carrier of current subscription
    protected CarrierResolver mCarrierResolver;
@@ -1885,12 +1887,19 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
    }

    /**
     * @return The instance of transport manager
     * @return The instance of transport manager.
     */
    public TransportManager getTransportManager() {
        return null;
    }

    /**
     * @return The instance of access networks manager.
     */
    public AccessNetworksManager getAccessNetworksManager() {
        return null;
    }

    /**
     * Retrieves the DeviceStateMonitor of the phone instance.
     */
+11 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import com.android.ims.ImsManager;
import com.android.internal.telephony.cdma.CdmaSubscriptionSourceManager;
import com.android.internal.telephony.cdma.EriManager;
import com.android.internal.telephony.data.DataNetworkController;
import com.android.internal.telephony.dataconnection.AccessNetworksManager;
import com.android.internal.telephony.dataconnection.DataEnabledSettings;
import com.android.internal.telephony.dataconnection.DcTracker;
import com.android.internal.telephony.dataconnection.LinkBandwidthEstimator;
@@ -403,6 +404,16 @@ public class TelephonyComponentFactory {
        return new TransportManager(phone);
    }

    /**
     * Make access networks manager
     *
     * @param phone The phone instance
     * @return The access networks manager
     */
    public AccessNetworksManager makeAccessNetworksManager(Phone phone) {
        return new AccessNetworksManager(phone);
    }

    public CdmaSubscriptionSourceManager
    getCdmaSubscriptionSourceManagerInstance(Context context, CommandsInterface ci, Handler h,
                                             int what, Object obj) {
+4 −58
Original line number Diff line number Diff line
@@ -17,14 +17,12 @@
package com.android.internal.telephony.data;

import android.annotation.NonNull;
import android.annotation.StringDef;
import android.net.NetworkAgent;
import android.net.NetworkRequest;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RegistrantList;
import android.os.SystemProperties;
import android.telephony.AccessNetworkConstants;
import android.telephony.data.DataProfile;
import android.util.IndentingPrintWriter;
@@ -34,13 +32,11 @@ import android.util.SparseArray;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.RIL;
import com.android.internal.telephony.dataconnection.AccessNetworksManager;
import com.android.telephony.Rlog;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@@ -52,36 +48,6 @@ import java.util.List;
public class DataNetworkController extends Handler {
    private final boolean VDBG;

    public static final String SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE =
            "ro.telephony.iwlan_operation_mode";

    @Retention(RetentionPolicy.SOURCE)
    @StringDef(prefix = {"IWLAN_OPERATION_MODE_"},
            value = {
                    IWLAN_OPERATION_MODE_DEFAULT,
                    IWLAN_OPERATION_MODE_LEGACY,
                    IWLAN_OPERATION_MODE_AP_ASSISTED})
    public @interface IwlanOperationMode {}

    /**
     * IWLAN default mode. On device that has IRadio 1.4 or above, it means
     * {@link #IWLAN_OPERATION_MODE_AP_ASSISTED}. On device that has IRadio 1.3 or below, it means
     * {@link #IWLAN_OPERATION_MODE_LEGACY}.
     */
    public static final String IWLAN_OPERATION_MODE_DEFAULT = "default";

    /**
     * IWLAN legacy mode. IWLAN is completely handled by the modem, and when the device is on
     * IWLAN, modem reports IWLAN as a RAT.
     */
    public static final String IWLAN_OPERATION_MODE_LEGACY = "legacy";

    /**
     * IWLAN application processor assisted mode. IWLAN is handled by the bound IWLAN data service
     * and network service separately.
     */
    public static final String IWLAN_OPERATION_MODE_AP_ASSISTED = "AP-assisted";

    /** Event for data config updated. */
    private static final int EVENT_DATA_CONFIG_UPDATED = 1;

@@ -109,6 +75,7 @@ public class DataNetworkController extends Handler {
    private final @NonNull DataProfileManager mDataProfileManager;
    private final @NonNull DataStallRecoveryManager mDataStallRecoveryManager;
    private final @NonNull DataTaskManager mDataTaskManager;
    private final @NonNull AccessNetworksManager mAccessNetworksManager;
    private final @NonNull SparseArray<DataServiceManager> mDataServiceManagers =
            new SparseArray<>();

@@ -209,9 +176,10 @@ public class DataNetworkController extends Handler {
        VDBG = Rlog.isLoggable(mLogTag, Log.VERBOSE);
        log("DataNetworkController created.");

        mAccessNetworksManager = phone.getAccessNetworksManager();
        mDataServiceManagers.put(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                new DataServiceManager(mPhone, looper, AccessNetworkConstants.TRANSPORT_TYPE_WWAN));
        if (!isIwlanLegacyMode()) {
        if (!mAccessNetworksManager.isInLegacyMode()) {
            mDataServiceManagers.put(AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
                    new DataServiceManager(mPhone, looper,
                            AccessNetworkConstants.TRANSPORT_TYPE_WWAN));
@@ -402,26 +370,6 @@ public class DataNetworkController extends Handler {
        return mDataConfigManager;
    }

    /**
     * @return {@code true} if the device operates in IWLAN legacy mode, otherwise {@code false}. In
     * legacy mode, IWLAN registration state is reported through cellular
     * {@link android.telephony.NetworkRegistrationInfo}.
     */
    public boolean isIwlanLegacyMode() {
        // Get IWLAN operation mode from the system property. If the system property is configured
        // to default or not configured, the mode is tied to IRadio version. For 1.4 or above, it's
        // AP-assisted mode, for 1.3 or below, it's legacy mode.
        String mode = SystemProperties.get(SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE);

        if (mode.equals(IWLAN_OPERATION_MODE_AP_ASSISTED)) {
            return false;
        } else if (mode.equals(IWLAN_OPERATION_MODE_LEGACY)) {
            return true;
        }

        return mPhone.getHalVersion().less(RIL.RADIO_HAL_VERSION_1_4);
    }

    /**
     * Register for internet data network validation status changed event.
     *
@@ -476,8 +424,6 @@ public class DataNetworkController extends Handler {
        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
        pw.println(DataNetworkController.class.getSimpleName() + "-" + mPhone.getPhoneId() + ":");
        pw.increaseIndent();
        pw.println("IWLAN operation mode="
                + SystemProperties.get(SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE));
        pw.println("Current data networks:");
        pw.increaseIndent();
        for (DataNetwork dn : mDataNetworkList) {
+231 −13
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.internal.telephony.dataconnection;

import android.annotation.NonNull;
import android.annotation.StringDef;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -30,8 +31,11 @@ import android.os.PersistableBundle;
import android.os.Registrant;
import android.os.RegistrantList;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.telephony.AccessNetworkConstants;
import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.Annotation.ApnType;
import android.telephony.AnomalyReporter;
import android.telephony.CarrierConfigManager;
@@ -41,17 +45,26 @@ import android.telephony.data.IQualifiedNetworksServiceCallback;
import android.telephony.data.QualifiedNetworksService;
import android.telephony.data.ThrottleStatus;
import android.text.TextUtils;
import android.util.IndentingPrintWriter;
import android.util.LocalLog;
import android.util.SparseArray;

import com.android.internal.telephony.Phone;
import com.android.internal.telephony.RIL;
import com.android.telephony.Rlog;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
@@ -60,8 +73,39 @@ import java.util.stream.Collectors;
 * networks changes.
 */
public class AccessNetworksManager extends Handler {
    private final String mLogTag;
    private static final boolean DBG = false;
    public static final String SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE =
            "ro.telephony.iwlan_operation_mode";

    @Retention(RetentionPolicy.SOURCE)
    @StringDef(prefix = {"IWLAN_OPERATION_MODE_"},
            value = {
                    IWLAN_OPERATION_MODE_DEFAULT,
                    IWLAN_OPERATION_MODE_LEGACY,
                    IWLAN_OPERATION_MODE_AP_ASSISTED})
    public @interface IwlanOperationMode {}

    /**
     * IWLAN default mode. On device that has IRadio 1.4 or above, it means
     * {@link #IWLAN_OPERATION_MODE_AP_ASSISTED}. On device that has IRadio 1.3 or below, it means
     * {@link #IWLAN_OPERATION_MODE_LEGACY}.
     */
    public static final String IWLAN_OPERATION_MODE_DEFAULT = "default";

    /**
     * IWLAN legacy mode. IWLAN is completely handled by the modem, and when the device is on
     * IWLAN, modem reports IWLAN as a RAT.
     */
    public static final String IWLAN_OPERATION_MODE_LEGACY = "legacy";

    /**
     * IWLAN application processor assisted mode. IWLAN is handled by the bound IWLAN data service
     * and network service separately.
     */
    public static final String IWLAN_OPERATION_MODE_AP_ASSISTED = "AP-assisted";

    private final String mLogTag;
    private final LocalLog mLocalLog = new LocalLog(64);
    private final UUID mAnomalyUUID = UUID.fromString("c2d1a639-00e2-4561-9619-6acf37d90590");
    private String mLastBoundPackageName;

@@ -91,6 +135,8 @@ public class AccessNetworksManager extends Handler {
    // Available networks. Key is the APN type.
    private final SparseArray<int[]> mAvailableNetworks = new SparseArray<>();

    private final @TransportType int[] mAvailableTransports;

    private final RegistrantList mQualifiedNetworksChangedRegistrants = new RegistrantList();

    private final Set<DataThrottler> mDataThrottlers = new HashSet<>();
@@ -111,6 +157,19 @@ public class AccessNetworksManager extends Handler {
        }
    };

    /**
     * The current transport of the APN type. The key is the APN type, and the value is the
     * transport.
     */
    private final Map<Integer, Integer> mCurrentTransports = new ConcurrentHashMap<>();

    /**
     * The preferred transport of the APN type. The key is the APN type, and the value is the
     * transport. The preferred transports are updated as soon as QNS changes the preference, while
     * the current transports are updated after handover complete.
     */
    private final Map<Integer, Integer> mPreferredTransports = new ConcurrentHashMap<>();

    /**
     * Registers the data throttler in order to receive APN status changes.
     *
@@ -261,8 +320,6 @@ public class AccessNetworksManager extends Handler {
            List<QualifiedNetworks> qualifiedNetworksList = new ArrayList<>();
            for (int supportedApnType : SUPPORTED_APN_TYPES) {
                if ((apnTypes & supportedApnType) == supportedApnType) {
                    // TODO: Verify the preference from data settings manager to make sure the order
                    // of the networks do not violate users/carrier's preference.
                    if (mAvailableNetworks.get(supportedApnType) != null) {
                        if (Arrays.equals(mAvailableNetworks.get(supportedApnType),
                                qualifiedNetworkTypes)) {
@@ -280,6 +337,7 @@ public class AccessNetworksManager extends Handler {

            if (!qualifiedNetworksList.isEmpty()) {
                mQualifiedNetworksChangedRegistrants.notifyResult(qualifiedNetworksList);
                setPreferredTransports(qualifiedNetworksList);
            }
        }
    }
@@ -295,6 +353,15 @@ public class AccessNetworksManager extends Handler {
                Context.CARRIER_CONFIG_SERVICE);
        mLogTag = "ANM-" + mPhone.getPhoneId();

        if (isInLegacyMode()) {
            log("operates in legacy mode.");
            // For legacy mode, WWAN is the only transport to handle all data connections, even
            // the IWLAN ones.
            mAvailableTransports = new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN};
        } else {
            log("operates in AP-assisted mode.");
            mAvailableTransports = new int[]{AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                    AccessNetworkConstants.TRANSPORT_TYPE_WLAN};
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
            try {
@@ -307,6 +374,7 @@ public class AccessNetworksManager extends Handler {
            }
            bindQualifiedNetworksService();
        }
    }

    /**
     * Find the qualified network service from configuration and binds to it. It reads the
@@ -446,6 +514,113 @@ public class AccessNetworksManager extends Handler {
        }
    }

    /**
     * @return {@code true} if the device operates in legacy mode, otherwise {@code false}.
     */
    public boolean isInLegacyMode() {
        // Get IWLAN operation mode from the system property. If the system property is configured
        // to default or not configured, the mode is tied to IRadio version. For 1.4 or above, it's
        // AP-assisted mode, for 1.3 or below, it's legacy mode.
        String mode = SystemProperties.get(SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE);

        if (mode.equals(IWLAN_OPERATION_MODE_AP_ASSISTED)) {
            return false;
        } else if (mode.equals(IWLAN_OPERATION_MODE_LEGACY)) {
            return true;
        }

        return mPhone.getHalVersion().less(RIL.RADIO_HAL_VERSION_1_4);
    }

    /**
     * @return The available transports. Note that on legacy devices, the only available transport
     * would be WWAN only. If the device is configured as AP-assisted mode, the available transport
     * will always be WWAN and WLAN (even if the device is not camped on IWLAN).
     * See {@link #isInLegacyMode()} for mode details.
     */
    public synchronized @NonNull int[] getAvailableTransports() {
        return mAvailableTransports;
    }

    /**
     * Get the transport based on the APN type.
     *
     * @param apnType APN type
     * @return The transport type
     */
    public int getCurrentTransport(@ApnType int apnType) {
        // In legacy mode, always route to cellular.
        if (isInLegacyMode()) {
            return AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
        }

        // If we can't find the corresponding transport, always route to cellular.
        return mCurrentTransports.get(apnType) == null
                ? AccessNetworkConstants.TRANSPORT_TYPE_WWAN : mCurrentTransports.get(apnType);
    }

    /**
     * Set the current transport of apn type.
     *
     * @param apnType The APN type
     * @param transport The transport. Must be WWAN or WLAN.
     */
    public void setCurrentTransport(@ApnType int apnType, int transport) {
        Integer previousTransport = mCurrentTransports.put(apnType, transport);
        if (previousTransport == null || previousTransport != transport) {
            logl("setCurrentTransport: apnType=" + ApnSetting.getApnTypeString(apnType)
                    + ", transport=" + AccessNetworkConstants.transportTypeToString(transport));
        }
    }

    private static @TransportType int getTransportFromAccessNetwork(int accessNetwork) {
        return accessNetwork == AccessNetworkType.IWLAN
                ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN
                : AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
    }

    private void setPreferredTransports(@NonNull List<QualifiedNetworks> networksList) {
        for (QualifiedNetworks networks : networksList) {
            if (networks.qualifiedNetworks.length > 0) {
                int transport = getTransportFromAccessNetwork(networks.qualifiedNetworks[0]);
                mPreferredTransports.put(networks.apnType, transport);
                logl("setPreferredTransports: apnType="
                        + ApnSetting.getApnTypeString(networks.apnType)
                        + ", transport=" + AccessNetworkConstants.transportTypeToString(transport));
            }
        }
    }

    /**
     * Get the  preferred transport.
     *
     * @param apnType APN type
     * @return The preferred transport.
     */
    public @TransportType int getPreferredTransport(@ApnType int apnType) {
        // In legacy mode, always preferred on cellular.
        if (isInLegacyMode()) {
            return AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
        }

        return mPreferredTransports.get(apnType) == null
                ? AccessNetworkConstants.TRANSPORT_TYPE_WWAN : mPreferredTransports.get(apnType);
    }

    /**
     * Check if there is any APN type's current transport is on IWLAN.
     *
     * @return {@code true} if there is any APN is on IWLAN, otherwise {@code false}.
     */
    public boolean isAnyApnOnIwlan() {
        for (int apnType : AccessNetworksManager.SUPPORTED_APN_TYPES) {
            if (getCurrentTransport(apnType) == AccessNetworkConstants.TRANSPORT_TYPE_WLAN) {
                return true;
            }
        }
        return false;
    }

    /**
     * Unregister for qualified networks changed event.
     *
@@ -469,4 +644,47 @@ public class AccessNetworksManager extends Handler {
        Rlog.e(mLogTag, s, ex);
    }

    private void logl(String s) {
        log(s);
        mLocalLog.log(s);
    }

    /**
     * Dump the state of access networks manager
     *
     * @param fd File descriptor
     * @param printWriter Print writer
     * @param args Arguments
     */
    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
        pw.println(AccessNetworksManager.class.getSimpleName() + "-" + mPhone.getPhoneId() + ":");
        pw.increaseIndent();
        pw.println("current transports=");
        pw.increaseIndent();
        for (int apnType : AccessNetworksManager.SUPPORTED_APN_TYPES) {
            pw.println(ApnSetting.getApnTypeString(apnType)
                    + ": " + AccessNetworkConstants.transportTypeToString(
                    getCurrentTransport(apnType)));
        }
        pw.decreaseIndent();
        pw.println("preferred transports=");
        pw.increaseIndent();
        for (int apnType : AccessNetworksManager.SUPPORTED_APN_TYPES) {
            pw.println(ApnSetting.getApnTypeString(apnType)
                    + ": " + AccessNetworkConstants.transportTypeToString(
                    getPreferredTransport(apnType)));
        }

        pw.decreaseIndent();
        pw.println("isInLegacy=" + isInLegacyMode());
        pw.println("IWLAN operation mode="
                + SystemProperties.get(SYSTEM_PROPERTIES_IWLAN_OPERATION_MODE));
        pw.println("Local logs=");
        pw.increaseIndent();
        mLocalLog.dump(fd, pw, args);
        pw.decreaseIndent();
        pw.decreaseIndent();
        pw.flush();
    }
}
Loading