diff --git a/api/current.txt b/api/current.txt index 68a22f2360cf7..167c2b4668afa 100644 --- a/api/current.txt +++ b/api/current.txt @@ -47830,6 +47830,7 @@ package android.telephony { method @Nullable public android.net.LinkProperties getLinkProperties(); method public int getNetworkType(); method public int getState(); + method public int getTransportType(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator CREATOR; } diff --git a/api/system-current.txt b/api/system-current.txt index 7276b37ba20b4..79fea6b9fc8d5 100755 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -10838,6 +10838,7 @@ package android.telephony { method @Deprecated public int getDataConnectionApnTypeBitMask(); method @Deprecated public int getDataConnectionFailCause(); method @Deprecated public int getDataConnectionState(); + method public int getId(); } public final class PreciseDisconnectCause { diff --git a/api/system-removed.txt b/api/system-removed.txt index 09544c11f8b76..3acc225284380 100644 --- a/api/system-removed.txt +++ b/api/system-removed.txt @@ -180,11 +180,6 @@ package android.telecom { package android.telephony { - public final class PreciseDataConnectionState implements android.os.Parcelable { - method @Deprecated @Nullable public android.net.LinkProperties getDataConnectionLinkProperties(); - method @Deprecated public int getDataConnectionNetworkType(); - } - public class TelephonyManager { method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void answerRingingCall(); method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public boolean endCall(); diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt index 30826e036c406..09aaf5bc3d972 100644 --- a/config/boot-image-profile.txt +++ b/config/boot-image-profile.txt @@ -18839,7 +18839,6 @@ HSPLandroid/telephony/PreciseDataConnectionState;->(Landroid/os/Parcel;)V HSPLandroid/telephony/PreciseDataConnectionState;->(Landroid/os/Parcel;Landroid/telephony/PreciseDataConnectionState$1;)V HPLandroid/telephony/PreciseDataConnectionState;->equals(Ljava/lang/Object;)Z HPLandroid/telephony/PreciseDataConnectionState;->getDataConnectionApn()Ljava/lang/String; -HPLandroid/telephony/PreciseDataConnectionState;->getDataConnectionLinkProperties()Landroid/net/LinkProperties; HPLandroid/telephony/PreciseDataConnectionState;->getNetworkType()I HPLandroid/telephony/PreciseDataConnectionState;->getState()I HSPLandroid/telephony/PreciseDataConnectionState;->toString()Ljava/lang/String; diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java index 2dbce7b0fc7b4..3673ae7f7a379 100644 --- a/core/java/android/telephony/TelephonyRegistryManager.java +++ b/core/java/android/telephony/TelephonyRegistryManager.java @@ -26,10 +26,8 @@ import android.os.Binder; import android.os.Build; import android.os.RemoteException; import android.os.ServiceManager; -import android.telephony.Annotation.ApnType; import android.telephony.Annotation.CallState; import android.telephony.Annotation.DataActivityType; -import android.telephony.Annotation.DataFailureCause; import android.telephony.Annotation.DisconnectCauses; import android.telephony.Annotation.NetworkType; import android.telephony.Annotation.PreciseCallStates; @@ -37,7 +35,6 @@ import android.telephony.Annotation.PreciseDisconnectCauses; import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SimActivationState; import android.telephony.Annotation.SrvccState; -import android.telephony.data.ApnSetting; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; import android.util.Log; @@ -413,17 +410,16 @@ public class TelephonyRegistryManager { * @param subId for which data connection state changed. * @param slotIndex for which data connections state changed. Can be derived from subId except * when subId is invalid. - * @param apnType the apn type bitmask, defined with {@code ApnSetting#TYPE_*} flags. * @param preciseState the PreciseDataConnectionState * - * @see android.telephony.PreciseDataConnection + * @see PreciseDataConnectionState * @see TelephonyManager#DATA_DISCONNECTED */ public void notifyDataConnectionForSubscriber(int slotIndex, int subId, - @ApnType int apnType, @Nullable PreciseDataConnectionState preciseState) { + @NonNull PreciseDataConnectionState preciseState) { try { sRegistry.notifyDataConnectionForSubscriber( - slotIndex, subId, apnType, preciseState); + slotIndex, subId, preciseState); } catch (RemoteException ex) { // system process is dead } @@ -622,25 +618,6 @@ public class TelephonyRegistryManager { } } - /** - * Notify precise data connection failed cause on certain subscription. - * - * @param subId for which data connection failed. - * @param slotIndex for which data conenction failed. Can be derived from subId except when - * subId is invalid. - * @param apnType the apn type bitmask, defined with {@code ApnSetting#TYPE_*} flags. - * @param apn the APN {@link ApnSetting#getApnName()} of this data connection. - * @param failCause data fail cause. - */ - public void notifyPreciseDataConnectionFailed(int subId, int slotIndex, @ApnType int apnType, - @Nullable String apn, @DataFailureCause int failCause) { - try { - sRegistry.notifyPreciseDataConnectionFailed(slotIndex, subId, apnType, apn, failCause); - } catch (RemoteException ex) { - // system process is dead - } - } - /** * Notify single Radio Voice Call Continuity (SRVCC) state change for the currently active call * on certain subscription. diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 5a04992a35b4f..ea09fc8cd34a3 100644 --- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -65,9 +65,7 @@ interface ITelephonyRegistry { void notifyDataActivity(int state); void notifyDataActivityForSubscriber(in int subId, int state); void notifyDataConnectionForSubscriber( - int phoneId, int subId, int apnType, in PreciseDataConnectionState preciseState); - @UnsupportedAppUsage - void notifyDataConnectionFailed(String apnType); + int phoneId, int subId, in PreciseDataConnectionState preciseState); // Uses CellIdentity which is Parcelable here; will convert to CellLocation in client. void notifyCellLocation(in CellIdentity cellLocation); void notifyCellLocationForSubscriber(in int subId, in CellIdentity cellLocation); @@ -77,8 +75,6 @@ interface ITelephonyRegistry { int foregroundCallState, int backgroundCallState); void notifyDisconnectCause(int phoneId, int subId, int disconnectCause, int preciseDisconnectCause); - void notifyPreciseDataConnectionFailed(int phoneId, int subId, int apnType, String apn, - int failCause); void notifyCellInfoForSubscriber(in int subId, in List cellInfo); void notifySrvccStateChanged(in int subId, in int lteState); void notifySimActivationStateChangedForPhoneId(in int phoneId, in int subId, diff --git a/non-updatable-api/current.txt b/non-updatable-api/current.txt index 0aa060546513a..d6c74b1e24f6d 100644 --- a/non-updatable-api/current.txt +++ b/non-updatable-api/current.txt @@ -45998,6 +45998,7 @@ package android.telephony { method @Nullable public android.net.LinkProperties getLinkProperties(); method public int getNetworkType(); method public int getState(); + method public int getTransportType(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator CREATOR; } diff --git a/non-updatable-api/system-current.txt b/non-updatable-api/system-current.txt index 6a6914a65a736..62a93b7d0ab69 100644 --- a/non-updatable-api/system-current.txt +++ b/non-updatable-api/system-current.txt @@ -9720,6 +9720,7 @@ package android.telephony { method @Deprecated public int getDataConnectionApnTypeBitMask(); method @Deprecated public int getDataConnectionFailCause(); method @Deprecated public int getDataConnectionState(); + method public int getId(); } public final class PreciseDisconnectCause { diff --git a/non-updatable-api/system-removed.txt b/non-updatable-api/system-removed.txt index ab4c6d1a71a0a..0c02c43b1084e 100644 --- a/non-updatable-api/system-removed.txt +++ b/non-updatable-api/system-removed.txt @@ -165,11 +165,6 @@ package android.telecom { package android.telephony { - public final class PreciseDataConnectionState implements android.os.Parcelable { - method @Deprecated @Nullable public android.net.LinkProperties getDataConnectionLinkProperties(); - method @Deprecated public int getDataConnectionNetworkType(); - } - public class TelephonyManager { method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void answerRingingCall(); method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public boolean endCall(); diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index fd5a621f1a255..df23da650a6ff 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -34,7 +34,6 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; -import android.net.LinkProperties; import android.os.Binder; import android.os.Build; import android.os.Bundle; @@ -46,8 +45,6 @@ import android.os.RemoteException; import android.os.UserHandle; import android.provider.DeviceConfig; import android.telephony.Annotation; -import android.telephony.Annotation.ApnType; -import android.telephony.Annotation.DataFailureCause; import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.SrvccState; import android.telephony.BarringInfo; @@ -63,7 +60,6 @@ import android.telephony.CellSignalStrengthLte; import android.telephony.CellSignalStrengthNr; import android.telephony.CellSignalStrengthTdscdma; import android.telephony.CellSignalStrengthWcdma; -import android.telephony.DataFailCause; import android.telephony.DisconnectCause; import android.telephony.LocationAccessPolicy; import android.telephony.PhoneCapability; @@ -81,7 +77,9 @@ import android.telephony.TelephonyManager; import android.telephony.data.ApnSetting; import android.telephony.emergency.EmergencyNumber; import android.telephony.ims.ImsReasonInfo; +import android.util.ArrayMap; import android.util.LocalLog; +import android.util.Pair; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.IBatteryStats; @@ -304,13 +302,18 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { @RadioPowerState private int mRadioPowerState = TelephonyManager.RADIO_POWER_UNAVAILABLE; - private final LocalLog mLocalLog = new LocalLog(100); + private final LocalLog mLocalLog = new LocalLog(200); - private final LocalLog mListenLog = new LocalLog(100); + private final LocalLog mListenLog = new LocalLog(00); - // Per-phoneMap of APN Type to DataConnectionState - private List> mPreciseDataConnectionStates = - new ArrayList>(); + /** + * Per-phone map of precise data connection state. The key of the map is the pair of transport + * type and APN setting. This is the cache to prevent redundant callbacks to the listeners. + * A precise data connection with state {@link TelephonyManager#DATA_DISCONNECTED} removes + * its entry from the map. + */ + private List, PreciseDataConnectionState>> + mPreciseDataConnectionStates; static final int ENFORCE_COARSE_LOCATION_PERMISSION_MASK = PhoneStateListener.LISTEN_REGISTRATION_FAILURE @@ -523,7 +526,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; - mPreciseDataConnectionStates.add(new HashMap()); + mPreciseDataConnectionStates.add(new ArrayMap<>()); mBarringInfo.add(i, new BarringInfo()); mTelephonyDisplayInfos[i] = null; } @@ -612,7 +615,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; - mPreciseDataConnectionStates.add(new HashMap()); + mPreciseDataConnectionStates.add(new ArrayMap<>()); mBarringInfo.add(i, new BarringInfo()); mTelephonyDisplayInfos[i] = null; } @@ -1689,38 +1692,25 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { * * @param phoneId the phoneId carrying the data connection * @param subId the subscriptionId for the data connection - * @param apnType the apn type bitmask, defined with {@code ApnSetting#TYPE_*} flags. * @param preciseState a PreciseDataConnectionState that has info about the data connection */ @Override - public void notifyDataConnectionForSubscriber( - int phoneId, int subId, @ApnType int apnType, PreciseDataConnectionState preciseState) { + public void notifyDataConnectionForSubscriber(int phoneId, int subId, + @NonNull PreciseDataConnectionState preciseState) { if (!checkNotifyPermission("notifyDataConnection()" )) { return; } - String apn = ""; - int state = TelephonyManager.DATA_UNKNOWN; - int networkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; - LinkProperties linkProps = null; + ApnSetting apnSetting = preciseState.getApnSetting(); - if (preciseState != null) { - apn = preciseState.getDataConnectionApn(); - state = preciseState.getState(); - networkType = preciseState.getNetworkType(); - linkProps = preciseState.getDataConnectionLinkProperties(); - } - if (VDBG) { - log("notifyDataConnectionForSubscriber: subId=" + subId - + " state=" + state + "' apn='" + apn - + "' apnType=" + apnType + " networkType=" + networkType - + "' preciseState=" + preciseState); - } + int apnTypes = apnSetting.getApnTypeBitmask(); + int state = preciseState.getState(); + int networkType = preciseState.getNetworkType(); synchronized (mRecords) { if (validatePhoneId(phoneId)) { // We only call the callback when the change is for default APN type. - if ((ApnSetting.TYPE_DEFAULT & apnType) != 0 + if ((ApnSetting.TYPE_DEFAULT & apnTypes) != 0 && (mDataConnectionState[phoneId] != state || mDataConnectionNetworkType[phoneId] != networkType)) { String str = "onDataConnectionStateChanged(" @@ -1749,19 +1739,13 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mDataConnectionNetworkType[phoneId] = networkType; } - boolean needsNotify = false; - // State has been cleared for this APN Type - if (preciseState == null) { - // We try clear the state and check if the state was previously not cleared - needsNotify = mPreciseDataConnectionStates.get(phoneId).remove(apnType) != null; - } else { - // We need to check to see if the state actually changed - PreciseDataConnectionState oldPreciseState = - mPreciseDataConnectionStates.get(phoneId).put(apnType, preciseState); - needsNotify = !preciseState.equals(oldPreciseState); - } - - if (needsNotify) { + Pair key = Pair.create(preciseState.getTransportType(), + preciseState.getApnSetting()); + PreciseDataConnectionState oldState = mPreciseDataConnectionStates.get(phoneId) + .remove(key); + log("Jack: oldState=" + oldState); + log("Jack: newState=" + preciseState); + if (!Objects.equals(oldState, preciseState)) { for (Record r : mRecords) { if (r.matchPhoneStateListenerEvent( PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) @@ -1773,54 +1757,22 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } } + handleRemoveListLocked(); + + broadcastDataConnectionStateChanged(phoneId, subId, preciseState); + + String str = "notifyDataConnectionForSubscriber: phoneId=" + phoneId + " subId=" + + subId + " " + preciseState; + log(str); + mLocalLog.log(str); + } + + // If the state is disconnected, it would be the end of life cycle of a data + // connection, so remove it from the cache. + if (preciseState.getState() != TelephonyManager.DATA_DISCONNECTED) { + mPreciseDataConnectionStates.get(phoneId).put(key, preciseState); } } - handleRemoveListLocked(); - } - - broadcastDataConnectionStateChanged(state, apn, apnType, subId); - } - - /** - * Stub to satisfy the ITelephonyRegistry aidl interface; do not use this function. - * @see #notifyDataConnectionFailedForSubscriber - */ - public void notifyDataConnectionFailed(String apnType) { - loge("This function should not be invoked"); - } - - private void notifyDataConnectionFailedForSubscriber(int phoneId, int subId, int apnType) { - if (!checkNotifyPermission("notifyDataConnectionFailed()")) { - return; - } - if (VDBG) { - log("notifyDataConnectionFailedForSubscriber: subId=" + subId - + " apnType=" + apnType); - } - synchronized (mRecords) { - if (validatePhoneId(phoneId)) { - mPreciseDataConnectionStates.get(phoneId).put( - apnType, - new PreciseDataConnectionState( - TelephonyManager.DATA_UNKNOWN, - TelephonyManager.NETWORK_TYPE_UNKNOWN, - apnType, null, null, - DataFailCause.NONE, null)); - for (Record r : mRecords) { - if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) - && idMatch(r.subId, subId, phoneId)) { - try { - r.callback.onPreciseDataConnectionStateChanged( - mPreciseDataConnectionStates.get(phoneId).get(apnType)); - } catch (RemoteException ex) { - mRemoveList.add(r.binder); - } - } - } - } - - handleRemoveListLocked(); } } @@ -1969,42 +1921,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - @Override - public void notifyPreciseDataConnectionFailed(int phoneId, int subId, @ApnType int apnType, - String apn, @DataFailureCause int failCause) { - if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) { - return; - } - - // precise notify invokes imprecise notify - notifyDataConnectionFailedForSubscriber(phoneId, subId, apnType); - - synchronized (mRecords) { - if (validatePhoneId(phoneId)) { - mPreciseDataConnectionStates.get(phoneId).put( - apnType, - new PreciseDataConnectionState( - TelephonyManager.DATA_UNKNOWN, - TelephonyManager.NETWORK_TYPE_UNKNOWN, - apnType, null, null, - failCause, null)); - for (Record r : mRecords) { - if (r.matchPhoneStateListenerEvent( - PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) - && idMatch(r.subId, subId, phoneId)) { - try { - r.callback.onPreciseDataConnectionStateChanged( - mPreciseDataConnectionStates.get(phoneId).get(apnType)); - } catch (RemoteException ex) { - mRemoveList.add(r.binder); - } - } - } - } - handleRemoveListLocked(); - } - } - @Override public void notifySrvccStateChanged(int subId, @SrvccState int state) { if (!checkNotifyPermission("notifySrvccStateChanged()")) { @@ -2575,16 +2491,18 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - private void broadcastDataConnectionStateChanged(int state, String apn, - int apnType, int subId) { + private void broadcastDataConnectionStateChanged(int slotIndex, int subId, + @NonNull PreciseDataConnectionState pdcs) { // Note: not reporting to the battery stats service here, because the // status bar takes care of that after taking into account all of the // required info. Intent intent = new Intent(ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); - intent.putExtra(PHONE_CONSTANTS_STATE_KEY, TelephonyUtils.dataStateToString(state)); - intent.putExtra(PHONE_CONSTANTS_DATA_APN_KEY, apn); + intent.putExtra(PHONE_CONSTANTS_STATE_KEY, + TelephonyUtils.dataStateToString(pdcs.getState())); + intent.putExtra(PHONE_CONSTANTS_DATA_APN_KEY, pdcs.getApnSetting().getApnName()); intent.putExtra(PHONE_CONSTANTS_DATA_APN_TYPE_KEY, - ApnSetting.getApnTypesStringFromBitmask(apnType)); + ApnSetting.getApnTypesStringFromBitmask(pdcs.getApnSetting().getApnTypeBitmask())); + intent.putExtra(PHONE_CONSTANTS_SLOT_KEY, slotIndex); intent.putExtra(PHONE_CONSTANTS_SUBSCRIPTION_KEY, subId); mContext.sendBroadcastAsUser(intent, UserHandle.ALL, Manifest.permission.READ_PHONE_STATE); } @@ -2941,7 +2859,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { /** * Returns a string representation of the radio technology (network type) * currently in use on the device. - * @param subId for which network type is returned + * @param type for which network type is returned * @return the name of the radio technology * */ diff --git a/telephony/api/system-current.txt b/telephony/api/system-current.txt index 8228d30d0a4f7..d95e7a6160810 100644 --- a/telephony/api/system-current.txt +++ b/telephony/api/system-current.txt @@ -316,6 +316,7 @@ package android.telephony { method @Deprecated public int getDataConnectionApnTypeBitMask(); method @Deprecated public int getDataConnectionFailCause(); method @Deprecated public int getDataConnectionState(); + method public int getId(); } public final class PreciseDisconnectCause { diff --git a/telephony/api/system-removed.txt b/telephony/api/system-removed.txt index c7fd30438dff0..ae46075c48298 100644 --- a/telephony/api/system-removed.txt +++ b/telephony/api/system-removed.txt @@ -1,11 +1,6 @@ // Signature format: 2.0 package android.telephony { - public final class PreciseDataConnectionState implements android.os.Parcelable { - method @Deprecated @Nullable public android.net.LinkProperties getDataConnectionLinkProperties(); - method @Deprecated public int getDataConnectionNetworkType(); - } - public class TelephonyManager { method @Deprecated @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void answerRingingCall(); method @Deprecated @RequiresPermission(android.Manifest.permission.CALL_PHONE) public boolean endCall(); diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java index b682bdd7aee33..fd9f46011c7e4 100644 --- a/telephony/java/android/telephony/PreciseDataConnectionState.java +++ b/telephony/java/android/telephony/PreciseDataConnectionState.java @@ -28,11 +28,15 @@ import android.net.LinkProperties; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; +import android.telephony.AccessNetworkConstants.TransportType; import android.telephony.Annotation.ApnType; import android.telephony.Annotation.DataFailureCause; import android.telephony.Annotation.DataState; import android.telephony.Annotation.NetworkType; import android.telephony.data.ApnSetting; +import android.telephony.data.DataCallResponse; + +import com.android.internal.telephony.util.TelephonyUtils; import java.util.Objects; @@ -53,14 +57,13 @@ import java.util.Objects; * */ public final class PreciseDataConnectionState implements Parcelable { - - private @DataState int mState = TelephonyManager.DATA_UNKNOWN; - private @NetworkType int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; - private @DataFailureCause int mFailCause = DataFailCause.NONE; - private @ApnType int mApnTypes = ApnSetting.TYPE_NONE; - private String mApn = ""; - private LinkProperties mLinkProperties = null; - private ApnSetting mApnSetting = null; + private final @TransportType int mTransportType; + private final int mId; + private final @DataState int mState; + private final @NetworkType int mNetworkType; + private final @DataFailureCause int mFailCause; + private final LinkProperties mLinkProperties; + private final ApnSetting mApnSetting; /** * Constructor @@ -77,60 +80,54 @@ public final class PreciseDataConnectionState implements Parcelable { @ApnType int apnTypes, @NonNull String apn, @Nullable LinkProperties linkProperties, @DataFailureCause int failCause) { - this(state, networkType, apnTypes, apn, linkProperties, failCause, null); + this(AccessNetworkConstants.TRANSPORT_TYPE_INVALID, -1, state, networkType, + linkProperties, failCause, new ApnSetting.Builder() + .setApnTypeBitmask(apnTypes) + .setApnName(apn) + .setEntryName(apn) + .build()); } /** * Constructor of PreciseDataConnectionState * - * @param state the state of the data connection - * @param networkType the access network that is/would carry this data connection - * @param apnTypes the APN types that this data connection carries - * @param apn the APN of this data connection - * @param linkProperties if the data connection is connected, the properties of the connection - * @param failCause in case a procedure related to this data connection fails, a non-zero error + * @param transportType The transport of the data connection + * @param id The id of the data connection + * @param state The state of the data connection + * @param networkType The access network that is/would carry this data connection + * @param linkProperties If the data connection is connected, the properties of the connection + * @param failCause In case a procedure related to this data connection fails, a non-zero error * code indicating the cause of the failure. - * @param apnSetting if there is a valid APN for this Data Connection, then the APN Settings; + * @param apnSetting If there is a valid APN for this Data Connection, then the APN Settings; * if there is no valid APN setting for the specific type, then this will be null - * @hide */ - public PreciseDataConnectionState(@DataState int state, - @NetworkType int networkType, - @ApnType int apnTypes, @NonNull String apn, - @Nullable LinkProperties linkProperties, - @DataFailureCause int failCause, - @Nullable ApnSetting apnSetting) { + private PreciseDataConnectionState(@TransportType int transportType, int id, + @DataState int state, @NetworkType int networkType, + @Nullable LinkProperties linkProperties, @DataFailureCause int failCause, + @Nullable ApnSetting apnSetting) { + mTransportType = transportType; + mId = id; mState = state; mNetworkType = networkType; - mApnTypes = apnTypes; - mApn = apn; mLinkProperties = linkProperties; mFailCause = failCause; mApnSetting = apnSetting; } - /** - * Empty Constructor - * - * @hide - */ - public PreciseDataConnectionState() { - } - /** * Construct a PreciseDataConnectionState object from the given parcel. * * @hide */ private PreciseDataConnectionState(Parcel in) { + mTransportType = in.readInt(); + mId = in.readInt(); mState = in.readInt(); mNetworkType = in.readInt(); - mApnTypes = in.readInt(); - mApn = in.readString(); - mLinkProperties = (LinkProperties) in.readParcelable(null); + mLinkProperties = in.readParcelable(LinkProperties.class.getClassLoader()); mFailCause = in.readInt(); - mApnSetting = (ApnSetting) in.readParcelable(null); + mApnSetting = in.readParcelable(ApnSetting.class.getClassLoader()); } /** @@ -160,29 +157,38 @@ public final class PreciseDataConnectionState implements Parcelable { } /** - * Returns the high-level state of this data connection. + * @return The transport type of this data connection. + */ + public @TransportType int getTransportType() { + return mTransportType; + } + + /** + * @return The unique id of the data connection + * + * Note this is the id assigned in {@link DataCallResponse}. + * The id remains the same for data connection handover between + * {@link AccessNetworkConstants#TRANSPORT_TYPE_WLAN} and + * {@link AccessNetworkConstants#TRANSPORT_TYPE_WWAN} + * + * @hide + */ + @SystemApi + public int getId() { + return mId; + } + + /** + * @return The high-level state of this data connection. */ public @DataState int getState() { return mState; } /** - * Returns the network type associated with this data connection. + * Get the network type associated with this data connection. * - * @deprecated use {@link getNetworkType()} - * @hide - * @removed Removed from the R preview SDK but was never part of the stable API surface. - */ - @Deprecated - @SystemApi - public @NetworkType int getDataConnectionNetworkType() { - return mNetworkType; - } - - /** - * Returns the network type associated with this data connection. - * - * Return the current/latest (radio) bearer technology that carries this data connection. + * @return The current/latest (radio) bearer technology that carries this data connection. * For a variety of reasons, the network type can change during the life of the data * connection, and this information is not reliable unless the physical link is currently * active; (there is currently no mechanism to know whether the physical link is active at @@ -202,7 +208,7 @@ public final class PreciseDataConnectionState implements Parcelable { @Deprecated @SystemApi public @ApnType int getDataConnectionApnTypeBitMask() { - return mApnTypes; + return (mApnSetting != null) ? mApnSetting.getApnTypeBitmask() : ApnSetting.TYPE_NONE; } /** @@ -215,21 +221,7 @@ public final class PreciseDataConnectionState implements Parcelable { @SystemApi @Deprecated public String getDataConnectionApn() { - return mApn; - } - - /** - * Get the properties of the network link {@link LinkProperties}. - * - * @deprecated use {@link #getLinkProperties()} - * @hide - * @removed Removed from the R preview SDK but was never part of the stable API surface. - */ - @Deprecated - @SystemApi - @Nullable - public LinkProperties getDataConnectionLinkProperties() { - return mLinkProperties; + return (mApnSetting != null) ? mApnSetting.getApnName() : ""; } /** @@ -265,7 +257,9 @@ public final class PreciseDataConnectionState implements Parcelable { /** * Return the APN Settings for this data connection. * - * @return the ApnSetting that was used to configure this data connection. + * @return the ApnSetting that was used to configure this data connection. Note that a data + * connection cannot be established without a valid {@link ApnSetting}. The return value would + * never be {@code null} even though it has {@link Nullable} annotation. */ public @Nullable ApnSetting getApnSetting() { return mApnSetting; @@ -278,10 +272,10 @@ public final class PreciseDataConnectionState implements Parcelable { @Override public void writeToParcel(@NonNull Parcel out, int flags) { + out.writeInt(mTransportType); + out.writeInt(mId); out.writeInt(mState); out.writeInt(mNetworkType); - out.writeInt(mApnTypes); - out.writeString(mApn); out.writeParcelable(mLinkProperties, flags); out.writeInt(mFailCause); out.writeParcelable(mApnSetting, flags); @@ -301,24 +295,23 @@ public final class PreciseDataConnectionState implements Parcelable { @Override public int hashCode() { - return Objects.hash(mState, mNetworkType, mApnTypes, mApn, mLinkProperties, - mFailCause, mApnSetting); + return Objects.hash(mTransportType, mId, mState, mNetworkType, mFailCause, + mLinkProperties, mApnSetting); } + @Override - public boolean equals(@Nullable Object obj) { - - if (!(obj instanceof PreciseDataConnectionState)) { - return false; - } - - PreciseDataConnectionState other = (PreciseDataConnectionState) obj; - return Objects.equals(mApn, other.mApn) && mApnTypes == other.mApnTypes - && mFailCause == other.mFailCause - && Objects.equals(mLinkProperties, other.mLinkProperties) - && mNetworkType == other.mNetworkType - && mState == other.mState - && Objects.equals(mApnSetting, other.mApnSetting); + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + PreciseDataConnectionState that = (PreciseDataConnectionState) o; + return mTransportType == that.mTransportType + && mId == that.mId + && mState == that.mState + && mNetworkType == that.mNetworkType + && mFailCause == that.mFailCause + && Objects.equals(mLinkProperties, that.mLinkProperties) + && Objects.equals(mApnSetting, that.mApnSetting); } @NonNull @@ -326,14 +319,137 @@ public final class PreciseDataConnectionState implements Parcelable { public String toString() { StringBuilder sb = new StringBuilder(); - sb.append("Data Connection state: " + mState); - sb.append(", Network type: " + mNetworkType); - sb.append(", APN types: " + ApnSetting.getApnTypesStringFromBitmask(mApnTypes)); - sb.append(", APN: " + mApn); - sb.append(", Link properties: " + mLinkProperties); - sb.append(", Fail cause: " + DataFailCause.toString(mFailCause)); - sb.append(", Apn Setting: " + mApnSetting); + sb.append(" state: " + TelephonyUtils.dataStateToString(mState)); + sb.append(", transport: " + + AccessNetworkConstants.transportTypeToString(mTransportType)); + sb.append(", id: " + mId); + sb.append(", network type: " + TelephonyManager.getNetworkTypeName(mNetworkType)); + sb.append(", APN Setting: " + mApnSetting); + sb.append(", link properties: " + mLinkProperties); + sb.append(", fail cause: " + DataFailCause.toString(mFailCause)); return sb.toString(); } + + /** + * {@link PreciseDataConnectionState} builder + * + * @hide + */ + public static final class Builder { + /** The transport type of the data connection */ + private @TransportType int mTransportType = AccessNetworkConstants.TRANSPORT_TYPE_INVALID; + + /** + * The unique ID of the data connection. This is the id assigned in + * {@link DataCallResponse)}. + */ + private int mId = -1; + + /** The state of the data connection */ + private @DataState int mState = TelephonyManager.DATA_UNKNOWN; + + /** The network type associated with this data connection */ + private @NetworkType int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; + + /** If the data connection is connected, the properties of the connection */ + private @Nullable LinkProperties mLinkProperties = null; + + /** + * In case a procedure related to this data connection fails, a non-zero error code + * indicating the cause of the failure. + */ + private @DataFailureCause int mFailCause = DataFailCause.NONE; + + /** The APN Setting for this data connection */ + private @Nullable ApnSetting mApnSetting = null; + + /** + * Set the transport type of the data connection. + * + * @param transportType The transport type of the data connection + * @return The builder + */ + public @NonNull Builder setTransportType(@TransportType int transportType) { + mTransportType = transportType; + return this; + } + + /** + * Set the id of the data connection. + * + * @param id The id of the data connection + * @return The builder + */ + public @NonNull Builder setId(int id) { + mId = id; + return this; + } + + /** + * Set the state of the data connection. + * + * @param state The state of the data connection + * @return The builder + */ + public @NonNull Builder setState(@DataState int state) { + mState = state; + return this; + } + + /** + * Set the network type associated with this data connection. + * + * @param networkType The network type + * @return The builder + */ + public @NonNull Builder setNetworkType(@NetworkType int networkType) { + mNetworkType = networkType; + return this; + } + + /** + * Set the link properties of the connection. + * + * @param linkProperties Link properties + * @return The builder + */ + public @NonNull Builder setLinkProperties(LinkProperties linkProperties) { + mLinkProperties = linkProperties; + return this; + } + + /** + * Set the fail cause of the data connection. + * + * @param failCause In case a procedure related to this data connection fails, a non-zero + * error code indicating the cause of the failure. + * @return The builder + */ + public @NonNull Builder setFailCause(@DataFailureCause int failCause) { + mFailCause = failCause; + return this; + } + + /** + * Set the APN Setting for this data connection. + * + * @param apnSetting APN setting + * @return This builder + */ + public @NonNull Builder setApnSetting(@NonNull ApnSetting apnSetting) { + mApnSetting = apnSetting; + return this; + } + + /** + * Build the {@link PreciseDataConnectionState} instance. + * + * @return The {@link PreciseDataConnectionState} instance + */ + public PreciseDataConnectionState build() { + return new PreciseDataConnectionState(mTransportType, mId, mState, mNetworkType, + mLinkProperties, mFailCause, mApnSetting); + } + } } diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java index e60ae896f9f80..ff9329ef97423 100644 --- a/telephony/java/android/telephony/data/ApnSetting.java +++ b/telephony/java/android/telephony/data/ApnSetting.java @@ -1214,12 +1214,16 @@ public class ApnSetting implements Parcelable { return false; } - // TODO - if we have this function we should also have hashCode. - // Also should handle changes in type order and perhaps case-insensitivity. + @Override + public int hashCode() { + return Objects.hash(mApnName, mProxyAddress, mProxyPort, mMmsc, mMmsProxyAddress, + mMmsProxyPort, mUser, mPassword, mAuthType, mApnTypeBitmask, mId, mOperatorNumeric, + mProtocol, mRoamingProtocol, mMtu, mCarrierEnabled, mNetworkTypeBitmask, mProfileId, + mPersistent, mMaxConns, mWaitTime, mMaxConnsTime, mMvnoType, mMvnoMatchData, + mApnSetId, mCarrierId, mSkip464Xlat); + } - /** - * @hide - */ + @Override public boolean equals(Object o) { if (o instanceof ApnSetting == false) { return false;