Loading src/java/com/android/internal/telephony/PhoneSwitcher.java +16 −11 Original line number Diff line number Diff line Loading @@ -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()); } } } Loading src/java/com/android/internal/telephony/dataconnection/ApnConfigType.java 0 → 100644 +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; } } src/java/com/android/internal/telephony/dataconnection/ApnConfigTypeRepository.java 0 → 100644 +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)); } } src/java/com/android/internal/telephony/dataconnection/ApnContext.java +41 −22 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading Loading @@ -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(); } /** Loading Loading @@ -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); Loading Loading @@ -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) { Loading src/java/com/android/internal/telephony/dataconnection/DcRequest.java +50 −29 Original line number Diff line number Diff line Loading @@ -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() { Loading @@ -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
src/java/com/android/internal/telephony/PhoneSwitcher.java +16 −11 Original line number Diff line number Diff line Loading @@ -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()); } } } Loading
src/java/com/android/internal/telephony/dataconnection/ApnConfigType.java 0 → 100644 +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; } }
src/java/com/android/internal/telephony/dataconnection/ApnConfigTypeRepository.java 0 → 100644 +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)); } }
src/java/com/android/internal/telephony/dataconnection/ApnContext.java +41 −22 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading Loading @@ -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(); } /** Loading Loading @@ -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); Loading Loading @@ -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) { Loading
src/java/com/android/internal/telephony/dataconnection/DcRequest.java +50 −29 Original line number Diff line number Diff line Loading @@ -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() { Loading @@ -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); } }