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

Commit 51995669 authored by Daniel Bright's avatar Daniel Bright Committed by Gerrit Code Review
Browse files

Merge changes from topic "network_attributes_two_commits"

* changes:
  Prevent non-cellular request additions
  Remove dependency on apn network attributes
parents 7fb2d607 5dfcc23f
Loading
Loading
Loading
Loading
+16 −11
Original line number Diff line number Diff line
@@ -693,21 +693,26 @@ public class PhoneSwitcher extends Handler {
    }

    private void onRequestNetwork(NetworkRequest networkRequest) {
        final DcRequest dcRequest = new DcRequest(networkRequest, mContext);
        final DcRequest dcRequest = DcRequest.create(networkRequest);
        if (dcRequest != null) {
            if (!mPrioritizedDcRequests.contains(dcRequest)) {
                collectRequestNetworkMetrics(networkRequest);
                mPrioritizedDcRequests.add(dcRequest);
                Collections.sort(mPrioritizedDcRequests);
                onEvaluate(REQUESTS_CHANGED, "netRequest");
                log("Added DcRequest, size: " + mPrioritizedDcRequests.size());
            }
        }
    }

    private void onReleaseNetwork(NetworkRequest networkRequest) {
        final DcRequest dcRequest = new DcRequest(networkRequest, mContext);

        final DcRequest dcRequest = DcRequest.create(networkRequest);
        if (dcRequest != null) {
            if (mPrioritizedDcRequests.remove(dcRequest)) {
                onEvaluate(REQUESTS_CHANGED, "netReleased");
                collectReleaseNetworkMetrics(networkRequest);
                log("Removed DcRequest, size: " + mPrioritizedDcRequests.size());
            }
        }
    }

+49 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.dataconnection;

import android.telephony.Annotation;

/**
 * Container of network configuration settings relevant for telephony module.
 */
class ApnConfigType {

    private final int mType;
    private final int mPriority;

    ApnConfigType(@Annotation.ApnType int type, int priority) {
        mType = type;
        mPriority = priority;
    }

    /**
     * Returns the apn type of this config type
     * @return Type of apn.
     */
    int getType() {
        return mType;
    }

    /**
     * Returns the priority of this apn config type.
     * @return The priority of this apn.
     */
    int getPriority() {
        return mPriority;
    }
}
+88 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.dataconnection;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.telephony.Annotation;
import android.telephony.data.ApnSetting;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * Hard coded configuration of specific network types that the telephony module needs.
 * Formerly stored in network attributes within the resources file.
 */
public final class ApnConfigTypeRepository {

    private static final ApnConfigTypeRepository sDefault = new ApnConfigTypeRepository();

    private final Map<Integer, ApnConfigType> mConfigTypeMap;

    ApnConfigTypeRepository() {
        mConfigTypeMap = new HashMap<>();
        setup();
    }

    /**
     * Gets the default instance of the repository.
     * @return The singleton instance of repository.
     */
    @NonNull
    public static ApnConfigTypeRepository getDefault() {
        return sDefault;
    }

    /**
     * Gets list of apn config types.
     * @return All apn config types.
     */
    public Collection<ApnConfigType> getTypes() {
        return mConfigTypeMap.values();
    }

    /**
     * Gets the apn config type by apn type.
     * @param type The ApnType to search for.
     * @return The config type matching the given apn type.
     */
    @Nullable
    public ApnConfigType getByType(@Annotation.ApnType int type) {
        return mConfigTypeMap.get(type);
    }

    private void setup() {
        add(ApnSetting.TYPE_DEFAULT, 0);
        add(ApnSetting.TYPE_MMS, 2);
        add(ApnSetting.TYPE_SUPL, 2);
        add(ApnSetting.TYPE_DUN, 2);
        add(ApnSetting.TYPE_HIPRI, 3);
        add(ApnSetting.TYPE_FOTA, 2);
        add(ApnSetting.TYPE_IMS, 2);
        add(ApnSetting.TYPE_CBS, 2);
        add(ApnSetting.TYPE_IA, 2);
        add(ApnSetting.TYPE_EMERGENCY, 2);
        add(ApnSetting.TYPE_MCX, 3);
        add(ApnSetting.TYPE_XCAP, 3);
    }

