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

Commit 8a83fe5e authored by Nagendra Prasad Nagarle Basavaraju's avatar Nagendra Prasad Nagarle Basavaraju Committed by Android (Google) Code Review
Browse files

Merge "[Esim Bootstrap Support] Restrict Data Usage for BootStrap sim" into main

parents a8f15be6 47a640a2
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -869,6 +869,14 @@ public class DataConfigManager extends Handler {
        return mCarrierConfig.getInt(CarrierConfigManager.KEY_DEFAULT_MTU_INT);
    }

    /**
     * @return the data limit in bytes that can be used for esim bootstrap usage.
     */
    public long getEsimBootStrapMaxDataLimitBytes() {
        return mResources.getInteger(
                com.android.internal.R.integer.config_esim_bootstrap_data_limit_bytes);
    }

    /**
     * Update the TCP buffer sizes from the resource overlays.
     */
+6 −2
Original line number Diff line number Diff line
@@ -257,7 +257,9 @@ public class DataEvaluation {
        /** Tracking area code changed. */
        TAC_CHANGED(true),
        /** Unsatisfied network request detached. */
        UNSATISFIED_REQUEST_DETACHED(true);
        UNSATISFIED_REQUEST_DETACHED(true),
        /** track bootstrap sim data usage */
        CHECK_DATA_USAGE(false);

        /**
         * {@code true} if the evaluation is due to environmental changes (i.e. SIM removal,
@@ -342,7 +344,9 @@ public class DataEvaluation {
        /** Data enabled settings are not ready. */
        DATA_SETTINGS_NOT_READY(true),
        /** Handover max retry stopped but network is not on the preferred transport. */
        HANDOVER_RETRY_STOPPED(true);
        HANDOVER_RETRY_STOPPED(true),
        /** BootStrap sim data limit reached. */
        DATA_LIMIT_REACHED(true);

        private final boolean mIsHardReason;

+6 −0
Original line number Diff line number Diff line
@@ -312,6 +312,7 @@ public class DataNetwork extends StateMachine {
                    TEAR_DOWN_REASON_ILLEGAL_STATE,
                    TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK,
                    TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED,
                    TEAR_DOWN_REASON_DATA_LIMIT_REACHED,
            })
    public @interface TearDownReason {}

