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

Commit ad21a5dc authored by Jack Yu's avatar Jack Yu Committed by Gerrit Code Review
Browse files

Merge "Added the skeleton of telephony data frameworks"

parents b26d731c e4d6e7b7
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -89,6 +89,7 @@ import com.android.ims.ImsManager;
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.DataEnabledSettings;
import com.android.internal.telephony.dataconnection.DcTracker;
import com.android.internal.telephony.dataconnection.LinkBandwidthEstimator;
@@ -335,6 +336,10 @@ public class GsmCdmaPhone extends Phone {
            mTransportManager.registerDataThrottler(dcTracker.getDataThrottler());
        }

        mDataNetworkController = mTelephonyComponentFactory.inject(
                DataNetworkController.class.getName())
                .makeDataNetworkController(this, getLooper());

        mCarrierResolver = mTelephonyComponentFactory.inject(CarrierResolver.class.getName())
                .makeCarrierResolver(this);
        mCarrierPrivilegesTracker = new CarrierPrivilegesTracker(Looper.myLooper(), this, context);
+19 −0
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ import com.android.ims.ImsException;
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.DataConnectionReasons;
import com.android.internal.telephony.dataconnection.DataEnabledSettings;
import com.android.internal.telephony.dataconnection.DcTracker;
@@ -304,6 +305,7 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
    // WLAN DcTracker is for IWLAN data connection. For IWLAN legacy mode, only one (WWAN) DcTracker
    // will be created.
    protected final SparseArray<DcTracker> mDcTrackers = new SparseArray<>();
    protected DataNetworkController mDataNetworkController;
    /* Used for dispatching signals to configured carrier apps */
    protected CarrierSignalAgent mCarrierSignalAgent;
    /* Used for dispatching carrier action from carrier apps */
@@ -4870,6 +4872,13 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
        return null;
    }

    /**
     * @return The data network controller
     */
    public @Nullable DataNetworkController getDataNetworkController() {
        return mDataNetworkController;
    }

    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        pw.println("Phone: subId=" + getSubId());
        pw.println(" mPhoneId=" + mPhoneId);
