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

Commit 64ef1f76 authored by Jack Yu's avatar Jack Yu Committed by Automerger Merge Worker
Browse files

Merge "Added the skeleton of telephony data frameworks" am: ad21a5dc

Original change: https://android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/1988652

Change-Id: I84183d3fe9e36e777863c076755ac47cd7aef73c
parents d2df940d ad21a5dc
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;
@@ -305,6 +306,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 */
@@ -4871,6 +4873,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);
@@ -4932,6 +4941,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