Expose PreciseDataConnectionState to Public API

1) Remove Unused Parameters for onDataConnectionState:
The data connection state broadcast includes a number of
parameters that are never used anywhere. To prepare for
updated code that relies on PreciseDataConnectionState,
remove the unused parameters that were internal-only and
included in the broadcast.

-LinkProperties
-NetworkCapabilities
-DataRoaming
-DataAllowed
-Interface name

2) Add Disconnecting State for Data Connections

Add a disconnecting state to correct a mismatch
between the internal and externally visible enums.

This will allow apps to know when connections are
in the process of being torn down, which in the case
of radio link issues could be as much as 15 seconds.

3) Expose PreciseDataConnection for Carrier Apps

Exposes the PSL for PreciseDataConnectionState along
with existing fields in the PreciseDataConnectionState
class.

-Make PreciseDataConnectionState public along with some
 of its fields.
-Expose onPreciseDataConnectionStateChanged.
-Add onPreciseDataConnectionStatesChanged to provide PDCS
 for all APNs in one cohesive batch.

4) Cache PreciseDataConnectionState by APN Type

In telephony registry, multiple different APN types
are all piped through the same cache entry, so every
time any APN changes relative to the previous type,
it triggers an update. This also means that when
a registrant requests the data connection state, only
the most recent type's state is updated.

This change caches entries in TelephonyRegistry based
on the APN's type (specifically the type among types
which triggered the change).

Bug: 143083105
Test: make update-api && make offline-sdk-docs
      (no functional change in this CL).
Test: atest FrameworksTelephonyTests

Merged-In: Ib6a769f5a0cae923ca47a842733bd28755a90ed5
Change-Id: Ib6a769f5a0cae923ca47a842733bd28755a90ed5
(cherry picked from commit 4d340f12c9)
This commit is contained in:
Nathan Harold
2019-12-05 17:27:56 -08:00
parent 69d7032777
commit c95b4e5421
11 changed files with 328 additions and 205 deletions

View File