    private void add(@Annotation.ApnType int type, int priority) {
        mConfigTypeMap.put(type, new ApnConfigType(type, priority));
    }
}
+41 −22
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.internal.telephony.dataconnection;

import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.net.NetworkConfig;
import android.net.NetworkRequest;
import android.os.Message;
import android.telephony.Annotation.ApnType;
@@ -59,13 +58,13 @@ public class ApnContext {

    private DctConstants.State mState;

    public final int priority;
    private final int mPriority;

    private ApnSetting mApnSetting;

    private DataConnection mDataConnection;

    String mReason;
    private String mReason;

    /**
     * user/app requested connection on this APN
@@ -73,15 +72,10 @@ public class ApnContext {
    AtomicBoolean mDataEnabled;

    private final Object mRefCountLock = new Object();
    private int mRefCount = 0;

    /**
     * carrier requirements met
     */
    AtomicBoolean mDependencyMet;

    private final DcTracker mDcTracker;


    /**
     * Remember this as a change in this value to a more permissive state
     * should cause us to retry even permanent failures
@@ -100,27 +94,40 @@ public class ApnContext {
    private final RetryManager mRetryManager;

    /**
     * AonContext constructor
     * ApnContext constructor
     * @param phone phone object
     * @param typeId APN type Id
     * @param logTag Tag for logging
     * @param tracker Data call tracker
     * @param priority Priority of APN type
     */
    public ApnContext(Phone phone, int typeId, String logTag, DcTracker tracker, int priority) {
        this(phone, ApnSetting.getApnTypeString(typeId), logTag, tracker, priority);
    }

    /**
     * ApnContext constructor
     * @param phone phone object
     * @param apnType APN type (e.g. default, supl, mms, etc...)
     * @param logTag Tag for logging
     * @param config Network configuration
     * @param tracker Data call tracker
     * @param priority Priority of APN type
     */
    public ApnContext(Phone phone, String apnType, String logTag, NetworkConfig config,
            DcTracker tracker) {
    public ApnContext(Phone phone, String apnType, String logTag, DcTracker tracker,
            int priority) {
        mPhone = phone;
        mApnType = apnType;
        mState = DctConstants.State.IDLE;
        setReason(Phone.REASON_DATA_ENABLED);
        mDataEnabled = new AtomicBoolean(false);
        mDependencyMet = new AtomicBoolean(config.dependencyMet);
        priority = config.priority;
        mPriority = priority;
        LOG_TAG = logTag;
        mDcTracker = tracker;
        mRetryManager = new RetryManager(phone, apnType);
    }



    /**
     * Get the APN type
     * @return The APN type
@@ -145,6 +152,23 @@ public class ApnContext {
        return mDataConnection;
    }

    /**
     * This priority is taken into account when concurrent data connections are not allowed.  The
     * APN with the HIGHER priority is given preference.
     * @return The priority of the APN type
     */
    public int getPriority() {
        return mPriority;
    }

    /**
     * Keeping for backwards compatibility and in case it's needed in the future
     * @return true
     */
    public boolean isDependencyMet() {
        return true;
    }

    /**
     * Set the associated data connection.
     * @param dc data connection
@@ -312,7 +336,7 @@ public class ApnContext {
     * @return True if ready, otherwise false.
     */
    public boolean isReady() {
        return mDataEnabled.get() && mDependencyMet.get();
        return mDataEnabled.get() && isDependencyMet();
    }

    /**
@@ -360,10 +384,6 @@ public class ApnContext {
        return mDataEnabled.get();
    }

    public boolean isDependencyMet() {
       return mDependencyMet.get();
    }

    public boolean isProvisioningApn() {
        String provisioningApn = mPhone.getContext().getResources()
                .getString(R.string.mobile_provisioning_apn);
@@ -619,8 +639,7 @@ public class ApnContext {
        // We don't print mDataConnection because its recursive.
        return "{mApnType=" + mApnType + " mState=" + getState() + " mWaitingApns={" +
                mRetryManager.getWaitingApns() + "}" + " mApnSetting={" + mApnSetting +
                "} mReason=" + mReason + " mDataEnabled=" + mDataEnabled + " mDependencyMet=" +
                mDependencyMet + "}";
                "} mReason=" + mReason + " mDataEnabled=" + mDataEnabled + "}";
    }

    private void log(String s) {
+50 −29
Original line number Diff line number Diff line
@@ -15,25 +15,68 @@
 */
package com.android.internal.telephony.dataconnection;

import android.content.Context;
import android.net.NetworkConfig;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
import android.net.TelephonyNetworkSpecifier;
import android.telephony.Annotation.ApnType;

import java.util.HashMap;
import com.android.telephony.Rlog;

/**
 * Wraps cellular network requests to configured apn types.
 */
public class DcRequest implements Comparable<DcRequest> {
    private static final String LOG_TAG = "DcRequest";

    @NonNull
    public final NetworkRequest networkRequest;
    public final int priority;
    public final @ApnType int apnType;

    public DcRequest(NetworkRequest nr, Context context) {
        initApnPriorities(context);
    private DcRequest(@NonNull final NetworkRequest nr, @ApnType final int type,
            int apnPriority) {
        networkRequest = nr;
        apnType = ApnContext.getApnTypeFromNetworkRequest(networkRequest);
        priority = priorityForApnType(apnType);
        priority = apnPriority;
        apnType = type;
    }

    /**
     * Create a DcRequest based off of the network request.  If the network request is not cellular,
     * then null is returned and a warning is generated.
     * @param networkRequest sets the type of dc request
     * @return corresponding DcRequest
     *
     */
    @Nullable
    public static DcRequest create(@NonNull final NetworkRequest networkRequest) {
        final int apnType = ApnContext.getApnTypeFromNetworkRequest(networkRequest);
        final ApnConfigType apnConfigType = ApnConfigTypeRepository.getDefault().getByType(apnType);
        if (apnConfigType == null) {
            Rlog.d(LOG_TAG, "Non cellular request ignored: " + networkRequest.toString());
            checkForAnomalousNetworkRequest(networkRequest);
            return null;
        } else {
            Rlog.d(LOG_TAG, "Cellular request confirmed: " + networkRequest.toString());
            return new DcRequest(networkRequest, apnType, apnConfigType.getPriority());
        }
    }

    private static void checkForAnomalousNetworkRequest(NetworkRequest networkRequest) {
        NetworkSpecifier specifier = networkRequest.getNetworkSpecifier();
        if (specifier != null) {
            if (specifier instanceof TelephonyNetworkSpecifier) {
                reportAnomalousNetworkRequest(networkRequest);
            }
        }
    }

    private static void reportAnomalousNetworkRequest(NetworkRequest networkRequest) {
        //TODO: Report anomaly if this happens
        Rlog.w(LOG_TAG, "A TelephonyNetworkSpecifier for a non-cellular request is invalid: "
                + networkRequest.toString());

    }

    public String toString() {
@@ -54,26 +97,4 @@ public class DcRequest implements Comparable<DcRequest> {
    public int compareTo(DcRequest o) {
        return o.priority - priority;
    }

    private static final HashMap<Integer, Integer> sApnPriorityMap =
            new HashMap<Integer, Integer>();

    private void initApnPriorities(Context context) {
        synchronized (sApnPriorityMap) {
            if (sApnPriorityMap.isEmpty()) {
                String[] networkConfigStrings = context.getResources().getStringArray(
                        com.android.internal.R.array.networkAttributes);
                for (String networkConfigString : networkConfigStrings) {
                    NetworkConfig networkConfig = new NetworkConfig(networkConfigString);
                    final int apnType = ApnContext.getApnTypeFromNetworkType(networkConfig.type);
                    sApnPriorityMap.put(apnType, networkConfig.priority);
                }
            }
        }
    }

    private int priorityForApnType(int apnType) {
        Integer priority = sApnPriorityMap.get(apnType);
        return (priority != null ? priority.intValue() : 0);
    }
}
Loading