@@ -4931,6 +4940,16 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
            }
        }

        if (mDataNetworkController != null) {
            try {
                mDataNetworkController.dump(fd, pw, args);
            } catch (Exception e) {
                e.printStackTrace();
            }
            pw.flush();
            pw.println("++++++++++++++++++++++++++++++++");
        }

        if (getServiceStateTracker() != null) {
            try {
                getServiceStateTracker().dump(fd, pw, args);
+13 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.text.TextUtils;
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.DataEnabledSettings;
import com.android.internal.telephony.dataconnection.DcTracker;
import com.android.internal.telephony.dataconnection.LinkBandwidthEstimator;
@@ -463,4 +464,16 @@ public class TelephonyComponentFactory {
    public LinkBandwidthEstimator makeLinkBandwidthEstimator(Phone phone) {
        return new LinkBandwidthEstimator(phone, mTelephonyFacade);
    }

    /**
     * Create a new data network controller instance. The instance is per-SIM. On multi-sim devices,
     * there will be multiple {@link DataNetworkController} instances.
     *
     * @param phone The phone object
     * @param looper The looper for event handling
     * @return The data network controller instance
     */
    public DataNetworkController makeDataNetworkController(Phone phone, Looper looper) {
        return new DataNetworkController(phone, looper);
    }
}
+4 −4
Original line number Diff line number Diff line
@@ -203,12 +203,12 @@ public class DataConfigManager extends Handler {
     * Dump the state of DataConfigManager
     *
     * @param fd File descriptor
     * @param printwriter Print writer
     * @param printWriter Print writer
     * @param args Arguments
     */
    public void dump(FileDescriptor fd, PrintWriter printwriter, String[] args) {
        IndentingPrintWriter pw = new IndentingPrintWriter(printwriter, "  ");
        pw.println("DataConfigManager-" + mPhone.getPhoneId() + ":");
    public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
        IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
        pw.println(DataConfigManager.class.getSimpleName() + "-" + mPhone.getPhoneId() + ":");
        pw.increaseIndent();
        pw.println("Network capability priority:");
        pw.increaseIndent();
+363 −0
Original line number Diff line number Diff line
/*
 * Copyright 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.telephony.data;

import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN;

import android.annotation.NonNull;
import android.net.LinkProperties;
import android.net.NetworkAgentConfig;
import android.net.NetworkCapabilities;
import android.net.NetworkProvider;
import android.net.NetworkScore;
import android.os.Looper;
import android.os.Message;
import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.data.DataProfile;
import android.telephony.data.DataService;
import android.util.IndentingPrintWriter;
import android.util.LocalLog;

import com.android.internal.telephony.Phone;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.telephony.Rlog;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * DataNetwork class represents a single PDN (Packet Data Network).
 *
 * The life cycle of a data network starts from {@link ConnectingState}. If setup data request
 * succeeds, then it enters {@link ConnectedState}, otherwise it enters
 * {@link DisconnectedState}.
 *
 * When data network is in {@link ConnectingState}, it can enter {@link HandoverState} if handover
 * between IWLAN and cellular occurs. After handover completes or fails, it return back to
 * {@link ConnectedState}. When the data network is about to be disconnected, it first enters
 * {@link DisconnectingState} when performing graceful tear down or when sending the data
 * deactivation request. At the end, it enters {@link DisconnectedState} when {@link DataService}
 * notifies data disconnected. Note that a unsolicited disconnected event from {@link DataService}
 * can immediately move data network transisted from {@link ConnectedState} to
 * {@link DisconnectedState}. {@link DisconnectedState} is the final state of a data network.
 *
 * State machine diagram:
 *
 *                                  ┌─────────┐
 *                                  │Handover │
 *                                  └─▲────┬──┘
 *                                    │    │
 *             ┌───────────┐        ┌─┴────▼──┐        ┌──────────────┐
 *             │Connecting ├────────►Connected├────────►Disconnecting │
 *             └─────┬─────┘        └────┬────┘        └───────┬──────┘
 *                   │                   │                     │
 *                   │             ┌─────▼──────┐              │
 *                   └─────────────►Disconnected◄──────────────┘
 *                                 └────────────┘
 *
 */
public class DataNetwork extends StateMachine {
    private final @NonNull Phone mPhone;
    private final String mLogTag;
    private final LocalLog mLocalLog = new LocalLog(128);
    private static final AtomicInteger sId = new AtomicInteger(0);

    private final DefaultState mDefaultState = new DefaultState();
    private final ConnectingState mConnectingState = new ConnectingState();
    private final ConnectedState mConnectedState = new ConnectedState();
    private final HandoverState mHandoverState = new HandoverState();
    private final DisconnectingState mDisconnectingState = new DisconnectingState();
    private final DisconnectedState mDisconnectedState = new DisconnectedState();

    /** The current transport of the data network. Could be WWAN or WLAN. */
    private @TransportType int mTransport;

    /** The network agent associated with this data network. */
    private final TelephonyNetworkAgent mNetworkAgent;

    /** The data profile used to establish this data network. */
    private final @NonNull DataProfile mDataProfile;

    /** The network capabilities of this data network. */
    private @NonNull NetworkCapabilities mNetworkCapabilities;

    /** The network score of this data network. */
    private @NonNull NetworkScore mNetworkScore;

    /** The link properties of this data network. */
    private @NonNull LinkProperties mLinkProperties;

    /** The network requests associated with this data network */
    private @NonNull List<TelephonyNetworkRequest> mAttachedNetworkRequestList = new ArrayList<>();

    /**
     * Constructor
     *
     * @param phone The phone instance.
     * @param looper The looper to be used by the state machine. Currently the handler thread is the
     * phone process's main thread.
     * @param transport The initial transport.
     * @param dataProfile The data profile for establishing the data network.
     */
    public DataNetwork(@NonNull Phone phone, @NonNull Looper looper, @TransportType int transport,
            @NonNull DataProfile dataProfile) {
        super("DataNetwork", looper);
        mPhone = phone;
        mTransport = transport;
        mLogTag = "DN-" + sId.incrementAndGet() + "-"
                + ((transport == TRANSPORT_TYPE_WWAN) ? "C" : "I");

        mDataProfile = dataProfile;
        mNetworkAgent = new TelephonyNetworkAgent(mPhone, looper, this);

        addState(mDefaultState);
        addState(mConnectingState, mDefaultState);
        addState(mConnectedState, mDefaultState);
        addState(mHandoverState, mDefaultState);
        addState(mDisconnectingState, mDefaultState);
        addState(mDisconnectedState, mDefaultState);
        setInitialState(mConnectingState);

        // This must stay at the end of constructor.
        start();
    }

    /**
     * The default state. Any events that were not handled by the child states fallback to this
     * state.
     *
     * @see DataNetwork for the state machine diagram.
     */
    private final class DefaultState extends State {
        @Override
        public void enter() {

        }

        @Override
        public void exit() {
        }

        @Override
        public boolean processMessage(Message msg) {
            return HANDLED;
        }
    }

    /**
     * The connecting state. This is the initial state of a data network.
     *
     * @see DataNetwork for the state machine diagram.
     */
    private final class ConnectingState extends State {
        @Override
        public void enter() {

        }

        @Override
        public void exit() {
        }

        @Override
        public boolean processMessage(Message msg) {
            return NOT_HANDLED;
        }
    }

    /**
     * The connected state. This is the state when data network becomes usable.
     *
     * @see DataNetwork for the state machine diagram.
     */
    private final class ConnectedState extends State {
        @Override
        public void enter() {
            mNetworkAgent.markConnected();
        }

        @Override
        public void exit() {
        }

        @Override
        public boolean processMessage(Message msg) {
            return NOT_HANDLED;
        }
    }

    /**
     * The handover state. This is the state when data network handover between IWLAN and cellular.
     *
     * @see DataNetwork for the state machine diagram.
     */
    private final class HandoverState extends State {
        @Override
        public void enter() {

        }

        @Override
        public void exit() {
        }

        @Override
        public boolean processMessage(Message msg) {
            return NOT_HANDLED;
        }
    }

    /**
     * The disconnecting state. This is the state when data network is about to be disconnected.
     *
     * @see DataNetwork for the state machine diagram.
     */
    private final class DisconnectingState extends State {
        @Override
        public void enter() {

        }

        @Override
        public void exit() {
        }

        @Override
        public boolean processMessage(Message msg) {
            return NOT_HANDLED;
        }
    }

    /**
     * The disconnected state. This is the final state of a data network.
     *
     * @see DataNetwork for the state machine diagram.
     */
    private final class DisconnectedState extends State {
        @Override
        public void enter() {
            // Immediately discard all the unprocessed events.
            quitNow();
            mNetworkAgent.unregister();
        }
    }

    /**
     * @return The network capabilities of this data network.
     */
    public @NonNull NetworkCapabilities getNetworkCapabilities() {
        return mNetworkCapabilities;
    }

    /**
     * @return The link properties of this data network.
     */
    public @NonNull LinkProperties getLinkProperties() {
        return mLinkProperties;
    }

    /**
     * @return The score of this data network. The higher score makes this data network more chances
     * to be selected as the active network of the device.
     */
    public @NonNull NetworkScore getNetworkScore() {
        return mNetworkScore;
    }

    /**
     * @return The network agent config for building the network agent.
     */
    public @NonNull NetworkAgentConfig getNetworkAgentConfig() {
        // TODO: Should not be null.
        return null;
    }

    /**
     * @return The network provider for building the network agent.
     */
    public @NonNull NetworkProvider getNetworkProvider() {
        // TODO: Should not be null.
        return null;
    }

    /**
     * @return The log tag for debug message use only.
     */
    public @NonNull String getLogTag() {
        return mLogTag;
    }

    /**
     * Log debug messages.
     * @param s debug messages
     */
    @Override
    protected void log(@NonNull String s) {
        Rlog.d(mLogTag, (getCurrentState() != null
                ? (getCurrentState().getName() + ": ") : "") + s);
    }

    /**
     * Log error messages.
     * @param s error messages
     */
    @Override
    protected void loge(@NonNull String s) {
        Rlog.e(mLogTag, (getCurrentState() != null
                ? (getCurrentState().getName() + ": ") : "") + s);
    }

    /**
     * Log debug messages and also log into the local log.
     * @param s debug messages
     */
    private void logl(@NonNull String s) {
        log(s);
        mLocalLog.log(s);
    }

    /**
     * Dump the state of DataNetwork
     *
     * @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(DataNetwork.class.getSimpleName() + "-" + mPhone.getPhoneId() + ":");
        super.dump(fd, pw, args);

        pw.increaseIndent();
        mNetworkAgent.dump(fd, pw, args);

        pw.println("Attached network requests:");
        for (TelephonyNetworkRequest request : mAttachedNetworkRequestList) {
            pw.println(mAttachedNetworkRequestList);
        }

        pw.println("Local logs:");
        pw.increaseIndent();
        mLocalLog.dump(fd, pw, args);
        pw.decreaseIndent();
        pw.decreaseIndent();
    }
}
Loading