@@ -44768,6 +44768,7 @@ package android.telephony {
method public void onDataConnectionStateChanged(int); method public void onDataConnectionStateChanged(int);
method public void onDataConnectionStateChanged(int, int); method public void onDataConnectionStateChanged(int, int);
method public void onMessageWaitingIndicatorChanged(boolean); method public void onMessageWaitingIndicatorChanged(boolean);
method @RequiresPermission("android.permission.MODIFY_PHONE_STATE") public void onPreciseDataConnectionStateChanged(@NonNull android.telephony.PreciseDataConnectionState);
method public void onServiceStateChanged(android.telephony.ServiceState); method public void onServiceStateChanged(android.telephony.ServiceState);
method @Deprecated public void onSignalStrengthChanged(int); method @Deprecated public void onSignalStrengthChanged(int);
method public void onSignalStrengthsChanged(android.telephony.SignalStrength); method public void onSignalStrengthsChanged(android.telephony.SignalStrength);
@@ -44782,12 +44783,23 @@ package android.telephony {
field public static final int LISTEN_EMERGENCY_NUMBER_LIST = 16777216; // 0x1000000 field public static final int LISTEN_EMERGENCY_NUMBER_LIST = 16777216; // 0x1000000
field public static final int LISTEN_MESSAGE_WAITING_INDICATOR = 4; // 0x4 field public static final int LISTEN_MESSAGE_WAITING_INDICATOR = 4; // 0x4
field public static final int LISTEN_NONE = 0; // 0x0 field public static final int LISTEN_NONE = 0; // 0x0
field @RequiresPermission("android.permission.MODIFY_PHONE_STATE") public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 4096; // 0x1000
field public static final int LISTEN_SERVICE_STATE = 1; // 0x1 field public static final int LISTEN_SERVICE_STATE = 1; // 0x1
field @Deprecated public static final int LISTEN_SIGNAL_STRENGTH = 2; // 0x2 field @Deprecated public static final int LISTEN_SIGNAL_STRENGTH = 2; // 0x2
field public static final int LISTEN_SIGNAL_STRENGTHS = 256; // 0x100 field public static final int LISTEN_SIGNAL_STRENGTHS = 256; // 0x100
field public static final int LISTEN_USER_MOBILE_DATA_STATE = 524288; // 0x80000 field public static final int LISTEN_USER_MOBILE_DATA_STATE = 524288; // 0x80000
} }
public final class PreciseDataConnectionState implements android.os.Parcelable {
method public int describeContents();
method public int getLastCauseCode();
method @Nullable public android.net.LinkProperties getLinkProperties();
method public int getNetworkType();
method public int getState();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PreciseDataConnectionState> CREATOR;
}
public final class RadioAccessSpecifier implements android.os.Parcelable { public final class RadioAccessSpecifier implements android.os.Parcelable {
ctor public RadioAccessSpecifier(int, int[], int[]); ctor public RadioAccessSpecifier(int, int[], int[]);
method public int describeContents(); method public int describeContents();
@@ -45292,6 +45304,7 @@ package android.telephony {
field public static final int DATA_CONNECTED = 2; // 0x2 field public static final int DATA_CONNECTED = 2; // 0x2
field public static final int DATA_CONNECTING = 1; // 0x1 field public static final int DATA_CONNECTING = 1; // 0x1
field public static final int DATA_DISCONNECTED = 0; // 0x0 field public static final int DATA_DISCONNECTED = 0; // 0x0
field public static final int DATA_DISCONNECTING = 4; // 0x4
field public static final int DATA_SUSPENDED = 3; // 0x3 field public static final int DATA_SUSPENDED = 3; // 0x3
field public static final int DATA_UNKNOWN = -1; // 0xffffffff field public static final int DATA_UNKNOWN = -1; // 0xffffffff
field public static final String EXTRA_CALL_VOICEMAIL_INTENT = "android.telephony.extra.CALL_VOICEMAIL_INTENT"; field public static final String EXTRA_CALL_VOICEMAIL_INTENT = "android.telephony.extra.CALL_VOICEMAIL_INTENT";

View File

@@ -8566,7 +8566,6 @@ package android.telephony {
method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber); method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber);
method public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber); method public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber);
method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onPreciseCallStateChanged(@NonNull android.telephony.PreciseCallState); method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onPreciseCallStateChanged(@NonNull android.telephony.PreciseCallState);
method @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public void onPreciseDataConnectionStateChanged(@NonNull android.telephony.PreciseDataConnectionState);
method public void onRadioPowerStateChanged(int); method public void onRadioPowerStateChanged(int);
method public void onSrvccStateChanged(int); method public void onSrvccStateChanged(int);
method public void onVoiceActivationStateChanged(int); method public void onVoiceActivationStateChanged(int);
@@ -8576,7 +8575,6 @@ package android.telephony {
field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000 field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_CALL = 268435456; // 0x10000000
field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000 field @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION) public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000
field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_PRECISE_CALL_STATE = 2048; // 0x800 field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_PRECISE_CALL_STATE = 2048; // 0x800
field @RequiresPermission("android.permission.READ_PRECISE_PHONE_STATE") public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 4096; // 0x1000
field public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000 field public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000
field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_SRVCC_STATE_CHANGED = 16384; // 0x4000 field @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public static final int LISTEN_SRVCC_STATE_CHANGED = 16384; // 0x4000
field public static final int LISTEN_VOICE_ACTIVATION_STATE = 131072; // 0x20000 field public static final int LISTEN_VOICE_ACTIVATION_STATE = 131072; // 0x20000
@@ -8602,13 +8600,12 @@ package android.telephony {
} }
public final class PreciseDataConnectionState implements android.os.Parcelable { public final class PreciseDataConnectionState implements android.os.Parcelable {
method public int describeContents(); method @Deprecated @NonNull public String getDataConnectionApn();
method @Nullable public String getDataConnectionApn(); method @Deprecated public int getDataConnectionApnTypeBitMask();
method public int getDataConnectionApnTypeBitMask(); method @Deprecated public int getDataConnectionFailCause();
method public int getDataConnectionFailCause(); method @Deprecated @Nullable public android.net.LinkProperties getDataConnectionLinkProperties();
method public int getDataConnectionState(); method @Deprecated public int getDataConnectionNetworkType();
method public void writeToParcel(android.os.Parcel, int); method @Deprecated public int getDataConnectionState();
field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PreciseDataConnectionState> CREATOR;
} }
public final class PreciseDisconnectCause { public final class PreciseDisconnectCause {

View File

@@ -3004,6 +3004,10 @@ package android.telephony {
field @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000 field @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public static final int LISTEN_OUTGOING_EMERGENCY_SMS = 536870912; // 0x20000000
} }
public final class PreciseDataConnectionState implements android.os.Parcelable {
ctor @Deprecated public PreciseDataConnectionState(int, int, int, @NonNull String, @Nullable android.net.LinkProperties, int);
}
public class ServiceState implements android.os.Parcelable { public class ServiceState implements android.os.Parcelable {
method public void addNetworkRegistrationInfo(android.telephony.NetworkRegistrationInfo); method public void addNetworkRegistrationInfo(android.telephony.NetworkRegistrationInfo);
method public void setCdmaSystemAndNetworkId(int, int); method public void setCdmaSystemAndNetworkId(int, int);

View File

@@ -35,8 +35,8 @@ import android.telephony.Annotation.SrvccState;
import android.telephony.emergency.EmergencyNumber; import android.telephony.emergency.EmergencyNumber;
import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.ImsReasonInfo;
import com.android.internal.telephony.IPhoneStateListener;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.IPhoneStateListener;
import dalvik.system.VMRuntime; import dalvik.system.VMRuntime;
@@ -188,12 +188,13 @@ public class PhoneStateListener {
/** /**
* Listen for {@link PreciseDataConnectionState} on the data connection (cellular). * Listen for {@link PreciseDataConnectionState} on the data connection (cellular).
* *
* @see #onPreciseDataConnectionStateChanged * <p>Requires permission {@link android.Manifest.permission#MODIFY_PHONE_STATE}
* or the calling app has carrier privileges
* (see {@link TelephonyManager#hasCarrierPrivileges}).
* *
* @hide * @see #onPreciseDataConnectionStateChanged
*/ */
@RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) @RequiresPermission((android.Manifest.permission.MODIFY_PHONE_STATE))
@SystemApi
public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 0x00001000; public static final int LISTEN_PRECISE_DATA_CONNECTION_STATE = 0x00001000;
/** /**
@@ -688,8 +689,9 @@ public class PhoneStateListener {
} }
/** /**
* Callback invoked when data connection state changes with precise information * Callback providing update about the default/internet data connection on the registered
* on the registered subscription. * subscription.
*
* Note, the registration subId comes from {@link TelephonyManager} object which registers * Note, the registration subId comes from {@link TelephonyManager} object which registers
* PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}. * PhoneStateListener by {@link TelephonyManager#listen(PhoneStateListener, int)}.
* If this TelephonyManager object was created with * If this TelephonyManager object was created with
@@ -697,12 +699,13 @@ public class PhoneStateListener {
* subId. Otherwise, this callback applies to * subId. Otherwise, this callback applies to
* {@link SubscriptionManager#getDefaultSubscriptionId()}. * {@link SubscriptionManager#getDefaultSubscriptionId()}.
* *
* @param dataConnectionState {@link PreciseDataConnectionState} * <p>Requires permission {@link android.Manifest.permission#MODIFY_PHONE_STATE}
* or the calling app has carrier privileges
* (see {@link TelephonyManager#hasCarrierPrivileges}).
* *
* @hide * @param dataConnectionState {@link PreciseDataConnectionState}
*/ */
@RequiresPermission((android.Manifest.permission.READ_PRECISE_PHONE_STATE)) @RequiresPermission((android.Manifest.permission.MODIFY_PHONE_STATE))
@SystemApi
public void onPreciseDataConnectionStateChanged( public void onPreciseDataConnectionStateChanged(
@NonNull PreciseDataConnectionState dataConnectionState) { @NonNull PreciseDataConnectionState dataConnectionState) {
// default implementation empty // default implementation empty
@@ -1011,12 +1014,22 @@ public class PhoneStateListener {
PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
if (psl == null) return; if (psl == null) return;
if (state == TelephonyManager.DATA_DISCONNECTING
&& VMRuntime.getRuntime().getTargetSdkVersion() < Build.VERSION_CODES.R) {
Binder.withCleanCallingIdentity(() -> mExecutor.execute(
() -> {
psl.onDataConnectionStateChanged(
TelephonyManager.DATA_CONNECTED, networkType);
psl.onDataConnectionStateChanged(TelephonyManager.DATA_CONNECTED);
}));
} else {
Binder.withCleanCallingIdentity(() -> mExecutor.execute( Binder.withCleanCallingIdentity(() -> mExecutor.execute(
() -> { () -> {
psl.onDataConnectionStateChanged(state, networkType); psl.onDataConnectionStateChanged(state, networkType);
psl.onDataConnectionStateChanged(state); psl.onDataConnectionStateChanged(state);
})); }));
} }
}
public void onDataActivity(int direction) { public void onDataActivity(int direction) {
PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); PhoneStateListener psl = mPhoneStateListenerWeakRef.get();

View File

@@ -21,19 +21,15 @@ import android.annotation.RequiresPermission;
import android.annotation.SystemApi; import android.annotation.SystemApi;
import android.annotation.TestApi; import android.annotation.TestApi;
import android.content.Context; import android.content.Context;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
import android.os.Binder; import android.os.Binder;
import android.os.Bundle; import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.HandlerExecutor; import android.os.HandlerExecutor;
import android.os.RemoteException; import android.os.RemoteException;
import android.os.ServiceManager; import android.os.ServiceManager;
import android.telephony.Annotation.ApnType;
import android.telephony.Annotation.CallState; import android.telephony.Annotation.CallState;
import android.telephony.Annotation.DataActivityType; import android.telephony.Annotation.DataActivityType;
import android.telephony.Annotation.DataFailureCause; import android.telephony.Annotation.DataFailureCause;
import android.telephony.Annotation.DataState;
import android.telephony.Annotation.NetworkType; import android.telephony.Annotation.NetworkType;
import android.telephony.Annotation.PreciseCallStates; import android.telephony.Annotation.PreciseCallStates;
import android.telephony.Annotation.RadioPowerState; import android.telephony.Annotation.RadioPowerState;
@@ -365,27 +361,18 @@ public class TelephonyRegistryManager {
* @param subId for which data connection state changed. * @param subId for which data connection state changed.
* @param slotIndex for which data connections state changed. Can be derived from subId except * @param slotIndex for which data connections state changed. Can be derived from subId except
* when subId is invalid. * when subId is invalid.
* @param state latest data connection state, e.g, * @param apnType the APN type that triggered this update
* @param isDataConnectivityPossible indicates if data is allowed * @param preciseState the PreciseDataConnectionState
* @param apn the APN {@link ApnSetting#getApnName()} of this data connection.
* @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN.
* @param linkProperties {@link LinkProperties} associated with this data connection.
* @param networkCapabilities {@link NetworkCapabilities} associated with this data connection.
* @param networkType associated with this data connection.
* @param roaming {@code true} indicates in roaming, {@false} otherwise.
* @see TelephonyManager#DATA_DISCONNECTED
* @see TelephonyManager#isDataConnectivityPossible()
* *
* @see android.telephony.PreciseDataConnection
* @see TelephonyManager#DATA_DISCONNECTED
* @hide * @hide
*/ */
public void notifyDataConnectionForSubscriber(int slotIndex, int subId, @DataState int state, public void notifyDataConnectionForSubscriber(int slotIndex, int subId,
boolean isDataConnectivityPossible, String apnType, PreciseDataConnectionState preciseState) {
@ApnType String apn, String apnType, LinkProperties linkProperties,
NetworkCapabilities networkCapabilities, int networkType, boolean roaming) {
try { try {
sRegistry.notifyDataConnectionForSubscriber(slotIndex, subId, state, sRegistry.notifyDataConnectionForSubscriber(
isDataConnectivityPossible, slotIndex, subId, apnType, preciseState);
apn, apnType, linkProperties, networkCapabilities, networkType, roaming);
} catch (RemoteException ex) { } catch (RemoteException ex) {
// system process is dead // system process is dead
} }
@@ -653,25 +640,6 @@ public class TelephonyRegistryManager {
} }
} }
/**
* Notify data connection failed on certain subscription.
*
* @param subId for which data connection failed.
* @param slotIndex for which data conenction faled. Can be derived from subId except when subId
* is invalid.
* @param apnType the apnType, "ims" for IMS APN, "emergency" for EMERGENCY APN. Note each data
* connection can support multiple anyTypes.
*
* @hide
*/
public void notifyDataConnectionFailed(int subId, int slotIndex, String apnType) {
try {
sRegistry.notifyDataConnectionFailedForSubscriber(slotIndex, subId, apnType);
} catch (RemoteException ex) {
// system process is dead
}
}
/** /**
* TODO change from bundle to CellLocation? * TODO change from bundle to CellLocation?
* @hide * @hide

View File

@@ -24,6 +24,8 @@ import android.telephony.CallQuality;
import android.telephony.CellInfo; import android.telephony.CellInfo;
import android.telephony.ims.ImsReasonInfo; import android.telephony.ims.ImsReasonInfo;
import android.telephony.PhoneCapability; import android.telephony.PhoneCapability;
import android.telephony.PhysicalChannelConfig;
import android.telephony.PreciseDataConnectionState;
import android.telephony.ServiceState; import android.telephony.ServiceState;
import android.telephony.SignalStrength; import android.telephony.SignalStrength;
import android.telephony.emergency.EmergencyNumber; import android.telephony.emergency.EmergencyNumber;
@@ -54,13 +56,8 @@ interface ITelephonyRegistry {
@UnsupportedAppUsage(maxTargetSdk = 28) @UnsupportedAppUsage(maxTargetSdk = 28)
void notifyDataActivity(int state); void notifyDataActivity(int state);
void notifyDataActivityForSubscriber(in int subId, int state); void notifyDataActivityForSubscriber(in int subId, int state);
void notifyDataConnection(int state, boolean isDataConnectivityPossible, void notifyDataConnectionForSubscriber(
String apn, String apnType, in LinkProperties linkProperties, int phoneId, int subId, String apnType, in PreciseDataConnectionState preciseState);
in NetworkCapabilities networkCapabilities, int networkType, boolean roaming);
void notifyDataConnectionForSubscriber(int phoneId, int subId, int state,
boolean isDataConnectivityPossible,
String apn, String apnType, in LinkProperties linkProperties,
in NetworkCapabilities networkCapabilities, int networkType, boolean roaming);
@UnsupportedAppUsage @UnsupportedAppUsage
void notifyDataConnectionFailed(String apnType); void notifyDataConnectionFailed(String apnType);
void notifyDataConnectionFailedForSubscriber(int phoneId, int subId, String apnType); void notifyDataConnectionFailedForSubscriber(int phoneId, int subId, String apnType);

View File

@@ -30,7 +30,6 @@ import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.net.LinkProperties; import android.net.LinkProperties;
import android.net.NetworkCapabilities;
import android.os.Binder; import android.os.Binder;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
@@ -256,7 +255,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
private final LocalLog mListenLog = new LocalLog(100); private final LocalLog mListenLog = new LocalLog(100);
private PreciseDataConnectionState[] mPreciseDataConnectionState; // Per-phoneMap of APN Type to DataConnectionState
private List<Map<String, PreciseDataConnectionState>> mPreciseDataConnectionStates =
new ArrayList<Map<String, PreciseDataConnectionState>>();
// Nothing here yet, but putting it here in case we want to add more in the future. // Nothing here yet, but putting it here in case we want to add more in the future.
static final int ENFORCE_COARSE_LOCATION_PERMISSION_MASK = 0; static final int ENFORCE_COARSE_LOCATION_PERMISSION_MASK = 0;
@@ -410,7 +411,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
mCallQuality = copyOf(mCallQuality, mNumPhones); mCallQuality = copyOf(mCallQuality, mNumPhones);
mCallNetworkType = copyOf(mCallNetworkType, mNumPhones); mCallNetworkType = copyOf(mCallNetworkType, mNumPhones);
mCallAttributes = copyOf(mCallAttributes, mNumPhones); mCallAttributes = copyOf(mCallAttributes, mNumPhones);
mPreciseDataConnectionState = copyOf(mPreciseDataConnectionState, mNumPhones);
mOutgoingCallEmergencyNumber = copyOf(mOutgoingCallEmergencyNumber, mNumPhones); mOutgoingCallEmergencyNumber = copyOf(mOutgoingCallEmergencyNumber, mNumPhones);
mOutgoingSmsEmergencyNumber = copyOf(mOutgoingSmsEmergencyNumber, mNumPhones); mOutgoingSmsEmergencyNumber = copyOf(mOutgoingSmsEmergencyNumber, mNumPhones);
@@ -418,6 +418,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
if (mNumPhones < oldNumPhones) { if (mNumPhones < oldNumPhones) {
cutListToSize(mCellInfo, mNumPhones); cutListToSize(mCellInfo, mNumPhones);
cutListToSize(mImsReasonInfo, mNumPhones); cutListToSize(mImsReasonInfo, mNumPhones);
cutListToSize(mPreciseDataConnectionStates, mNumPhones);
return; return;
} }
@@ -448,7 +449,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mPreciseDataConnectionState[i] = new PreciseDataConnectionState(); mPreciseDataConnectionStates.add(new HashMap<String, PreciseDataConnectionState>());
} }
// Note that location can be null for non-phone builds like // Note that location can be null for non-phone builds like
@@ -509,7 +510,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
mCallQuality = new CallQuality[numPhones]; mCallQuality = new CallQuality[numPhones];
mCallNetworkType = new int[numPhones]; mCallNetworkType = new int[numPhones];
mCallAttributes = new CallAttributes[numPhones]; mCallAttributes = new CallAttributes[numPhones];
mPreciseDataConnectionState = new PreciseDataConnectionState[numPhones]; mPreciseDataConnectionStates = new ArrayList<>();
mCellInfo = new ArrayList<>(); mCellInfo = new ArrayList<>();
mImsReasonInfo = new ArrayList<>(); mImsReasonInfo = new ArrayList<>();
mEmergencyNumberList = new HashMap<>(); mEmergencyNumberList = new HashMap<>();
@@ -541,7 +542,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE; mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mPreciseDataConnectionState[i] = new PreciseDataConnectionState(); mPreciseDataConnectionStates.add(new HashMap<String, PreciseDataConnectionState>());
} }
// Note that location can be null for non-phone builds like // Note that location can be null for non-phone builds like
@@ -896,8 +897,10 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
} }
if ((events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) { if ((events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
try { try {
r.callback.onPreciseDataConnectionStateChanged( for (PreciseDataConnectionState pdcs
mPreciseDataConnectionState[phoneId]); : mPreciseDataConnectionStates.get(phoneId).values()) {
r.callback.onPreciseDataConnectionStateChanged(pdcs);
}
} catch (RemoteException ex) { } catch (RemoteException ex) {
remove(r.binder); remove(r.binder);
} }
@@ -911,7 +914,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
} }
if ((events & PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE) !=0) { if ((events & PhoneStateListener.LISTEN_VOICE_ACTIVATION_STATE) !=0) {
try { try {
r.callback.onVoiceActivationStateChanged(mVoiceActivationState[phoneId]); r.callback.onVoiceActivationStateChanged(
mVoiceActivationState[phoneId]);
} catch (RemoteException ex) { } catch (RemoteException ex) {
remove(r.binder); remove(r.binder);
} }
@@ -1469,30 +1473,38 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
} }
} }
public void notifyDataConnection(int state, boolean isDataAllowed, String apn, String apnType, /**
LinkProperties linkProperties, * Send a notification to registrants that the data connection state has changed.
NetworkCapabilities networkCapabilities, int networkType, *
boolean roaming) { * @param phoneId the phoneId carrying the data connection
notifyDataConnectionForSubscriber(SubscriptionManager.DEFAULT_PHONE_INDEX, * @param subId the subscriptionId for the data connection
SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, state, * @param apnType the APN type that triggered a change in the data connection
isDataAllowed, apn, apnType, linkProperties, * @param preciseState a PreciseDataConnectionState that has info about the data connection
networkCapabilities, networkType, roaming); */
} public void notifyDataConnectionForSubscriber(
int phoneId, int subId, String apnType, PreciseDataConnectionState preciseState) {
public void notifyDataConnectionForSubscriber(int phoneId, int subId, int state,
boolean isDataAllowed,
String apn, String apnType,
LinkProperties linkProperties, NetworkCapabilities networkCapabilities,
int networkType, boolean roaming) {
if (!checkNotifyPermission("notifyDataConnection()" )) { if (!checkNotifyPermission("notifyDataConnection()" )) {
return; return;
} }
String apn = "";
int state = TelephonyManager.DATA_UNKNOWN;
int networkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
LinkProperties linkProps = null;
if (preciseState != null) {
apn = preciseState.getDataConnectionApn();
state = preciseState.getState();
networkType = preciseState.getNetworkType();
linkProps = preciseState.getDataConnectionLinkProperties();
}
if (VDBG) { if (VDBG) {
log("notifyDataConnectionForSubscriber: subId=" + subId log("notifyDataConnectionForSubscriber: subId=" + subId
+ " state=" + state + " isDataAllowed=" + isDataAllowed + " state=" + state + "' apn='" + apn
+ "' apn='" + apn + "' apnType=" + apnType + " networkType=" + networkType + "' apnType=" + apnType + " networkType=" + networkType
+ " mRecords.size()=" + mRecords.size()); + "' preciseState=" + preciseState);
} }
synchronized (mRecords) { synchronized (mRecords) {
if (validatePhoneId(phoneId)) { if (validatePhoneId(phoneId)) {
// We only call the callback when the change is for default APN type. // We only call the callback when the change is for default APN type.
@@ -1524,33 +1536,45 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
mDataConnectionState[phoneId] = state; mDataConnectionState[phoneId] = state;
mDataConnectionNetworkType[phoneId] = networkType; mDataConnectionNetworkType[phoneId] = networkType;
} }
mPreciseDataConnectionState[phoneId] = new PreciseDataConnectionState(
state, networkType, boolean needsNotify = false;
ApnSetting.getApnTypesBitmaskFromString(apnType), apn, // State has been cleared for this APN Type
linkProperties, DataFailCause.NONE); 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) {
for (Record r : mRecords) { for (Record r : mRecords) {
if (r.matchPhoneStateListenerEvent( if (r.matchPhoneStateListenerEvent(
PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)
&& idMatch(r.subId, subId, phoneId)) { && idMatch(r.subId, subId, phoneId)) {
try { try {
r.callback.onPreciseDataConnectionStateChanged( r.callback.onPreciseDataConnectionStateChanged(preciseState);
mPreciseDataConnectionState[phoneId]);
} catch (RemoteException ex) { } catch (RemoteException ex) {
mRemoveList.add(r.binder); mRemoveList.add(r.binder);
} }
} }
} }
} }
}
handleRemoveListLocked(); handleRemoveListLocked();
} }
broadcastDataConnectionStateChanged(state, isDataAllowed, apn, apnType, linkProperties,
networkCapabilities, roaming, subId); broadcastDataConnectionStateChanged(state, apn, apnType, subId);
} }
/**
* Stub to satisfy the ITelephonyRegistry aidl interface; do not use this function.
* @see #notifyDataConnectionFailedForSubscriber
*/
public void notifyDataConnectionFailed(String apnType) { public void notifyDataConnectionFailed(String apnType) {
notifyDataConnectionFailedForSubscriber(SubscriptionManager.DEFAULT_PHONE_INDEX, loge("This function should not be invoked");
SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
apnType);
} }
public void notifyDataConnectionFailedForSubscriber(int phoneId, int subId, String apnType) { public void notifyDataConnectionFailedForSubscriber(int phoneId, int subId, String apnType) {
@@ -1563,17 +1587,20 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
} }
synchronized (mRecords) { synchronized (mRecords) {
if (validatePhoneId(phoneId)) { if (validatePhoneId(phoneId)) {
mPreciseDataConnectionState[phoneId] = new PreciseDataConnectionState( mPreciseDataConnectionStates.get(phoneId).put(
TelephonyManager.DATA_UNKNOWN,TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType,
new PreciseDataConnectionState(
TelephonyManager.DATA_UNKNOWN,
TelephonyManager.NETWORK_TYPE_UNKNOWN,
ApnSetting.getApnTypesBitmaskFromString(apnType), null, null, ApnSetting.getApnTypesBitmaskFromString(apnType), null, null,
DataFailCause.NONE); DataFailCause.NONE));
for (Record r : mRecords) { for (Record r : mRecords) {
if (r.matchPhoneStateListenerEvent( if (r.matchPhoneStateListenerEvent(
PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)
&& idMatch(r.subId, subId, phoneId)) { && idMatch(r.subId, subId, phoneId)) {
try { try {
r.callback.onPreciseDataConnectionStateChanged( r.callback.onPreciseDataConnectionStateChanged(
mPreciseDataConnectionState[phoneId]); mPreciseDataConnectionStates.get(phoneId).get(apnType));
} catch (RemoteException ex) { } catch (RemoteException ex) {
mRemoveList.add(r.binder); mRemoveList.add(r.binder);
} }
@@ -1738,25 +1765,32 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) { if (!checkNotifyPermission("notifyPreciseDataConnectionFailed()")) {
return; return;
} }
// precise notify invokes imprecise notify
notifyDataConnectionFailedForSubscriber(phoneId, subId, apnType);
synchronized (mRecords) { synchronized (mRecords) {
if (validatePhoneId(phoneId)) { if (validatePhoneId(phoneId)) {
mPreciseDataConnectionState[phoneId] = new PreciseDataConnectionState( mPreciseDataConnectionStates.get(phoneId).put(
TelephonyManager.DATA_UNKNOWN, TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType,
ApnSetting.getApnTypesBitmaskFromString(apnType), apn, null, failCause); new PreciseDataConnectionState(
TelephonyManager.DATA_UNKNOWN,
TelephonyManager.NETWORK_TYPE_UNKNOWN,
ApnSetting.getApnTypesBitmaskFromString(apnType), null, null,
failCause));
for (Record r : mRecords) { for (Record r : mRecords) {
if (r.matchPhoneStateListenerEvent( if (r.matchPhoneStateListenerEvent(
PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE)
&& idMatch(r.subId, subId, phoneId)) { && idMatch(r.subId, subId, phoneId)) {
try { try {
r.callback.onPreciseDataConnectionStateChanged( r.callback.onPreciseDataConnectionStateChanged(
mPreciseDataConnectionState[phoneId]); mPreciseDataConnectionStates.get(phoneId).get(apnType));
} catch (RemoteException ex) { } catch (RemoteException ex) {
mRemoveList.add(r.binder); mRemoveList.add(r.binder);
} }
} }
} }
} }
handleRemoveListLocked(); handleRemoveListLocked();
} }
} }
@@ -2014,7 +2048,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
} }
} }
@Override @Override
public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " "); final IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
@@ -2052,7 +2085,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
pw.println("mCallQuality=" + mCallQuality[i]); pw.println("mCallQuality=" + mCallQuality[i]);
pw.println("mCallAttributes=" + mCallAttributes[i]); pw.println("mCallAttributes=" + mCallAttributes[i]);
pw.println("mCallNetworkType=" + mCallNetworkType[i]); pw.println("mCallNetworkType=" + mCallNetworkType[i]);
pw.println("mPreciseDataConnectionState=" + mPreciseDataConnectionState[i]); pw.println("mPreciseDataConnectionStates=" + mPreciseDataConnectionStates.get(i));
pw.println("mOutgoingCallEmergencyNumber=" + mOutgoingCallEmergencyNumber[i]); pw.println("mOutgoingCallEmergencyNumber=" + mOutgoingCallEmergencyNumber[i]);
pw.println("mOutgoingSmsEmergencyNumber=" + mOutgoingSmsEmergencyNumber[i]); pw.println("mOutgoingSmsEmergencyNumber=" + mOutgoingSmsEmergencyNumber[i]);
pw.decreaseIndent(); pw.decreaseIndent();
@@ -2212,29 +2245,13 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
} }
} }
private void broadcastDataConnectionStateChanged(int state, boolean isDataAllowed, String apn, private void broadcastDataConnectionStateChanged(int state, String apn,
String apnType, LinkProperties linkProperties, String apnType, int subId) {
NetworkCapabilities networkCapabilities,
boolean roaming, int subId) {
// Note: not reporting to the battery stats service here, because the // Note: not reporting to the battery stats service here, because the
// status bar takes care of that after taking into account all of the // status bar takes care of that after taking into account all of the
// required info. // required info.
Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); Intent intent = new Intent(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
intent.putExtra(TelephonyManager.EXTRA_STATE, dataStateToString(state)); intent.putExtra(TelephonyManager.EXTRA_STATE, dataStateToString(state));
if (!isDataAllowed) {
intent.putExtra(PhoneConstants.NETWORK_UNAVAILABLE_KEY, true);
}
if (linkProperties != null) {
intent.putExtra(PhoneConstants.DATA_LINK_PROPERTIES_KEY, linkProperties);
String iface = linkProperties.getInterfaceName();
if (iface != null) {
intent.putExtra(PhoneConstants.DATA_IFACE_NAME_KEY, iface);
}
}
if (networkCapabilities != null) {
intent.putExtra(PhoneConstants.DATA_NETWORK_CAPABILITIES_KEY, networkCapabilities);
}
if (roaming) intent.putExtra(PhoneConstants.DATA_NETWORK_ROAMING_KEY, true);
intent.putExtra(PhoneConstants.DATA_APN_KEY, apn); intent.putExtra(PhoneConstants.DATA_APN_KEY, apn);
intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType);

View File

@@ -19,8 +19,10 @@ package android.telephony;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.annotation.SystemApi; import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage; import android.annotation.UnsupportedAppUsage;
import android.net.LinkProperties; import android.net.LinkProperties;
import android.os.Build;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.telephony.Annotation.ApnType; import android.telephony.Annotation.ApnType;
@@ -29,6 +31,8 @@ import android.telephony.Annotation.DataState;
import android.telephony.Annotation.NetworkType; import android.telephony.Annotation.NetworkType;
import android.telephony.data.ApnSetting; import android.telephony.data.ApnSetting;
import dalvik.system.VMRuntime;
import java.util.Objects; import java.util.Objects;
@@ -46,35 +50,62 @@ import java.util.Objects;
* <li>Data connection fail cause. * <li>Data connection fail cause.
* </ul> * </ul>
* *
* @hide
*/ */
@SystemApi
public final class PreciseDataConnectionState implements Parcelable { public final class PreciseDataConnectionState implements Parcelable {
private @DataState int mState = TelephonyManager.DATA_UNKNOWN; private @DataState int mState = TelephonyManager.DATA_UNKNOWN;
private @NetworkType int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN; private @NetworkType int mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
private @DataFailureCause int mFailCause = DataFailCause.NONE; private @DataFailureCause int mFailCause = DataFailCause.NONE;
private @ApnType int mAPNTypes = ApnSetting.TYPE_NONE; private @ApnType int mApnTypes = ApnSetting.TYPE_NONE;
private String mAPN = ""; private String mApn = "";
private LinkProperties mLinkProperties = null; private LinkProperties mLinkProperties = null;
private ApnSetting mApnSetting = null;
/** /**
* Constructor * Constructor
* *
* @deprecated this constructor has been superseded and should not be used.
* @hide * @hide
*/ */
@UnsupportedAppUsage @TestApi
@Deprecated
@UnsupportedAppUsage // (maxTargetSdk = Build.VERSION_CODES.Q)
// FIXME: figure out how to remove the UnsupportedAppUsage and delete this constructor
public PreciseDataConnectionState(@DataState int state, public PreciseDataConnectionState(@DataState int state,
@NetworkType int networkType, @NetworkType int networkType,
@ApnType int apnTypes, String apn, @ApnType int apnTypes, @NonNull String apn,
LinkProperties linkProperties, @Nullable LinkProperties linkProperties,
@DataFailureCause int failCause) { @DataFailureCause int failCause) {
this(state, networkType, apnTypes, apn, linkProperties, failCause, null);
}
/**
* Constructor
*
* @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 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
* @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.
* @hide
*/
public PreciseDataConnectionState(@DataState int state,
@NetworkType int networkType,
@ApnType int apnTypes, @NonNull String apn,
@Nullable LinkProperties linkProperties,
@DataFailureCause int failCause,
@Nullable ApnSetting apnSetting) {
mState = state; mState = state;
mNetworkType = networkType; mNetworkType = networkType;
mAPNTypes = apnTypes; mApnTypes = apnTypes;
mAPN = apn; mApn = apn;
mLinkProperties = linkProperties; mLinkProperties = linkProperties;
mFailCause = failCause; mFailCause = failCause;
mApnSetting = apnSetting;
} }
/** /**
@@ -93,76 +124,160 @@ public final class PreciseDataConnectionState implements Parcelable {
private PreciseDataConnectionState(Parcel in) { private PreciseDataConnectionState(Parcel in) {
mState = in.readInt(); mState = in.readInt();
mNetworkType = in.readInt(); mNetworkType = in.readInt();
mAPNTypes = in.readInt(); mApnTypes = in.readInt();
mAPN = in.readString(); mApn = in.readString();
mLinkProperties = (LinkProperties) in.readParcelable(null); mLinkProperties = (LinkProperties) in.readParcelable(null);
mFailCause = in.readInt(); mFailCause = in.readInt();
mApnSetting = (ApnSetting) in.readParcelable(null);
} }
/** /**
* Returns the state of data connection that supported the apn types returned by * Returns the state of data connection that supported the apn types returned by
* {@link #getDataConnectionApnTypeBitMask()} * {@link #getDataConnectionApnTypeBitMask()}
*
* @deprecated use {@link #getState()}
* @hide
*/ */
@Deprecated
@SystemApi
public @DataState int getDataConnectionState() { public @DataState int getDataConnectionState() {
if (mState == TelephonyManager.DATA_DISCONNECTING
&& VMRuntime.getRuntime().getTargetSdkVersion() < Build.VERSION_CODES.R) {
return TelephonyManager.DATA_CONNECTED;
}
return mState;
}
/**
* Returns the high-level state of this data connection.
*/
public @DataState int getState() {
return mState; return mState;
} }
/** /**
* Returns the network type associated with this data connection. * Returns the network type associated with this data connection.
*
* @deprecated use {@link getNetworkType()}
* @hide * @hide
*/ */
@Deprecated
@SystemApi
public @NetworkType int getDataConnectionNetworkType() { public @NetworkType int getDataConnectionNetworkType() {
return mNetworkType; return mNetworkType;
} }
/** /**
* Returns the data connection APN types supported by this connection and triggers * Returns the network type associated with this data connection.
* {@link PreciseDataConnectionState} change. *
* 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
* any given moment). Thus, this value is generally correct but may not be relied-upon to
* represent the status of the radio bearer at any given moment.
*/ */
public @ApnType int getDataConnectionApnTypeBitMask() { public @NetworkType int getNetworkType() {
return mAPNTypes; return mNetworkType;
} }
/** /**
* Returns APN {@link ApnSetting} of this data connection. * Returns the APN types mapped to this data connection.
*
* @deprecated use {@link #getApnSetting()}
* @hide
*/ */
@Nullable @Deprecated
@SystemApi
public @ApnType int getDataConnectionApnTypeBitMask() {
return mApnTypes;
}
/**
* Returns APN of this data connection.
*
* @deprecated use {@link #getApnSetting()}
* @hide
*/
@NonNull
@SystemApi
@Deprecated
public String getDataConnectionApn() { public String getDataConnectionApn() {
return mAPN; return mApn;
} }
/** /**
* Get the properties of the network link {@link LinkProperties}. * Get the properties of the network link {@link LinkProperties}.
*
* @deprecated use {@link #getLinkProperties()}
* @hide * @hide
*/ */
@UnsupportedAppUsage @Deprecated
@SystemApi
@Nullable
public LinkProperties getDataConnectionLinkProperties() { public LinkProperties getDataConnectionLinkProperties() {
return mLinkProperties; return mLinkProperties;
} }
/** /**
* Returns data connection fail cause, in case there was a failure. * Get the properties of the network link {@link LinkProperties}.
*/ */
public @Annotation.DataFailureCause int getDataConnectionFailCause() { @Nullable
public LinkProperties getLinkProperties() {
return mLinkProperties;
}
/**
* Returns the cause code generated by the most recent state change.
*
* @deprecated use {@link #getLastCauseCode()}
* @hide
*/
@Deprecated
@SystemApi
public int getDataConnectionFailCause() {
return mFailCause; return mFailCause;
} }
/**
* Returns the cause code generated by the most recent state change.
*
* Return the cause code for the most recent change in {@link #getState}. In the event of an
* error, this cause code will be non-zero.
*/
// FIXME(b144774287): some of these cause codes should have a prescribed meaning.
public int getLastCauseCode() {
return mFailCause;
}
/**
* Return the APN Settings for this data connection.
*
* Returns the ApnSetting that was used to configure this data connection.
*/
// FIXME: This shouldn't be nullable; update once the ApnSetting is supplied correctly
@Nullable ApnSetting getApnSetting() {
return mApnSetting;
}
@Override @Override
public int describeContents() { public int describeContents() {
return 0; return 0;
} }
@Override @Override
public void writeToParcel(Parcel out, int flags) { public void writeToParcel(@NonNull Parcel out, int flags) {
out.writeInt(mState); out.writeInt(mState);
out.writeInt(mNetworkType); out.writeInt(mNetworkType);
out.writeInt(mAPNTypes); out.writeInt(mApnTypes);
out.writeString(mAPN); out.writeString(mApn);
out.writeParcelable(mLinkProperties, flags); out.writeParcelable(mLinkProperties, flags);
out.writeInt(mFailCause); out.writeInt(mFailCause);
out.writeParcelable(mApnSetting, flags);
} }
public static final @android.annotation.NonNull Parcelable.Creator<PreciseDataConnectionState> CREATOR public static final @NonNull Parcelable.Creator<PreciseDataConnectionState> CREATOR
= new Parcelable.Creator<PreciseDataConnectionState>() { = new Parcelable.Creator<PreciseDataConnectionState>() {
public PreciseDataConnectionState createFromParcel(Parcel in) { public PreciseDataConnectionState createFromParcel(Parcel in) {
@@ -176,8 +291,8 @@ public final class PreciseDataConnectionState implements Parcelable {
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(mState, mNetworkType, mAPNTypes, mAPN, mLinkProperties, return Objects.hash(mState, mNetworkType, mApnTypes, mApn, mLinkProperties,
mFailCause); mFailCause, mApnSetting);
} }
@Override @Override
@@ -188,11 +303,12 @@ public final class PreciseDataConnectionState implements Parcelable {
} }
PreciseDataConnectionState other = (PreciseDataConnectionState) obj; PreciseDataConnectionState other = (PreciseDataConnectionState) obj;
return Objects.equals(mAPN, other.mAPN) && mAPNTypes == other.mAPNTypes return Objects.equals(mApn, other.mApn) && mApnTypes == other.mApnTypes
&& mFailCause == other.mFailCause && mFailCause == other.mFailCause
&& Objects.equals(mLinkProperties, other.mLinkProperties) && Objects.equals(mLinkProperties, other.mLinkProperties)
&& mNetworkType == other.mNetworkType && mNetworkType == other.mNetworkType
&& mState == other.mState; && mState == other.mState
&& Objects.equals(mApnSetting, other.mApnSetting);
} }
@NonNull @NonNull
@@ -202,10 +318,11 @@ public final class PreciseDataConnectionState implements Parcelable {
sb.append("Data Connection state: " + mState); sb.append("Data Connection state: " + mState);
sb.append(", Network type: " + mNetworkType); sb.append(", Network type: " + mNetworkType);
sb.append(", APN types: " + ApnSetting.getApnTypesStringFromBitmask(mAPNTypes)); sb.append(", APN types: " + ApnSetting.getApnTypesStringFromBitmask(mApnTypes));
sb.append(", APN: " + mAPN); sb.append(", APN: " + mApn);
sb.append(", Link properties: " + mLinkProperties); sb.append(", Link properties: " + mLinkProperties);
sb.append(", Fail cause: " + DataFailCause.toString(mFailCause)); sb.append(", Fail cause: " + DataFailCause.toString(mFailCause));
sb.append(", Apn Setting: " + mApnSetting);
return sb.toString(); return sb.toString();
} }

View File

@@ -789,18 +789,6 @@ public class TelephonyManager {
*/ */
public static final String EXTRA_DATA_APN = PhoneConstants.DATA_APN_KEY; public static final String EXTRA_DATA_APN = PhoneConstants.DATA_APN_KEY;
/**
* The lookup key used with the {@link #ACTION_PRECISE_DATA_CONNECTION_STATE_CHANGED} broadcast
* for an String representation of the data interface.
*
* <p class="note">
* Retrieve with
* {@link android.content.Intent#getParcelableExtra(String name)}.
*
* @hide
*/
public static final String EXTRA_DATA_LINK_PROPERTIES_KEY = PhoneConstants.DATA_LINK_PROPERTIES_KEY;
/** /**
* Broadcast intent action for letting the default dialer to know to show voicemail * Broadcast intent action for letting the default dialer to know to show voicemail
* notification. * notification.
@@ -5061,6 +5049,7 @@ public class TelephonyManager {
DATA_CONNECTING, DATA_CONNECTING,
DATA_CONNECTED, DATA_CONNECTED,
DATA_SUSPENDED, DATA_SUSPENDED,
DATA_DISCONNECTING,
}) })
@Retention(RetentionPolicy.SOURCE) @Retention(RetentionPolicy.SOURCE)
public @interface DataState{} public @interface DataState{}
@@ -5077,6 +5066,12 @@ public class TelephonyManager {
* traffic is temporarily unavailable. For example, in a 2G network, * traffic is temporarily unavailable. For example, in a 2G network,
* data activity may be suspended when a voice call arrives. */ * data activity may be suspended when a voice call arrives. */
public static final int DATA_SUSPENDED = 3; public static final int DATA_SUSPENDED = 3;
/**
* Data connection state: Disconnecting.
*
* IP traffic may be available but will cease working imminently.
*/
public static final int DATA_DISCONNECTING = 4;
/** /**
* Returns a constant indicating the current data connection state * Returns a constant indicating the current data connection state
@@ -5086,14 +5081,21 @@ public class TelephonyManager {
* @see #DATA_CONNECTING * @see #DATA_CONNECTING
* @see #DATA_CONNECTED * @see #DATA_CONNECTED
* @see #DATA_SUSPENDED * @see #DATA_SUSPENDED
* @see #DATA_DISCONNECTING
*/ */
public int getDataState() { public int getDataState() {
try { try {
ITelephony telephony = getITelephony(); ITelephony telephony = getITelephony();
if (telephony == null) if (telephony == null)
return DATA_DISCONNECTED; return DATA_DISCONNECTED;
return telephony.getDataStateForSubId( int state = telephony.getDataStateForSubId(
getSubId(SubscriptionManager.getActiveDataSubscriptionId())); getSubId(SubscriptionManager.getActiveDataSubscriptionId()));
if (state == TelephonyManager.DATA_DISCONNECTING
&& VMRuntime.getRuntime().getTargetSdkVersion() < Build.VERSION_CODES.R) {
return TelephonyManager.DATA_CONNECTED;
}
return state;
} catch (RemoteException ex) { } catch (RemoteException ex) {
// the phone process is restarting. // the phone process is restarting.
return DATA_DISCONNECTED; return DATA_DISCONNECTED;
@@ -5114,6 +5116,7 @@ public class TelephonyManager {
case DATA_CONNECTING: return "CONNECTING"; case DATA_CONNECTING: return "CONNECTING";
case DATA_CONNECTED: return "CONNECTED"; case DATA_CONNECTED: return "CONNECTED";
case DATA_SUSPENDED: return "SUSPENDED"; case DATA_SUSPENDED: return "SUSPENDED";
case DATA_DISCONNECTING: return "DISCONNECTING";
} }
return "UNKNOWN(" + state + ")"; return "UNKNOWN(" + state + ")";
} }

View File

@@ -16,14 +16,10 @@
package com.android.internal.telephony; package com.android.internal.telephony;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager; import android.telephony.TelephonyManager;
import android.telephony.PreciseCallState;
import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.PhoneConstants;
import java.util.List;
public class PhoneConstantConversions { public class PhoneConstantConversions {
/** /**
* Convert the {@link PhoneConstants.State} enum into the TelephonyManager.CALL_STATE_* * Convert the {@link PhoneConstants.State} enum into the TelephonyManager.CALL_STATE_*
@@ -67,6 +63,8 @@ public class PhoneConstantConversions {
return TelephonyManager.DATA_CONNECTED; return TelephonyManager.DATA_CONNECTED;
case SUSPENDED: case SUSPENDED:
return TelephonyManager.DATA_SUSPENDED; return TelephonyManager.DATA_SUSPENDED;
case DISCONNECTING:
return TelephonyManager.DATA_DISCONNECTING;
default: default:
return TelephonyManager.DATA_DISCONNECTED; return TelephonyManager.DATA_DISCONNECTED;
} }
@@ -84,6 +82,8 @@ public class PhoneConstantConversions {
return PhoneConstants.DataState.CONNECTED; return PhoneConstants.DataState.CONNECTED;
case TelephonyManager.DATA_SUSPENDED: case TelephonyManager.DATA_SUSPENDED:
return PhoneConstants.DataState.SUSPENDED; return PhoneConstants.DataState.SUSPENDED;
case TelephonyManager.DATA_DISCONNECTING:
return PhoneConstants.DataState.DISCONNECTING;
default: default:
return PhoneConstants.DataState.DISCONNECTED; return PhoneConstants.DataState.DISCONNECTED;
} }

View File

@@ -49,6 +49,7 @@ public class PhoneConstants {
* <ul> * <ul>
* <li>CONNECTED = IP traffic should be available</li> * <li>CONNECTED = IP traffic should be available</li>
* <li>CONNECTING = Currently setting up data connection</li> * <li>CONNECTING = Currently setting up data connection</li>
* <li>DISCONNECTING = IP temporarily available</li>
* <li>DISCONNECTED = IP not available</li> * <li>DISCONNECTED = IP not available</li>
* <li>SUSPENDED = connection is created but IP traffic is * <li>SUSPENDED = connection is created but IP traffic is
* temperately not available. i.e. voice call is in place * temperately not available. i.e. voice call is in place
@@ -65,7 +66,8 @@ public class PhoneConstants {
@UnsupportedAppUsage @UnsupportedAppUsage
DISCONNECTED, DISCONNECTED,
@UnsupportedAppUsage @UnsupportedAppUsage
SUSPENDED; SUSPENDED,
DISCONNECTING;
}; };
public static final String STATE_KEY = "state"; public static final String STATE_KEY = "state";
@@ -98,20 +100,12 @@ public class PhoneConstants {
public static final String PHONE_NAME_KEY = "phoneName"; public static final String PHONE_NAME_KEY = "phoneName";
public static final String DATA_NETWORK_TYPE_KEY = "networkType"; public static final String DATA_NETWORK_TYPE_KEY = "networkType";
public static final String DATA_FAILURE_CAUSE_KEY = "failCause";
public static final String DATA_APN_TYPE_KEY = "apnType"; public static final String DATA_APN_TYPE_KEY = "apnType";
public static final String DATA_APN_KEY = "apn"; public static final String DATA_APN_KEY = "apn";
public static final String DATA_LINK_PROPERTIES_KEY = "linkProperties";
public static final String DATA_NETWORK_CAPABILITIES_KEY = "networkCapabilities";
public static final String DATA_IFACE_NAME_KEY = "iface";
public static final String NETWORK_UNAVAILABLE_KEY = "networkUnvailable";
public static final String DATA_NETWORK_ROAMING_KEY = "networkRoaming";
public static final String PHONE_IN_ECM_STATE = "phoneinECMState"; public static final String PHONE_IN_ECM_STATE = "phoneinECMState";
public static final String PHONE_IN_EMERGENCY_CALL = "phoneInEmergencyCall"; public static final String PHONE_IN_EMERGENCY_CALL = "phoneInEmergencyCall";
public static final String REASON_LINK_PROPERTIES_CHANGED = "linkPropertiesChanged";
/** /**
* Return codes for supplyPinReturnResult and * Return codes for supplyPinReturnResult and
* supplyPukReturnResult APIs * supplyPukReturnResult APIs