@@ -408,6 +409,9 @@ public class DataNetwork extends StateMachine {
    /** Data network tear down due to preferred data switched to another phone. */
    public static final int TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED = 30;

    /** Data network tear down due to bootstrap sim data limit reached. */
    public static final int TEAR_DOWN_REASON_DATA_LIMIT_REACHED = 31;

    //********************************************************************************************//
    // WHENEVER ADD A NEW TEAR DOWN REASON, PLEASE UPDATE DataDeactivateReasonEnum in enums.proto //
    //********************************************************************************************//
@@ -3757,6 +3761,8 @@ public class DataNetwork extends StateMachine {
                return "TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK";
            case TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED:
                return "TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED";
            case TEAR_DOWN_REASON_DATA_LIMIT_REACHED:
                return "TEAR_DOWN_REASON_DATA_LIMIT_REACHED";
            default:
                return "UNKNOWN(" + reason + ")";
        }
+106 −1
Original line number Diff line number Diff line
@@ -20,6 +20,8 @@ import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.usage.NetworkStats;
import android.app.usage.NetworkStatsManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -29,6 +31,7 @@ import android.net.NetworkCapabilities;
import android.net.NetworkPolicyManager;
import android.net.NetworkPolicyManager.SubscriptionCallback;
import android.net.NetworkRequest;
import android.net.NetworkTemplate;
import android.net.Uri;
import android.os.AsyncResult;
import android.os.Handler;
@@ -238,6 +241,18 @@ public class DataNetworkController extends Handler {
    private static final long REEVALUATE_UNSATISFIED_NETWORK_REQUESTS_AFTER_DETACHED_DELAY_MILLIS =
            TimeUnit.SECONDS.toMillis(1);

    /**
     * The delay in milliseconds to re-evaluate existing data networks for bootstrap sim data usage
     * limit.
     */
    private static final long REEVALUATE_BOOTSTRAP_SIM_DATA_USAGE_MILLIS =
            TimeUnit.SECONDS.toMillis(60);

    /**
     * bootstrap sim total data usage bytes
     */
    private long mBootStrapSimTotalDataUsageBytes = 0L;

    private final Phone mPhone;
    private final String mLogTag;
    private final LocalLog mLocalLog = new LocalLog(128);
@@ -1682,8 +1697,15 @@ public class DataNetworkController extends Handler {
        }

        if (!evaluation.containsDisallowedReasons()) {
            if (transport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN
                    && isEsimBootStrapProvisioningActivated()
                    && isEsimBootStrapMaxDataLimitReached()) {
                log("BootStrap Sim Data Usage limit reached");
                evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_LIMIT_REACHED);
            } else {
                evaluation.setCandidateDataProfile(dataProfile);
            }
        }

        networkRequest.setEvaluation(evaluation);
        // EXTERNAL_QUERY generates too many log spam.
@@ -1698,6 +1720,61 @@ public class DataNetworkController extends Handler {
        return evaluation;
    }

    /**
     * This method
     *  - At evaluation network request and evaluation data network determines, if
     *    bootstrap sim current data usage reached bootstrap sim max data limit allowed set
     *    at {@link DataConfigManager#getEsimBootStrapMaxDataLimitBytes()}
     *  - Query the current data usage at {@link #getDataUsage()}
     *
     * @return true, if bootstrap sim data limit is reached
     *         else false, if bootstrap sim max data limit allowed set is -1(Unlimited) or current
     *         bootstrap sim total data usage is less than bootstrap sim max data limit allowed.
     *
     */
    private boolean isEsimBootStrapMaxDataLimitReached() {
        long esimBootStrapMaxDataLimitBytes =
                mDataConfigManager.getEsimBootStrapMaxDataLimitBytes();

        if (esimBootStrapMaxDataLimitBytes < 0L) {
            return false;
        }

        log("current bootstrap sim data Usage: " + mBootStrapSimTotalDataUsageBytes);
        if (mBootStrapSimTotalDataUsageBytes >= esimBootStrapMaxDataLimitBytes) {
            return true;
        } else {
            mBootStrapSimTotalDataUsageBytes = getDataUsage();
            return mBootStrapSimTotalDataUsageBytes >= esimBootStrapMaxDataLimitBytes;
        }
    }

    /**
     * Query network usage statistics summaries based on {@link
     * NetworkStatsManager#querySummaryForDevice(NetworkTemplate, long, long)}
     *
     * @return Data usage in bytes for the connected networks related to the current subscription
     */
    private long getDataUsage() {
        NetworkStatsManager networkStatsManager =
                        mPhone.getContext().getSystemService(NetworkStatsManager.class);

        if (networkStatsManager != null) {
            final NetworkTemplate.Builder builder =
                    new NetworkTemplate.Builder(NetworkTemplate.MATCH_MOBILE);
            final String subscriberId = mPhone.getSubscriberId();

            if (!TextUtils.isEmpty(subscriberId)) {
                builder.setSubscriberIds(Set.of(subscriberId));
                NetworkTemplate template = builder.build();
                final NetworkStats.Bucket ret = networkStatsManager
                        .querySummaryForDevice(template, 0L, System.currentTimeMillis());
                return ret.getRxBytes() + ret.getTxBytes();
            }
        }
        return 0L;
    }

    /**
     * @return The grouped unsatisfied network requests. The network requests that have the same
     * network capabilities is grouped into one {@link NetworkRequestList}.
@@ -1784,6 +1861,25 @@ public class DataNetworkController extends Handler {
            evaluation.addDataDisallowedReason(DataDisallowedReason.SERVICE_OPTION_NOT_SUPPORTED);
        }

        // Check whether data limit reached for bootstrap sim, else re-evaluate based on the timer
        // set.
        if (isEsimBootStrapProvisioningActivated()
                && dataNetwork.getTransport() == AccessNetworkConstants.TRANSPORT_TYPE_WWAN) {
            if (isEsimBootStrapMaxDataLimitReached()) {
                log("BootStrap Sim Data Usage limit reached");
                evaluation.addDataDisallowedReason(DataDisallowedReason.DATA_LIMIT_REACHED);
            } else {
                if (!hasMessages(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS)) {
                    sendMessageDelayed(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS,
                            DataEvaluationReason.CHECK_DATA_USAGE),
                            REEVALUATE_BOOTSTRAP_SIM_DATA_USAGE_MILLIS);
                } else {
                    log("skip scheduling evaluating existing data networks since already"
                            + "scheduled");
                }
            }
        }

        // Check if there are other network that has higher priority, and only single data network
        // is allowed.
        if (isOnlySingleDataNetworkAllowed(dataNetwork.getTransport())
@@ -2166,6 +2262,8 @@ public class DataNetworkController extends Handler {
                    return DataNetwork.TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK;
                case HANDOVER_RETRY_STOPPED:
                    return DataNetwork.TEAR_DOWN_REASON_HANDOVER_FAILED;
                case DATA_LIMIT_REACHED:
                    return DataNetwork.TEAR_DOWN_REASON_DATA_LIMIT_REACHED;
            }
        }
        return DataNetwork.TEAR_DOWN_REASON_NONE;
@@ -2794,6 +2892,12 @@ public class DataNetworkController extends Handler {
                    + TelephonyUtils.dataStateToString(mImsDataNetworkState) + " to CONNECTED.");
            mImsDataNetworkState = TelephonyManager.DATA_CONNECTED;
        }

        if (isEsimBootStrapProvisioningActivated()) {
            sendMessageDelayed(obtainMessage(EVENT_REEVALUATE_EXISTING_DATA_NETWORKS,
                    DataEvaluationReason.CHECK_DATA_USAGE),
                    REEVALUATE_BOOTSTRAP_SIM_DATA_USAGE_MILLIS);
        }
    }

    /**
@@ -4039,6 +4143,7 @@ public class DataNetworkController extends Handler {
                .map(TelephonyManager::getNetworkTypeName).collect(Collectors.joining(",")));
        pw.println("mImsThrottleCounter=" + mImsThrottleCounter);
        pw.println("mNetworkUnwantedCounter=" + mNetworkUnwantedCounter);
        pw.println("mBootStrapSimTotalDataUsageBytes=" + mBootStrapSimTotalDataUsageBytes);
        pw.println("Local logs:");
        pw.increaseIndent();
        mLocalLog.dump(fd, pw, args);
+8 −0
Original line number Diff line number Diff line
@@ -58,6 +58,14 @@ public class DataEvaluationTest extends TelephonyTest {
        mDataEvaluationUT.removeDataDisallowedReason(
                DataEvaluation.DataDisallowedReason.DATA_DISABLED);
        assertThat(mDataEvaluationUT.getDataDisallowedReasons().size()).isEqualTo(1);

        mDataEvaluationUT.addDataDisallowedReason(
                DataEvaluation.DataDisallowedReason.DATA_LIMIT_REACHED);
        assertThat(mDataEvaluationUT.getDataDisallowedReasons().size()).isEqualTo(2);

        mDataEvaluationUT.removeDataDisallowedReason(
                DataEvaluation.DataDisallowedReason.ROAMING_DISABLED);
        assertThat(mDataEvaluationUT.getDataDisallowedReasons().size()).isEqualTo(1);
    }


Loading