diff options
57 files changed, 3444 insertions, 420 deletions
diff --git a/Android.bp b/Android.bp index a21cd2803267..416613d03e79 100644 --- a/Android.bp +++ b/Android.bp @@ -187,7 +187,6 @@ java_defaults { "core/java/android/hardware/radio/ITunerCallback.aidl", "core/java/android/hardware/soundtrigger/IRecognitionStatusCallback.aidl", "core/java/android/hardware/usb/IUsbManager.aidl", - "core/java/android/net/ICaptivePortal.aidl", "core/java/android/net/IConnectivityManager.aidl", "core/java/android/net/IIpConnectivityMetrics.aidl", "core/java/android/net/IEthernetManager.aidl", @@ -826,6 +825,7 @@ aidl_interface { srcs: [ "core/java/android/net/ApfCapabilitiesParcelable.aidl", "core/java/android/net/DhcpResultsParcelable.aidl", + "core/java/android/net/ICaptivePortal.aidl", "core/java/android/net/INetworkMonitor.aidl", "core/java/android/net/INetworkMonitorCallbacks.aidl", "core/java/android/net/IIpMemoryStore.aidl", diff --git a/api/current.txt b/api/current.txt index bd769e09dec3..a81d5b18a32d 100755 --- a/api/current.txt +++ b/api/current.txt @@ -9952,7 +9952,7 @@ package android.content { field public static final String ACTION_MY_PACKAGE_REPLACED = "android.intent.action.MY_PACKAGE_REPLACED"; field public static final String ACTION_MY_PACKAGE_SUSPENDED = "android.intent.action.MY_PACKAGE_SUSPENDED"; field public static final String ACTION_MY_PACKAGE_UNSUSPENDED = "android.intent.action.MY_PACKAGE_UNSUSPENDED"; - field public static final String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL"; + field @Deprecated public static final String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL"; field public static final String ACTION_OPEN_DOCUMENT = "android.intent.action.OPEN_DOCUMENT"; field public static final String ACTION_OPEN_DOCUMENT_TREE = "android.intent.action.OPEN_DOCUMENT_TREE"; field public static final String ACTION_PACKAGES_SUSPENDED = "android.intent.action.PACKAGES_SUSPENDED"; @@ -20918,7 +20918,7 @@ package android.icu.util { ctor public JapaneseCalendar(int, int, int, int); ctor public JapaneseCalendar(int, int, int); ctor public JapaneseCalendar(int, int, int, int, int, int); - field public static final int CURRENT_ERA; + field @Deprecated public static final int CURRENT_ERA; field public static final int HEISEI; field public static final int MEIJI; field public static final int SHOWA; @@ -27560,24 +27560,24 @@ package android.net { field public static final android.os.Parcelable.Creator<android.net.RouteInfo> CREATOR; } - public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory { + @Deprecated public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory { ctor @Deprecated public SSLCertificateSocketFactory(int); - method public java.net.Socket createSocket(java.net.Socket, String, int, boolean) throws java.io.IOException; - method public java.net.Socket createSocket(java.net.InetAddress, int, java.net.InetAddress, int) throws java.io.IOException; - method public java.net.Socket createSocket(java.net.InetAddress, int) throws java.io.IOException; - method public java.net.Socket createSocket(String, int, java.net.InetAddress, int) throws java.io.IOException; - method public java.net.Socket createSocket(String, int) throws java.io.IOException; - method public static javax.net.SocketFactory getDefault(int); - method public static javax.net.ssl.SSLSocketFactory getDefault(int, android.net.SSLSessionCache); - method public String[] getDefaultCipherSuites(); - method public static javax.net.ssl.SSLSocketFactory getInsecure(int, android.net.SSLSessionCache); - method public byte[] getNpnSelectedProtocol(java.net.Socket); - method public String[] getSupportedCipherSuites(); - method public void setHostname(java.net.Socket, String); - method public void setKeyManagers(javax.net.ssl.KeyManager[]); - method public void setNpnProtocols(byte[][]); - method public void setTrustManagers(javax.net.ssl.TrustManager[]); - method public void setUseSessionTickets(java.net.Socket, boolean); + method @Deprecated public java.net.Socket createSocket(java.net.Socket, String, int, boolean) throws java.io.IOException; + method @Deprecated public java.net.Socket createSocket(java.net.InetAddress, int, java.net.InetAddress, int) throws java.io.IOException; + method @Deprecated public java.net.Socket createSocket(java.net.InetAddress, int) throws java.io.IOException; + method @Deprecated public java.net.Socket createSocket(String, int, java.net.InetAddress, int) throws java.io.IOException; + method @Deprecated public java.net.Socket createSocket(String, int) throws java.io.IOException; + method @Deprecated public static javax.net.SocketFactory getDefault(int); + method @Deprecated public static javax.net.ssl.SSLSocketFactory getDefault(int, android.net.SSLSessionCache); + method @Deprecated public String[] getDefaultCipherSuites(); + method @Deprecated public static javax.net.ssl.SSLSocketFactory getInsecure(int, android.net.SSLSessionCache); + method @Deprecated public byte[] getNpnSelectedProtocol(java.net.Socket); + method @Deprecated public String[] getSupportedCipherSuites(); + method @Deprecated public void setHostname(java.net.Socket, String); + method @Deprecated public void setKeyManagers(javax.net.ssl.KeyManager[]); + method @Deprecated public void setNpnProtocols(byte[][]); + method @Deprecated public void setTrustManagers(javax.net.ssl.TrustManager[]); + method @Deprecated public void setUseSessionTickets(java.net.Socket, boolean); } public final class SSLSessionCache { @@ -27766,6 +27766,8 @@ package android.net { public class VpnService extends android.app.Service { ctor public VpnService(); + method public final boolean isAlwaysOn(); + method public final boolean isLockdownEnabled(); method public android.os.IBinder onBind(android.content.Intent); method public void onRevoke(); method public static android.content.Intent prepare(android.content.Context); @@ -33292,10 +33294,13 @@ package android.os { method public static final void setThreadPriority(int, int) throws java.lang.IllegalArgumentException, java.lang.SecurityException; method public static final void setThreadPriority(int) throws java.lang.IllegalArgumentException, java.lang.SecurityException; method @Deprecated public static final boolean supportsProcesses(); + field public static final int BLUETOOTH_UID = 1002; // 0x3ea field public static final int FIRST_APPLICATION_UID = 10000; // 0x2710 field public static final int INVALID_UID = -1; // 0xffffffff field public static final int LAST_APPLICATION_UID = 19999; // 0x4e1f field public static final int PHONE_UID = 1001; // 0x3e9 + field public static final int ROOT_UID = 0; // 0x0 + field public static final int SHELL_UID = 2000; // 0x7d0 field public static final int SIGNAL_KILL = 9; // 0x9 field public static final int SIGNAL_QUIT = 3; // 0x3 field public static final int SIGNAL_USR1 = 10; // 0xa @@ -43230,7 +43235,9 @@ package android.telephony.data { field public static final int PROTOCOL_IP = 0; // 0x0 field public static final int PROTOCOL_IPV4V6 = 2; // 0x2 field public static final int PROTOCOL_IPV6 = 1; // 0x1 + field public static final int PROTOCOL_NON_IP = 4; // 0x4 field public static final int PROTOCOL_PPP = 3; // 0x3 + field public static final int PROTOCOL_UNSTRUCTURED = 5; // 0x5 field public static final int TYPE_CBS = 128; // 0x80 field public static final int TYPE_DEFAULT = 17; // 0x11 field public static final int TYPE_DUN = 8; // 0x8 diff --git a/api/removed.txt b/api/removed.txt index 356ed912f74e..05d52d4e40c0 100644 --- a/api/removed.txt +++ b/api/removed.txt @@ -320,7 +320,7 @@ package android.net { @IntDef({0x0, 0xa, 0x14, 0x1e}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) public static @interface NetworkBadging.Badging { } - public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory { + @Deprecated public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory { method @Deprecated public static org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory(int, android.net.SSLSessionCache); } diff --git a/api/system-current.txt b/api/system-current.txt index 1320d146d902..6d2473673051 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -3025,6 +3025,8 @@ package android.metrics { package android.net { public class CaptivePortal implements android.os.Parcelable { + ctor public CaptivePortal(android.os.IBinder); + method public void useNetwork(); field public static final int APP_RETURN_DISMISSED = 0; // 0x0 field public static final int APP_RETURN_UNWANTED = 1; // 0x1 field public static final int APP_RETURN_WANTED_AS_IS = 2; // 0x2 @@ -3061,14 +3063,30 @@ package android.net { public final class LinkProperties implements android.os.Parcelable { ctor public LinkProperties(); + method public boolean addDnsServer(java.net.InetAddress); method public boolean addRoute(android.net.RouteInfo); method public void clear(); + method public String getTcpBufferSizes(); + method public java.util.List<java.net.InetAddress> getValidatedPrivateDnsServers(); + method public boolean hasGlobalIPv6Address(); + method public boolean hasIPv4Address(); + method public boolean hasIPv6DefaultRoute(); + method public boolean isIPv4Provisioned(); + method public boolean isIPv6Provisioned(); + method public boolean isProvisioned(); + method public boolean isReachable(java.net.InetAddress); + method public boolean removeDnsServer(java.net.InetAddress); + method public boolean removeRoute(android.net.RouteInfo); method public void setDnsServers(java.util.Collection<java.net.InetAddress>); method public void setDomains(String); method public void setHttpProxy(android.net.ProxyInfo); method public void setInterfaceName(String); method public void setLinkAddresses(java.util.Collection<android.net.LinkAddress>); method public void setMtu(int); + method public void setPrivateDnsServerName(@Nullable String); + method public void setTcpBufferSizes(String); + method public void setUsePrivateDns(boolean); + method public void setValidatedPrivateDnsServers(java.util.Collection<java.net.InetAddress>); } public class Network implements android.os.Parcelable { @@ -3077,6 +3095,8 @@ package android.net { public final class NetworkCapabilities implements android.os.Parcelable { method public int getSignalStrength(); + method public int[] getTransportTypes(); + method public boolean satisfiedByNetworkCapabilities(android.net.NetworkCapabilities); field public static final int NET_CAPABILITY_OEM_PAID = 22; // 0x16 } @@ -3252,6 +3272,7 @@ package android.net.metrics { public class IpConnectivityLog { method public boolean log(long, android.net.metrics.IpConnectivityLog.Event); method public boolean log(String, android.net.metrics.IpConnectivityLog.Event); + method public boolean log(android.net.Network, int[], android.net.metrics.IpConnectivityLog.Event); method public boolean log(int, int[], android.net.metrics.IpConnectivityLog.Event); method public boolean log(android.net.metrics.IpConnectivityLog.Event); } @@ -3319,6 +3340,17 @@ package android.net.metrics { } +package android.net.util { + + public class SocketUtils { + method public static void bindSocketToInterface(java.io.FileDescriptor, String) throws android.system.ErrnoException; + method public static java.net.SocketAddress makeNetlinkSocketAddress(int, int); + method public static java.net.SocketAddress makePacketSocketAddress(short, int); + method public static java.net.SocketAddress makePacketSocketAddress(int, byte[]); + } + +} + package android.net.wifi { @Deprecated public class RttManager { @@ -4001,6 +4033,12 @@ package android.os { method public void onResult(android.os.Bundle); } + public class ServiceSpecificException extends java.lang.RuntimeException { + ctor public ServiceSpecificException(int, String); + ctor public ServiceSpecificException(int); + field public final int errorCode; + } + public final class StatsDimensionsValue implements android.os.Parcelable { method public int describeContents(); method public boolean getBooleanValue(); @@ -5317,42 +5355,211 @@ package android.telephony { } public final class DataFailCause { + field public static final int ACCESS_ATTEMPT_ALREADY_IN_PROGRESS = 2219; // 0x8ab + field public static final int ACCESS_BLOCK = 2087; // 0x827 + field public static final int ACCESS_BLOCK_ALL = 2088; // 0x828 + field public static final int ACCESS_CLASS_DSAC_REJECTION = 2108; // 0x83c + field public static final int ACCESS_CONTROL_LIST_CHECK_FAILURE = 2128; // 0x850 + field public static final int ACTIVATION_REJECTED_BCM_VIOLATION = 48; // 0x30 field public static final int ACTIVATION_REJECT_GGSN = 30; // 0x1e field public static final int ACTIVATION_REJECT_UNSPECIFIED = 31; // 0x1f field public static final int ACTIVE_PDP_CONTEXT_MAX_NUMBER_REACHED = 65; // 0x41 + field public static final int APN_DISABLED = 2045; // 0x7fd + field public static final int APN_DISALLOWED_ON_ROAMING = 2059; // 0x80b + field public static final int APN_MISMATCH = 2054; // 0x806 + field public static final int APN_PARAMETERS_CHANGED = 2060; // 0x80c + field public static final int APN_PENDING_HANDOVER = 2041; // 0x7f9 field public static final int APN_TYPE_CONFLICT = 112; // 0x70 field public static final int AUTH_FAILURE_ON_EMERGENCY_CALL = 122; // 0x7a + field public static final int BEARER_HANDLING_NOT_SUPPORTED = 60; // 0x3c + field public static final int CALL_DISALLOWED_IN_ROAMING = 2068; // 0x814 + field public static final int CALL_PREEMPT_BY_EMERGENCY_APN = 127; // 0x7f + field public static final int CANNOT_ENCODE_OTA_MESSAGE = 2159; // 0x86f + field public static final int CDMA_ALERT_STOP = 2077; // 0x81d + field public static final int CDMA_INCOMING_CALL = 2076; // 0x81c + field public static final int CDMA_INTERCEPT = 2073; // 0x819 + field public static final int CDMA_LOCK = 2072; // 0x818 + field public static final int CDMA_RELEASE_DUE_TO_SO_REJECTION = 2075; // 0x81b + field public static final int CDMA_REORDER = 2074; // 0x81a + field public static final int CDMA_RETRY_ORDER = 2086; // 0x826 + field public static final int CHANNEL_ACQUISITION_FAILURE = 2078; // 0x81e + field public static final int CLOSE_IN_PROGRESS = 2030; // 0x7ee + field public static final int COLLISION_WITH_NETWORK_INITIATED_REQUEST = 56; // 0x38 field public static final int COMPANION_IFACE_IN_USE = 118; // 0x76 + field public static final int CONCURRENT_SERVICES_INCOMPATIBLE = 2083; // 0x823 + field public static final int CONCURRENT_SERVICES_NOT_ALLOWED = 2091; // 0x82b + field public static final int CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STATION = 2080; // 0x820 field public static final int CONDITIONAL_IE_ERROR = 100; // 0x64 + field public static final int CONGESTION = 2106; // 0x83a + field public static final int CONNECTION_RELEASED = 2113; // 0x841 + field public static final int CS_DOMAIN_NOT_AVAILABLE = 2181; // 0x885 + field public static final int CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED = 2188; // 0x88c + field public static final int DATA_PLAN_EXPIRED = 2198; // 0x896 + field public static final int DATA_ROAMING_SETTINGS_DISABLED = 2064; // 0x810 + field public static final int DATA_SETTINGS_DISABLED = 2063; // 0x80f + field public static final int DBM_OR_SMS_IN_PROGRESS = 2211; // 0x8a3 + field public static final int DDS_SWITCHED = 2065; // 0x811 + field public static final int DDS_SWITCH_IN_PROGRESS = 2067; // 0x813 + field public static final int DRB_RELEASED_BY_RRC = 2112; // 0x840 + field public static final int DS_EXPLICIT_DEACTIVATION = 2125; // 0x84d + field public static final int DUAL_SWITCH = 2227; // 0x8b3 + field public static final int DUN_CALL_DISALLOWED = 2056; // 0x808 + field public static final int DUPLICATE_BEARER_ID = 2118; // 0x846 + field public static final int EHRPD_TO_HRPD_FALLBACK = 2049; // 0x801 + field public static final int EMBMS_NOT_ENABLED = 2193; // 0x891 + field public static final int EMBMS_REGULAR_DEACTIVATION = 2195; // 0x893 field public static final int EMERGENCY_IFACE_ONLY = 116; // 0x74 + field public static final int EMERGENCY_MODE = 2221; // 0x8ad field public static final int EMM_ACCESS_BARRED = 115; // 0x73 field public static final int EMM_ACCESS_BARRED_INFINITE_RETRY = 121; // 0x79 + field public static final int EMM_ATTACH_FAILED = 2115; // 0x843 + field public static final int EMM_ATTACH_STARTED = 2116; // 0x844 + field public static final int EMM_DETACHED = 2114; // 0x842 + field public static final int EMM_T3417_EXPIRED = 2130; // 0x852 + field public static final int EMM_T3417_EXT_EXPIRED = 2131; // 0x853 + field public static final int EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED = 2178; // 0x882 + field public static final int EPS_SERVICES_NOT_ALLOWED_IN_PLMN = 2179; // 0x883 field public static final int ERROR_UNSPECIFIED = 65535; // 0xffff + field public static final int ESM_BAD_OTA_MESSAGE = 2122; // 0x84a + field public static final int ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK = 2120; // 0x848 + field public static final int ESM_COLLISION_SCENARIOS = 2119; // 0x847 + field public static final int ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT = 2124; // 0x84c + field public static final int ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL = 2123; // 0x84b + field public static final int ESM_FAILURE = 2182; // 0x886 field public static final int ESM_INFO_NOT_RECEIVED = 53; // 0x35 + field public static final int ESM_LOCAL_CAUSE_NONE = 2126; // 0x84e + field public static final int ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER = 2121; // 0x849 + field public static final int ESM_PROCEDURE_TIME_OUT = 2155; // 0x86b + field public static final int ESM_UNKNOWN_EPS_BEARER_CONTEXT = 2111; // 0x83f + field public static final int EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE = 2201; // 0x899 + field public static final int EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY = 2200; // 0x898 + field public static final int EVDO_HDR_CHANGED = 2202; // 0x89a + field public static final int EVDO_HDR_CONNECTION_SETUP_TIMEOUT = 2206; // 0x89e + field public static final int EVDO_HDR_EXITED = 2203; // 0x89b + field public static final int EVDO_HDR_NO_SESSION = 2204; // 0x89c + field public static final int EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL = 2205; // 0x89d + field public static final int FADE = 2217; // 0x8a9 + field public static final int FAILED_TO_ACQUIRE_COLOCATED_HDR = 2207; // 0x89f field public static final int FEATURE_NOT_SUPP = 40; // 0x28 field public static final int FILTER_SEMANTIC_ERROR = 44; // 0x2c field public static final int FILTER_SYTAX_ERROR = 45; // 0x2d + field public static final int FORBIDDEN_APN_NAME = 2066; // 0x812 field public static final int GPRS_REGISTRATION_FAIL = -2; // 0xfffffffe + field public static final int GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED = 2097; // 0x831 + field public static final int GPRS_SERVICES_NOT_ALLOWED = 2098; // 0x832 + field public static final int GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN = 2103; // 0x837 + field public static final int HANDOFF_PREFERENCE_CHANGED = 2251; // 0x8cb + field public static final int HDR_ACCESS_FAILURE = 2213; // 0x8a5 + field public static final int HDR_FADE = 2212; // 0x8a4 + field public static final int HDR_NO_LOCK_GRANTED = 2210; // 0x8a2 field public static final int IFACE_AND_POL_FAMILY_MISMATCH = 120; // 0x78 field public static final int IFACE_MISMATCH = 117; // 0x75 + field public static final int ILLEGAL_ME = 2096; // 0x830 + field public static final int ILLEGAL_MS = 2095; // 0x82f + field public static final int IMEI_NOT_ACCEPTED = 2177; // 0x881 + field public static final int IMPLICITLY_DETACHED = 2100; // 0x834 + field public static final int IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER = 2176; // 0x880 + field public static final int INCOMING_CALL_REJECTED = 2092; // 0x82c field public static final int INSUFFICIENT_RESOURCES = 26; // 0x1a + field public static final int INTERFACE_IN_USE = 2058; // 0x80a field public static final int INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN = 114; // 0x72 + field public static final int INTERNAL_EPC_NONEPC_TRANSITION = 2057; // 0x809 + field public static final int INVALID_CONNECTION_ID = 2156; // 0x86c + field public static final int INVALID_DNS_ADDR = 123; // 0x7b + field public static final int INVALID_EMM_STATE = 2190; // 0x88e field public static final int INVALID_MANDATORY_INFO = 96; // 0x60 + field public static final int INVALID_MODE = 2223; // 0x8af field public static final int INVALID_PCSCF_ADDR = 113; // 0x71 + field public static final int INVALID_PCSCF_OR_DNS_ADDRESS = 124; // 0x7c + field public static final int INVALID_PRIMARY_NSAPI = 2158; // 0x86e + field public static final int INVALID_SIM_STATE = 2224; // 0x8b0 field public static final int INVALID_TRANSACTION_ID = 81; // 0x51 + field public static final int IPV6_ADDRESS_TRANSFER_FAILED = 2047; // 0x7ff + field public static final int IPV6_PREFIX_UNAVAILABLE = 2250; // 0x8ca field public static final int IP_ADDRESS_MISMATCH = 119; // 0x77 + field public static final int IP_VERSION_MISMATCH = 2055; // 0x807 + field public static final int IRAT_HANDOVER_FAILED = 2194; // 0x892 + field public static final int IS707B_MAX_ACCESS_PROBES = 2089; // 0x829 + field public static final int LIMITED_TO_IPV4 = 2234; // 0x8ba + field public static final int LIMITED_TO_IPV6 = 2235; // 0x8bb field public static final int LLC_SNDCP = 25; // 0x19 + field public static final int LOCAL_END = 2215; // 0x8a7 + field public static final int LOCATION_AREA_NOT_ALLOWED = 2102; // 0x836 field public static final int LOST_CONNECTION = 65540; // 0x10004 + field public static final int LOWER_LAYER_REGISTRATION_FAILURE = 2197; // 0x895 + field public static final int LOW_POWER_MODE_OR_POWERING_DOWN = 2044; // 0x7fc + field public static final int LTE_NAS_SERVICE_REQUEST_FAILED = 2117; // 0x845 + field public static final int LTE_THROTTLING_NOT_REQUIRED = 2127; // 0x84f + field public static final int MAC_FAILURE = 2183; // 0x887 + field public static final int MAXIMIUM_NSAPIS_EXCEEDED = 2157; // 0x86d + field public static final int MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED = 2166; // 0x876 + field public static final int MAX_ACCESS_PROBE = 2079; // 0x81f + field public static final int MAX_IPV4_CONNECTIONS = 2052; // 0x804 + field public static final int MAX_IPV6_CONNECTIONS = 2053; // 0x805 + field public static final int MAX_PPP_INACTIVITY_TIMER_EXPIRED = 2046; // 0x7fe field public static final int MESSAGE_INCORRECT_SEMANTIC = 95; // 0x5f field public static final int MESSAGE_TYPE_UNSUPPORTED = 97; // 0x61 + field public static final int MIP_CONFIG_FAILURE = 2050; // 0x802 + field public static final int MIP_FA_ADMIN_PROHIBITED = 2001; // 0x7d1 + field public static final int MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED = 2012; // 0x7dc + field public static final int MIP_FA_ENCAPSULATION_UNAVAILABLE = 2008; // 0x7d8 + field public static final int MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE = 2004; // 0x7d4 + field public static final int MIP_FA_INSUFFICIENT_RESOURCES = 2002; // 0x7d2 + field public static final int MIP_FA_MALFORMED_REPLY = 2007; // 0x7d7 + field public static final int MIP_FA_MALFORMED_REQUEST = 2006; // 0x7d6 + field public static final int MIP_FA_MISSING_CHALLENGE = 2017; // 0x7e1 + field public static final int MIP_FA_MISSING_HOME_ADDRESS = 2015; // 0x7df + field public static final int MIP_FA_MISSING_HOME_AGENT = 2014; // 0x7de + field public static final int MIP_FA_MISSING_NAI = 2013; // 0x7dd + field public static final int MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE = 2003; // 0x7d3 + field public static final int MIP_FA_REASON_UNSPECIFIED = 2000; // 0x7d0 + field public static final int MIP_FA_REQUESTED_LIFETIME_TOO_LONG = 2005; // 0x7d5 + field public static final int MIP_FA_REVERSE_TUNNEL_IS_MANDATORY = 2011; // 0x7db + field public static final int MIP_FA_REVERSE_TUNNEL_UNAVAILABLE = 2010; // 0x7da + field public static final int MIP_FA_STALE_CHALLENGE = 2018; // 0x7e2 + field public static final int MIP_FA_UNKNOWN_CHALLENGE = 2016; // 0x7e0 + field public static final int MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE = 2009; // 0x7d9 + field public static final int MIP_HA_ADMIN_PROHIBITED = 2020; // 0x7e4 + field public static final int MIP_HA_ENCAPSULATION_UNAVAILABLE = 2029; // 0x7ed + field public static final int MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE = 2023; // 0x7e7 + field public static final int MIP_HA_INSUFFICIENT_RESOURCES = 2021; // 0x7e5 + field public static final int MIP_HA_MALFORMED_REQUEST = 2025; // 0x7e9 + field public static final int MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE = 2022; // 0x7e6 + field public static final int MIP_HA_REASON_UNSPECIFIED = 2019; // 0x7e3 + field public static final int MIP_HA_REGISTRATION_ID_MISMATCH = 2024; // 0x7e8 + field public static final int MIP_HA_REVERSE_TUNNEL_IS_MANDATORY = 2028; // 0x7ec + field public static final int MIP_HA_REVERSE_TUNNEL_UNAVAILABLE = 2027; // 0x7eb + field public static final int MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS = 2026; // 0x7ea field public static final int MISSING_UNKNOWN_APN = 27; // 0x1b + field public static final int MODEM_APP_PREEMPTED = 2032; // 0x7f0 + field public static final int MODEM_RESTART = 2037; // 0x7f5 + field public static final int MSC_TEMPORARILY_NOT_REACHABLE = 2180; // 0x884 field public static final int MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE = 101; // 0x65 field public static final int MSG_TYPE_NONCOMPATIBLE_STATE = 98; // 0x62 + field public static final int MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK = 2099; // 0x833 + field public static final int MULTIPLE_PDP_CALL_NOT_ALLOWED = 2192; // 0x890 field public static final int MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED = 55; // 0x37 + field public static final int NAS_LAYER_FAILURE = 2191; // 0x88f + field public static final int NAS_REQUEST_REJECTED_BY_NETWORK = 2167; // 0x877 field public static final int NAS_SIGNALLING = 14; // 0xe field public static final int NETWORK_FAILURE = 38; // 0x26 + field public static final int NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH = 2154; // 0x86a + field public static final int NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH = 2153; // 0x869 + field public static final int NETWORK_INITIATED_TERMINATION = 2031; // 0x7ef field public static final int NONE = 0; // 0x0 + field public static final int NON_IP_NOT_SUPPORTED = 2069; // 0x815 + field public static final int NORMAL_RELEASE = 2218; // 0x8aa + field public static final int NO_CDMA_SERVICE = 2084; // 0x824 + field public static final int NO_COLLOCATED_HDR = 2225; // 0x8b1 + field public static final int NO_EPS_BEARER_CONTEXT_ACTIVATED = 2189; // 0x88d + field public static final int NO_GPRS_CONTEXT = 2094; // 0x82e + field public static final int NO_HYBRID_HDR_SERVICE = 2209; // 0x8a1 + field public static final int NO_PDP_CONTEXT_ACTIVATED = 2107; // 0x83b + field public static final int NO_RESPONSE_FROM_BASE_STATION = 2081; // 0x821 + field public static final int NO_SERVICE = 2216; // 0x8a8 + field public static final int NO_SERVICE_ON_GATEWAY = 2093; // 0x82d field public static final int NSAPI_IN_USE = 35; // 0x23 + field public static final int NULL_APN_DISALLOWED = 2061; // 0x80d field public static final int OEM_DCFAILCAUSE_1 = 4097; // 0x1001 field public static final int OEM_DCFAILCAUSE_10 = 4106; // 0x100a field public static final int OEM_DCFAILCAUSE_11 = 4107; // 0x100b @@ -5368,33 +5575,126 @@ package android.telephony { field public static final int OEM_DCFAILCAUSE_7 = 4103; // 0x1007 field public static final int OEM_DCFAILCAUSE_8 = 4104; // 0x1008 field public static final int OEM_DCFAILCAUSE_9 = 4105; // 0x1009 + field public static final int ONLY_IPV4V6_ALLOWED = 57; // 0x39 field public static final int ONLY_IPV4_ALLOWED = 50; // 0x32 field public static final int ONLY_IPV6_ALLOWED = 51; // 0x33 + field public static final int ONLY_NON_IP_ALLOWED = 58; // 0x3a field public static final int ONLY_SINGLE_BEARER_ALLOWED = 52; // 0x34 field public static final int OPERATOR_BARRED = 8; // 0x8 + field public static final int OTASP_COMMIT_IN_PROGRESS = 2208; // 0x8a0 field public static final int PDN_CONN_DOES_NOT_EXIST = 54; // 0x36 + field public static final int PDN_INACTIVITY_TIMER_EXPIRED = 2051; // 0x803 + field public static final int PDN_IPV4_CALL_DISALLOWED = 2033; // 0x7f1 + field public static final int PDN_IPV4_CALL_THROTTLED = 2034; // 0x7f2 + field public static final int PDN_IPV6_CALL_DISALLOWED = 2035; // 0x7f3 + field public static final int PDN_IPV6_CALL_THROTTLED = 2036; // 0x7f4 + field public static final int PDN_NON_IP_CALL_DISALLOWED = 2071; // 0x817 + field public static final int PDN_NON_IP_CALL_THROTTLED = 2070; // 0x816 + field public static final int PDP_ACTIVATE_MAX_RETRY_FAILED = 2109; // 0x83d + field public static final int PDP_DUPLICATE = 2104; // 0x838 + field public static final int PDP_ESTABLISH_TIMEOUT_EXPIRED = 2161; // 0x871 + field public static final int PDP_INACTIVE_TIMEOUT_EXPIRED = 2163; // 0x873 + field public static final int PDP_LOWERLAYER_ERROR = 2164; // 0x874 + field public static final int PDP_MODIFY_COLLISION = 2165; // 0x875 + field public static final int PDP_MODIFY_TIMEOUT_EXPIRED = 2162; // 0x872 + field public static final int PDP_PPP_NOT_SUPPORTED = 2038; // 0x7f6 field public static final int PDP_WITHOUT_ACTIVE_TFT = 46; // 0x2e + field public static final int PHONE_IN_USE = 2222; // 0x8ae + field public static final int PHYSICAL_LINK_CLOSE_IN_PROGRESS = 2040; // 0x7f8 + field public static final int PLMN_NOT_ALLOWED = 2101; // 0x835 + field public static final int PPP_AUTH_FAILURE = 2229; // 0x8b5 + field public static final int PPP_CHAP_FAILURE = 2232; // 0x8b8 + field public static final int PPP_CLOSE_IN_PROGRESS = 2233; // 0x8b9 + field public static final int PPP_OPTION_MISMATCH = 2230; // 0x8b6 + field public static final int PPP_PAP_FAILURE = 2231; // 0x8b7 + field public static final int PPP_TIMEOUT = 2228; // 0x8b4 field public static final int PREF_RADIO_TECH_CHANGED = -4; // 0xfffffffc + field public static final int PROFILE_BEARER_INCOMPATIBLE = 2042; // 0x7fa field public static final int PROTOCOL_ERRORS = 111; // 0x6f field public static final int QOS_NOT_ACCEPTED = 37; // 0x25 + field public static final int RADIO_ACCESS_BEARER_FAILURE = 2110; // 0x83e + field public static final int RADIO_ACCESS_BEARER_SETUP_FAILURE = 2160; // 0x870 field public static final int RADIO_NOT_AVAILABLE = 65537; // 0x10001 field public static final int RADIO_POWER_OFF = -5; // 0xfffffffb + field public static final int REDIRECTION_OR_HANDOFF_IN_PROGRESS = 2220; // 0x8ac field public static final int REGISTRATION_FAIL = -1; // 0xffffffff field public static final int REGULAR_DEACTIVATION = 36; // 0x24 + field public static final int REJECTED_BY_BASE_STATION = 2082; // 0x822 + field public static final int RRC_CONNECTION_ABORTED_AFTER_HANDOVER = 2173; // 0x87d + field public static final int RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE = 2174; // 0x87e + field public static final int RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE = 2171; // 0x87b + field public static final int RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE = 2175; // 0x87f + field public static final int RRC_CONNECTION_ABORT_REQUEST = 2151; // 0x867 + field public static final int RRC_CONNECTION_ACCESS_BARRED = 2139; // 0x85b + field public static final int RRC_CONNECTION_ACCESS_STRATUM_FAILURE = 2137; // 0x859 + field public static final int RRC_CONNECTION_ANOTHER_PROCEDURE_IN_PROGRESS = 2138; // 0x85a + field public static final int RRC_CONNECTION_CELL_NOT_CAMPED = 2144; // 0x860 + field public static final int RRC_CONNECTION_CELL_RESELECTION = 2140; // 0x85c + field public static final int RRC_CONNECTION_CONFIG_FAILURE = 2141; // 0x85d + field public static final int RRC_CONNECTION_INVALID_REQUEST = 2168; // 0x878 + field public static final int RRC_CONNECTION_LINK_FAILURE = 2143; // 0x85f + field public static final int RRC_CONNECTION_NORMAL_RELEASE = 2147; // 0x863 + field public static final int RRC_CONNECTION_OUT_OF_SERVICE_DURING_CELL_REGISTER = 2150; // 0x866 + field public static final int RRC_CONNECTION_RADIO_LINK_FAILURE = 2148; // 0x864 + field public static final int RRC_CONNECTION_REESTABLISHMENT_FAILURE = 2149; // 0x865 + field public static final int RRC_CONNECTION_REJECT_BY_NETWORK = 2146; // 0x862 + field public static final int RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE = 2172; // 0x87c + field public static final int RRC_CONNECTION_RF_UNAVAILABLE = 2170; // 0x87a + field public static final int RRC_CONNECTION_SYSTEM_INFORMATION_BLOCK_READ_ERROR = 2152; // 0x868 + field public static final int RRC_CONNECTION_SYSTEM_INTERVAL_FAILURE = 2145; // 0x861 + field public static final int RRC_CONNECTION_TIMER_EXPIRED = 2142; // 0x85e + field public static final int RRC_CONNECTION_TRACKING_AREA_ID_CHANGED = 2169; // 0x879 + field public static final int RRC_UPLINK_CONNECTION_RELEASE = 2134; // 0x856 + field public static final int RRC_UPLINK_DATA_TRANSMISSION_FAILURE = 2132; // 0x854 + field public static final int RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER = 2133; // 0x855 + field public static final int RRC_UPLINK_ERROR_REQUEST_FROM_NAS = 2136; // 0x858 + field public static final int RRC_UPLINK_RADIO_LINK_FAILURE = 2135; // 0x857 + field public static final int RUIM_NOT_PRESENT = 2085; // 0x825 + field public static final int SECURITY_MODE_REJECTED = 2186; // 0x88a + field public static final int SERVICE_NOT_ALLOWED_ON_PLMN = 2129; // 0x851 field public static final int SERVICE_OPTION_NOT_SUBSCRIBED = 33; // 0x21 field public static final int SERVICE_OPTION_NOT_SUPPORTED = 32; // 0x20 field public static final int SERVICE_OPTION_OUT_OF_ORDER = 34; // 0x22 field public static final int SIGNAL_LOST = -3; // 0xfffffffd + field public static final int SIM_CARD_CHANGED = 2043; // 0x7fb + field public static final int SYNCHRONIZATION_FAILURE = 2184; // 0x888 + field public static final int TEST_LOOPBACK_REGULAR_DEACTIVATION = 2196; // 0x894 field public static final int TETHERED_CALL_ACTIVE = -6; // 0xfffffffa field public static final int TFT_SEMANTIC_ERROR = 41; // 0x29 field public static final int TFT_SYTAX_ERROR = 42; // 0x2a + field public static final int THERMAL_EMERGENCY = 2090; // 0x82a + field public static final int THERMAL_MITIGATION = 2062; // 0x80e + field public static final int TRAT_SWAP_FAILED = 2048; // 0x800 + field public static final int UE_INITIATED_DETACH_OR_DISCONNECT = 128; // 0x80 + field public static final int UE_IS_ENTERING_POWERSAVE_MODE = 2226; // 0x8b2 + field public static final int UE_RAT_CHANGE = 2105; // 0x839 + field public static final int UE_SECURITY_CAPABILITIES_MISMATCH = 2185; // 0x889 + field public static final int UMTS_HANDOVER_TO_IWLAN = 2199; // 0x897 field public static final int UMTS_REACTIVATION_REQ = 39; // 0x27 + field public static final int UNACCEPTABLE_NON_EPS_AUTHENTICATION = 2187; // 0x88b field public static final int UNKNOWN = 65536; // 0x10000 field public static final int UNKNOWN_INFO_ELEMENT = 99; // 0x63 field public static final int UNKNOWN_PDP_ADDRESS_TYPE = 28; // 0x1c field public static final int UNKNOWN_PDP_CONTEXT = 43; // 0x2b + field public static final int UNPREFERRED_RAT = 2039; // 0x7f7 + field public static final int UNSUPPORTED_1X_PREV = 2214; // 0x8a6 field public static final int UNSUPPORTED_APN_IN_CURRENT_PLMN = 66; // 0x42 + field public static final int UNSUPPORTED_QCI_VALUE = 59; // 0x3b field public static final int USER_AUTHENTICATION = 29; // 0x1d + field public static final int VSNCP_ADMINISTRATIVELY_PROHIBITED = 2245; // 0x8c5 + field public static final int VSNCP_APN_UNATHORIZED = 2238; // 0x8be + field public static final int VSNCP_GEN_ERROR = 2237; // 0x8bd + field public static final int VSNCP_INSUFFICIENT_PARAMETERS = 2243; // 0x8c3 + field public static final int VSNCP_NO_PDN_GATEWAY_ADDRESS = 2240; // 0x8c0 + field public static final int VSNCP_PDN_EXISTS_FOR_THIS_APN = 2248; // 0x8c8 + field public static final int VSNCP_PDN_GATEWAY_REJECT = 2242; // 0x8c2 + field public static final int VSNCP_PDN_GATEWAY_UNREACHABLE = 2241; // 0x8c1 + field public static final int VSNCP_PDN_ID_IN_USE = 2246; // 0x8c6 + field public static final int VSNCP_PDN_LIMIT_EXCEEDED = 2239; // 0x8bf + field public static final int VSNCP_RECONNECT_NOT_ALLOWED = 2249; // 0x8c9 + field public static final int VSNCP_RESOURCE_UNAVAILABLE = 2244; // 0x8c4 + field public static final int VSNCP_SUBSCRIBER_LIMITATION = 2247; // 0x8c7 + field public static final int VSNCP_TIMEOUT = 2236; // 0x8bc } public class DisconnectCause { diff --git a/api/test-current.txt b/api/test-current.txt index 46f98e52fb70..d5ab31f9c74c 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -599,6 +599,8 @@ package android.media.audiofx { package android.net { public class CaptivePortal implements android.os.Parcelable { + ctor public CaptivePortal(android.os.IBinder); + method public void useNetwork(); field public static final int APP_RETURN_DISMISSED = 0; // 0x0 field public static final int APP_RETURN_UNWANTED = 1; // 0x1 field public static final int APP_RETURN_WANTED_AS_IS = 2; // 0x2 @@ -620,6 +622,25 @@ package android.net { method public boolean isSameAddressAs(android.net.LinkAddress); } + public final class LinkProperties implements android.os.Parcelable { + method public boolean addDnsServer(java.net.InetAddress); + method public String getTcpBufferSizes(); + method public java.util.List<java.net.InetAddress> getValidatedPrivateDnsServers(); + method public boolean hasGlobalIPv6Address(); + method public boolean hasIPv4Address(); + method public boolean hasIPv6DefaultRoute(); + method public boolean isIPv4Provisioned(); + method public boolean isIPv6Provisioned(); + method public boolean isProvisioned(); + method public boolean isReachable(java.net.InetAddress); + method public boolean removeDnsServer(java.net.InetAddress); + method public boolean removeRoute(android.net.RouteInfo); + method public void setPrivateDnsServerName(@Nullable String); + method public void setTcpBufferSizes(String); + method public void setUsePrivateDns(boolean); + method public void setValidatedPrivateDnsServers(java.util.Collection<java.net.InetAddress>); + } + public class Network implements android.os.Parcelable { method public android.net.Network getPrivateDnsBypassingCopy(); } @@ -627,6 +648,7 @@ package android.net { public final class NetworkCapabilities implements android.os.Parcelable { method public int[] getCapabilities(); method public int[] getTransportTypes(); + method public boolean satisfiedByNetworkCapabilities(android.net.NetworkCapabilities); } public final class RouteInfo implements android.os.Parcelable { @@ -718,6 +740,7 @@ package android.net.metrics { public class IpConnectivityLog { method public boolean log(long, android.net.metrics.IpConnectivityLog.Event); method public boolean log(String, android.net.metrics.IpConnectivityLog.Event); + method public boolean log(android.net.Network, int[], android.net.metrics.IpConnectivityLog.Event); method public boolean log(int, int[], android.net.metrics.IpConnectivityLog.Event); method public boolean log(android.net.metrics.IpConnectivityLog.Event); } diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt index 2bd813e14937..cfcb58d396cf 100644 --- a/config/hiddenapi-greylist.txt +++ b/config/hiddenapi-greylist.txt @@ -985,7 +985,6 @@ Landroid/os/PowerManager;->mService:Landroid/os/IPowerManager; Landroid/os/PowerManager;->setPowerSaveMode(Z)Z Landroid/os/PowerManager;->validateWakeLockParameters(ILjava/lang/String;)V Landroid/os/PowerManager;->wakeUp(JLjava/lang/String;)V -Landroid/os/Process;->BLUETOOTH_UID:I Landroid/os/Process;->DRM_UID:I Landroid/os/Process;->getFreeMemory()J Landroid/os/Process;->getParentPid(I)I @@ -1012,10 +1011,8 @@ Landroid/os/Process;->PROC_TERM_MASK:I Landroid/os/Process;->PROC_ZERO_TERM:I Landroid/os/Process;->readProcFile(Ljava/lang/String;[I[Ljava/lang/String;[J[F)Z Landroid/os/Process;->readProcLines(Ljava/lang/String;[Ljava/lang/String;[J)V -Landroid/os/Process;->ROOT_UID:I Landroid/os/Process;->setArgV0(Ljava/lang/String;)V Landroid/os/Process;->setProcessGroup(II)V -Landroid/os/Process;->SHELL_UID:I Landroid/os/Process;->VPN_UID:I Landroid/os/Process;->WIFI_UID:I Landroid/os/RecoverySystem;->verifyPackageCompatibility(Ljava/io/InputStream;)Z @@ -1057,8 +1054,6 @@ Landroid/os/ServiceManager;->sServiceManager:Landroid/os/IServiceManager; Landroid/os/ServiceManagerNative;->asInterface(Landroid/os/IBinder;)Landroid/os/IServiceManager; Landroid/os/ServiceManagerProxy;->getService(Ljava/lang/String;)Landroid/os/IBinder; Landroid/os/ServiceManagerProxy;->mRemote:Landroid/os/IBinder; -Landroid/os/ServiceSpecificException;-><init>(ILjava/lang/String;)V -Landroid/os/ServiceSpecificException;->errorCode:I Landroid/os/SharedMemory;->getFd()I Landroid/os/ShellCommand;->peekNextArg()Ljava/lang/String; Landroid/os/StatFs;->mStat:Landroid/system/StructStatVfs; diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index bc62b9e03602..2963947c03c6 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -2990,7 +2990,18 @@ public class Intent implements Parcelable, Cloneable { * * <p class="note">This is a protected intent that can only be sent * by the system. + * + * <p class="note">If the user has chosen a {@link android.telecom.CallRedirectionService} to + * handle redirection of outgoing calls, this intent will NOT be sent as an ordered broadcast. + * This means that attempts to re-write the outgoing call by other apps using this intent will + * be ignored. + * </p> + * + * @deprecated Apps that redirect outgoing calls should use the + * {@link android.telecom.CallRedirectionService} API. Apps that perform call screening + * should use the {@link android.telecom.CallScreeningService} API. */ + @Deprecated @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String ACTION_NEW_OUTGOING_CALL = "android.intent.action.NEW_OUTGOING_CALL"; diff --git a/core/java/android/net/CaptivePortal.java b/core/java/android/net/CaptivePortal.java index 4047068f1c7b..3b0126673779 100644 --- a/core/java/android/net/CaptivePortal.java +++ b/core/java/android/net/CaptivePortal.java @@ -45,6 +45,8 @@ public class CaptivePortal implements Parcelable { private final IBinder mBinder; /** @hide */ + @SystemApi + @TestApi public CaptivePortal(IBinder binder) { mBinder = binder; } @@ -107,6 +109,8 @@ public class CaptivePortal implements Parcelable { * connectivity for apps because the captive portal is still in place. * @hide */ + @SystemApi + @TestApi public void useNetwork() { try { ICaptivePortal.Stub.asInterface(mBinder).appResponse(APP_RETURN_WANTED_AS_IS); diff --git a/core/java/android/net/ICaptivePortal.aidl b/core/java/android/net/ICaptivePortal.aidl index a013e79106e7..56ae57dc0e8d 100644 --- a/core/java/android/net/ICaptivePortal.aidl +++ b/core/java/android/net/ICaptivePortal.aidl @@ -20,7 +20,6 @@ package android.net; * Interface to inform NetworkMonitor of decisions of app handling captive portal. * @hide */ -interface ICaptivePortal -{ - oneway void appResponse(int response); +oneway interface ICaptivePortal { + void appResponse(int response); } diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl index da5d96e49d02..3d34574440dd 100644 --- a/core/java/android/net/IConnectivityManager.aidl +++ b/core/java/android/net/IConnectivityManager.aidl @@ -187,4 +187,6 @@ interface IConnectivityManager byte[] getNetworkWatchlistConfigHash(); int getConnectionOwnerUid(in ConnectionInfo connectionInfo); + boolean isCallerCurrentAlwaysOnVpnApp(); + boolean isCallerCurrentAlwaysOnVpnLockdownApp(); } diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index c2963fd605c0..21b6a8eb1990 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -19,6 +19,7 @@ package android.net; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.os.Build; import android.os.Parcel; @@ -368,7 +369,8 @@ public final class LinkProperties implements Parcelable { * @return true if the DNS server was added, false if it was already present. * @hide */ - @UnsupportedAppUsage + @TestApi + @SystemApi public boolean addDnsServer(InetAddress dnsServer) { if (dnsServer != null && !mDnses.contains(dnsServer)) { mDnses.add(dnsServer); @@ -384,7 +386,8 @@ public final class LinkProperties implements Parcelable { * @return true if the DNS server was removed, false if it did not exist. * @hide */ - @UnsupportedAppUsage + @TestApi + @SystemApi public boolean removeDnsServer(InetAddress dnsServer) { if (dnsServer != null) { return mDnses.remove(dnsServer); @@ -423,6 +426,8 @@ public final class LinkProperties implements Parcelable { * @param usePrivateDns The private DNS state. * @hide */ + @TestApi + @SystemApi public void setUsePrivateDns(boolean usePrivateDns) { mUsePrivateDns = usePrivateDns; } @@ -448,6 +453,8 @@ public final class LinkProperties implements Parcelable { * @param privateDnsServerName The private DNS server name. * @hide */ + @TestApi + @SystemApi public void setPrivateDnsServerName(@Nullable String privateDnsServerName) { mPrivateDnsServerName = privateDnsServerName; } @@ -510,6 +517,8 @@ public final class LinkProperties implements Parcelable { * object. * @hide */ + @TestApi + @SystemApi public void setValidatedPrivateDnsServers(Collection<InetAddress> dnsServers) { mValidatedPrivateDnses.clear(); for (InetAddress dnsServer: dnsServers) { @@ -525,6 +534,8 @@ public final class LinkProperties implements Parcelable { * DNS servers on this link. * @hide */ + @TestApi + @SystemApi public List<InetAddress> getValidatedPrivateDnsServers() { return Collections.unmodifiableList(mValidatedPrivateDnses); } @@ -636,7 +647,8 @@ public final class LinkProperties implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @TestApi + @SystemApi public void setTcpBufferSizes(String tcpBufferSizes) { mTcpBufferSizes = tcpBufferSizes; } @@ -648,7 +660,8 @@ public final class LinkProperties implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @TestApi + @SystemApi public String getTcpBufferSizes() { return mTcpBufferSizes; } @@ -699,7 +712,8 @@ public final class LinkProperties implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @TestApi + @SystemApi public boolean removeRoute(RouteInfo route) { return route != null && Objects.equals(mIfaceName, route.getInterface()) && @@ -960,7 +974,8 @@ public final class LinkProperties implements Parcelable { * @return {@code true} if there is an IPv4 address, {@code false} otherwise. * @hide */ - @UnsupportedAppUsage + @TestApi + @SystemApi public boolean hasIPv4Address() { for (LinkAddress address : mLinkAddresses) { if (address.getAddress() instanceof Inet4Address) { @@ -988,7 +1003,8 @@ public final class LinkProperties implements Parcelable { * @return {@code true} if there is a global preferred IPv6 address, {@code false} otherwise. * @hide */ - @UnsupportedAppUsage + @TestApi + @SystemApi public boolean hasGlobalIPv6Address() { for (LinkAddress address : mLinkAddresses) { if (address.getAddress() instanceof Inet6Address && address.isGlobalPreferred()) { @@ -1020,7 +1036,8 @@ public final class LinkProperties implements Parcelable { * @return {@code true} if there is an IPv6 default route, {@code false} otherwise. * @hide */ - @UnsupportedAppUsage + @TestApi + @SystemApi public boolean hasIPv6DefaultRoute() { for (RouteInfo r : mRoutes) { if (r.isIPv6Default()) { @@ -1099,6 +1116,8 @@ public final class LinkProperties implements Parcelable { * @return {@code true} if the link is provisioned, {@code false} otherwise. * @hide */ + @TestApi + @SystemApi public boolean isIPv4Provisioned() { return (hasIPv4Address() && hasIPv4DefaultRoute() && @@ -1112,7 +1131,8 @@ public final class LinkProperties implements Parcelable { * @return {@code true} if the link is provisioned, {@code false} otherwise. * @hide */ - @UnsupportedAppUsage + @TestApi + @SystemApi public boolean isIPv6Provisioned() { return (hasGlobalIPv6Address() && hasIPv6DefaultRoute() && @@ -1126,7 +1146,8 @@ public final class LinkProperties implements Parcelable { * @return {@code true} if the link is provisioned, {@code false} otherwise. * @hide */ - @UnsupportedAppUsage + @TestApi + @SystemApi public boolean isProvisioned() { return (isIPv4Provisioned() || isIPv6Provisioned()); } @@ -1138,7 +1159,8 @@ public final class LinkProperties implements Parcelable { * {@code false} otherwise. * @hide */ - @UnsupportedAppUsage + @TestApi + @SystemApi public boolean isReachable(InetAddress ip) { final List<RouteInfo> allRoutes = getAllRoutes(); // If we don't have a route to this IP address, it's not reachable. diff --git a/core/java/android/net/LinkPropertiesParcelable.aidl b/core/java/android/net/LinkPropertiesParcelable.aidl index b153dc70e1b8..6b52239b4168 100644 --- a/core/java/android/net/LinkPropertiesParcelable.aidl +++ b/core/java/android/net/LinkPropertiesParcelable.aidl @@ -35,5 +35,4 @@ parcelable LinkPropertiesParcelable { int mtu; String tcpBufferSizes; IpPrefixParcelable nat64Prefix; - LinkPropertiesParcelable[] stackedLinks; }
\ No newline at end of file diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java index 1b44c920a205..7e9bda14b199 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -712,6 +712,7 @@ public final class NetworkCapabilities implements Parcelable { * @hide */ @TestApi + @SystemApi public @Transport int[] getTransportTypes() { return BitUtils.unpackBits(mTransportTypes); } @@ -1312,6 +1313,8 @@ public final class NetworkCapabilities implements Parcelable { * * @hide */ + @TestApi + @SystemApi public boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc) { return satisfiedByNetworkCapabilities(nc, false); } diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java index abc1cac02c7e..90dccb5b82d5 100644 --- a/core/java/android/net/SSLCertificateSocketFactory.java +++ b/core/java/android/net/SSLCertificateSocketFactory.java @@ -86,7 +86,16 @@ import javax.net.ssl.X509TrustManager; * <p>On development devices, "setprop socket.relaxsslcheck yes" bypasses all * SSL certificate and hostname checks for testing purposes. This setting * requires root access. + * + * @deprecated This class has less error-prone replacements using standard APIs. To create an + * {@code SSLSocket}, obtain an {@link SSLSocketFactory} from {@link SSLSocketFactory#getDefault()} + * or {@link javax.net.ssl.SSLContext#getSocketFactory()}. To verify hostnames, pass + * {@code "HTTPS"} to + * {@link javax.net.ssl.SSLParameters#setEndpointIdentificationAlgorithm(String)}. To enable ALPN, + * use {@link javax.net.ssl.SSLParameters#setApplicationProtocols(String[])}. To enable SNI, + * use {@link javax.net.ssl.SSLParameters#setServerNames(java.util.List)}. */ +@Deprecated public class SSLCertificateSocketFactory extends SSLSocketFactory { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) private static final String TAG = "SSLCertificateSocketFactory"; diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java index f0c0462cec18..37bf3a71ce62 100644 --- a/core/java/android/net/VpnService.java +++ b/core/java/android/net/VpnService.java @@ -368,6 +368,29 @@ public class VpnService extends Service { } /** + * Returns whether the service is running in always-on VPN mode. + */ + public final boolean isAlwaysOn() { + try { + return getService().isCallerCurrentAlwaysOnVpnApp(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** + * Returns whether the service is running in always-on VPN mode blocking connections without + * VPN. + */ + public final boolean isLockdownEnabled() { + try { + return getService().isCallerCurrentAlwaysOnVpnLockdownApp(); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Return the communication interface to the service. This method returns * {@code null} on {@link Intent}s other than {@link #SERVICE_INTERFACE} * action. Applications overriding this method must identify the intent diff --git a/core/java/android/net/metrics/IpConnectivityLog.java b/core/java/android/net/metrics/IpConnectivityLog.java index c04fcdcadb10..16aea31b97c9 100644 --- a/core/java/android/net/metrics/IpConnectivityLog.java +++ b/core/java/android/net/metrics/IpConnectivityLog.java @@ -21,6 +21,7 @@ import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.net.ConnectivityMetricsEvent; import android.net.IIpConnectivityMetrics; +import android.net.Network; import android.os.Parcelable; import android.os.RemoteException; import android.os.ServiceManager; @@ -128,6 +129,18 @@ public class IpConnectivityLog { /** * Log an IpConnectivity event. + * @param network the network associated with the event. + * @param transports the current transports of the network associated with the event, as defined + * in NetworkCapabilities. + * @param data is a Parcelable instance representing the event. + * @return true if the event was successfully logged. + */ + public boolean log(Network network, int[] transports, Event data) { + return log(network.netId, transports, data); + } + + /** + * Log an IpConnectivity event. * @param netid the id of the network associated with the event. * @param transports the current transports of the network associated with the event, as defined * in NetworkCapabilities. diff --git a/core/java/android/net/util/SocketUtils.java b/core/java/android/net/util/SocketUtils.java new file mode 100644 index 000000000000..de67cf5952f4 --- /dev/null +++ b/core/java/android/net/util/SocketUtils.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net.util; + +import static android.system.OsConstants.SOL_SOCKET; +import static android.system.OsConstants.SO_BINDTODEVICE; + +import android.annotation.SystemApi; +import android.net.NetworkUtils; +import android.system.ErrnoException; +import android.system.NetlinkSocketAddress; +import android.system.Os; +import android.system.PacketSocketAddress; + +import java.io.FileDescriptor; +import java.net.SocketAddress; + +/** + * Collection of utilities to interact with raw sockets. + * @hide + */ +@SystemApi +public class SocketUtils { + /** + * Create a raw datagram socket that is bound to an interface. + * + * <p>Data sent through the socket will go directly to the underlying network, ignoring VPNs. + */ + public static void bindSocketToInterface(FileDescriptor socket, String iface) + throws ErrnoException { + // SO_BINDTODEVICE actually takes a string. This works because the first member + // of struct ifreq is a NULL-terminated interface name. + // TODO: add a setsockoptString() + Os.setsockoptIfreq(socket, SOL_SOCKET, SO_BINDTODEVICE, iface); + NetworkUtils.protectFromVpn(socket); + } + + /** + * Make a socket address to communicate with netlink. + */ + public static SocketAddress makeNetlinkSocketAddress(int portId, int groupsMask) { + return new NetlinkSocketAddress(portId, groupsMask); + } + + /** + * Make a socket address to bind to packet sockets. + */ + public static SocketAddress makePacketSocketAddress(short protocol, int ifIndex) { + return new PacketSocketAddress(protocol, ifIndex); + } + + /** + * Make a socket address to send raw packets. + */ + public static SocketAddress makePacketSocketAddress(int ifIndex, byte[] hwAddr) { + return new PacketSocketAddress(ifIndex, hwAddr); + } + + private SocketUtils() {} +} diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index 0040825917e4..8254c534c7df 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -46,7 +46,6 @@ public class Process { /** * Defines the root UID. - * @hide */ public static final int ROOT_UID = 0; @@ -62,7 +61,6 @@ public class Process { /** * Defines the UID/GID for the user shell. - * @hide */ public static final int SHELL_UID = 2000; @@ -116,7 +114,6 @@ public class Process { /** * Defines the UID/GID for the Bluetooth service process. - * @hide */ public static final int BLUETOOTH_UID = 1002; diff --git a/core/java/android/os/ServiceSpecificException.java b/core/java/android/os/ServiceSpecificException.java index 3e0f6dae04d8..3b0f26ae8867 100644 --- a/core/java/android/os/ServiceSpecificException.java +++ b/core/java/android/os/ServiceSpecificException.java @@ -15,6 +15,8 @@ */ package android.os; +import android.annotation.SystemApi; + /** * An exception specific to a service. * @@ -28,6 +30,7 @@ package android.os; * * @hide */ +@SystemApi public class ServiceSpecificException extends RuntimeException { public final int errorCode; diff --git a/core/java/com/android/internal/util/Protocol.java b/core/java/com/android/internal/util/Protocol.java index 1aa32cce11e8..276cad9f6d6d 100644 --- a/core/java/com/android/internal/util/Protocol.java +++ b/core/java/com/android/internal/util/Protocol.java @@ -53,7 +53,6 @@ public class Protocol { public static final int BASE_WIFI_PASSPOINT_MANAGER = 0x00028000; public static final int BASE_WIFI_PASSPOINT_SERVICE = 0x00028100; public static final int BASE_WIFI_LOGGER = 0x00028300; - public static final int BASE_DHCP = 0x00030000; public static final int BASE_DATA_CONNECTION = 0x00040000; public static final int BASE_DATA_CONNECTION_AC = 0x00041000; public static final int BASE_DATA_CONNECTION_TRACKER = 0x00042000; @@ -62,7 +61,6 @@ public class Protocol { public static final int BASE_NETWORK_STATE_TRACKER = 0x00070000; public static final int BASE_CONNECTIVITY_MANAGER = 0x00080000; public static final int BASE_NETWORK_AGENT = 0x00081000; - public static final int BASE_NETWORK_MONITOR = 0x00082000; public static final int BASE_NETWORK_FACTORY = 0x00083000; public static final int BASE_ETHERNET = 0x00084000; public static final int BASE_LOWPAN = 0x00085000; diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp index 62aa1f38ca30..978254175da4 100644 --- a/core/jni/android_util_Process.cpp +++ b/core/jni/android_util_Process.cpp @@ -22,10 +22,10 @@ #include <utils/Log.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> -#include <cutils/sched_policy.h> #include <utils/String8.h> #include <utils/Vector.h> #include <processgroup/processgroup.h> +#include <processgroup/sched_policy.h> #include "core_jni_helpers.h" diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index d4fe1edf0e7a..691027dbf83d 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -53,13 +53,13 @@ #include <android-base/stringprintf.h> #include <cutils/fs.h> #include <cutils/multiuser.h> -#include <cutils/sched_policy.h> #include <private/android_filesystem_config.h> #include <utils/String8.h> #include <selinux/android.h> #include <seccomp_policy.h> #include <stats_event_list.h> #include <processgroup/processgroup.h> +#include <processgroup/sched_policy.h> #include "core_jni_helpers.h" #include <nativehelper/JNIHelp.h> diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java b/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java index 14e293694ebd..7b112dfc125c 100644 --- a/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java +++ b/packages/NetworkStack/src/android/net/dhcp/DhcpServer.java @@ -29,7 +29,6 @@ import static android.system.OsConstants.AF_INET; import static android.system.OsConstants.IPPROTO_UDP; import static android.system.OsConstants.SOCK_DGRAM; import static android.system.OsConstants.SOL_SOCKET; -import static android.system.OsConstants.SO_BINDTODEVICE; import static android.system.OsConstants.SO_BROADCAST; import static android.system.OsConstants.SO_REUSEADDR; @@ -45,6 +44,7 @@ import android.net.MacAddress; import android.net.NetworkUtils; import android.net.TrafficStats; import android.net.util.SharedLog; +import android.net.util.SocketUtils; import android.os.Handler; import android.os.HandlerThread; import android.os.Looper; @@ -629,14 +629,10 @@ public class DhcpServer extends IDhcpServer.Stub { final int oldTag = TrafficStats.getAndSetThreadStatsTag(TAG_SYSTEM_DHCP_SERVER); try { mSocket = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + SocketUtils.bindSocketToInterface(mSocket, mIfName); Os.setsockoptInt(mSocket, SOL_SOCKET, SO_REUSEADDR, 1); - // SO_BINDTODEVICE actually takes a string. This works because the first member - // of struct ifreq is a NULL-terminated interface name. - // TODO: add a setsockoptString() - Os.setsockoptIfreq(mSocket, SOL_SOCKET, SO_BINDTODEVICE, mIfName); Os.setsockoptInt(mSocket, SOL_SOCKET, SO_BROADCAST, 1); Os.bind(mSocket, Inet4Address.ANY, DHCP_SERVER); - NetworkUtils.protectFromVpn(mSocket); return mSocket; } catch (IOException | ErrnoException e) { diff --git a/packages/NetworkStack/src/android/net/dhcp/DhcpServingParams.java b/packages/NetworkStack/src/android/net/dhcp/DhcpServingParams.java index f38888aafbd6..868f3bed4eed 100644 --- a/packages/NetworkStack/src/android/net/dhcp/DhcpServingParams.java +++ b/packages/NetworkStack/src/android/net/dhcp/DhcpServingParams.java @@ -30,10 +30,10 @@ import android.annotation.Nullable; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.NetworkUtils; - -import com.google.android.collect.Sets; +import android.util.ArraySet; import java.net.Inet4Address; +import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.Set; @@ -208,7 +208,7 @@ public class DhcpServingParams { * but it must always be set explicitly before building the {@link DhcpServingParams}. */ public Builder setDefaultRouters(@NonNull Inet4Address... defaultRouters) { - return setDefaultRouters(Sets.newArraySet(defaultRouters)); + return setDefaultRouters(new ArraySet<>(Arrays.asList(defaultRouters))); } /** @@ -238,7 +238,7 @@ public class DhcpServingParams { * building the {@link DhcpServingParams}. */ public Builder setDnsServers(@NonNull Inet4Address... dnsServers) { - return setDnsServers(Sets.newArraySet(dnsServers)); + return setDnsServers(new ArraySet<>(Arrays.asList(dnsServers))); } /** @@ -268,7 +268,7 @@ public class DhcpServingParams { * and do not need to be set here. */ public Builder setExcludedAddrs(@NonNull Inet4Address... excludedAddrs) { - return setExcludedAddrs(Sets.newArraySet(excludedAddrs)); + return setExcludedAddrs(new ArraySet<>(Arrays.asList(excludedAddrs))); } /** diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java index c8a8e1f8e3db..a3d7852c9f4a 100644 --- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java +++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java @@ -24,6 +24,7 @@ import static android.net.ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL; import static android.net.ConnectivityManager.TYPE_MOBILE; import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_INVALID; +import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static android.net.metrics.ValidationProbeEvent.DNS_FAILURE; @@ -80,7 +81,6 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; -import com.android.internal.util.Protocol; import com.android.internal.util.RingBufferIndices; import com.android.internal.util.State; import com.android.internal.util.StateMachine; @@ -150,29 +150,28 @@ public class NetworkMonitor extends StateMachine { } } - private static final int BASE = Protocol.BASE_NETWORK_MONITOR; /** * ConnectivityService has sent a notification to indicate that network has connected. * Initiates Network Validation. */ - private static final int CMD_NETWORK_CONNECTED = BASE + 1; + private static final int CMD_NETWORK_CONNECTED = 1; /** * Message to self indicating it's time to evaluate a network's connectivity. * arg1 = Token to ignore old messages. */ - private static final int CMD_REEVALUATE = BASE + 6; + private static final int CMD_REEVALUATE = 6; /** * ConnectivityService has sent a notification to indicate that network has disconnected. */ - private static final int CMD_NETWORK_DISCONNECTED = BASE + 7; + private static final int CMD_NETWORK_DISCONNECTED = 7; /** * Force evaluation even if it has succeeded in the past. * arg1 = UID responsible for requesting this reeval. Will be billed for data. */ - private static final int CMD_FORCE_REEVALUATION = BASE + 8; + private static final int CMD_FORCE_REEVALUATION = 8; /** * Message to self indicating captive portal app finished. @@ -181,7 +180,7 @@ public class NetworkMonitor extends StateMachine { * APP_RETURN_WANTED_AS_IS * obj = mCaptivePortalLoggedInResponseToken as String */ - private static final int CMD_CAPTIVE_PORTAL_APP_FINISHED = BASE + 9; + private static final int CMD_CAPTIVE_PORTAL_APP_FINISHED = 9; /** * Message indicating sign-in app should be launched. @@ -190,14 +189,14 @@ public class NetworkMonitor extends StateMachine { * ConnectivityService when the user touches the "sign into * network" button in the wifi access point detail page. */ - private static final int CMD_LAUNCH_CAPTIVE_PORTAL_APP = BASE + 11; + private static final int CMD_LAUNCH_CAPTIVE_PORTAL_APP = 11; /** * Retest network to see if captive portal is still in place. * arg1 = UID responsible for requesting this reeval. Will be billed for data. * 0 indicates self-initiated, so nobody to blame. */ - private static final int CMD_CAPTIVE_PORTAL_RECHECK = BASE + 12; + private static final int CMD_CAPTIVE_PORTAL_RECHECK = 12; /** * ConnectivityService notifies NetworkMonitor of settings changes to @@ -210,20 +209,20 @@ public class NetworkMonitor extends StateMachine { * states, including being ignored until after an ongoing captive portal * validation phase is completed. */ - private static final int CMD_PRIVATE_DNS_SETTINGS_CHANGED = BASE + 13; - private static final int CMD_EVALUATE_PRIVATE_DNS = BASE + 15; + private static final int CMD_PRIVATE_DNS_SETTINGS_CHANGED = 13; + private static final int CMD_EVALUATE_PRIVATE_DNS = 15; /** * Message to self indicating captive portal detection is completed. * obj = CaptivePortalProbeResult for detection result; */ - public static final int CMD_PROBE_COMPLETE = BASE + 16; + public static final int CMD_PROBE_COMPLETE = 16; /** * ConnectivityService notifies NetworkMonitor of DNS query responses event. * arg1 = returncode in OnDnsEvent which indicates the response code for the DNS query. */ - public static final int EVENT_DNS_NOTIFICATION = BASE + 17; + public static final int EVENT_DNS_NOTIFICATION = 17; // Start mReevaluateDelayMs at this value and double. private static final int INITIAL_REEVALUATE_DELAY_MS = 1000; @@ -245,7 +244,6 @@ public class NetworkMonitor extends StateMachine { private final INetworkMonitorCallbacks mCallback; private final Network mNetwork; private final Network mNonPrivateDnsBypassNetwork; - private final int mNetId; private final TelephonyManager mTelephonyManager; private final WifiManager mWifiManager; private final ConnectivityManager mCm; @@ -322,7 +320,7 @@ public class NetworkMonitor extends StateMachine { NetworkRequest defaultRequest, IpConnectivityLog logger, SharedLog validationLogs, Dependencies deps) { // Add suffix indicating which NetworkMonitor we're talking about. - super(TAG + "/" + network.netId); + super(TAG + "/" + network.toString()); // Logs with a tag of the form given just above, e.g. // <timestamp> 862 2402 D NetworkMonitor/NetworkAgentInfo [WIFI () - 100]: ... @@ -335,7 +333,6 @@ public class NetworkMonitor extends StateMachine { mDependencies = deps; mNonPrivateDnsBypassNetwork = network; mNetwork = deps.getPrivateDnsBypassNetwork(network); - mNetId = mNetwork.netId; mTelephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); mCm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); @@ -471,7 +468,7 @@ public class NetworkMonitor extends StateMachine { @Override protected void log(String s) { - if (DBG) Log.d(TAG + "/" + mNetwork.netId, s); + if (DBG) Log.d(TAG + "/" + mNetwork.toString(), s); } private void validationLog(int probeType, Object url, String msg) { @@ -795,7 +792,7 @@ public class NetworkMonitor extends StateMachine { CustomIntentReceiver(String action, int token, int what) { mToken = token; mWhat = what; - mAction = action + "_" + mNetId + "_" + token; + mAction = action + "_" + mNetwork.getNetworkHandle() + "_" + token; mContext.registerReceiver(this, new IntentFilter(mAction)); } public PendingIntent getPendingIntent() { @@ -1088,11 +1085,6 @@ public class NetworkMonitor extends StateMachine { return mDependencies.getSetting(mContext, Settings.Global.CAPTIVE_PORTAL_USE_HTTPS, 1) == 1; } - private boolean getWifiScansAlwaysAvailableDisabled() { - return mDependencies.getSetting( - mContext, Settings.Global.WIFI_SCAN_ALWAYS_AVAILABLE, 0) == 0; - } - private String getCaptivePortalServerHttpsUrl() { return mDependencies.getSetting(mContext, Settings.Global.CAPTIVE_PORTAL_HTTPS_URL, DEFAULT_HTTPS_URL); @@ -1484,7 +1476,7 @@ public class NetworkMonitor extends StateMachine { */ private void sendNetworkConditionsBroadcast(boolean responseReceived, boolean isCaptivePortal, long requestTimestampMs, long responseTimestampMs) { - if (getWifiScansAlwaysAvailableDisabled()) { + if (!mWifiManager.isScanAlwaysAvailable()) { return; } @@ -1568,7 +1560,7 @@ public class NetworkMonitor extends StateMachine { private void logNetworkEvent(int evtype) { int[] transports = mNetworkCapabilities.getTransportTypes(); - mMetricsLog.log(mNetId, transports, new NetworkEvent(evtype)); + mMetricsLog.log(mNetwork, transports, new NetworkEvent(evtype)); } private int networkEventType(ValidationStage s, EvaluationResult r) { @@ -1590,7 +1582,8 @@ public class NetworkMonitor extends StateMachine { private void maybeLogEvaluationResult(int evtype) { if (mEvaluationTimer.isRunning()) { int[] transports = mNetworkCapabilities.getTransportTypes(); - mMetricsLog.log(mNetId, transports, new NetworkEvent(evtype, mEvaluationTimer.stop())); + mMetricsLog.log(mNetwork, transports, + new NetworkEvent(evtype, mEvaluationTimer.stop())); mEvaluationTimer.reset(); } } @@ -1603,7 +1596,7 @@ public class NetworkMonitor extends StateMachine { .setReturnCode(probeResult) .setDurationMs(durationMs) .build(); - mMetricsLog.log(mNetId, transports, ev); + mMetricsLog.log(mNetwork, transports, ev); } @VisibleForTesting @@ -1743,7 +1736,7 @@ public class NetworkMonitor extends StateMachine { boolean result = false; // Reevaluation will generate traffic. Thus, set a minimal reevaluation timer to limit the // possible traffic cost in metered network. - if (mNetworkCapabilities.isMetered() + if (!mNetworkCapabilities.hasCapability(NET_CAPABILITY_NOT_METERED) && (SystemClock.elapsedRealtime() - getLastProbeTime() < mDataStallMinEvaluateTime)) { return false; diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 00550d9c660e..919a5ab4eecd 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -6346,6 +6346,20 @@ public class ConnectivityService extends IConnectivityManager.Stub } } + @GuardedBy("mVpns") + private Vpn getVpnIfOwner() { + final int uid = Binder.getCallingUid(); + final int user = UserHandle.getUserId(uid); + + final Vpn vpn = mVpns.get(user); + if (vpn == null) { + return null; + } else { + final VpnInfo info = vpn.getVpnInfo(); + return (info == null || info.ownerUid != uid) ? null : vpn; + } + } + /** * Caller either needs to be an active VPN, or hold the NETWORK_STACK permission * for testing. @@ -6354,14 +6368,10 @@ public class ConnectivityService extends IConnectivityManager.Stub if (checkNetworkStackPermission()) { return null; } - final int uid = Binder.getCallingUid(); - final int user = UserHandle.getUserId(uid); synchronized (mVpns) { - Vpn vpn = mVpns.get(user); - try { - if (vpn.getVpnInfo().ownerUid == uid) return vpn; - } catch (NullPointerException e) { - /* vpn is null, or VPN is not connected and getVpnInfo() is null. */ + Vpn vpn = getVpnIfOwner(); + if (vpn != null) { + return vpn; } } throw new SecurityException("App must either be an active VPN or have the NETWORK_STACK " @@ -6390,4 +6400,20 @@ public class ConnectivityService extends IConnectivityManager.Stub return uid; } + + @Override + public boolean isCallerCurrentAlwaysOnVpnApp() { + synchronized (mVpns) { + Vpn vpn = getVpnIfOwner(); + return vpn != null && vpn.getAlwaysOn(); + } + } + + @Override + public boolean isCallerCurrentAlwaysOnVpnLockdownApp() { + synchronized (mVpns) { + Vpn vpn = getVpnIfOwner(); + return vpn != null && vpn.getLockdown(); + } + } } diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 602aedbc2d00..c72c9ddf3f7a 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -60,7 +60,6 @@ import android.net.NetworkMisc; import android.net.NetworkUtils; import android.net.RouteInfo; import android.net.UidRange; -import android.net.Uri; import android.net.VpnService; import android.os.Binder; import android.os.Build.VERSION_CODES; @@ -71,7 +70,6 @@ import android.os.INetworkManagementService; import android.os.Looper; import android.os.Parcel; import android.os.ParcelFileDescriptor; -import android.os.PatternMatcher; import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; @@ -100,6 +98,8 @@ import com.android.server.DeviceIdleController; import com.android.server.LocalServices; import com.android.server.net.BaseNetworkObserver; +import libcore.io.IoUtils; + import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -121,8 +121,6 @@ import java.util.SortedSet; import java.util.TreeSet; import java.util.concurrent.atomic.AtomicInteger; -import libcore.io.IoUtils; - /** * @hide */ @@ -346,11 +344,18 @@ public class Vpn { * * @return {@code true} if VPN lockdown is enabled. */ - public boolean getLockdown() { + public synchronized boolean getLockdown() { return mLockdown; } /** + * Returns whether VPN is configured as always-on. + */ + public synchronized boolean getAlwaysOn() { + return mAlwaysOn; + } + + /** * Checks if a VPN app supports always-on mode. * * In order to support the always-on feature, an app has to diff --git a/services/net/java/android/net/apf/ApfFilter.java b/services/net/java/android/net/apf/ApfFilter.java index 3351b25d0eec..494395285f5b 100644 --- a/services/net/java/android/net/apf/ApfFilter.java +++ b/services/net/java/android/net/apf/ApfFilter.java @@ -20,6 +20,7 @@ import static android.net.util.NetworkConstants.ICMPV6_ECHO_REQUEST_TYPE; import static android.net.util.NetworkConstants.ICMPV6_NEIGHBOR_ADVERTISEMENT; import static android.net.util.NetworkConstants.ICMPV6_ROUTER_ADVERTISEMENT; import static android.net.util.NetworkConstants.ICMPV6_ROUTER_SOLICITATION; +import static android.net.util.SocketUtils.makePacketSocketAddress; import static android.system.OsConstants.AF_PACKET; import static android.system.OsConstants.ARPHRD_ETHER; import static android.system.OsConstants.ETH_P_ARP; @@ -55,7 +56,6 @@ import android.os.PowerManager; import android.os.SystemClock; import android.system.ErrnoException; import android.system.Os; -import android.system.PacketSocketAddress; import android.text.format.DateUtils; import android.util.Log; import android.util.Pair; @@ -72,6 +72,7 @@ import java.io.IOException; import java.net.Inet4Address; import java.net.Inet6Address; import java.net.InetAddress; +import java.net.SocketAddress; import java.net.SocketException; import java.net.UnknownHostException; import java.nio.BufferUnderflowException; @@ -472,7 +473,7 @@ public class ApfFilter { installNewProgramLocked(); } socket = Os.socket(AF_PACKET, SOCK_RAW, ETH_P_IPV6); - PacketSocketAddress addr = new PacketSocketAddress( + SocketAddress addr = makePacketSocketAddress( (short) ETH_P_IPV6, mInterfaceParams.index); Os.bind(socket, addr); NetworkUtils.attachRaFilter(socket, mApfCapabilities.apfPacketFormat); diff --git a/services/net/java/android/net/dhcp/DhcpClient.java b/services/net/java/android/net/dhcp/DhcpClient.java index 15acc0ede8b2..04ac9a301813 100644 --- a/services/net/java/android/net/dhcp/DhcpClient.java +++ b/services/net/java/android/net/dhcp/DhcpClient.java @@ -28,6 +28,7 @@ import static android.net.dhcp.DhcpPacket.DHCP_SUBNET_MASK; import static android.net.dhcp.DhcpPacket.DHCP_VENDOR_INFO; import static android.net.dhcp.DhcpPacket.INADDR_ANY; import static android.net.dhcp.DhcpPacket.INADDR_BROADCAST; +import static android.net.util.SocketUtils.makePacketSocketAddress; import static android.system.OsConstants.AF_INET; import static android.system.OsConstants.AF_PACKET; import static android.system.OsConstants.ETH_P_IP; @@ -35,7 +36,6 @@ import static android.system.OsConstants.IPPROTO_UDP; import static android.system.OsConstants.SOCK_DGRAM; import static android.system.OsConstants.SOCK_RAW; import static android.system.OsConstants.SOL_SOCKET; -import static android.system.OsConstants.SO_BINDTODEVICE; import static android.system.OsConstants.SO_BROADCAST; import static android.system.OsConstants.SO_RCVBUF; import static android.system.OsConstants.SO_REUSEADDR; @@ -44,23 +44,22 @@ import android.content.Context; import android.net.DhcpResults; import android.net.NetworkUtils; import android.net.TrafficStats; +import android.net.ip.IpClient; import android.net.metrics.DhcpClientEvent; import android.net.metrics.DhcpErrorEvent; import android.net.metrics.IpConnectivityLog; import android.net.util.InterfaceParams; +import android.net.util.SocketUtils; import android.os.Message; import android.os.SystemClock; import android.system.ErrnoException; import android.system.Os; -import android.system.PacketSocketAddress; import android.util.EventLog; import android.util.Log; import android.util.SparseArray; -import android.util.TimeUtils; import com.android.internal.util.HexDump; import com.android.internal.util.MessageUtils; -import com.android.internal.util.Protocol; import com.android.internal.util.State; import com.android.internal.util.StateMachine; import com.android.internal.util.WakeupMessage; @@ -70,6 +69,7 @@ import libcore.io.IoBridge; import java.io.FileDescriptor; import java.io.IOException; import java.net.Inet4Address; +import java.net.SocketAddress; import java.net.SocketException; import java.nio.ByteBuffer; import java.util.Arrays; @@ -117,7 +117,8 @@ public class DhcpClient extends StateMachine { // t=0, t=2, t=6, t=14, t=30, allowing for 10% jitter. private static final int DHCP_TIMEOUT_MS = 36 * SECONDS; - private static final int PUBLIC_BASE = Protocol.BASE_DHCP; + // DhcpClient uses IpClient's handler. + private static final int PUBLIC_BASE = IpClient.DHCPCLIENT_CMD_BASE; /* Commands from controller to start/stop DHCP */ public static final int CMD_START_DHCP = PUBLIC_BASE + 1; @@ -147,7 +148,7 @@ public class DhcpClient extends StateMachine { public static final int DHCP_FAILURE = 2; // Internal messages. - private static final int PRIVATE_BASE = Protocol.BASE_DHCP + 100; + private static final int PRIVATE_BASE = IpClient.DHCPCLIENT_CMD_BASE + 100; private static final int CMD_KICK = PRIVATE_BASE + 1; private static final int CMD_RECEIVED_PACKET = PRIVATE_BASE + 2; private static final int CMD_TIMEOUT = PRIVATE_BASE + 3; @@ -204,7 +205,7 @@ public class DhcpClient extends StateMachine { private InterfaceParams mIface; // TODO: MacAddress-ify more of this class hierarchy. private byte[] mHwAddr; - private PacketSocketAddress mInterfaceBroadcastAddr; + private SocketAddress mInterfaceBroadcastAddr; private int mTransactionId; private long mTransactionStartMillis; private DhcpResults mDhcpLease; @@ -293,7 +294,7 @@ public class DhcpClient extends StateMachine { } mHwAddr = mIface.macAddr.toByteArray(); - mInterfaceBroadcastAddr = new PacketSocketAddress(mIface.index, DhcpPacket.ETHER_BROADCAST); + mInterfaceBroadcastAddr = makePacketSocketAddress(mIface.index, DhcpPacket.ETHER_BROADCAST); return true; } @@ -309,7 +310,7 @@ public class DhcpClient extends StateMachine { private boolean initPacketSocket() { try { mPacketSock = Os.socket(AF_PACKET, SOCK_RAW, ETH_P_IP); - PacketSocketAddress addr = new PacketSocketAddress((short) ETH_P_IP, mIface.index); + SocketAddress addr = makePacketSocketAddress((short) ETH_P_IP, mIface.index); Os.bind(mPacketSock, addr); NetworkUtils.attachDhcpFilter(mPacketSock); } catch(SocketException|ErrnoException e) { @@ -323,12 +324,11 @@ public class DhcpClient extends StateMachine { final int oldTag = TrafficStats.getAndSetThreadStatsTag(TrafficStats.TAG_SYSTEM_DHCP); try { mUdpSock = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + SocketUtils.bindSocketToInterface(mUdpSock, mIfaceName); Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_REUSEADDR, 1); - Os.setsockoptIfreq(mUdpSock, SOL_SOCKET, SO_BINDTODEVICE, mIfaceName); Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_BROADCAST, 1); Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_RCVBUF, 0); Os.bind(mUdpSock, Inet4Address.ANY, DhcpPacket.DHCP_CLIENT); - NetworkUtils.protectFromVpn(mUdpSock); } catch(SocketException|ErrnoException e) { Log.e(TAG, "Error creating UDP socket", e); return false; @@ -544,13 +544,13 @@ public class DhcpClient extends StateMachine { private String messageToString(Message message) { long now = SystemClock.uptimeMillis(); - StringBuilder b = new StringBuilder(" "); - TimeUtils.formatDuration(message.getWhen() - now, b); - b.append(" ").append(messageName(message.what)) + return new StringBuilder(" ") + .append(message.getWhen() - now) + .append(messageName(message.what)) .append(" ").append(message.arg1) .append(" ").append(message.arg2) - .append(" ").append(message.obj); - return b.toString(); + .append(" ").append(message.obj) + .toString(); } @Override diff --git a/services/net/java/android/net/ip/ConnectivityPacketTracker.java b/services/net/java/android/net/ip/ConnectivityPacketTracker.java index bef425a37da4..385dd52e4576 100644 --- a/services/net/java/android/net/ip/ConnectivityPacketTracker.java +++ b/services/net/java/android/net/ip/ConnectivityPacketTracker.java @@ -16,6 +16,7 @@ package android.net.ip; +import static android.net.util.SocketUtils.makePacketSocketAddress; import static android.system.OsConstants.AF_PACKET; import static android.system.OsConstants.ARPHRD_ETHER; import static android.system.OsConstants.ETH_P_ALL; @@ -28,7 +29,6 @@ import android.net.util.PacketReader; import android.os.Handler; import android.system.ErrnoException; import android.system.Os; -import android.system.PacketSocketAddress; import android.text.TextUtils; import android.util.LocalLog; import android.util.Log; @@ -103,7 +103,7 @@ public class ConnectivityPacketTracker { try { s = Os.socket(AF_PACKET, SOCK_RAW, 0); NetworkUtils.attachControlPacketFilter(s, ARPHRD_ETHER); - Os.bind(s, new PacketSocketAddress((short) ETH_P_ALL, mInterface.index)); + Os.bind(s, makePacketSocketAddress((short) ETH_P_ALL, mInterface.index)); } catch (ErrnoException | IOException e) { logError("Failed to create packet tracking socket: ", e); closeFd(s); diff --git a/services/net/java/android/net/ip/InterfaceController.java b/services/net/java/android/net/ip/InterfaceController.java index 55dfcef81890..b3af67cdbdc3 100644 --- a/services/net/java/android/net/ip/InterfaceController.java +++ b/services/net/java/android/net/ip/InterfaceController.java @@ -18,13 +18,14 @@ package android.net.ip; import android.net.INetd; import android.net.InterfaceConfiguration; +import android.net.InterfaceConfigurationParcel; import android.net.LinkAddress; import android.net.util.SharedLog; -import android.os.INetworkManagementService; import android.os.RemoteException; import android.os.ServiceSpecificException; import android.system.OsConstants; +import java.net.Inet4Address; import java.net.InetAddress; @@ -39,76 +40,96 @@ public class InterfaceController { private final static boolean DBG = false; private final String mIfName; - private final INetworkManagementService mNMS; private final INetd mNetd; private final SharedLog mLog; - public InterfaceController(String ifname, INetworkManagementService nms, INetd netd, - SharedLog log) { + public InterfaceController(String ifname, INetd netd, SharedLog log) { mIfName = ifname; - mNMS = nms; mNetd = netd; mLog = log; } - public boolean setIPv4Address(LinkAddress address) { - final InterfaceConfiguration ifcg = new InterfaceConfiguration(); - ifcg.setLinkAddress(address); + private boolean setInterfaceConfig(InterfaceConfiguration config) { + final InterfaceConfigurationParcel cfgParcel = config.toParcel(mIfName); + try { - mNMS.setInterfaceConfig(mIfName, ifcg); - if (DBG) mLog.log("IPv4 configuration succeeded"); - } catch (IllegalStateException | RemoteException e) { - logError("IPv4 configuration failed: %s", e); + mNetd.interfaceSetCfg(cfgParcel); + } catch (RemoteException | ServiceSpecificException e) { + logError("Setting IPv4 address to %s/%d failed: %s", + cfgParcel.ipv4Addr, cfgParcel.prefixLength, e); return false; } return true; } - public boolean clearIPv4Address() { - try { - final InterfaceConfiguration ifcg = new InterfaceConfiguration(); - ifcg.setLinkAddress(new LinkAddress("0.0.0.0/0")); - mNMS.setInterfaceConfig(mIfName, ifcg); - } catch (IllegalStateException | RemoteException e) { - logError("Failed to clear IPv4 address on interface %s: %s", mIfName, e); + /** + * Set the IPv4 address of the interface. + */ + public boolean setIPv4Address(LinkAddress address) { + if (!(address.getAddress() instanceof Inet4Address)) { return false; } - return true; + final InterfaceConfiguration ifConfig = new InterfaceConfiguration(); + ifConfig.setLinkAddress(address); + return setInterfaceConfig(ifConfig); } - public boolean enableIPv6() { + /** + * Clear the IPv4Address of the interface. + */ + public boolean clearIPv4Address() { + final InterfaceConfiguration ifConfig = new InterfaceConfiguration(); + ifConfig.setLinkAddress(new LinkAddress("0.0.0.0/0")); + return setInterfaceConfig(ifConfig); + } + + private boolean setEnableIPv6(boolean enabled) { try { - mNMS.enableIpv6(mIfName); - } catch (IllegalStateException | RemoteException e) { - logError("enabling IPv6 failed: %s", e); + mNetd.interfaceSetEnableIPv6(mIfName, enabled); + } catch (RemoteException | ServiceSpecificException e) { + logError("%s IPv6 failed: %s", (enabled ? "enabling" : "disabling"), e); return false; } return true; } + /** + * Enable IPv6 on the interface. + */ + public boolean enableIPv6() { + return setEnableIPv6(true); + } + + /** + * Disable IPv6 on the interface. + */ public boolean disableIPv6() { - try { - mNMS.disableIpv6(mIfName); - } catch (IllegalStateException | RemoteException e) { - logError("disabling IPv6 failed: %s", e); - return false; - } - return true; + return setEnableIPv6(false); } + /** + * Enable or disable IPv6 privacy extensions on the interface. + * @param enabled Whether the extensions should be enabled. + */ public boolean setIPv6PrivacyExtensions(boolean enabled) { try { - mNMS.setInterfaceIpv6PrivacyExtensions(mIfName, enabled); - } catch (IllegalStateException | RemoteException e) { - logError("error setting IPv6 privacy extensions: %s", e); + mNetd.interfaceSetIPv6PrivacyExtensions(mIfName, enabled); + } catch (RemoteException | ServiceSpecificException e) { + logError("error %s IPv6 privacy extensions: %s", + (enabled ? "enabling" : "disabling"), e); return false; } return true; } + /** + * Set IPv6 address generation mode on the interface. + * + * <p>IPv6 should be disabled before changing the mode. + */ public boolean setIPv6AddrGenModeIfSupported(int mode) { try { - mNMS.setIPv6AddrGenMode(mIfName, mode); + mNetd.setIPv6AddrGenMode(mIfName, mode); } catch (RemoteException e) { logError("Unable to set IPv6 addrgen mode: %s", e); return false; @@ -121,10 +142,16 @@ public class InterfaceController { return true; } + /** + * Add an address to the interface. + */ public boolean addAddress(LinkAddress addr) { return addAddress(addr.getAddress(), addr.getPrefixLength()); } + /** + * Add an address to the interface. + */ public boolean addAddress(InetAddress ip, int prefixLen) { try { mNetd.interfaceAddAddress(mIfName, ip.getHostAddress(), prefixLen); @@ -135,6 +162,9 @@ public class InterfaceController { return true; } + /** + * Remove an address from the interface. + */ public boolean removeAddress(InetAddress ip, int prefixLen) { try { mNetd.interfaceDelAddress(mIfName, ip.getHostAddress(), prefixLen); @@ -145,9 +175,12 @@ public class InterfaceController { return true; } + /** + * Remove all addresses from the interface. + */ public boolean clearAllAddresses() { try { - mNMS.clearInterfaceAddresses(mIfName); + mNetd.interfaceClearAddrs(mIfName); } catch (Exception e) { logError("Failed to clear addresses: %s", e); return false; diff --git a/services/net/java/android/net/ip/IpClient.java b/services/net/java/android/net/ip/IpClient.java index 9f1557354dc4..8187ac566a3f 100644 --- a/services/net/java/android/net/ip/IpClient.java +++ b/services/net/java/android/net/ip/IpClient.java @@ -24,7 +24,6 @@ import android.net.INetd; import android.net.IpPrefix; import android.net.LinkAddress; import android.net.LinkProperties; -import android.net.LinkProperties.ProvisioningChange; import android.net.Network; import android.net.ProvisioningConfigurationParcelable; import android.net.ProxyInfo; @@ -359,6 +358,9 @@ public class IpClient extends StateMachine { private static final int CMD_JUMP_RUNNING_TO_STOPPING = 101; private static final int CMD_JUMP_STOPPING_TO_STOPPED = 102; + // IpClient shares a handler with DhcpClient: commands must not overlap + public static final int DHCPCLIENT_CMD_BASE = 1000; + private static final int MAX_LOG_RECORDS = 500; private static final int MAX_PACKET_RECORDS = 100; @@ -371,6 +373,11 @@ public class IpClient extends StateMachine { private static final int IMMEDIATE_FAILURE_DURATION = 0; + private static final int PROV_CHANGE_STILL_NOT_PROVISIONED = 1; + private static final int PROV_CHANGE_LOST_PROVISIONING = 2; + private static final int PROV_CHANGE_GAINED_PROVISIONING = 3; + private static final int PROV_CHANGE_STILL_PROVISIONED = 4; + private final State mStoppedState = new StoppedState(); private final State mStoppingState = new StoppingState(); private final State mStartedState = new StartedState(); @@ -479,7 +486,7 @@ public class IpClient extends StateMachine { // TODO: Consider creating, constructing, and passing in some kind of // InterfaceController.Dependencies class. - mInterfaceCtrl = new InterfaceController(mInterfaceName, mNwService, deps.getNetd(), mLog); + mInterfaceCtrl = new InterfaceController(mInterfaceName, deps.getNetd(), mLog); mNetlinkTracker = new NetlinkTracker( mInterfaceName, @@ -911,18 +918,18 @@ public class IpClient extends StateMachine { // object that is a correct and complete assessment of what changed, taking // account of the asymmetries described in the comments in this function. // Then switch to using it everywhere (IpReachabilityMonitor, etc.). - private ProvisioningChange compareProvisioning(LinkProperties oldLp, LinkProperties newLp) { - ProvisioningChange delta; + private int compareProvisioning(LinkProperties oldLp, LinkProperties newLp) { + int delta; InitialConfiguration config = mConfiguration != null ? mConfiguration.mInitialConfig : null; final boolean wasProvisioned = isProvisioned(oldLp, config); final boolean isProvisioned = isProvisioned(newLp, config); if (!wasProvisioned && isProvisioned) { - delta = ProvisioningChange.GAINED_PROVISIONING; + delta = PROV_CHANGE_GAINED_PROVISIONING; } else if (wasProvisioned && isProvisioned) { - delta = ProvisioningChange.STILL_PROVISIONED; + delta = PROV_CHANGE_STILL_PROVISIONED; } else if (!wasProvisioned && !isProvisioned) { - delta = ProvisioningChange.STILL_NOT_PROVISIONED; + delta = PROV_CHANGE_STILL_NOT_PROVISIONED; } else { // (wasProvisioned && !isProvisioned) // @@ -934,7 +941,7 @@ public class IpClient extends StateMachine { // that to be a network without DNS servers and connect anyway. // // See the comment below. - delta = ProvisioningChange.LOST_PROVISIONING; + delta = PROV_CHANGE_LOST_PROVISIONING; } final boolean lostIPv6 = oldLp.isIPv6Provisioned() && !newLp.isIPv6Provisioned(); @@ -970,7 +977,7 @@ public class IpClient extends StateMachine { // delta will never be LOST_PROVISIONING. So check for loss of // provisioning here too. if (lostIPv4Address || (lostIPv6 && !ignoreIPv6ProvisioningLoss)) { - delta = ProvisioningChange.LOST_PROVISIONING; + delta = PROV_CHANGE_LOST_PROVISIONING; } // Additionally: @@ -979,15 +986,15 @@ public class IpClient extends StateMachine { // IPv6 default route then also consider the loss of that default route // to be a loss of provisioning. See b/27962810. if (oldLp.hasGlobalIPv6Address() && (lostIPv6Router && !ignoreIPv6ProvisioningLoss)) { - delta = ProvisioningChange.LOST_PROVISIONING; + delta = PROV_CHANGE_LOST_PROVISIONING; } return delta; } - private void dispatchCallback(ProvisioningChange delta, LinkProperties newLp) { + private void dispatchCallback(int delta, LinkProperties newLp) { switch (delta) { - case GAINED_PROVISIONING: + case PROV_CHANGE_GAINED_PROVISIONING: if (DBG) { Log.d(mTag, "onProvisioningSuccess()"); } @@ -995,7 +1002,7 @@ public class IpClient extends StateMachine { mCallback.onProvisioningSuccess(newLp); break; - case LOST_PROVISIONING: + case PROV_CHANGE_LOST_PROVISIONING: if (DBG) { Log.d(mTag, "onProvisioningFailure()"); } @@ -1015,7 +1022,7 @@ public class IpClient extends StateMachine { // Updates all IpClient-related state concerned with LinkProperties. // Returns a ProvisioningChange for possibly notifying other interested // parties that are not fronted by IpClient. - private ProvisioningChange setLinkProperties(LinkProperties newLp) { + private int setLinkProperties(LinkProperties newLp) { if (mApfFilter != null) { mApfFilter.setLinkProperties(newLp); } @@ -1023,10 +1030,10 @@ public class IpClient extends StateMachine { mIpReachabilityMonitor.updateLinkProperties(newLp); } - ProvisioningChange delta = compareProvisioning(mLinkProperties, newLp); + int delta = compareProvisioning(mLinkProperties, newLp); mLinkProperties = new LinkProperties(newLp); - if (delta == ProvisioningChange.GAINED_PROVISIONING) { + if (delta == PROV_CHANGE_GAINED_PROVISIONING) { // TODO: Add a proper ProvisionedState and cancel the alarm in // its enter() method. mProvisioningTimeoutAlarm.cancel(); @@ -1122,17 +1129,17 @@ public class IpClient extends StateMachine { if (Objects.equals(newLp, mLinkProperties)) { return true; } - final ProvisioningChange delta = setLinkProperties(newLp); + final int delta = setLinkProperties(newLp); if (sendCallbacks) { dispatchCallback(delta, newLp); } - return (delta != ProvisioningChange.LOST_PROVISIONING); + return (delta != PROV_CHANGE_LOST_PROVISIONING); } private void handleIPv4Success(DhcpResults dhcpResults) { mDhcpResults = new DhcpResults(dhcpResults); final LinkProperties newLp = assembleLinkProperties(); - final ProvisioningChange delta = setLinkProperties(newLp); + final int delta = setLinkProperties(newLp); if (DBG) { Log.d(mTag, "onNewDhcpResults(" + Objects.toString(dhcpResults) + ")"); @@ -1160,7 +1167,7 @@ public class IpClient extends StateMachine { private void handleProvisioningFailure() { final LinkProperties newLp = assembleLinkProperties(); - ProvisioningChange delta = setLinkProperties(newLp); + int delta = setLinkProperties(newLp); // If we've gotten here and we're still not provisioned treat that as // a total loss of provisioning. // @@ -1169,12 +1176,12 @@ public class IpClient extends StateMachine { // timeout expired. // // Regardless: GAME OVER. - if (delta == ProvisioningChange.STILL_NOT_PROVISIONED) { - delta = ProvisioningChange.LOST_PROVISIONING; + if (delta == PROV_CHANGE_STILL_NOT_PROVISIONED) { + delta = PROV_CHANGE_LOST_PROVISIONING; } dispatchCallback(delta, newLp); - if (delta == ProvisioningChange.LOST_PROVISIONING) { + if (delta == PROV_CHANGE_LOST_PROVISIONING) { transitionTo(mStoppingState); } } @@ -1646,7 +1653,7 @@ public class IpClient extends StateMachine { mDhcpClient.sendMessage(DhcpClient.EVENT_LINKADDRESS_CONFIGURED); } else { logError("Failed to set IPv4 address."); - dispatchCallback(ProvisioningChange.LOST_PROVISIONING, + dispatchCallback(PROV_CHANGE_LOST_PROVISIONING, new LinkProperties(mLinkProperties)); transitionTo(mStoppingState); } diff --git a/services/net/java/android/net/ip/IpNeighborMonitor.java b/services/net/java/android/net/ip/IpNeighborMonitor.java index 34bf4b63a883..eb993a4243a9 100644 --- a/services/net/java/android/net/ip/IpNeighborMonitor.java +++ b/services/net/java/android/net/ip/IpNeighborMonitor.java @@ -19,6 +19,7 @@ package android.net.ip; import static android.net.netlink.NetlinkConstants.RTM_DELNEIGH; import static android.net.netlink.NetlinkConstants.hexify; import static android.net.netlink.NetlinkConstants.stringForNlMsgType; +import static android.net.util.SocketUtils.makeNetlinkSocketAddress; import android.net.MacAddress; import android.net.netlink.NetlinkErrorMessage; @@ -31,7 +32,6 @@ import android.net.util.SharedLog; import android.os.Handler; import android.os.SystemClock; import android.system.ErrnoException; -import android.system.NetlinkSocketAddress; import android.system.Os; import android.system.OsConstants; import android.util.Log; @@ -148,15 +148,12 @@ public class IpNeighborMonitor extends PacketReader { try { fd = NetlinkSocket.forProto(OsConstants.NETLINK_ROUTE); - Os.bind(fd, (SocketAddress)(new NetlinkSocketAddress(0, OsConstants.RTMGRP_NEIGH))); - Os.connect(fd, (SocketAddress)(new NetlinkSocketAddress(0, 0))); + Os.bind(fd, makeNetlinkSocketAddress(0, OsConstants.RTMGRP_NEIGH)); + NetlinkSocket.connectToKernel(fd); if (VDBG) { - final NetlinkSocketAddress nlAddr = (NetlinkSocketAddress) Os.getsockname(fd); - Log.d(TAG, "bound to sockaddr_nl{" - + BitUtils.uint32(nlAddr.getPortId()) + ", " - + nlAddr.getGroupsMask() - + "}"); + final SocketAddress nlAddr = Os.getsockname(fd); + Log.d(TAG, "bound to sockaddr_nl{" + nlAddr.toString() + "}"); } } catch (ErrnoException|SocketException e) { logError("Failed to create rtnetlink socket", e); diff --git a/services/net/java/android/net/ip/IpReachabilityMonitor.java b/services/net/java/android/net/ip/IpReachabilityMonitor.java index 8b02156430f1..29e2f0c308d5 100644 --- a/services/net/java/android/net/ip/IpReachabilityMonitor.java +++ b/services/net/java/android/net/ip/IpReachabilityMonitor.java @@ -23,7 +23,6 @@ import static android.net.metrics.IpReachabilityEvent.PROVISIONING_LOST_ORGANIC; import android.content.Context; import android.net.LinkProperties; -import android.net.LinkProperties.ProvisioningChange; import android.net.RouteInfo; import android.net.ip.IpNeighborMonitor.NeighborEvent; import android.net.metrics.IpConnectivityLog; @@ -308,10 +307,11 @@ public class IpReachabilityMonitor { } } - final ProvisioningChange delta = LinkProperties.compareProvisioning( - mLinkProperties, whatIfLp); + final boolean lostProvisioning = + (mLinkProperties.isIPv4Provisioned() && !whatIfLp.isIPv4Provisioned()) + || (mLinkProperties.isIPv6Provisioned() && !whatIfLp.isIPv6Provisioned()); - if (delta == ProvisioningChange.LOST_PROVISIONING) { + if (lostProvisioning) { final String logMsg = "FAILURE: LOST_PROVISIONING, " + event; Log.w(TAG, logMsg); if (mCallback != null) { @@ -320,7 +320,7 @@ public class IpReachabilityMonitor { mCallback.notifyLost(ip, logMsg); } } - logNudFailed(delta); + logNudFailed(lostProvisioning); } private boolean avoidingBadLinks() { @@ -370,11 +370,10 @@ public class IpReachabilityMonitor { mMetricsLog.log(mInterfaceParams.name, new IpReachabilityEvent(eventType)); } - private void logNudFailed(ProvisioningChange delta) { + private void logNudFailed(boolean lostProvisioning) { long duration = SystemClock.elapsedRealtime() - mLastProbeTimeMs; boolean isFromProbe = (duration < getProbeWakeLockDuration()); - boolean isProvisioningLost = (delta == ProvisioningChange.LOST_PROVISIONING); - int eventType = nudFailureEventType(isFromProbe, isProvisioningLost); + int eventType = nudFailureEventType(isFromProbe, lostProvisioning); mMetricsLog.log(mInterfaceParams.name, new IpReachabilityEvent(eventType)); } diff --git a/services/net/java/android/net/ip/IpServer.java b/services/net/java/android/net/ip/IpServer.java index 8b22f68286af..7910c9a69310 100644 --- a/services/net/java/android/net/ip/IpServer.java +++ b/services/net/java/android/net/ip/IpServer.java @@ -226,7 +226,7 @@ public class IpServer extends StateMachine { mNetd = deps.getNetdService(); mStatsService = statsService; mCallback = callback; - mInterfaceCtrl = new InterfaceController(ifaceName, nMService, mNetd, mLog); + mInterfaceCtrl = new InterfaceController(ifaceName, mNetd, mLog); mIfaceName = ifaceName; mInterfaceType = interfaceType; mLinkProperties = new LinkProperties(); diff --git a/services/net/java/android/net/netlink/NetlinkSocket.java b/services/net/java/android/net/netlink/NetlinkSocket.java index 40098c1532b1..2a98d90e5577 100644 --- a/services/net/java/android/net/netlink/NetlinkSocket.java +++ b/services/net/java/android/net/netlink/NetlinkSocket.java @@ -16,26 +16,26 @@ package android.net.netlink; +import static android.net.util.SocketUtils.makeNetlinkSocketAddress; import static android.system.OsConstants.AF_NETLINK; import static android.system.OsConstants.EIO; import static android.system.OsConstants.EPROTO; import static android.system.OsConstants.ETIMEDOUT; +import static android.system.OsConstants.SOCK_DGRAM; +import static android.system.OsConstants.SOL_SOCKET; import static android.system.OsConstants.SO_RCVBUF; import static android.system.OsConstants.SO_RCVTIMEO; import static android.system.OsConstants.SO_SNDTIMEO; -import static android.system.OsConstants.SOCK_DGRAM; -import static android.system.OsConstants.SOL_SOCKET; import android.system.ErrnoException; -import android.system.NetlinkSocketAddress; import android.system.Os; import android.system.StructTimeval; import android.util.Log; + import libcore.io.IoUtils; import java.io.FileDescriptor; import java.io.InterruptedIOException; -import java.net.SocketAddress; import java.net.SocketException; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -106,7 +106,7 @@ public class NetlinkSocket { } public static void connectToKernel(FileDescriptor fd) throws ErrnoException, SocketException { - Os.connect(fd, (SocketAddress) (new NetlinkSocketAddress(0, 0))); + Os.connect(fd, makeNetlinkSocketAddress(0, 0)); } private static void checkTimeout(long timeoutMs) { diff --git a/services/net/java/android/net/shared/LinkPropertiesParcelableUtil.java b/services/net/java/android/net/shared/LinkPropertiesParcelableUtil.java index d5213dfcebf8..51d955d5c2ad 100644 --- a/services/net/java/android/net/shared/LinkPropertiesParcelableUtil.java +++ b/services/net/java/android/net/shared/LinkPropertiesParcelableUtil.java @@ -182,9 +182,6 @@ public final class LinkPropertiesParcelableUtil { parcel.mtu = lp.getMtu(); parcel.tcpBufferSizes = lp.getTcpBufferSizes(); parcel.nat64Prefix = toStableParcelable(lp.getNat64Prefix()); - parcel.stackedLinks = toParcelableArray( - lp.getStackedLinks(), LinkPropertiesParcelableUtil::toStableParcelable, - LinkPropertiesParcelable.class); return parcel; } @@ -216,9 +213,6 @@ public final class LinkPropertiesParcelableUtil { lp.setMtu(parcel.mtu); lp.setTcpBufferSizes(parcel.tcpBufferSizes); lp.setNat64Prefix(fromStableParcelable(parcel.nat64Prefix)); - for (LinkPropertiesParcelable stackedLink : parcel.stackedLinks) { - lp.addStackedLink(fromStableParcelable(stackedLink)); - } return lp; } } diff --git a/telecomm/java/android/telecom/Conference.java b/telecomm/java/android/telecom/Conference.java index a39e885204b7..7d1f8ce75919 100644 --- a/telecomm/java/android/telecom/Conference.java +++ b/telecomm/java/android/telecom/Conference.java @@ -19,6 +19,7 @@ package android.telecom; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SystemApi; +import android.net.Uri; import android.os.Bundle; import android.os.SystemClock; import android.telecom.Connection.VideoProvider; @@ -64,6 +65,10 @@ public abstract class Conference extends Conferenceable { public void onStatusHintsChanged(Conference conference, StatusHints statusHints) {} public void onExtrasChanged(Conference c, Bundle extras) {} public void onExtrasRemoved(Conference c, List<String> keys) {} + public void onConferenceStateChanged(Conference c, boolean isConference) {} + public void onAddressChanged(Conference c, Uri newAddress, int presentation) {} + public void onCallerDisplayNameChanged( + Conference c, String callerDisplayName, int presentation) {} } private final Set<Listener> mListeners = new CopyOnWriteArraySet<>(); @@ -946,6 +951,62 @@ public abstract class Conference extends Conferenceable { public void onExtrasChanged(Bundle extras) {} /** + * Set whether Telecom should treat this {@link Conference} as a conference call or if it + * should treat it as a single-party call. + * This method is used as part of a workaround regarding IMS conference calls and user + * expectation. In IMS, once a conference is formed, the UE is connected to an IMS conference + * server. If all participants of the conference drop out of the conference except for one, the + * UE is still connected to the IMS conference server. At this point, the user logically + * assumes they're no longer in a conference, yet the underlying network actually is. + * To help provide a better user experiece, IMS conference calls can pretend to actually be a + * single-party call when the participant count drops to 1. Although the dialer/phone app + * could perform this trickery, it makes sense to do this in Telephony since a fix there will + * ensure that bluetooth head units, auto and wearable apps all behave consistently. + * + * @param isConference {@code true} if this {@link Conference} should be treated like a + * conference call, {@code false} if it should be treated like a single-party call. + * @hide + */ + public void setConferenceState(boolean isConference) { + for (Listener l : mListeners) { + l.onConferenceStateChanged(this, isConference); + } + } + + /** + * Sets the address of this {@link Conference}. Used when {@link #setConferenceState(boolean)} + * is called to mark a conference temporarily as NOT a conference. + * + * @param address The new address. + * @param presentation The presentation requirements for the address. + * See {@link TelecomManager} for valid values. + * @hide + */ + public final void setAddress(Uri address, int presentation) { + Log.d(this, "setAddress %s", address); + for (Listener l : mListeners) { + l.onAddressChanged(this, address, presentation); + } + } + + /** + * Sets the caller display name (CNAP) of this {@link Conference}. Used when + * {@link #setConferenceState(boolean)} is called to mark a conference temporarily as NOT a + * conference. + * + * @param callerDisplayName The new display name. + * @param presentation The presentation requirements for the handle. + * See {@link TelecomManager} for valid values. + * @hide + */ + public final void setCallerDisplayName(String callerDisplayName, int presentation) { + Log.d(this, "setCallerDisplayName %s", callerDisplayName); + for (Listener l : mListeners) { + l.onCallerDisplayNameChanged(this, callerDisplayName, presentation); + } + } + + /** * Handles a change to extras received from Telecom. * * @param extras The new extras. diff --git a/telecomm/java/android/telecom/ConnectionService.java b/telecomm/java/android/telecom/ConnectionService.java index 4c2d22fdc0de..82db0d2ecb96 100644 --- a/telecomm/java/android/telecom/ConnectionService.java +++ b/telecomm/java/android/telecom/ConnectionService.java @@ -1254,6 +1254,31 @@ public abstract class ConnectionService extends Service { mAdapter.removeExtras(id, keys); } } + + @Override + public void onConferenceStateChanged(Conference c, boolean isConference) { + String id = mIdByConference.get(c); + if (id != null) { + mAdapter.setConferenceState(id, isConference); + } + } + + @Override + public void onAddressChanged(Conference c, Uri newAddress, int presentation) { + String id = mIdByConference.get(c); + if (id != null) { + mAdapter.setAddress(id, newAddress, presentation); + } + } + + @Override + public void onCallerDisplayNameChanged(Conference c, String callerDisplayName, + int presentation) { + String id = mIdByConference.get(c); + if (id != null) { + mAdapter.setCallerDisplayName(id, callerDisplayName, presentation); + } + } }; private final Connection.Listener mConnectionListener = new Connection.Listener() { diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapter.java b/telecomm/java/android/telecom/ConnectionServiceAdapter.java index 520e7eda6f69..6c3f4f34ff2d 100644 --- a/telecomm/java/android/telecom/ConnectionServiceAdapter.java +++ b/telecomm/java/android/telecom/ConnectionServiceAdapter.java @@ -653,4 +653,22 @@ final class ConnectionServiceAdapter implements DeathRecipient { } } } + + /** + * Sets whether a conference is treated as a conference or a single party call. + * See {@link Conference#setConferenceState(boolean)} for more information. + * + * @param callId The ID of the telecom call. + * @param isConference {@code true} if this call should be treated as a conference, + * {@code false} otherwise. + */ + void setConferenceState(String callId, boolean isConference) { + Log.v(this, "setConferenceState: %s %b", callId, isConference); + for (IConnectionServiceAdapter adapter : mAdapters) { + try { + adapter.setConferenceState(callId, isConference, Log.getExternalSession()); + } catch (RemoteException ignored) { + } + } + } } diff --git a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java index 78d65e643abc..f99b218bd9b9 100644 --- a/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java +++ b/telecomm/java/android/telecom/ConnectionServiceAdapterServant.java @@ -74,6 +74,7 @@ final class ConnectionServiceAdapterServant { private static final int MSG_ON_RTT_UPGRADE_REQUEST = 33; private static final int MSG_SET_PHONE_ACCOUNT_CHANGED = 34; private static final int MSG_CONNECTION_SERVICE_FOCUS_RELEASED = 35; + private static final int MSG_SET_CONFERENCE_STATE = 36; private final IConnectionServiceAdapter mDelegate; @@ -333,6 +334,14 @@ final class ConnectionServiceAdapterServant { case MSG_CONNECTION_SERVICE_FOCUS_RELEASED: mDelegate.onConnectionServiceFocusReleased(null /*Session.Info*/); break; + case MSG_SET_CONFERENCE_STATE: + SomeArgs args = (SomeArgs) msg.obj; + try { + mDelegate.setConferenceState((String) args.arg1, (Boolean) args.arg2, + (Session.Info) args.arg3); + } finally { + args.recycle(); + } } } }; @@ -615,6 +624,16 @@ final class ConnectionServiceAdapterServant { public void resetConnectionTime(String callId, Session.Info sessionInfo) { // Do nothing } + + @Override + public void setConferenceState(String callId, boolean isConference, + Session.Info sessionInfo) { + SomeArgs args = SomeArgs.obtain(); + args.arg1 = callId; + args.arg2 = isConference; + args.arg3 = sessionInfo; + mHandler.obtainMessage(MSG_SET_CONFERENCE_STATE, args).sendToTarget(); + } }; public ConnectionServiceAdapterServant(IConnectionServiceAdapter delegate) { diff --git a/telecomm/java/android/telecom/RemoteConnectionService.java b/telecomm/java/android/telecom/RemoteConnectionService.java index 9821dcbce85e..744544eb01f1 100644 --- a/telecomm/java/android/telecom/RemoteConnectionService.java +++ b/telecomm/java/android/telecom/RemoteConnectionService.java @@ -471,6 +471,12 @@ final class RemoteConnectionService { public void resetConnectionTime(String callId, Session.Info sessionInfo) { // Do nothing } + + @Override + public void setConferenceState(String callId, boolean isConference, + Session.Info sessionInfo) { + // Do nothing + } }; private final ConnectionServiceAdapterServant mServant = diff --git a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl index 0157a5863363..76ac88e9fbaa 100644 --- a/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl +++ b/telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl @@ -123,4 +123,6 @@ oneway interface IConnectionServiceAdapter { void onConnectionServiceFocusReleased(in Session.Info sessionInfo); void resetConnectionTime(String callIdi, in Session.Info sessionInfo); + + void setConferenceState(String callId, boolean isConference, in Session.Info sessionInfo); } diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java index 26ec6ded8224..85c53f243037 100644 --- a/telephony/java/android/telephony/DataFailCause.java +++ b/telephony/java/android/telephony/DataFailCause.java @@ -42,7 +42,7 @@ public final class DataFailCause { // This series of errors as specified by the standards // specified in ril.h - /** Operator determined barring. */ + /** Operator determined barring. (no retry) */ public static final int OPERATOR_BARRED = 0x08; /** NAS signalling. */ public static final int NAS_SIGNALLING = 0x0E; @@ -91,6 +91,11 @@ public final class DataFailCause { public static final int FILTER_SYTAX_ERROR = 0x2D; /** Packet Data Protocol (PDP) without active traffic flow template (TFT). */ public static final int PDP_WITHOUT_ACTIVE_TFT = 0x2E; + /** + * UE requested to modify QoS parameters or the bearer control mode, which is not compatible + * with the selected bearer control mode. + */ + public static final int ACTIVATION_REJECTED_BCM_VIOLATION = 0x30; /** Packet Data Protocol (PDP) type IPv4 only allowed. */ public static final int ONLY_IPV4_ALLOWED = 0x32; /* no retry */ /** Packet Data Protocol (PDP) type IPv6 only allowed. */ @@ -103,6 +108,27 @@ public final class DataFailCause { public static final int PDN_CONN_DOES_NOT_EXIST = 0x36; /** Multiple connections to a same PDN is not allowed. */ public static final int MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED = 0x37; + /** + * Network has already initiated the activation, modification, or deactivation of bearer + * resources that was requested by the UE. + */ + public static final int COLLISION_WITH_NETWORK_INITIATED_REQUEST = 0x38; + /** + * Network supports IPv4v6 PDP type only. Non-IP type is not allowed. In LTE mode of operation, + * this is a PDN throttling cause code, meaning the UE may throttle further requests to the + * same APN. + */ + public static final int ONLY_IPV4V6_ALLOWED = 0x39; + /** + * Network supports non-IP PDP type only. IPv4, IPv6 and IPv4v6 is not allowed. In LTE mode of + * operation, this is a PDN throttling cause code, meaning the UE can throttle further requests + * to the same APN. + */ + public static final int ONLY_NON_IP_ALLOWED = 0x3A; + /** QCI (QoS Class Identifier) indicated in the UE request cannot be supported. */ + public static final int UNSUPPORTED_QCI_VALUE = 0x3B; + /** Procedure requested by the UE was rejected because the bearer handling is not supported. */ + public static final int BEARER_HANDLING_NOT_SUPPORTED = 0x3C; /** Max number of Packet Data Protocol (PDP) context reached. */ public static final int ACTIVE_PDP_CONTEXT_MAX_NUMBER_REACHED = 0x41; /** Unsupported APN in current public land mobile network (PLMN). */ @@ -146,6 +172,742 @@ public final class DataFailCause { public static final int EMM_ACCESS_BARRED_INFINITE_RETRY = 0x79; /** Authentication failure on emergency call. */ public static final int AUTH_FAILURE_ON_EMERGENCY_CALL = 0x7A; + /** Not receiving a DNS address that was mandatory. */ + public static final int INVALID_DNS_ADDR = 0x7B; + /** Not receiving either a PCSCF or a DNS address, one of them being mandatory. */ + public static final int INVALID_PCSCF_OR_DNS_ADDRESS = 0x7C; + /** Emergency call bring up on a different ePDG. */ + public static final int CALL_PREEMPT_BY_EMERGENCY_APN = 0x7F; + /** UE performs a detach or disconnect PDN action based on TE requirements. */ + public static final int UE_INITIATED_DETACH_OR_DISCONNECT = 0x80; + + /** Reason unspecified for foreign agent rejected MIP (Mobile IP) registration. */ + public static final int MIP_FA_REASON_UNSPECIFIED = 0x7D0; + /** Foreign agent administratively prohibited MIP (Mobile IP) registration. */ + public static final int MIP_FA_ADMIN_PROHIBITED = 0x7D1; + /** Foreign agent rejected MIP (Mobile IP) registration because of insufficient resources. */ + public static final int MIP_FA_INSUFFICIENT_RESOURCES = 0x7D2; + /** + * Foreign agent rejected MIP (Mobile IP) registration because of MN-AAA authenticator was + * wrong. + */ + public static final int MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE = 0x7D3; + /** + * Foreign agent rejected MIP (Mobile IP) registration because of home agent authentication + * failure. + */ + public static final int MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE = 0x7D4; + /** + * Foreign agent rejected MIP (Mobile IP) registration because of requested lifetime was too + * long. + */ + public static final int MIP_FA_REQUESTED_LIFETIME_TOO_LONG = 0x7D5; + /** Foreign agent rejected MIP (Mobile IP) registration because of malformed request. */ + public static final int MIP_FA_MALFORMED_REQUEST = 0x7D6; + /** Foreign agent rejected MIP (Mobile IP) registration because of malformed reply. */ + public static final int MIP_FA_MALFORMED_REPLY = 0x7D7; + /** + * Foreign agent rejected MIP (Mobile IP) registration because of requested encapsulation was + * unavailable. + */ + public static final int MIP_FA_ENCAPSULATION_UNAVAILABLE = 0x7D8; + /** + * Foreign agent rejected MIP (Mobile IP) registration of VJ Header Compression was + * unavailable. + */ + public static final int MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE = 0x7D9; + /** + * Foreign agent rejected MIP (Mobile IP) registration because of reverse tunnel was + * unavailable. + */ + public static final int MIP_FA_REVERSE_TUNNEL_UNAVAILABLE = 0x7DA; + /** + * Foreign agent rejected MIP (Mobile IP) registration because of reverse tunnel was mandatory + * but not requested by device. + */ + public static final int MIP_FA_REVERSE_TUNNEL_IS_MANDATORY = 0x7DB; + /** + * Foreign agent rejected MIP (Mobile IP) registration because of delivery style was not + * supported. + */ + public static final int MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED = 0x7DC; + /** + * Foreign agent rejected MIP (Mobile IP) registration because of missing NAI (Network Access + * Identifier). + */ + public static final int MIP_FA_MISSING_NAI = 0x7DD; + /** Foreign agent rejected MIP (Mobile IP) registration because of missing Home Agent. */ + public static final int MIP_FA_MISSING_HOME_AGENT = 0x7DE; + /** Foreign agent rejected MIP (Mobile IP) registration because of missing Home Address. */ + public static final int MIP_FA_MISSING_HOME_ADDRESS = 0x7DF; + /** Foreign agent rejected MIP (Mobile IP) registration because of unknown challenge. */ + public static final int MIP_FA_UNKNOWN_CHALLENGE = 0x7E0; + /** Foreign agent rejected MIP (Mobile IP) registration because of missing challenge. */ + public static final int MIP_FA_MISSING_CHALLENGE = 0x7E1; + /** Foreign agent rejected MIP (Mobile IP) registration because of stale challenge. */ + public static final int MIP_FA_STALE_CHALLENGE = 0x7E2; + /** Reason unspecified for home agent rejected MIP (Mobile IP) registration. */ + public static final int MIP_HA_REASON_UNSPECIFIED = 0x7E3; + /** Home agent administratively prohibited MIP (Mobile IP) registration. */ + public static final int MIP_HA_ADMIN_PROHIBITED = 0x7E4; + /** Home agent rejected MIP (Mobile IP) registration because of insufficient resources. */ + public static final int MIP_HA_INSUFFICIENT_RESOURCES = 0x7E5; + /** + * Home agent rejected MIP (Mobile IP) registration because of MN-HA authenticator was + * wrong. + */ + public static final int MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE = 0x7E6; + /** + * Home agent rejected MIP (Mobile IP) registration because of foreign agent authentication + * failure. + */ + public static final int MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE = 0x7E7; + /** Home agent rejected MIP (Mobile IP) registration because of registration id mismatch. */ + public static final int MIP_HA_REGISTRATION_ID_MISMATCH = 0x7E8; + /** Home agent rejected MIP (Mobile IP) registration because of malformed request. */ + public static final int MIP_HA_MALFORMED_REQUEST = 0x7E9; + /** Home agent rejected MIP (Mobile IP) registration because of unknown home agent address. */ + public static final int MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS = 0x7EA; + /** + * Home agent rejected MIP (Mobile IP) registration because of reverse tunnel was + * unavailable. + */ + public static final int MIP_HA_REVERSE_TUNNEL_UNAVAILABLE = 0x7EB; + /** + * Home agent rejected MIP (Mobile IP) registration because of reverse tunnel is mandatory but + * not requested by device. + */ + public static final int MIP_HA_REVERSE_TUNNEL_IS_MANDATORY = 0x7EC; + /** Home agent rejected MIP (Mobile IP) registration because of encapsulation unavailable. */ + public static final int MIP_HA_ENCAPSULATION_UNAVAILABLE = 0x7ED; + /** Tearing down is in progress. */ + public static final int CLOSE_IN_PROGRESS = 0x7EE; + /** Brought down by the network. */ + public static final int NETWORK_INITIATED_TERMINATION = 0x7EF; + /** Another application in modem preempts the data call. */ + public static final int MODEM_APP_PREEMPTED = 0x7F0; + /** + * IPV4 PDN is in throttled state due to network providing only IPV6 address during the + * previous VSNCP bringup (subs_limited_to_v6). + */ + public static final int PDN_IPV4_CALL_DISALLOWED = 0x7F1; + /** IPV4 PDN is in throttled state due to previous VSNCP bringup failure(s). */ + public static final int PDN_IPV4_CALL_THROTTLED = 0x7F2; + /** + * IPV6 PDN is in throttled state due to network providing only IPV4 address during the + * previous VSNCP bringup (subs_limited_to_v4). + */ + public static final int PDN_IPV6_CALL_DISALLOWED = 0x7F3; + /** IPV6 PDN is in throttled state due to previous VSNCP bringup failure(s). */ + public static final int PDN_IPV6_CALL_THROTTLED = 0x7F4; + /** Modem restart. */ + public static final int MODEM_RESTART = 0x7F5; + /** PDP PPP calls are not supported. */ + public static final int PDP_PPP_NOT_SUPPORTED = 0x7F6; + /** RAT on which the data call is attempted/connected is no longer the preferred RAT. */ + public static final int UNPREFERRED_RAT = 0x7F7; + /** Physical link is in the process of cleanup. */ + public static final int PHYSICAL_LINK_CLOSE_IN_PROGRESS = 0x7F8; + /** Interface bring up is attempted for an APN that is yet to be handed over to target RAT. */ + public static final int APN_PENDING_HANDOVER = 0x7F9; + /** APN bearer type in the profile does not match preferred network mode. */ + public static final int PROFILE_BEARER_INCOMPATIBLE = 0x7FA; + /** Card was refreshed or removed. */ + public static final int SIM_CARD_CHANGED = 0x7FB; + /** Device is going into lower power mode or powering down. */ + public static final int LOW_POWER_MODE_OR_POWERING_DOWN = 0x7FC; + /** APN has been disabled. */ + public static final int APN_DISABLED = 0x7FD; + /** Maximum PPP inactivity timer expired. */ + public static final int MAX_PPP_INACTIVITY_TIMER_EXPIRED = 0x7FE; + /** IPv6 address transfer failed. */ + public static final int IPV6_ADDRESS_TRANSFER_FAILED = 0x7FF; + /** Target RAT swap failed. */ + public static final int TRAT_SWAP_FAILED = 0x800; + /** Device falls back from eHRPD to HRPD. */ + public static final int EHRPD_TO_HRPD_FALLBACK = 0x801; + /** + * UE is in MIP-only configuration but the MIP configuration fails on call bring up due to + * incorrect provisioning. + */ + public static final int MIP_CONFIG_FAILURE = 0x802; + /** + * PDN inactivity timer expired due to no data transmission in a configurable duration of time. + */ + public static final int PDN_INACTIVITY_TIMER_EXPIRED = 0x803; + /** + * IPv4 data call bring up is rejected because the UE already maintains the allotted maximum + * number of IPv4 data connections. + */ + public static final int MAX_IPV4_CONNECTIONS = 0x804; + /** + * IPv6 data call bring up is rejected because the UE already maintains the allotted maximum + * number of IPv6 data connections. + */ + public static final int MAX_IPV6_CONNECTIONS = 0x805; + /** + * New PDN bring up is rejected during interface selection because the UE has already allotted + * the available interfaces for other PDNs. + */ + public static final int APN_MISMATCH = 0x806; + /** + * New call bring up is rejected since the existing data call IP type doesn't match the + * requested IP. + */ + public static final int IP_VERSION_MISMATCH = 0x807; + /** Dial up networking (DUN) call bring up is rejected since UE is in eHRPD RAT. */ + public static final int DUN_CALL_DISALLOWED = 0x808; + /*** Rejected/Brought down since UE is transition between EPC and NONEPC RAT. */ + public static final int INTERNAL_EPC_NONEPC_TRANSITION = 0x809; + /** The current interface is being in use. */ + public static final int INTERFACE_IN_USE = 0x80A; + /** PDN connection to the APN is disallowed on the roaming network. */ + public static final int APN_DISALLOWED_ON_ROAMING = 0x80B; + /** APN-related parameters are changed. */ + public static final int APN_PARAMETERS_CHANGED = 0x80C; + /** PDN is attempted to be brought up with NULL APN but NULL APN is not supported. */ + public static final int NULL_APN_DISALLOWED = 0x80D; + /** + * Thermal level increases and causes calls to be torn down when normal mode of operation is + * not allowed. + */ + public static final int THERMAL_MITIGATION = 0x80E; + /** + * PDN Connection to a given APN is disallowed because data is disabled from the device user + * interface settings. + */ + public static final int DATA_SETTINGS_DISABLED = 0x80F; + /** + * PDN Connection to a given APN is disallowed because data roaming is disabled from the device + * user interface settings and the UE is roaming. + */ + public static final int DATA_ROAMING_SETTINGS_DISABLED = 0x810; + /** DDS (Default data subscription) switch occurs. */ + public static final int DDS_SWITCHED = 0x811; + /** PDN being brought up with an APN that is part of forbidden APN Name list. */ + public static final int FORBIDDEN_APN_NAME = 0x812; + /** Default data subscription switch is in progress. */ + public static final int DDS_SWITCH_IN_PROGRESS = 0x813; + /** Roaming is disallowed during call bring up. */ + public static final int CALL_DISALLOWED_IN_ROAMING = 0x814; + /** + * UE is unable to bring up a non-IP data call because the device is not camped on a NB1 cell. + */ + public static final int NON_IP_NOT_SUPPORTED = 0x815; + /** Non-IP PDN is in throttled state due to previous VSNCP bringup failure(s). */ + public static final int PDN_NON_IP_CALL_THROTTLED = 0x816; + /** Non-IP PDN is in disallowed state due to the network providing only an IP address. */ + public static final int PDN_NON_IP_CALL_DISALLOWED = 0x817; + /** Device in CDMA locked state. */ + public static final int CDMA_LOCK = 0x818; + /** Received an intercept order from the base station. */ + public static final int CDMA_INTERCEPT = 0x819; + /** Receiving a reorder from the base station. */ + public static final int CDMA_REORDER = 0x81A; + /** Receiving a release from the base station with a SO (Service Option) Reject reason. */ + public static final int CDMA_RELEASE_DUE_TO_SO_REJECTION = 0x81B; + /** Receiving an incoming call from the base station. */ + public static final int CDMA_INCOMING_CALL = 0x81C; + /** Received an alert stop from the base station due to incoming only. */ + public static final int CDMA_ALERT_STOP = 0x81D; + /** + * Channel acquisition failures. This indicates that device has failed acquiring all the + * channels in the PRL. + */ + public static final int CHANNEL_ACQUISITION_FAILURE = 0x81E; + /** Maximum access probes transmitted. */ + public static final int MAX_ACCESS_PROBE = 0x81F; + /** Concurrent service is not supported by base station. */ + public static final int CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STATION = 0x820; + /** There was no response received from the base station. */ + public static final int NO_RESPONSE_FROM_BASE_STATION = 0x821; + /** The base station rejecting the call. */ + public static final int REJECTED_BY_BASE_STATION = 0x822; + /** The concurrent services requested were not compatible. */ + public static final int CONCURRENT_SERVICES_INCOMPATIBLE = 0x823; + /** Device does not have CDMA service. */ + public static final int NO_CDMA_SERVICE = 0x824; + /** RUIM not being present. */ + public static final int RUIM_NOT_PRESENT = 0x825; + /** Receiving a retry order from the base station. */ + public static final int CDMA_RETRY_ORDER = 0x826; + /** Access blocked by the base station. */ + public static final int ACCESS_BLOCK = 0x827; + /** Access blocked by the base station for all mobile devices. */ + public static final int ACCESS_BLOCK_ALL = 0x828; + /** Maximum access probes for the IS-707B call. */ + public static final int IS707B_MAX_ACCESS_PROBES = 0x829; + /** Put device in thermal emergency. */ + public static final int THERMAL_EMERGENCY = 0x82A; + /** In favor of a voice call or SMS when concurrent voice and data are not supported. */ + public static final int CONCURRENT_SERVICES_NOT_ALLOWED = 0x82B; + /** The other clients rejected incoming call. */ + public static final int INCOMING_CALL_REJECTED = 0x82C; + /** No service on the gateway. */ + public static final int NO_SERVICE_ON_GATEWAY = 0x82D; + /** GPRS context is not available. */ + public static final int NO_GPRS_CONTEXT = 0x82E; + /** + * Network refuses service to the MS because either an identity of the MS is not acceptable to + * the network or the MS does not pass the authentication check. + */ + public static final int ILLEGAL_MS = 0x82F; + /** ME could not be authenticated and the ME used is not acceptable to the network. */ + public static final int ILLEGAL_ME = 0x830; + /** Not allowed to operate either GPRS or non-GPRS services. */ + public static final int GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED = 0x831; + /** MS is not allowed to operate GPRS services. */ + public static final int GPRS_SERVICES_NOT_ALLOWED = 0x832; + /** No matching identity or context could be found in the network. */ + public static final int MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK = 0x833; + /** + * Mobile reachable timer has expired, or the GMM context data related to the subscription does + * not exist in the SGSN. + */ + public static final int IMPLICITLY_DETACHED = 0x834; + /** + * UE requests GPRS service, or the network initiates a detach request in a PLMN which does not + * offer roaming for GPRS services to that MS. + */ + public static final int PLMN_NOT_ALLOWED = 0x835; + /** + * MS requests service, or the network initiates a detach request, in a location area where the + * HPLMN determines that the MS, by subscription, is not allowed to operate. + */ + public static final int LOCATION_AREA_NOT_ALLOWED = 0x836; + /** + * UE requests GPRS service or the network initiates a detach request in a PLMN that does not + * offer roaming for GPRS services. + */ + public static final int GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN = 0x837; + /** PDP context already exists. */ + public static final int PDP_DUPLICATE = 0x838; + /** RAT change on the UE. */ + public static final int UE_RAT_CHANGE = 0x839; + /** Network cannot serve a request from the MS due to congestion. */ + public static final int CONGESTION = 0x83A; + /** + * MS requests an establishment of the radio access bearers for all active PDP contexts by + * sending a service request message indicating data to the network, but the SGSN does not have + * any active PDP context. + */ + public static final int NO_PDP_CONTEXT_ACTIVATED = 0x83B; + /** Access class blocking restrictions for the current camped cell. */ + public static final int ACCESS_CLASS_DSAC_REJECTION = 0x83C; + /** SM attempts PDP activation for a maximum of four attempts. */ + public static final int PDP_ACTIVATE_MAX_RETRY_FAILED = 0x83D; + /** Radio access bearer failure. */ + public static final int RADIO_ACCESS_BEARER_FAILURE = 0x83E; + /** Invalid EPS bearer identity in the request. */ + public static final int ESM_UNKNOWN_EPS_BEARER_CONTEXT = 0x83F; + /** Data radio bearer is released by the RRC. */ + public static final int DRB_RELEASED_BY_RRC = 0x840; + /** Indicate the connection was released. */ + public static final int CONNECTION_RELEASED = 0x841; + /** UE is detached. */ + public static final int EMM_DETACHED = 0x842; + /** Attach procedure is rejected by the network. */ + public static final int EMM_ATTACH_FAILED = 0x843; + /** Attach procedure is started for EMC purposes. */ + public static final int EMM_ATTACH_STARTED = 0x844; + /** Service request procedure failure. */ + public static final int LTE_NAS_SERVICE_REQUEST_FAILED = 0x845; + /** Active dedicated bearer was requested using the same default bearer ID. */ + public static final int DUPLICATE_BEARER_ID = 0x846; + /** Collision scenarios for the UE and network-initiated procedures. */ + public static final int ESM_COLLISION_SCENARIOS = 0x847; + /** Bearer must be deactivated to synchronize with the network. */ + public static final int ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK = 0x848; + /** Active dedicated bearer was requested for an existing default bearer. */ + public static final int ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER = 0x849; + /** Bad OTA message is received from the network. */ + public static final int ESM_BAD_OTA_MESSAGE = 0x84A; + /** Download server rejected the call. */ + public static final int ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL = 0x84B; + /** PDN was disconnected by the downlaod server due to IRAT. */ + public static final int ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT = 0x84C; + /** Dedicated bearer will be deactivated regardless of the network response. */ + public static final int DS_EXPLICIT_DEACTIVATION = 0x84D; + /** No specific local cause is mentioned, usually a valid OTA cause. */ + public static final int ESM_LOCAL_CAUSE_NONE = 0x84E; + /** Throttling is not needed for this service request failure. */ + public static final int LTE_THROTTLING_NOT_REQUIRED = 0x84F; + /** Access control list check failure at the lower layer. */ + public static final int ACCESS_CONTROL_LIST_CHECK_FAILURE = 0x850; + /** Service is not allowed on the requested PLMN. */ + public static final int SERVICE_NOT_ALLOWED_ON_PLMN = 0x851; + /** T3417 timer expiration of the service request procedure. */ + public static final int EMM_T3417_EXPIRED = 0x852; + /** Extended service request fails due to expiration of the T3417 EXT timer. */ + public static final int EMM_T3417_EXT_EXPIRED = 0x853; + /** Transmission failure of radio resource control (RRC) uplink data. */ + public static final int RRC_UPLINK_DATA_TRANSMISSION_FAILURE = 0x854; + /** Radio resource control (RRC) uplink data delivery failed due to a handover. */ + public static final int RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER = 0x855; + /** Radio resource control (RRC) uplink data delivery failed due to a connection release. */ + public static final int RRC_UPLINK_CONNECTION_RELEASE = 0x856; + /** Radio resource control (RRC) uplink data delivery failed due to a radio link failure. */ + public static final int RRC_UPLINK_RADIO_LINK_FAILURE = 0x857; + /** + * Radio resource control (RRC) is not connected but the non-access stratum (NAS) sends an + * uplink data request. + */ + public static final int RRC_UPLINK_ERROR_REQUEST_FROM_NAS = 0x858; + /** Radio resource control (RRC) connection failure at access stratum. */ + public static final int RRC_CONNECTION_ACCESS_STRATUM_FAILURE = 0x859; + /** + * Radio resource control (RRC) connection establishment is aborted due to another procedure. + */ + public static final int RRC_CONNECTION_ANOTHER_PROCEDURE_IN_PROGRESS = 0x85A; + /** Radio resource control (RRC) connection establishment failed due to access barrred. */ + public static final int RRC_CONNECTION_ACCESS_BARRED = 0x85B; + /** + * Radio resource control (RRC) connection establishment failed due to cell reselection at + * access stratum. + */ + public static final int RRC_CONNECTION_CELL_RESELECTION = 0x85C; + /** + * Connection establishment failed due to configuration failure at the radio resource control + * (RRC). + */ + public static final int RRC_CONNECTION_CONFIG_FAILURE = 0x85D; + /** Radio resource control (RRC) connection could not be established in the time limit. */ + public static final int RRC_CONNECTION_TIMER_EXPIRED = 0x85E; + /** + * Connection establishment failed due to a link failure at the radio resource control (RRC). + */ + public static final int RRC_CONNECTION_LINK_FAILURE = 0x85F; + /** + * Connection establishment failed as the radio resource control (RRC) is not camped on any + * cell. + */ + public static final int RRC_CONNECTION_CELL_NOT_CAMPED = 0x860; + /** + * Connection establishment failed due to a service interval failure at the radio resource + * control (RRC). + */ + public static final int RRC_CONNECTION_SYSTEM_INTERVAL_FAILURE = 0x861; + /** + * Radio resource control (RRC) connection establishment failed due to the network rejecting + * the UE connection request. + */ + public static final int RRC_CONNECTION_REJECT_BY_NETWORK = 0x862; + /** Normal radio resource control (RRC) connection release. */ + public static final int RRC_CONNECTION_NORMAL_RELEASE = 0x863; + /** + * Radio resource control (RRC) connection release failed due to radio link failure conditions. + */ + public static final int RRC_CONNECTION_RADIO_LINK_FAILURE = 0x864; + /** Radio resource control (RRC) connection re-establishment failure. */ + public static final int RRC_CONNECTION_REESTABLISHMENT_FAILURE = 0x865; + /** UE is out of service during the call register. */ + public static final int RRC_CONNECTION_OUT_OF_SERVICE_DURING_CELL_REGISTER = 0x866; + /** + * Connection has been released by the radio resource control (RRC) due to an abort request. + */ + public static final int RRC_CONNECTION_ABORT_REQUEST = 0x867; + /** + * Radio resource control (RRC) connection released due to a system information block read + * error. + */ + public static final int RRC_CONNECTION_SYSTEM_INFORMATION_BLOCK_READ_ERROR = 0x868; + /** Network-initiated detach with reattach. */ + public static final int NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH = 0x869; + /** Network-initiated detach without reattach. */ + public static final int NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH = 0x86A; + /** ESM procedure maximum attempt timeout failure. */ + public static final int ESM_PROCEDURE_TIME_OUT = 0x86B; + /** + * No PDP exists with the given connection ID while modifying or deactivating or activation for + * an already active PDP. + */ + public static final int INVALID_CONNECTION_ID = 0x86C; + /** Maximum NSAPIs have been exceeded during PDP activation. */ + public static final int MAXIMIUM_NSAPIS_EXCEEDED = 0x86D; + /** Primary context for NSAPI does not exist. */ + public static final int INVALID_PRIMARY_NSAPI = 0x86E; + /** Unable to encode the OTA message for MT PDP or deactivate PDP. */ + public static final int CANNOT_ENCODE_OTA_MESSAGE = 0x86F; + /** + * Radio access bearer is not established by the lower layers during activation, modification, + * or deactivation. + */ + public static final int RADIO_ACCESS_BEARER_SETUP_FAILURE = 0x870; + /** Expiration of the PDP establish timer with a maximum of five retries. */ + public static final int PDP_ESTABLISH_TIMEOUT_EXPIRED = 0x871; + /** Expiration of the PDP modify timer with a maximum of four retries. */ + public static final int PDP_MODIFY_TIMEOUT_EXPIRED = 0x872; + /** Expiration of the PDP deactivate timer with a maximum of four retries. */ + public static final int PDP_INACTIVE_TIMEOUT_EXPIRED = 0x873; + /** PDP activation failed due to RRC_ABORT or a forbidden PLMN. */ + public static final int PDP_LOWERLAYER_ERROR = 0x874; + /** MO PDP modify collision when the MT PDP is already in progress. */ + public static final int PDP_MODIFY_COLLISION = 0x875; + /** Maximum size of the L2 message was exceeded. */ + public static final int MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED = 0x876; + /** Non-access stratum (NAS) request was rejected by the network. */ + public static final int NAS_REQUEST_REJECTED_BY_NETWORK = 0x877; + /** + * Radio resource control (RRC) connection establishment failure due to an error in the request + * message. + */ + public static final int RRC_CONNECTION_INVALID_REQUEST = 0x878; + /** + * Radio resource control (RRC) connection establishment failure due to a change in the + * tracking area ID. + */ + public static final int RRC_CONNECTION_TRACKING_AREA_ID_CHANGED = 0x879; + /** + * Radio resource control (RRC) connection establishment failure due to the RF was unavailable. + */ + public static final int RRC_CONNECTION_RF_UNAVAILABLE = 0x87A; + /** + * Radio resource control (RRC) connection was aborted before deactivating the LTE stack due to + * a successful LTE to WCDMA/GSM/TD-SCDMA IRAT change. + */ + public static final int RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE = 0x87B; + /** + * If the UE has an LTE radio link failure before security is established, the radio resource + * control (RRC) connection must be released and the UE must return to idle. + */ + public static final int RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE = 0x87C; + /** + * Radio resource control (RRC) connection was aborted by the non-access stratum (NAS) after an + * IRAT to LTE IRAT handover. + */ + public static final int RRC_CONNECTION_ABORTED_AFTER_HANDOVER = 0x87D; + /** + * Radio resource control (RRC) connection was aborted before deactivating the LTE stack after + * a successful LTE to GSM/EDGE IRAT cell change order procedure. + */ + public static final int RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE = 0x87E; + /** + * Radio resource control (RRC) connection was aborted in the middle of a LTE to GSM IRAT cell + * change order procedure. + */ + public static final int RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE = 0x87F; + /** IMSI present in the UE is unknown in the home subscriber server. */ + public static final int IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER = 0x880; + /** IMEI of the UE is not accepted by the network. */ + public static final int IMEI_NOT_ACCEPTED = 0x881; + /** EPS and non-EPS services are not allowed by the network. */ + public static final int EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED = 0x882; + /** EPS services are not allowed in the PLMN. */ + public static final int EPS_SERVICES_NOT_ALLOWED_IN_PLMN = 0x883; + /** Mobile switching center is temporarily unreachable. */ + public static final int MSC_TEMPORARILY_NOT_REACHABLE = 0x884; + /** CS domain is not available. */ + public static final int CS_DOMAIN_NOT_AVAILABLE = 0x885; + /** ESM level failure. */ + public static final int ESM_FAILURE = 0x886; + /** MAC level failure. */ + public static final int MAC_FAILURE = 0x887; + /** Synchronization failure. */ + public static final int SYNCHRONIZATION_FAILURE = 0x888; + /** UE security capabilities mismatch. */ + public static final int UE_SECURITY_CAPABILITIES_MISMATCH = 0x889; + /** Unspecified security mode reject. */ + public static final int SECURITY_MODE_REJECTED = 0x88A; + /** Unacceptable non-EPS authentication. */ + public static final int UNACCEPTABLE_NON_EPS_AUTHENTICATION = 0x88B; + /** CS fallback call establishment is not allowed. */ + public static final int CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED = 0x88C; + /** No EPS bearer context was activated. */ + public static final int NO_EPS_BEARER_CONTEXT_ACTIVATED = 0x88D; + /** Invalid EMM state. */ + public static final int INVALID_EMM_STATE = 0x88E; + /** Non-Access Spectrum layer failure. */ + public static final int NAS_LAYER_FAILURE = 0x88F; + /** Multiple PDP call feature is disabled. */ + public static final int MULTIPLE_PDP_CALL_NOT_ALLOWED = 0x890; + /** Data call has been brought down because EMBMS is not enabled at the RRC layer. */ + public static final int EMBMS_NOT_ENABLED = 0x891; + /** Data call was unsuccessfully transferred during the IRAT handover. */ + public static final int IRAT_HANDOVER_FAILED = 0x892; + /** EMBMS data call has been successfully brought down. */ + public static final int EMBMS_REGULAR_DEACTIVATION = 0x893; + /** Test loop-back data call has been successfully brought down. */ + public static final int TEST_LOOPBACK_REGULAR_DEACTIVATION = 0x894; + /** Lower layer registration failure. */ + public static final int LOWER_LAYER_REGISTRATION_FAILURE = 0x895; + /** + * Network initiates a detach on LTE with error cause ""data plan has been replenished or has + * expired. + */ + public static final int DATA_PLAN_EXPIRED = 0x896; + /** UMTS interface is brought down due to handover from UMTS to iWLAN. */ + public static final int UMTS_HANDOVER_TO_IWLAN = 0x897; + /** Received a connection deny due to general or network busy on EVDO network. */ + public static final int EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY = 0x898; + /** Received a connection deny due to billing or authentication failure on EVDO network. */ + public static final int EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE = 0x899; + /** HDR system has been changed due to redirection or the PRL was not preferred. */ + public static final int EVDO_HDR_CHANGED = 0x89A; + /** Device exited HDR due to redirection or the PRL was not preferred. */ + public static final int EVDO_HDR_EXITED = 0x89B; + /** Device does not have an HDR session. */ + public static final int EVDO_HDR_NO_SESSION = 0x89C; + /** It is ending an HDR call origination in favor of a GPS fix. */ + public static final int EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL = 0x89D; + /** Connection setup on the HDR system was time out. */ + public static final int EVDO_HDR_CONNECTION_SETUP_TIMEOUT = 0x89E; + /** Device failed to acquire a co-located HDR for origination. */ + public static final int FAILED_TO_ACQUIRE_COLOCATED_HDR = 0x89F; + /** OTASP commit is in progress. */ + public static final int OTASP_COMMIT_IN_PROGRESS = 0x8A0; + /** Device has no hybrid HDR service. */ + public static final int NO_HYBRID_HDR_SERVICE = 0x8A1; + /** HDR module could not be obtained because of the RF locked. */ + public static final int HDR_NO_LOCK_GRANTED = 0x8A2; + /** DBM or SMS is in progress. */ + public static final int DBM_OR_SMS_IN_PROGRESS = 0x8A3; + /** HDR module released the call due to fade. */ + public static final int HDR_FADE = 0x8A4; + /** HDR system access failure. */ + public static final int HDR_ACCESS_FAILURE = 0x8A5; + /** + * P_rev supported by 1 base station is less than 6, which is not supported for a 1X data call. + * The UE must be in the footprint of BS which has p_rev >= 6 to support this SO33 call. + */ + public static final int UNSUPPORTED_1X_PREV = 0x8A6; + /** Client ended the data call. */ + public static final int LOCAL_END = 0x8A7; + /** Device has no service. */ + public static final int NO_SERVICE = 0x8A8; + /** Device lost the system due to fade. */ + public static final int FADE = 0x8A9; + /** Receiving a release from the base station with no reason. */ + public static final int NORMAL_RELEASE = 0x8AA; + /** Access attempt is already in progress. */ + public static final int ACCESS_ATTEMPT_ALREADY_IN_PROGRESS = 0x8AB; + /** Device is in the process of redirecting or handing off to a different target system. */ + public static final int REDIRECTION_OR_HANDOFF_IN_PROGRESS = 0x8AC; + /** Device is operating in Emergency mode. */ + public static final int EMERGENCY_MODE = 0x8AD; + /** Device is in use (e.g., voice call). */ + public static final int PHONE_IN_USE = 0x8AE; + /** + * Device operational mode is different from the mode requested in the traffic channel bring up. + */ + public static final int INVALID_MODE = 0x8AF; + /** SIM was marked by the network as invalid for the circuit and/or packet service domain. */ + public static final int INVALID_SIM_STATE = 0x8B0; + /** There is no co-located HDR. */ + public static final int NO_COLLOCATED_HDR = 0x8B1; + /** UE is entering power save mode. */ + public static final int UE_IS_ENTERING_POWERSAVE_MODE = 0x8B2; + /** Dual switch from single standby to dual standby is in progress. */ + public static final int DUAL_SWITCH = 0x8B3; + /** + * Data call bring up fails in the PPP setup due to a timeout. + * (e.g., an LCP conf ack was not received from the network) + */ + public static final int PPP_TIMEOUT = 0x8B4; + /** + * Data call bring up fails in the PPP setup due to an authorization failure. + * (e.g., authorization is required, but not negotiated with the network during an LCP phase) + */ + public static final int PPP_AUTH_FAILURE = 0x8B5; + /** Data call bring up fails in the PPP setup due to an option mismatch. */ + public static final int PPP_OPTION_MISMATCH = 0x8B6; + /** Data call bring up fails in the PPP setup due to a PAP failure. */ + public static final int PPP_PAP_FAILURE = 0x8B7; + /** Data call bring up fails in the PPP setup due to a CHAP failure. */ + public static final int PPP_CHAP_FAILURE = 0x8B8; + /** + * Data call bring up fails in the PPP setup because the PPP is in the process of cleaning the + * previous PPP session. + */ + public static final int PPP_CLOSE_IN_PROGRESS = 0x8B9; + /** + * IPv6 interface bring up fails because the network provided only the IPv4 address for the + * upcoming PDN permanent client can reattempt a IPv6 call bring up after the IPv4 interface is + * also brought down. However, there is no guarantee that the network will provide a IPv6 + * address. + */ + public static final int LIMITED_TO_IPV4 = 0x8BA; + /** + * IPv4 interface bring up fails because the network provided only the IPv6 address for the + * upcoming PDN permanent client can reattempt a IPv4 call bring up after the IPv6 interface is + * also brought down. However there is no guarantee that the network will provide a IPv4 + * address. + */ + public static final int LIMITED_TO_IPV6 = 0x8BB; + /** Data call bring up fails in the VSNCP phase due to a VSNCP timeout error. */ + public static final int VSNCP_TIMEOUT = 0x8BC; + /** + * Data call bring up fails in the VSNCP phase due to a general error. It's used when there is + * no other specific error code available to report the failure. + */ + public static final int VSNCP_GEN_ERROR = 0x8BD; + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of the VSNCP + * configuration request because the requested APN is unauthorized. + */ + public static final int VSNCP_APN_UNATHORIZED = 0x8BE; + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of the VSNCP + * configuration request because the PDN limit has been exceeded. + */ + public static final int VSNCP_PDN_LIMIT_EXCEEDED = 0x8BF; + /** + * Data call bring up fails in the VSNCP phase due to the network rejected the VSNCP + * configuration request due to no PDN gateway address. + */ + public static final int VSNCP_NO_PDN_GATEWAY_ADDRESS = 0x8C0; + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of the VSNCP + * configuration request because the PDN gateway is unreachable. + */ + public static final int VSNCP_PDN_GATEWAY_UNREACHABLE = 0x8C1; + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of the VSNCP + * configuration request due to a PDN gateway reject. + */ + public static final int VSNCP_PDN_GATEWAY_REJECT = 0x8C2; + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of the VSNCP + * configuration request with the reason of insufficient parameter. + */ + public static final int VSNCP_INSUFFICIENT_PARAMETERS = 0x8C3; + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of the VSNCP + * configuration request with the reason of resource unavailable. + */ + public static final int VSNCP_RESOURCE_UNAVAILABLE = 0x8C4; + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of the VSNCP + * configuration request with the reason of administratively prohibited at the HSGW. + */ + public static final int VSNCP_ADMINISTRATIVELY_PROHIBITED = 0x8C5; + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of PDN ID in use, or + * all existing PDNs are brought down with this end reason because one of the PDN bring up was + * rejected by the network with the reason of PDN ID in use. + */ + public static final int VSNCP_PDN_ID_IN_USE = 0x8C6; + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of the VSNCP + * configuration request for the reason of subscriber limitation. + */ + public static final int VSNCP_SUBSCRIBER_LIMITATION = 0x8C7; + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of the VSNCP + * configuration request because the PDN exists for this APN. + */ + public static final int VSNCP_PDN_EXISTS_FOR_THIS_APN = 0x8C8; + /** + * Data call bring up fails in the VSNCP phase due to a network rejection of the VSNCP + * configuration request with reconnect to this PDN not allowed, or an active data call is + * terminated by the network because reconnection to this PDN is not allowed. Upon receiving + * this error code from the network, the modem infinitely throttles the PDN until the next + * power cycle. + */ + public static final int VSNCP_RECONNECT_NOT_ALLOWED = 0x8C9; + /** Device failure to obtain the prefix from the network. */ + public static final int IPV6_PREFIX_UNAVAILABLE = 0x8CA; + /** System preference change back to SRAT during handoff */ + public static final int HANDOFF_PREFERENCE_CHANGED = 0x8CB; // OEM sepecific error codes. To be used by OEMs when they don't // want to reveal error code which would be replaced by ERROR_UNSPECIFIED @@ -226,12 +988,18 @@ public final class DataFailCause { FILTER_SEMANTIC_ERROR, FILTER_SYTAX_ERROR, PDP_WITHOUT_ACTIVE_TFT, + ACTIVATION_REJECTED_BCM_VIOLATION, ONLY_IPV4_ALLOWED, ONLY_IPV6_ALLOWED, ONLY_SINGLE_BEARER_ALLOWED, ESM_INFO_NOT_RECEIVED, PDN_CONN_DOES_NOT_EXIST, MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED, + COLLISION_WITH_NETWORK_INITIATED_REQUEST, + ONLY_IPV4V6_ALLOWED, + ONLY_NON_IP_ALLOWED, + UNSUPPORTED_QCI_VALUE, + BEARER_HANDLING_NOT_SUPPORTED, ACTIVE_PDP_CONTEXT_MAX_NUMBER_REACHED, UNSUPPORTED_APN_IN_CURRENT_PLMN, INVALID_TRANSACTION_ID, @@ -242,7 +1010,7 @@ public final class DataFailCause { UNKNOWN_INFO_ELEMENT, CONDITIONAL_IE_ERROR, MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE, - PROTOCOL_ERRORS, /* no retry */ + PROTOCOL_ERRORS, APN_TYPE_CONFLICT, INVALID_PCSCF_ADDR, INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN, @@ -254,6 +1022,262 @@ public final class DataFailCause { IFACE_AND_POL_FAMILY_MISMATCH, EMM_ACCESS_BARRED_INFINITE_RETRY, AUTH_FAILURE_ON_EMERGENCY_CALL, + INVALID_DNS_ADDR, + INVALID_PCSCF_OR_DNS_ADDRESS, + CALL_PREEMPT_BY_EMERGENCY_APN, + UE_INITIATED_DETACH_OR_DISCONNECT, + MIP_FA_REASON_UNSPECIFIED, + MIP_FA_ADMIN_PROHIBITED, + MIP_FA_INSUFFICIENT_RESOURCES, + MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE, + MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE, + MIP_FA_REQUESTED_LIFETIME_TOO_LONG, + MIP_FA_MALFORMED_REQUEST, + MIP_FA_MALFORMED_REPLY, + MIP_FA_ENCAPSULATION_UNAVAILABLE, + MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE, + MIP_FA_REVERSE_TUNNEL_UNAVAILABLE, + MIP_FA_REVERSE_TUNNEL_IS_MANDATORY, + MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED, + MIP_FA_MISSING_NAI, + MIP_FA_MISSING_HOME_AGENT, + MIP_FA_MISSING_HOME_ADDRESS, + MIP_FA_UNKNOWN_CHALLENGE, + MIP_FA_MISSING_CHALLENGE, + MIP_FA_STALE_CHALLENGE, + MIP_HA_REASON_UNSPECIFIED, + MIP_HA_ADMIN_PROHIBITED, + MIP_HA_INSUFFICIENT_RESOURCES, + MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE, + MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE, + MIP_HA_REGISTRATION_ID_MISMATCH, + MIP_HA_MALFORMED_REQUEST, + MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS, + MIP_HA_REVERSE_TUNNEL_UNAVAILABLE, + MIP_HA_REVERSE_TUNNEL_IS_MANDATORY, + MIP_HA_ENCAPSULATION_UNAVAILABLE, + CLOSE_IN_PROGRESS, + NETWORK_INITIATED_TERMINATION, + MODEM_APP_PREEMPTED, + PDN_IPV4_CALL_DISALLOWED, + PDN_IPV4_CALL_THROTTLED, + PDN_IPV6_CALL_DISALLOWED, + PDN_IPV6_CALL_THROTTLED, + MODEM_RESTART, + PDP_PPP_NOT_SUPPORTED, + UNPREFERRED_RAT, + PHYSICAL_LINK_CLOSE_IN_PROGRESS, + APN_PENDING_HANDOVER, + PROFILE_BEARER_INCOMPATIBLE, + SIM_CARD_CHANGED, + LOW_POWER_MODE_OR_POWERING_DOWN, + APN_DISABLED, + MAX_PPP_INACTIVITY_TIMER_EXPIRED, + IPV6_ADDRESS_TRANSFER_FAILED, + TRAT_SWAP_FAILED, + EHRPD_TO_HRPD_FALLBACK, + MIP_CONFIG_FAILURE, + PDN_INACTIVITY_TIMER_EXPIRED, + MAX_IPV4_CONNECTIONS, + MAX_IPV6_CONNECTIONS, + APN_MISMATCH, + IP_VERSION_MISMATCH, + DUN_CALL_DISALLOWED, + INTERNAL_EPC_NONEPC_TRANSITION, + INTERFACE_IN_USE, + APN_DISALLOWED_ON_ROAMING, + APN_PARAMETERS_CHANGED, + NULL_APN_DISALLOWED, + THERMAL_MITIGATION, + DATA_SETTINGS_DISABLED, + DATA_ROAMING_SETTINGS_DISABLED, + DDS_SWITCHED, + FORBIDDEN_APN_NAME, + DDS_SWITCH_IN_PROGRESS, + CALL_DISALLOWED_IN_ROAMING, + NON_IP_NOT_SUPPORTED, + PDN_NON_IP_CALL_THROTTLED, + PDN_NON_IP_CALL_DISALLOWED, + CDMA_LOCK, + CDMA_INTERCEPT, + CDMA_REORDER, + CDMA_RELEASE_DUE_TO_SO_REJECTION, + CDMA_INCOMING_CALL, + CDMA_ALERT_STOP, + CHANNEL_ACQUISITION_FAILURE, + MAX_ACCESS_PROBE, + CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STATION, + NO_RESPONSE_FROM_BASE_STATION, + REJECTED_BY_BASE_STATION, + CONCURRENT_SERVICES_INCOMPATIBLE, + NO_CDMA_SERVICE, + RUIM_NOT_PRESENT, + CDMA_RETRY_ORDER, + ACCESS_BLOCK, + ACCESS_BLOCK_ALL, + IS707B_MAX_ACCESS_PROBES, + THERMAL_EMERGENCY, + CONCURRENT_SERVICES_NOT_ALLOWED, + INCOMING_CALL_REJECTED, + NO_SERVICE_ON_GATEWAY, + NO_GPRS_CONTEXT, + ILLEGAL_MS, + ILLEGAL_ME, + GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED, + GPRS_SERVICES_NOT_ALLOWED, + MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK, + IMPLICITLY_DETACHED, + PLMN_NOT_ALLOWED, + LOCATION_AREA_NOT_ALLOWED, + GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN, + PDP_DUPLICATE, + UE_RAT_CHANGE, + CONGESTION, + NO_PDP_CONTEXT_ACTIVATED, + ACCESS_CLASS_DSAC_REJECTION, + PDP_ACTIVATE_MAX_RETRY_FAILED, + RADIO_ACCESS_BEARER_FAILURE, + ESM_UNKNOWN_EPS_BEARER_CONTEXT, + DRB_RELEASED_BY_RRC, + CONNECTION_RELEASED, + EMM_DETACHED, + EMM_ATTACH_FAILED, + EMM_ATTACH_STARTED, + LTE_NAS_SERVICE_REQUEST_FAILED, + DUPLICATE_BEARER_ID, + ESM_COLLISION_SCENARIOS, + ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK, + ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER, + ESM_BAD_OTA_MESSAGE, + ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL, + ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT, + DS_EXPLICIT_DEACTIVATION, + ESM_LOCAL_CAUSE_NONE, + LTE_THROTTLING_NOT_REQUIRED, + ACCESS_CONTROL_LIST_CHECK_FAILURE, + SERVICE_NOT_ALLOWED_ON_PLMN, + EMM_T3417_EXPIRED, + EMM_T3417_EXT_EXPIRED, + RRC_UPLINK_DATA_TRANSMISSION_FAILURE, + RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER, + RRC_UPLINK_CONNECTION_RELEASE, + RRC_UPLINK_RADIO_LINK_FAILURE, + RRC_UPLINK_ERROR_REQUEST_FROM_NAS, + RRC_CONNECTION_ACCESS_STRATUM_FAILURE, + RRC_CONNECTION_ANOTHER_PROCEDURE_IN_PROGRESS, + RRC_CONNECTION_ACCESS_BARRED, + RRC_CONNECTION_CELL_RESELECTION, + RRC_CONNECTION_CONFIG_FAILURE, + RRC_CONNECTION_TIMER_EXPIRED, + RRC_CONNECTION_LINK_FAILURE, + RRC_CONNECTION_CELL_NOT_CAMPED, + RRC_CONNECTION_SYSTEM_INTERVAL_FAILURE, + RRC_CONNECTION_REJECT_BY_NETWORK, + RRC_CONNECTION_NORMAL_RELEASE, + RRC_CONNECTION_RADIO_LINK_FAILURE, + RRC_CONNECTION_REESTABLISHMENT_FAILURE, + RRC_CONNECTION_OUT_OF_SERVICE_DURING_CELL_REGISTER, + RRC_CONNECTION_ABORT_REQUEST, + RRC_CONNECTION_SYSTEM_INFORMATION_BLOCK_READ_ERROR, + NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH, + NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH, + ESM_PROCEDURE_TIME_OUT, + INVALID_CONNECTION_ID, + MAXIMIUM_NSAPIS_EXCEEDED, + INVALID_PRIMARY_NSAPI, + CANNOT_ENCODE_OTA_MESSAGE, + RADIO_ACCESS_BEARER_SETUP_FAILURE, + PDP_ESTABLISH_TIMEOUT_EXPIRED, + PDP_MODIFY_TIMEOUT_EXPIRED, + PDP_INACTIVE_TIMEOUT_EXPIRED, + PDP_LOWERLAYER_ERROR, + PDP_MODIFY_COLLISION, + MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED, + NAS_REQUEST_REJECTED_BY_NETWORK, + RRC_CONNECTION_INVALID_REQUEST, + RRC_CONNECTION_TRACKING_AREA_ID_CHANGED, + RRC_CONNECTION_RF_UNAVAILABLE, + RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE, + RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE, + RRC_CONNECTION_ABORTED_AFTER_HANDOVER, + RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE, + RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE, + IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER, + IMEI_NOT_ACCEPTED, + EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED, + EPS_SERVICES_NOT_ALLOWED_IN_PLMN, + MSC_TEMPORARILY_NOT_REACHABLE, + CS_DOMAIN_NOT_AVAILABLE, + ESM_FAILURE, + MAC_FAILURE, + SYNCHRONIZATION_FAILURE, + UE_SECURITY_CAPABILITIES_MISMATCH, + SECURITY_MODE_REJECTED, + UNACCEPTABLE_NON_EPS_AUTHENTICATION, + CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED, + NO_EPS_BEARER_CONTEXT_ACTIVATED, + INVALID_EMM_STATE, + NAS_LAYER_FAILURE, + MULTIPLE_PDP_CALL_NOT_ALLOWED, + EMBMS_NOT_ENABLED, + IRAT_HANDOVER_FAILED, + EMBMS_REGULAR_DEACTIVATION, + TEST_LOOPBACK_REGULAR_DEACTIVATION, + LOWER_LAYER_REGISTRATION_FAILURE, + DATA_PLAN_EXPIRED, + UMTS_HANDOVER_TO_IWLAN, + EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY, + EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE, + EVDO_HDR_CHANGED, + EVDO_HDR_EXITED, + EVDO_HDR_NO_SESSION, + EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL, + EVDO_HDR_CONNECTION_SETUP_TIMEOUT, + FAILED_TO_ACQUIRE_COLOCATED_HDR, + OTASP_COMMIT_IN_PROGRESS, + NO_HYBRID_HDR_SERVICE, + HDR_NO_LOCK_GRANTED, + DBM_OR_SMS_IN_PROGRESS, + HDR_FADE, + HDR_ACCESS_FAILURE, + UNSUPPORTED_1X_PREV, + LOCAL_END, + NO_SERVICE, + FADE, + NORMAL_RELEASE, + ACCESS_ATTEMPT_ALREADY_IN_PROGRESS, + REDIRECTION_OR_HANDOFF_IN_PROGRESS, + EMERGENCY_MODE, + PHONE_IN_USE, + INVALID_MODE, + INVALID_SIM_STATE, + NO_COLLOCATED_HDR, + UE_IS_ENTERING_POWERSAVE_MODE, + DUAL_SWITCH, + PPP_TIMEOUT, + PPP_AUTH_FAILURE, + PPP_OPTION_MISMATCH, + PPP_PAP_FAILURE, + PPP_CHAP_FAILURE, + PPP_CLOSE_IN_PROGRESS, + LIMITED_TO_IPV4, + LIMITED_TO_IPV6, + VSNCP_TIMEOUT, + VSNCP_GEN_ERROR, + VSNCP_APN_UNATHORIZED, + VSNCP_PDN_LIMIT_EXCEEDED, + VSNCP_NO_PDN_GATEWAY_ADDRESS, + VSNCP_PDN_GATEWAY_UNREACHABLE, + VSNCP_PDN_GATEWAY_REJECT, + VSNCP_INSUFFICIENT_PARAMETERS, + VSNCP_RESOURCE_UNAVAILABLE, + VSNCP_ADMINISTRATIVELY_PROHIBITED, + VSNCP_PDN_ID_IN_USE, + VSNCP_SUBSCRIBER_LIMITATION, + VSNCP_PDN_EXISTS_FOR_THIS_APN, + VSNCP_RECONNECT_NOT_ALLOWED, + IPV6_PREFIX_UNAVAILABLE, + HANDOFF_PREFERENCE_CHANGED, OEM_DCFAILCAUSE_1, OEM_DCFAILCAUSE_2, OEM_DCFAILCAUSE_3, @@ -317,6 +1341,7 @@ public final class DataFailCause { sFailCauseMap.put(FILTER_SEMANTIC_ERROR, "FILTER_SEMANTIC_ERROR"); sFailCauseMap.put(FILTER_SYTAX_ERROR, "FILTER_SYTAX_ERROR"); sFailCauseMap.put(PDP_WITHOUT_ACTIVE_TFT, "PDP_WITHOUT_ACTIVE_TFT"); + sFailCauseMap.put(ACTIVATION_REJECTED_BCM_VIOLATION, "ACTIVATION_REJECTED_BCM_VIOLATION"); sFailCauseMap.put(ONLY_IPV4_ALLOWED, "ONLY_IPV4_ALLOWED"); sFailCauseMap.put(ONLY_IPV6_ALLOWED, "ONLY_IPV6_ALLOWED"); sFailCauseMap.put(ONLY_SINGLE_BEARER_ALLOWED, "ONLY_SINGLE_BEARER_ALLOWED"); @@ -324,6 +1349,12 @@ public final class DataFailCause { sFailCauseMap.put(PDN_CONN_DOES_NOT_EXIST, "PDN_CONN_DOES_NOT_EXIST"); sFailCauseMap.put(MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED, "MULTI_CONN_TO_SAME_PDN_NOT_ALLOWED"); + sFailCauseMap.put(COLLISION_WITH_NETWORK_INITIATED_REQUEST, + "COLLISION_WITH_NETWORK_INITIATED_REQUEST"); + sFailCauseMap.put(ONLY_IPV4V6_ALLOWED, "ONLY_IPV4V6_ALLOWED"); + sFailCauseMap.put(ONLY_NON_IP_ALLOWED, "ONLY_NON_IP_ALLOWED"); + sFailCauseMap.put(UNSUPPORTED_QCI_VALUE, "UNSUPPORTED_QCI_VALUE"); + sFailCauseMap.put(BEARER_HANDLING_NOT_SUPPORTED, "BEARER_HANDLING_NOT_SUPPORTED"); sFailCauseMap.put(ACTIVE_PDP_CONTEXT_MAX_NUMBER_REACHED, "ACTIVE_PDP_CONTEXT_MAX_NUMBER_REACHED"); sFailCauseMap.put(UNSUPPORTED_APN_IN_CURRENT_PLMN, @@ -353,6 +1384,301 @@ public final class DataFailCause { "EMM_ACCESS_BARRED_INFINITE_RETRY"); sFailCauseMap.put(AUTH_FAILURE_ON_EMERGENCY_CALL, "AUTH_FAILURE_ON_EMERGENCY_CALL"); + sFailCauseMap.put(INVALID_DNS_ADDR, "INVALID_DNS_ADDR"); + sFailCauseMap.put(INVALID_PCSCF_OR_DNS_ADDRESS, "INVALID_PCSCF_OR_DNS_ADDRESS"); + sFailCauseMap.put(CALL_PREEMPT_BY_EMERGENCY_APN, "CALL_PREEMPT_BY_EMERGENCY_APN"); + sFailCauseMap.put(UE_INITIATED_DETACH_OR_DISCONNECT, "UE_INITIATED_DETACH_OR_DISCONNECT"); + sFailCauseMap.put(MIP_FA_REASON_UNSPECIFIED, "MIP_FA_REASON_UNSPECIFIED"); + sFailCauseMap.put(MIP_FA_ADMIN_PROHIBITED, "MIP_FA_ADMIN_PROHIBITED"); + sFailCauseMap.put(MIP_FA_INSUFFICIENT_RESOURCES, "MIP_FA_INSUFFICIENT_RESOURCES"); + sFailCauseMap.put(MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE, + "MIP_FA_MOBILE_NODE_AUTHENTICATION_FAILURE"); + sFailCauseMap.put(MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE, + "MIP_FA_HOME_AGENT_AUTHENTICATION_FAILURE"); + sFailCauseMap.put(MIP_FA_REQUESTED_LIFETIME_TOO_LONG, "MIP_FA_REQUESTED_LIFETIME_TOO_LONG"); + sFailCauseMap.put(MIP_FA_MALFORMED_REQUEST, "MIP_FA_MALFORMED_REQUEST"); + sFailCauseMap.put(MIP_FA_MALFORMED_REPLY, "MIP_FA_MALFORMED_REPLY"); + sFailCauseMap.put(MIP_FA_ENCAPSULATION_UNAVAILABLE, "MIP_FA_ENCAPSULATION_UNAVAILABLE"); + sFailCauseMap.put(MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE, + "MIP_FA_VJ_HEADER_COMPRESSION_UNAVAILABLE"); + sFailCauseMap.put(MIP_FA_REVERSE_TUNNEL_UNAVAILABLE, "MIP_FA_REVERSE_TUNNEL_UNAVAILABLE"); + sFailCauseMap.put(MIP_FA_REVERSE_TUNNEL_IS_MANDATORY, "MIP_FA_REVERSE_TUNNEL_IS_MANDATORY"); + sFailCauseMap.put(MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED, + "MIP_FA_DELIVERY_STYLE_NOT_SUPPORTED"); + sFailCauseMap.put(MIP_FA_MISSING_NAI, "MIP_FA_MISSING_NAI"); + sFailCauseMap.put(MIP_FA_MISSING_HOME_AGENT, "MIP_FA_MISSING_HOME_AGENT"); + sFailCauseMap.put(MIP_FA_MISSING_HOME_ADDRESS, "MIP_FA_MISSING_HOME_ADDRESS"); + sFailCauseMap.put(MIP_FA_UNKNOWN_CHALLENGE, "MIP_FA_UNKNOWN_CHALLENGE"); + sFailCauseMap.put(MIP_FA_MISSING_CHALLENGE, "MIP_FA_MISSING_CHALLENGE"); + sFailCauseMap.put(MIP_FA_STALE_CHALLENGE, "MIP_FA_STALE_CHALLENGE"); + sFailCauseMap.put(MIP_HA_REASON_UNSPECIFIED, "MIP_HA_REASON_UNSPECIFIED"); + sFailCauseMap.put(MIP_HA_ADMIN_PROHIBITED, "MIP_HA_ADMIN_PROHIBITED"); + sFailCauseMap.put(MIP_HA_INSUFFICIENT_RESOURCES, "MIP_HA_INSUFFICIENT_RESOURCES"); + sFailCauseMap.put(MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE, + "MIP_HA_MOBILE_NODE_AUTHENTICATION_FAILURE"); + sFailCauseMap.put(MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE, + "MIP_HA_FOREIGN_AGENT_AUTHENTICATION_FAILURE"); + sFailCauseMap.put(MIP_HA_REGISTRATION_ID_MISMATCH, "MIP_HA_REGISTRATION_ID_MISMATCH"); + sFailCauseMap.put(MIP_HA_MALFORMED_REQUEST, "MIP_HA_MALFORMED_REQUEST"); + sFailCauseMap.put(MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS, "MIP_HA_UNKNOWN_HOME_AGENT_ADDRESS"); + sFailCauseMap.put(MIP_HA_REVERSE_TUNNEL_UNAVAILABLE, "MIP_HA_REVERSE_TUNNEL_UNAVAILABLE"); + sFailCauseMap.put(MIP_HA_REVERSE_TUNNEL_IS_MANDATORY, "MIP_HA_REVERSE_TUNNEL_IS_MANDATORY"); + sFailCauseMap.put(MIP_HA_ENCAPSULATION_UNAVAILABLE, "MIP_HA_ENCAPSULATION_UNAVAILABLE"); + sFailCauseMap.put(CLOSE_IN_PROGRESS, "CLOSE_IN_PROGRESS"); + sFailCauseMap.put(NETWORK_INITIATED_TERMINATION, "NETWORK_INITIATED_TERMINATION"); + sFailCauseMap.put(MODEM_APP_PREEMPTED, "MODEM_APP_PREEMPTED"); + sFailCauseMap.put(PDN_IPV4_CALL_DISALLOWED, "PDN_IPV4_CALL_DISALLOWED"); + sFailCauseMap.put(PDN_IPV4_CALL_THROTTLED, "PDN_IPV4_CALL_THROTTLED"); + sFailCauseMap.put(PDN_IPV6_CALL_DISALLOWED, "PDN_IPV6_CALL_DISALLOWED"); + sFailCauseMap.put(PDN_IPV6_CALL_THROTTLED, "PDN_IPV6_CALL_THROTTLED"); + sFailCauseMap.put(MODEM_RESTART, "MODEM_RESTART"); + sFailCauseMap.put(PDP_PPP_NOT_SUPPORTED, "PDP_PPP_NOT_SUPPORTED"); + sFailCauseMap.put(UNPREFERRED_RAT, "UNPREFERRED_RAT"); + sFailCauseMap.put(PHYSICAL_LINK_CLOSE_IN_PROGRESS, "PHYSICAL_LINK_CLOSE_IN_PROGRESS"); + sFailCauseMap.put(APN_PENDING_HANDOVER, "APN_PENDING_HANDOVER"); + sFailCauseMap.put(PROFILE_BEARER_INCOMPATIBLE, "PROFILE_BEARER_INCOMPATIBLE"); + sFailCauseMap.put(SIM_CARD_CHANGED, "SIM_CARD_CHANGED"); + sFailCauseMap.put(LOW_POWER_MODE_OR_POWERING_DOWN, "LOW_POWER_MODE_OR_POWERING_DOWN"); + sFailCauseMap.put(APN_DISABLED, "APN_DISABLED"); + sFailCauseMap.put(MAX_PPP_INACTIVITY_TIMER_EXPIRED, "MAX_PPP_INACTIVITY_TIMER_EXPIRED"); + sFailCauseMap.put(IPV6_ADDRESS_TRANSFER_FAILED, "IPV6_ADDRESS_TRANSFER_FAILED"); + sFailCauseMap.put(TRAT_SWAP_FAILED, "TRAT_SWAP_FAILED"); + sFailCauseMap.put(EHRPD_TO_HRPD_FALLBACK, "EHRPD_TO_HRPD_FALLBACK"); + sFailCauseMap.put(MIP_CONFIG_FAILURE, "MIP_CONFIG_FAILURE"); + sFailCauseMap.put(PDN_INACTIVITY_TIMER_EXPIRED, "PDN_INACTIVITY_TIMER_EXPIRED"); + sFailCauseMap.put(MAX_IPV4_CONNECTIONS, "MAX_IPV4_CONNECTIONS"); + sFailCauseMap.put(MAX_IPV6_CONNECTIONS, "MAX_IPV6_CONNECTIONS"); + sFailCauseMap.put(APN_MISMATCH, "APN_MISMATCH"); + sFailCauseMap.put(IP_VERSION_MISMATCH, "IP_VERSION_MISMATCH"); + sFailCauseMap.put(DUN_CALL_DISALLOWED, "DUN_CALL_DISALLOWED"); + sFailCauseMap.put(INTERNAL_EPC_NONEPC_TRANSITION, "INTERNAL_EPC_NONEPC_TRANSITION"); + sFailCauseMap.put(INTERFACE_IN_USE, "INTERFACE_IN_USE"); + sFailCauseMap.put(APN_DISALLOWED_ON_ROAMING, "APN_DISALLOWED_ON_ROAMING"); + sFailCauseMap.put(APN_PARAMETERS_CHANGED, "APN_PARAMETERS_CHANGED"); + sFailCauseMap.put(NULL_APN_DISALLOWED, "NULL_APN_DISALLOWED"); + sFailCauseMap.put(THERMAL_MITIGATION, "THERMAL_MITIGATION"); + sFailCauseMap.put(DATA_SETTINGS_DISABLED, "DATA_SETTINGS_DISABLED"); + sFailCauseMap.put(DATA_ROAMING_SETTINGS_DISABLED, "DATA_ROAMING_SETTINGS_DISABLED"); + sFailCauseMap.put(DDS_SWITCHED, "DDS_SWITCHED"); + sFailCauseMap.put(FORBIDDEN_APN_NAME, "FORBIDDEN_APN_NAME"); + sFailCauseMap.put(DDS_SWITCH_IN_PROGRESS, "DDS_SWITCH_IN_PROGRESS"); + sFailCauseMap.put(CALL_DISALLOWED_IN_ROAMING, "CALL_DISALLOWED_IN_ROAMING"); + sFailCauseMap.put(NON_IP_NOT_SUPPORTED, "NON_IP_NOT_SUPPORTED"); + sFailCauseMap.put(PDN_NON_IP_CALL_THROTTLED, "PDN_NON_IP_CALL_THROTTLED"); + sFailCauseMap.put(PDN_NON_IP_CALL_DISALLOWED, "PDN_NON_IP_CALL_DISALLOWED"); + sFailCauseMap.put(CDMA_LOCK, "CDMA_LOCK"); + sFailCauseMap.put(CDMA_INTERCEPT, "CDMA_INTERCEPT"); + sFailCauseMap.put(CDMA_REORDER, "CDMA_REORDER"); + sFailCauseMap.put(CDMA_RELEASE_DUE_TO_SO_REJECTION, "CDMA_RELEASE_DUE_TO_SO_REJECTION"); + sFailCauseMap.put(CDMA_INCOMING_CALL, "CDMA_INCOMING_CALL"); + sFailCauseMap.put(CDMA_ALERT_STOP, "CDMA_ALERT_STOP"); + sFailCauseMap.put(CHANNEL_ACQUISITION_FAILURE, "CHANNEL_ACQUISITION_FAILURE"); + sFailCauseMap.put(MAX_ACCESS_PROBE, "MAX_ACCESS_PROBE"); + sFailCauseMap.put(CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STATION, + "CONCURRENT_SERVICE_NOT_SUPPORTED_BY_BASE_STATION"); + sFailCauseMap.put(NO_RESPONSE_FROM_BASE_STATION, "NO_RESPONSE_FROM_BASE_STATION"); + sFailCauseMap.put(REJECTED_BY_BASE_STATION, "REJECTED_BY_BASE_STATION"); + sFailCauseMap.put(CONCURRENT_SERVICES_INCOMPATIBLE, "CONCURRENT_SERVICES_INCOMPATIBLE"); + sFailCauseMap.put(NO_CDMA_SERVICE, "NO_CDMA_SERVICE"); + sFailCauseMap.put(RUIM_NOT_PRESENT, "RUIM_NOT_PRESENT"); + sFailCauseMap.put(CDMA_RETRY_ORDER, "CDMA_RETRY_ORDER"); + sFailCauseMap.put(ACCESS_BLOCK, "ACCESS_BLOCK"); + sFailCauseMap.put(ACCESS_BLOCK_ALL, "ACCESS_BLOCK_ALL"); + sFailCauseMap.put(IS707B_MAX_ACCESS_PROBES, "IS707B_MAX_ACCESS_PROBES"); + sFailCauseMap.put(THERMAL_EMERGENCY, "THERMAL_EMERGENCY"); + sFailCauseMap.put(CONCURRENT_SERVICES_NOT_ALLOWED, "CONCURRENT_SERVICES_NOT_ALLOWED"); + sFailCauseMap.put(INCOMING_CALL_REJECTED, "INCOMING_CALL_REJECTED"); + sFailCauseMap.put(NO_SERVICE_ON_GATEWAY, "NO_SERVICE_ON_GATEWAY"); + sFailCauseMap.put(NO_GPRS_CONTEXT, "NO_GPRS_CONTEXT"); + sFailCauseMap.put(ILLEGAL_MS, "ILLEGAL_MS"); + sFailCauseMap.put(ILLEGAL_ME, "ILLEGAL_ME"); + sFailCauseMap.put(GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED, + "GPRS_SERVICES_AND_NON_GPRS_SERVICES_NOT_ALLOWED"); + sFailCauseMap.put(GPRS_SERVICES_NOT_ALLOWED, "GPRS_SERVICES_NOT_ALLOWED"); + sFailCauseMap.put(MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK, + "MS_IDENTITY_CANNOT_BE_DERIVED_BY_THE_NETWORK"); + sFailCauseMap.put(IMPLICITLY_DETACHED, "IMPLICITLY_DETACHED"); + sFailCauseMap.put(PLMN_NOT_ALLOWED, "PLMN_NOT_ALLOWED"); + sFailCauseMap.put(LOCATION_AREA_NOT_ALLOWED, "LOCATION_AREA_NOT_ALLOWED"); + sFailCauseMap.put(GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN, + "GPRS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN"); + sFailCauseMap.put(PDP_DUPLICATE, "PDP_DUPLICATE"); + sFailCauseMap.put(UE_RAT_CHANGE, "UE_RAT_CHANGE"); + sFailCauseMap.put(CONGESTION, "CONGESTION"); + sFailCauseMap.put(NO_PDP_CONTEXT_ACTIVATED, "NO_PDP_CONTEXT_ACTIVATED"); + sFailCauseMap.put(ACCESS_CLASS_DSAC_REJECTION, "ACCESS_CLASS_DSAC_REJECTION"); + sFailCauseMap.put(PDP_ACTIVATE_MAX_RETRY_FAILED, "PDP_ACTIVATE_MAX_RETRY_FAILED"); + sFailCauseMap.put(RADIO_ACCESS_BEARER_FAILURE, "RADIO_ACCESS_BEARER_FAILURE"); + sFailCauseMap.put(ESM_UNKNOWN_EPS_BEARER_CONTEXT, "ESM_UNKNOWN_EPS_BEARER_CONTEXT"); + sFailCauseMap.put(DRB_RELEASED_BY_RRC, "DRB_RELEASED_BY_RRC"); + sFailCauseMap.put(CONNECTION_RELEASED, "CONNECTION_RELEASED"); + sFailCauseMap.put(EMM_DETACHED, "EMM_DETACHED"); + sFailCauseMap.put(EMM_ATTACH_FAILED, "EMM_ATTACH_FAILED"); + sFailCauseMap.put(EMM_ATTACH_STARTED, "EMM_ATTACH_STARTED"); + sFailCauseMap.put(LTE_NAS_SERVICE_REQUEST_FAILED, "LTE_NAS_SERVICE_REQUEST_FAILED"); + sFailCauseMap.put(DUPLICATE_BEARER_ID, "DUPLICATE_BEARER_ID"); + sFailCauseMap.put(ESM_COLLISION_SCENARIOS, "ESM_COLLISION_SCENARIOS"); + sFailCauseMap.put(ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK, + "ESM_BEARER_DEACTIVATED_TO_SYNC_WITH_NETWORK"); + sFailCauseMap.put(ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER, + "ESM_NW_ACTIVATED_DED_BEARER_WITH_ID_OF_DEF_BEARER"); + sFailCauseMap.put(ESM_BAD_OTA_MESSAGE, "ESM_BAD_OTA_MESSAGE"); + sFailCauseMap.put(ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL, + "ESM_DOWNLOAD_SERVER_REJECTED_THE_CALL"); + sFailCauseMap.put(ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT, + "ESM_CONTEXT_TRANSFERRED_DUE_TO_IRAT"); + sFailCauseMap.put(DS_EXPLICIT_DEACTIVATION, "DS_EXPLICIT_DEACTIVATION"); + sFailCauseMap.put(ESM_LOCAL_CAUSE_NONE, "ESM_LOCAL_CAUSE_NONE"); + sFailCauseMap.put(LTE_THROTTLING_NOT_REQUIRED, "LTE_THROTTLING_NOT_REQUIRED"); + sFailCauseMap.put(ACCESS_CONTROL_LIST_CHECK_FAILURE, + "ACCESS_CONTROL_LIST_CHECK_FAILURE"); + sFailCauseMap.put(SERVICE_NOT_ALLOWED_ON_PLMN, "SERVICE_NOT_ALLOWED_ON_PLMN"); + sFailCauseMap.put(EMM_T3417_EXPIRED, "EMM_T3417_EXPIRED"); + sFailCauseMap.put(EMM_T3417_EXT_EXPIRED, "EMM_T3417_EXT_EXPIRED"); + sFailCauseMap.put(RRC_UPLINK_DATA_TRANSMISSION_FAILURE, + "RRC_UPLINK_DATA_TRANSMISSION_FAILURE"); + sFailCauseMap.put(RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER, + "RRC_UPLINK_DELIVERY_FAILED_DUE_TO_HANDOVER"); + sFailCauseMap.put(RRC_UPLINK_CONNECTION_RELEASE, "RRC_UPLINK_CONNECTION_RELEASE"); + sFailCauseMap.put(RRC_UPLINK_RADIO_LINK_FAILURE, "RRC_UPLINK_RADIO_LINK_FAILURE"); + sFailCauseMap.put(RRC_UPLINK_ERROR_REQUEST_FROM_NAS, "RRC_UPLINK_ERROR_REQUEST_FROM_NAS"); + sFailCauseMap.put(RRC_CONNECTION_ACCESS_STRATUM_FAILURE, + "RRC_CONNECTION_ACCESS_STRATUM_FAILURE"); + sFailCauseMap.put(RRC_CONNECTION_ANOTHER_PROCEDURE_IN_PROGRESS, + "RRC_CONNECTION_ANOTHER_PROCEDURE_IN_PROGRESS"); + sFailCauseMap.put(RRC_CONNECTION_ACCESS_BARRED, "RRC_CONNECTION_ACCESS_BARRED"); + sFailCauseMap.put(RRC_CONNECTION_CELL_RESELECTION, "RRC_CONNECTION_CELL_RESELECTION"); + sFailCauseMap.put(RRC_CONNECTION_CONFIG_FAILURE, "RRC_CONNECTION_CONFIG_FAILURE"); + sFailCauseMap.put(RRC_CONNECTION_TIMER_EXPIRED, "RRC_CONNECTION_TIMER_EXPIRED"); + sFailCauseMap.put(RRC_CONNECTION_LINK_FAILURE, "RRC_CONNECTION_LINK_FAILURE"); + sFailCauseMap.put(RRC_CONNECTION_CELL_NOT_CAMPED, "RRC_CONNECTION_CELL_NOT_CAMPED"); + sFailCauseMap.put(RRC_CONNECTION_SYSTEM_INTERVAL_FAILURE, + "RRC_CONNECTION_SYSTEM_INTERVAL_FAILURE"); + sFailCauseMap.put(RRC_CONNECTION_REJECT_BY_NETWORK, "RRC_CONNECTION_REJECT_BY_NETWORK"); + sFailCauseMap.put(RRC_CONNECTION_NORMAL_RELEASE, "RRC_CONNECTION_NORMAL_RELEASE"); + sFailCauseMap.put(RRC_CONNECTION_RADIO_LINK_FAILURE, "RRC_CONNECTION_RADIO_LINK_FAILURE"); + sFailCauseMap.put(RRC_CONNECTION_REESTABLISHMENT_FAILURE, + "RRC_CONNECTION_REESTABLISHMENT_FAILURE"); + sFailCauseMap.put(RRC_CONNECTION_OUT_OF_SERVICE_DURING_CELL_REGISTER, + "RRC_CONNECTION_OUT_OF_SERVICE_DURING_CELL_REGISTER"); + sFailCauseMap.put(RRC_CONNECTION_ABORT_REQUEST, "RRC_CONNECTION_ABORT_REQUEST"); + sFailCauseMap.put(RRC_CONNECTION_SYSTEM_INFORMATION_BLOCK_READ_ERROR, + "RRC_CONNECTION_SYSTEM_INFORMATION_BLOCK_READ_ERROR"); + sFailCauseMap.put(NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH, + "NETWORK_INITIATED_DETACH_WITH_AUTO_REATTACH"); + sFailCauseMap.put(NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH, + "NETWORK_INITIATED_DETACH_NO_AUTO_REATTACH"); + sFailCauseMap.put(ESM_PROCEDURE_TIME_OUT, "ESM_PROCEDURE_TIME_OUT"); + sFailCauseMap.put(INVALID_CONNECTION_ID, "INVALID_CONNECTION_ID"); + sFailCauseMap.put(MAXIMIUM_NSAPIS_EXCEEDED, "MAXIMIUM_NSAPIS_EXCEEDED"); + sFailCauseMap.put(INVALID_PRIMARY_NSAPI, "INVALID_PRIMARY_NSAPI"); + sFailCauseMap.put(CANNOT_ENCODE_OTA_MESSAGE, "CANNOT_ENCODE_OTA_MESSAGE"); + sFailCauseMap.put(RADIO_ACCESS_BEARER_SETUP_FAILURE, "RADIO_ACCESS_BEARER_SETUP_FAILURE"); + sFailCauseMap.put(PDP_ESTABLISH_TIMEOUT_EXPIRED, "PDP_ESTABLISH_TIMEOUT_EXPIRED"); + sFailCauseMap.put(PDP_MODIFY_TIMEOUT_EXPIRED, "PDP_MODIFY_TIMEOUT_EXPIRED"); + sFailCauseMap.put(PDP_INACTIVE_TIMEOUT_EXPIRED, "PDP_INACTIVE_TIMEOUT_EXPIRED"); + sFailCauseMap.put(PDP_LOWERLAYER_ERROR, "PDP_LOWERLAYER_ERROR"); + sFailCauseMap.put(PDP_MODIFY_COLLISION, "PDP_MODIFY_COLLISION"); + sFailCauseMap.put(MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED, + "MAXINUM_SIZE_OF_L2_MESSAGE_EXCEEDED"); + sFailCauseMap.put(NAS_REQUEST_REJECTED_BY_NETWORK, "NAS_REQUEST_REJECTED_BY_NETWORK"); + sFailCauseMap.put(RRC_CONNECTION_INVALID_REQUEST, "RRC_CONNECTION_INVALID_REQUEST"); + sFailCauseMap.put(RRC_CONNECTION_TRACKING_AREA_ID_CHANGED, + "RRC_CONNECTION_TRACKING_AREA_ID_CHANGED"); + sFailCauseMap.put(RRC_CONNECTION_RF_UNAVAILABLE, "RRC_CONNECTION_RF_UNAVAILABLE"); + sFailCauseMap.put(RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE, + "RRC_CONNECTION_ABORTED_DUE_TO_IRAT_CHANGE"); + sFailCauseMap.put(RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE, + "RRC_CONNECTION_RELEASED_SECURITY_NOT_ACTIVE"); + sFailCauseMap.put(RRC_CONNECTION_ABORTED_AFTER_HANDOVER, + "RRC_CONNECTION_ABORTED_AFTER_HANDOVER"); + sFailCauseMap.put(RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE, + "RRC_CONNECTION_ABORTED_AFTER_IRAT_CELL_CHANGE"); + sFailCauseMap.put(RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE, + "RRC_CONNECTION_ABORTED_DURING_IRAT_CELL_CHANGE"); + sFailCauseMap.put(IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER, + "IMSI_UNKNOWN_IN_HOME_SUBSCRIBER_SERVER"); + sFailCauseMap.put(IMEI_NOT_ACCEPTED, "IMEI_NOT_ACCEPTED"); + sFailCauseMap.put(EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED, + "EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED"); + sFailCauseMap.put(EPS_SERVICES_NOT_ALLOWED_IN_PLMN, "EPS_SERVICES_NOT_ALLOWED_IN_PLMN"); + sFailCauseMap.put(MSC_TEMPORARILY_NOT_REACHABLE, "MSC_TEMPORARILY_NOT_REACHABLE"); + sFailCauseMap.put(CS_DOMAIN_NOT_AVAILABLE, "CS_DOMAIN_NOT_AVAILABLE"); + sFailCauseMap.put(ESM_FAILURE, "ESM_FAILURE"); + sFailCauseMap.put(MAC_FAILURE, "MAC_FAILURE"); + sFailCauseMap.put(SYNCHRONIZATION_FAILURE, "SYNCHRONIZATION_FAILURE"); + sFailCauseMap.put(UE_SECURITY_CAPABILITIES_MISMATCH, "UE_SECURITY_CAPABILITIES_MISMATCH"); + sFailCauseMap.put(SECURITY_MODE_REJECTED, "SECURITY_MODE_REJECTED"); + sFailCauseMap.put(UNACCEPTABLE_NON_EPS_AUTHENTICATION, + "UNACCEPTABLE_NON_EPS_AUTHENTICATION"); + sFailCauseMap.put(CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED, + "CS_FALLBACK_CALL_ESTABLISHMENT_NOT_ALLOWED"); + sFailCauseMap.put(NO_EPS_BEARER_CONTEXT_ACTIVATED, "NO_EPS_BEARER_CONTEXT_ACTIVATED"); + sFailCauseMap.put(INVALID_EMM_STATE, "INVALID_EMM_STATE"); + sFailCauseMap.put(NAS_LAYER_FAILURE, "NAS_LAYER_FAILURE"); + sFailCauseMap.put(MULTIPLE_PDP_CALL_NOT_ALLOWED, "MULTIPLE_PDP_CALL_NOT_ALLOWED"); + sFailCauseMap.put(EMBMS_NOT_ENABLED, "EMBMS_NOT_ENABLED"); + sFailCauseMap.put(IRAT_HANDOVER_FAILED, "IRAT_HANDOVER_FAILED"); + sFailCauseMap.put(EMBMS_REGULAR_DEACTIVATION, "EMBMS_REGULAR_DEACTIVATION"); + sFailCauseMap.put(TEST_LOOPBACK_REGULAR_DEACTIVATION, "TEST_LOOPBACK_REGULAR_DEACTIVATION"); + sFailCauseMap.put(LOWER_LAYER_REGISTRATION_FAILURE, "LOWER_LAYER_REGISTRATION_FAILURE"); + sFailCauseMap.put(DATA_PLAN_EXPIRED, "DATA_PLAN_EXPIRED"); + sFailCauseMap.put(UMTS_HANDOVER_TO_IWLAN, "UMTS_HANDOVER_TO_IWLAN"); + sFailCauseMap.put(EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY, + "EVDO_CONNECTION_DENY_BY_GENERAL_OR_NETWORK_BUSY"); + sFailCauseMap.put(EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE, + "EVDO_CONNECTION_DENY_BY_BILLING_OR_AUTHENTICATION_FAILURE"); + sFailCauseMap.put(EVDO_HDR_CHANGED, "EVDO_HDR_CHANGED"); + sFailCauseMap.put(EVDO_HDR_EXITED, "EVDO_HDR_EXITED"); + sFailCauseMap.put(EVDO_HDR_NO_SESSION, "EVDO_HDR_NO_SESSION"); + sFailCauseMap.put(EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL, + "EVDO_USING_GPS_FIX_INSTEAD_OF_HDR_CALL"); + sFailCauseMap.put(EVDO_HDR_CONNECTION_SETUP_TIMEOUT, "EVDO_HDR_CONNECTION_SETUP_TIMEOUT"); + sFailCauseMap.put(FAILED_TO_ACQUIRE_COLOCATED_HDR, "FAILED_TO_ACQUIRE_COLOCATED_HDR"); + sFailCauseMap.put(OTASP_COMMIT_IN_PROGRESS, "OTASP_COMMIT_IN_PROGRESS"); + sFailCauseMap.put(NO_HYBRID_HDR_SERVICE, "NO_HYBRID_HDR_SERVICE"); + sFailCauseMap.put(HDR_NO_LOCK_GRANTED, "HDR_NO_LOCK_GRANTED"); + sFailCauseMap.put(DBM_OR_SMS_IN_PROGRESS, "DBM_OR_SMS_IN_PROGRESS"); + sFailCauseMap.put(HDR_FADE, "HDR_FADE"); + sFailCauseMap.put(HDR_ACCESS_FAILURE, "HDR_ACCESS_FAILURE"); + sFailCauseMap.put(UNSUPPORTED_1X_PREV, "UNSUPPORTED_1X_PREV"); + sFailCauseMap.put(LOCAL_END, "LOCAL_END"); + sFailCauseMap.put(NO_SERVICE, "NO_SERVICE"); + sFailCauseMap.put(FADE, "FADE"); + sFailCauseMap.put(NORMAL_RELEASE, "NORMAL_RELEASE"); + sFailCauseMap.put(ACCESS_ATTEMPT_ALREADY_IN_PROGRESS, "ACCESS_ATTEMPT_ALREADY_IN_PROGRESS"); + sFailCauseMap.put(REDIRECTION_OR_HANDOFF_IN_PROGRESS, "REDIRECTION_OR_HANDOFF_IN_PROGRESS"); + sFailCauseMap.put(EMERGENCY_MODE, "EMERGENCY_MODE"); + sFailCauseMap.put(PHONE_IN_USE, "PHONE_IN_USE"); + sFailCauseMap.put(INVALID_MODE, "INVALID_MODE"); + sFailCauseMap.put(INVALID_SIM_STATE, "INVALID_SIM_STATE"); + sFailCauseMap.put(NO_COLLOCATED_HDR, "NO_COLLOCATED_HDR"); + sFailCauseMap.put(UE_IS_ENTERING_POWERSAVE_MODE, "UE_IS_ENTERING_POWERSAVE_MODE"); + sFailCauseMap.put(DUAL_SWITCH, "DUAL_SWITCH"); + sFailCauseMap.put(PPP_TIMEOUT, "PPP_TIMEOUT"); + sFailCauseMap.put(PPP_AUTH_FAILURE, "PPP_AUTH_FAILURE"); + sFailCauseMap.put(PPP_OPTION_MISMATCH, "PPP_OPTION_MISMATCH"); + sFailCauseMap.put(PPP_PAP_FAILURE, "PPP_PAP_FAILURE"); + sFailCauseMap.put(PPP_CHAP_FAILURE, "PPP_CHAP_FAILURE"); + sFailCauseMap.put(PPP_CLOSE_IN_PROGRESS, "PPP_CLOSE_IN_PROGRESS"); + sFailCauseMap.put(LIMITED_TO_IPV4, "LIMITED_TO_IPV4"); + sFailCauseMap.put(LIMITED_TO_IPV6, "LIMITED_TO_IPV6"); + sFailCauseMap.put(VSNCP_TIMEOUT, "VSNCP_TIMEOUT"); + sFailCauseMap.put(VSNCP_GEN_ERROR, "VSNCP_GEN_ERROR"); + sFailCauseMap.put(VSNCP_APN_UNATHORIZED, "VSNCP_APN_UNATHORIZED"); + sFailCauseMap.put(VSNCP_PDN_LIMIT_EXCEEDED, "VSNCP_PDN_LIMIT_EXCEEDED"); + sFailCauseMap.put(VSNCP_NO_PDN_GATEWAY_ADDRESS, "VSNCP_NO_PDN_GATEWAY_ADDRESS"); + sFailCauseMap.put(VSNCP_PDN_GATEWAY_UNREACHABLE, "VSNCP_PDN_GATEWAY_UNREACHABLE"); + sFailCauseMap.put(VSNCP_PDN_GATEWAY_REJECT, "VSNCP_PDN_GATEWAY_REJECT"); + sFailCauseMap.put(VSNCP_INSUFFICIENT_PARAMETERS, "VSNCP_INSUFFICIENT_PARAMETERS"); + sFailCauseMap.put(VSNCP_RESOURCE_UNAVAILABLE, "VSNCP_RESOURCE_UNAVAILABLE"); + sFailCauseMap.put(VSNCP_ADMINISTRATIVELY_PROHIBITED, "VSNCP_ADMINISTRATIVELY_PROHIBITED"); + sFailCauseMap.put(VSNCP_PDN_ID_IN_USE, "VSNCP_PDN_ID_IN_USE"); + sFailCauseMap.put(VSNCP_SUBSCRIBER_LIMITATION, "VSNCP_SUBSCRIBER_LIMITATION"); + sFailCauseMap.put(VSNCP_PDN_EXISTS_FOR_THIS_APN, "VSNCP_PDN_EXISTS_FOR_THIS_APN"); + sFailCauseMap.put(VSNCP_RECONNECT_NOT_ALLOWED, "VSNCP_RECONNECT_NOT_ALLOWED"); + sFailCauseMap.put(IPV6_PREFIX_UNAVAILABLE, "IPV6_PREFIX_UNAVAILABLE"); + sFailCauseMap.put(HANDOFF_PREFERENCE_CHANGED, "HANDOFF_PREFERENCE_CHANGED"); sFailCauseMap.put(OEM_DCFAILCAUSE_1, "OEM_DCFAILCAUSE_1"); sFailCauseMap.put(OEM_DCFAILCAUSE_2, "OEM_DCFAILCAUSE_2"); sFailCauseMap.put(OEM_DCFAILCAUSE_3, "OEM_DCFAILCAUSE_3"); diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java index 8d148c36f3e7..0e695309fce2 100644 --- a/telephony/java/android/telephony/data/ApnSetting.java +++ b/telephony/java/android/telephony/data/ApnSetting.java @@ -140,15 +140,19 @@ public class ApnSetting implements Parcelable { @Retention(RetentionPolicy.SOURCE) public @interface AuthType {} - // Possible values for protocol. - /** Protocol type for IP. */ + // Possible values for protocol which is defined in TS 27.007 section 10.1.1. + /** Internet protocol. */ public static final int PROTOCOL_IP = 0; - /** Protocol type for IPV6. */ + /** Internet protocol, version 6. */ public static final int PROTOCOL_IPV6 = 1; - /** Protocol type for IPV4V6. */ + /** Virtual PDP type introduced to handle dual IP stack UE capability. */ public static final int PROTOCOL_IPV4V6 = 2; - /** Protocol type for PPP. */ + /** Point to point protocol. */ public static final int PROTOCOL_PPP = 3; + /** Transfer of Non-IP data to external packet data network. */ + public static final int PROTOCOL_NON_IP = 4; + /** Transfer of Unstructured data to the Data Network via N6. */ + public static final int PROTOCOL_UNSTRUCTURED = 5; /** @hide */ @IntDef(prefix = { "PROTOCOL_" }, value = { @@ -156,6 +160,8 @@ public class ApnSetting implements Parcelable { PROTOCOL_IPV6, PROTOCOL_IPV4V6, PROTOCOL_PPP, + PROTOCOL_NON_IP, + PROTOCOL_UNSTRUCTURED, }) @Retention(RetentionPolicy.SOURCE) public @interface ProtocolType {} @@ -217,11 +223,15 @@ public class ApnSetting implements Parcelable { PROTOCOL_STRING_MAP.put("IPV6", PROTOCOL_IPV6); PROTOCOL_STRING_MAP.put("IPV4V6", PROTOCOL_IPV4V6); PROTOCOL_STRING_MAP.put("PPP", PROTOCOL_PPP); + PROTOCOL_STRING_MAP.put("NON-IP", PROTOCOL_NON_IP); + PROTOCOL_STRING_MAP.put("UNSTRUCTURED", PROTOCOL_UNSTRUCTURED); PROTOCOL_INT_MAP = new ArrayMap<Integer, String>(); PROTOCOL_INT_MAP.put(PROTOCOL_IP, "IP"); PROTOCOL_INT_MAP.put(PROTOCOL_IPV6, "IPV6"); PROTOCOL_INT_MAP.put(PROTOCOL_IPV4V6, "IPV4V6"); PROTOCOL_INT_MAP.put(PROTOCOL_PPP, "PPP"); + PROTOCOL_INT_MAP.put(PROTOCOL_NON_IP, "NON-IP"); + PROTOCOL_INT_MAP.put(PROTOCOL_UNSTRUCTURED, "UNSTRUCTURED"); MVNO_TYPE_STRING_MAP = new ArrayMap<String, Integer>(); MVNO_TYPE_STRING_MAP.put("spn", MVNO_TYPE_SPN); diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java index 25f51333350b..294c79ba57a2 100644 --- a/telephony/java/android/telephony/data/DataCallResponse.java +++ b/telephony/java/android/telephony/data/DataCallResponse.java @@ -52,8 +52,7 @@ public final class DataCallResponse implements Parcelable { * @param status Data call fail cause. 0 indicates no error. * @param suggestedRetryTime The suggested data retry time in milliseconds. * @param cid The unique id of the data connection. - * @param active Data connection active status. 0 = inactive, 1 = active/physical link down, - * 2 = active/physical link up. + * @param active Data connection active status. 0 = inactive, 1 = dormant, 2 = active. * @param type The connection protocol, should be one of the PDP_type values in TS 27.007 * section 10.1.1. For example, "IP", "IPV6", "IPV4V6", or "PPP". * @param ifname The network interface name. @@ -124,7 +123,7 @@ public final class DataCallResponse implements Parcelable { public int getCallId() { return mCid; } /** - * @return 0 = inactive, 1 = active/physical link down, 2 = active/physical link up. + * @return 0 = inactive, 1 = dormant, 2 = active. */ public int getActive() { return mActive; } diff --git a/telephony/java/android/telephony/euicc/EuiccManager.java b/telephony/java/android/telephony/euicc/EuiccManager.java index 95dfffd30e72..a5c0442948ac 100644 --- a/telephony/java/android/telephony/euicc/EuiccManager.java +++ b/telephony/java/android/telephony/euicc/EuiccManager.java @@ -291,7 +291,7 @@ public class EuiccManager { public boolean isEnabled() { // In the future, this may reach out to IEuiccController (if non-null) to check any dynamic // restrictions. - return getIEuiccController() != null; + return getIEuiccController() != null && mCardId != TelephonyManager.INVALID_CARD_ID; } /** diff --git a/tests/net/Android.mk b/tests/net/Android.mk index f6f35fdadcd1..685067377166 100644 --- a/tests/net/Android.mk +++ b/tests/net/Android.mk @@ -54,6 +54,7 @@ LOCAL_JNI_SHARED_LIBRARIES := \ libnativehelper \ libpackagelistparser \ libpcre2 \ + libprocessgroup \ libselinux \ libui \ libutils \ diff --git a/tests/net/java/android/net/ip/IpClientTest.java b/tests/net/java/android/net/ip/IpClientTest.java index a2dcfef50a49..7a83757aa262 100644 --- a/tests/net/java/android/net/ip/IpClientTest.java +++ b/tests/net/java/android/net/ip/IpClientTest.java @@ -122,13 +122,14 @@ public class IpClientTest { private IpClient makeIpClient(String ifname) throws Exception { setTestInterfaceParams(ifname); final IpClient ipc = new IpClient(mContext, ifname, mCb, mDependecies); - verify(mNMService, timeout(TEST_TIMEOUT_MS).times(1)).disableIpv6(ifname); - verify(mNMService, timeout(TEST_TIMEOUT_MS).times(1)).clearInterfaceAddresses(ifname); + verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(ifname, false); + verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(ifname); ArgumentCaptor<BaseNetworkObserver> arg = ArgumentCaptor.forClass(BaseNetworkObserver.class); verify(mNMService, times(1)).registerObserver(arg.capture()); mObserver = arg.getValue(); reset(mNMService); + reset(mNetd); // Verify IpClient doesn't call onLinkPropertiesChange() when it starts. verify(mCb, never()).onLinkPropertiesChange(any()); reset(mCb); @@ -200,8 +201,8 @@ public class IpClientTest { verify(mCb, never()).onProvisioningFailure(any()); ipc.shutdown(); - verify(mNMService, timeout(TEST_TIMEOUT_MS).times(1)).disableIpv6(iface); - verify(mNMService, timeout(TEST_TIMEOUT_MS).times(1)).clearInterfaceAddresses(iface); + verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(iface, false); + verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(iface); verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)) .onLinkPropertiesChange(eq(makeEmptyLinkProperties(iface))); } @@ -251,8 +252,8 @@ public class IpClientTest { verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)).onProvisioningSuccess(eq(want)); ipc.shutdown(); - verify(mNMService, timeout(TEST_TIMEOUT_MS).times(1)).disableIpv6(iface); - verify(mNMService, timeout(TEST_TIMEOUT_MS).times(1)).clearInterfaceAddresses(iface); + verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceSetEnableIPv6(iface, false); + verify(mNetd, timeout(TEST_TIMEOUT_MS).times(1)).interfaceClearAddrs(iface); verify(mCb, timeout(TEST_TIMEOUT_MS).times(1)) .onLinkPropertiesChange(eq(makeEmptyLinkProperties(iface))); } diff --git a/tests/net/java/android/net/ip/IpServerTest.java b/tests/net/java/android/net/ip/IpServerTest.java index c3162af1868d..80aac047a723 100644 --- a/tests/net/java/android/net/ip/IpServerTest.java +++ b/tests/net/java/android/net/ip/IpServerTest.java @@ -33,6 +33,7 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.argThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; @@ -47,6 +48,7 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; +import android.net.INetd; import android.net.INetworkStatsService; import android.net.InterfaceConfiguration; import android.net.IpPrefix; @@ -92,6 +94,7 @@ public class IpServerTest { private static final int MAKE_DHCPSERVER_TIMEOUT_MS = 1000; @Mock private INetworkManagementService mNMService; + @Mock private INetd mNetd; @Mock private INetworkStatsService mStatsService; @Mock private IpServer.Callback mCallback; @Mock private InterfaceConfiguration mInterfaceConfiguration; @@ -112,16 +115,6 @@ public class IpServerTest { } private void initStateMachine(int interfaceType, boolean usingLegacyDhcp) throws Exception { - mIpServer = new IpServer( - IFACE_NAME, mLooper.getLooper(), interfaceType, mSharedLog, - mNMService, mStatsService, mCallback, usingLegacyDhcp, mDependencies); - mIpServer.start(); - // Starting the state machine always puts us in a consistent state and notifies - // the rest of the world that we've changed from an unknown to available state. - mLooper.dispatchAll(); - reset(mNMService, mStatsService, mCallback); - when(mNMService.getInterfaceConfig(IFACE_NAME)).thenReturn(mInterfaceConfiguration); - doAnswer(inv -> { final IDhcpServerCallbacks cb = inv.getArgument(2); new Thread(() -> { @@ -135,6 +128,17 @@ public class IpServerTest { }).when(mDependencies).makeDhcpServer(any(), mDhcpParamsCaptor.capture(), any()); when(mDependencies.getRouterAdvertisementDaemon(any())).thenReturn(mRaDaemon); when(mDependencies.getInterfaceParams(IFACE_NAME)).thenReturn(TEST_IFACE_PARAMS); + when(mDependencies.getNetdService()).thenReturn(mNetd); + + mIpServer = new IpServer( + IFACE_NAME, mLooper.getLooper(), interfaceType, mSharedLog, + mNMService, mStatsService, mCallback, usingLegacyDhcp, mDependencies); + mIpServer.start(); + // Starting the state machine always puts us in a consistent state and notifies + // the rest of the world that we've changed from an unknown to available state. + mLooper.dispatchAll(); + reset(mNMService, mStatsService, mCallback); + when(mNMService.getInterfaceConfig(IFACE_NAME)).thenReturn(mInterfaceConfiguration); when(mRaDaemon.start()).thenReturn(true); } @@ -223,9 +227,9 @@ public class IpServerTest { initTetheredStateMachine(TETHERING_BLUETOOTH, null); dispatchCommand(IpServer.CMD_TETHER_UNREQUESTED); - InOrder inOrder = inOrder(mNMService, mStatsService, mCallback); + InOrder inOrder = inOrder(mNMService, mNetd, mStatsService, mCallback); inOrder.verify(mNMService).untetherInterface(IFACE_NAME); - inOrder.verify(mNMService).setInterfaceConfig(eq(IFACE_NAME), any()); + inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg -> IFACE_NAME.equals(cfg.ifName))); inOrder.verify(mCallback).updateInterfaceState( mIpServer, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR); inOrder.verify(mCallback).updateLinkProperties( @@ -318,12 +322,12 @@ public class IpServerTest { initTetheredStateMachine(TETHERING_BLUETOOTH, UPSTREAM_IFACE); dispatchCommand(IpServer.CMD_TETHER_UNREQUESTED); - InOrder inOrder = inOrder(mNMService, mStatsService, mCallback); + InOrder inOrder = inOrder(mNMService, mNetd, mStatsService, mCallback); inOrder.verify(mStatsService).forceUpdate(); inOrder.verify(mNMService).stopInterfaceForwarding(IFACE_NAME, UPSTREAM_IFACE); inOrder.verify(mNMService).disableNat(IFACE_NAME, UPSTREAM_IFACE); inOrder.verify(mNMService).untetherInterface(IFACE_NAME); - inOrder.verify(mNMService).setInterfaceConfig(eq(IFACE_NAME), any()); + inOrder.verify(mNetd).interfaceSetCfg(argThat(cfg -> IFACE_NAME.equals(cfg.ifName))); inOrder.verify(mCallback).updateInterfaceState( mIpServer, STATE_AVAILABLE, TETHER_ERROR_NO_ERROR); inOrder.verify(mCallback).updateLinkProperties( diff --git a/tests/net/java/android/net/shared/LinkPropertiesParcelableUtilTest.java b/tests/net/java/android/net/shared/LinkPropertiesParcelableUtilTest.java index 6f711c0b5743..b6d01dbc1cac 100644 --- a/tests/net/java/android/net/shared/LinkPropertiesParcelableUtilTest.java +++ b/tests/net/java/android/net/shared/LinkPropertiesParcelableUtilTest.java @@ -48,61 +48,52 @@ public class LinkPropertiesParcelableUtilTest { private LinkProperties mLinkProperties; private static final String TEST_LINKPROPS_IFACE = "TEST_IFACE"; - private static final String TEST_STACKED_LINK_1_IFACE = "TEST_STACKED_IFACE_1"; - private static final String TEST_STACKED_LINK_2_IFACE = "TEST_STACKED_IFACE_2"; @Before public void setUp() { - mLinkProperties = makeLinkProperties(TEST_LINKPROPS_IFACE); - mLinkProperties.addStackedLink(makeLinkProperties(TEST_STACKED_LINK_1_IFACE)); - mLinkProperties.addStackedLink(makeLinkProperties(TEST_STACKED_LINK_2_IFACE)); - } - - private static LinkProperties makeLinkProperties(String iface) { - final LinkProperties lp = new LinkProperties(); - lp.setInterfaceName(iface); - lp.setLinkAddresses(Arrays.asList( + mLinkProperties = new LinkProperties(); + mLinkProperties.setInterfaceName(TEST_LINKPROPS_IFACE); + mLinkProperties.setLinkAddresses(Arrays.asList( new LinkAddress(InetAddresses.parseNumericAddress("192.168.0.42"), 16), new LinkAddress(InetAddresses.parseNumericAddress("2001:db8::7"), 42))); - lp.setDnsServers(Arrays.asList( + mLinkProperties.setDnsServers(Arrays.asList( InetAddresses.parseNumericAddress("2001:db8::42"), InetAddresses.parseNumericAddress("192.168.1.1") )); - lp.setValidatedPrivateDnsServers(Arrays.asList( + mLinkProperties.setValidatedPrivateDnsServers(Arrays.asList( InetAddresses.parseNumericAddress("2001:db8::43"), InetAddresses.parseNumericAddress("192.168.42.43") )); - lp.setPcscfServers(Arrays.asList( + mLinkProperties.setPcscfServers(Arrays.asList( InetAddresses.parseNumericAddress("2001:db8::47"), InetAddresses.parseNumericAddress("192.168.42.47") )); - lp.setUsePrivateDns(true); - lp.setPrivateDnsServerName("test.example.com"); - lp.setDomains("test1.example.com,test2.example.com"); - lp.addRoute(new RouteInfo( + mLinkProperties.setUsePrivateDns(true); + mLinkProperties.setPrivateDnsServerName("test.example.com"); + mLinkProperties.setDomains("test1.example.com,test2.example.com"); + mLinkProperties.addRoute(new RouteInfo( new IpPrefix(InetAddresses.parseNumericAddress("2001:db8::44"), 45), InetAddresses.parseNumericAddress("2001:db8::45"), - iface, + TEST_LINKPROPS_IFACE, RouteInfo.RTN_UNICAST )); - lp.addRoute(new RouteInfo( + mLinkProperties.addRoute(new RouteInfo( new IpPrefix(InetAddresses.parseNumericAddress("192.168.44.45"), 16), InetAddresses.parseNumericAddress("192.168.45.1"), - iface, + TEST_LINKPROPS_IFACE, RouteInfo.RTN_THROW )); - lp.setHttpProxy(new ProxyInfo("test3.example.com", 8000, + mLinkProperties.setHttpProxy(new ProxyInfo("test3.example.com", 8000, "excl1.example.com,excl2.example.com")); - lp.setMtu(5000); - lp.setTcpBufferSizes("1,2,3,4,5,6"); - lp.setNat64Prefix(new IpPrefix(InetAddresses.parseNumericAddress("2001:db8::48"), 96)); + mLinkProperties.setMtu(5000); + mLinkProperties.setTcpBufferSizes("1,2,3,4,5,6"); + mLinkProperties.setNat64Prefix( + new IpPrefix(InetAddresses.parseNumericAddress("2001:db8::48"), 96)); // Verify that this test does not miss any new field added later. // If any added field is not included in LinkProperties#equals, assertLinkPropertiesEquals // must also be updated. assertFieldCountEquals(14, LinkProperties.class); - - return lp; } @Test @@ -186,7 +177,7 @@ public class LinkPropertiesParcelableUtilTest { private static void assertLinkPropertiesEquals(LinkProperties expected, LinkProperties actual) { assertEquals(expected, actual); - // LinkProperties equals() does not include stacked links - assertEquals(expected.getStackedLinks(), actual.getStackedLinks()); + // Equality on stacked links is not tested as they should not be passed to processes using + // LinkPropertiesParcelable. } } diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java index 1ea83c2bbb6b..b6356076db60 100644 --- a/tests/net/java/com/android/server/connectivity/TetheringTest.java +++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java @@ -803,13 +803,14 @@ public class TetheringTest { sendWifiApStateChanged(WIFI_AP_STATE_ENABLED, TEST_WLAN_IFNAME, IFACE_IP_MODE_TETHERED); mLooper.dispatchAll(); - // We verify get/set called thrice here: once for setup and twice during - // teardown because all events happen over the course of the single + // We verify get/set called thrice here: twice for setup (on NMService) and once during + // teardown (on Netd) because all events happen over the course of the single // dispatchAll() above. Note that once the IpServer IPv4 address config // code is refactored the two calls during shutdown will revert to one. verify(mNMService, times(2)).getInterfaceConfig(TEST_WLAN_IFNAME); - verify(mNMService, times(3)) + verify(mNMService, times(2)) .setInterfaceConfig(eq(TEST_WLAN_IFNAME), any(InterfaceConfiguration.class)); + verify(mNetd, times(1)).interfaceSetCfg(argThat(p -> TEST_WLAN_IFNAME.equals(p.ifName))); verify(mNMService, times(1)).tetherInterface(TEST_WLAN_IFNAME); verify(mWifiManager).updateInterfaceIpState( TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED); diff --git a/tests/net/java/com/android/server/connectivity/VpnTest.java b/tests/net/java/com/android/server/connectivity/VpnTest.java index 9bf758797ed2..0b74d878f069 100644 --- a/tests/net/java/com/android/server/connectivity/VpnTest.java +++ b/tests/net/java/com/android/server/connectivity/VpnTest.java @@ -57,7 +57,6 @@ import android.content.pm.ServiceInfo; import android.content.pm.UserInfo; import android.content.res.Resources; import android.net.ConnectivityManager; -import android.net.IConnectivityManager; import android.net.IpPrefix; import android.net.LinkProperties; import android.net.Network; @@ -97,7 +96,6 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; -import java.util.stream.Collectors; import java.util.stream.Stream; /** @@ -240,6 +238,30 @@ public class VpnTest { } @Test + public void testGetAlwaysAndOnGetLockDown() throws Exception { + final Vpn vpn = createVpn(primaryUser.id); + + // Default state. + assertFalse(vpn.getAlwaysOn()); + assertFalse(vpn.getLockdown()); + + // Set always-on without lockdown. + assertTrue(vpn.setAlwaysOnPackage(PKGS[1], false)); + assertTrue(vpn.getAlwaysOn()); + assertFalse(vpn.getLockdown()); + + // Set always-on with lockdown. + assertTrue(vpn.setAlwaysOnPackage(PKGS[1], true)); + assertTrue(vpn.getAlwaysOn()); + assertTrue(vpn.getLockdown()); + + // Remove always-on configuration. + assertTrue(vpn.setAlwaysOnPackage(null, false)); + assertFalse(vpn.getAlwaysOn()); + assertFalse(vpn.getLockdown()); + } + + @Test public void testLockdownChangingPackage() throws Exception { final Vpn vpn = createVpn(primaryUser.id); final UidRange user = UidRange.createForUser(primaryUser.id); diff --git a/tools/apilint/apilint.py b/tools/apilint/apilint.py index 70a47cf42755..75c3eba7765b 100644 --- a/tools/apilint/apilint.py +++ b/tools/apilint/apilint.py @@ -26,7 +26,7 @@ $ git blame api/current.txt -t -e > /tmp/currentblame.txt $ apilint.py /tmp/currentblame.txt previous.txt --no-color """ -import re, sys, collections, traceback, argparse +import re, sys, collections, traceback, argparse, itertools BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8) @@ -50,38 +50,37 @@ def format(fg=None, bg=None, bright=False, bold=False, dim=False, reset=False): return "\033[%sm" % (";".join(codes)) -def ident(raw): - """Strips superficial signature changes, giving us a strong key that - can be used to identify members across API levels.""" - raw = raw.replace(" deprecated ", " ") - raw = raw.replace(" synchronized ", " ") - raw = raw.replace(" final ", " ") - raw = re.sub("<.+?>", "", raw) - if " throws " in raw: - raw = raw[:raw.index(" throws ")] - return raw - - class Field(): - def __init__(self, clazz, line, raw, blame): + def __init__(self, clazz, line, raw, blame, sig_format = 1): self.clazz = clazz self.line = line self.raw = raw.strip(" {;") self.blame = blame - raw = raw.split() - self.split = list(raw) + if sig_format == 2: + V2LineParser(raw).parse_into_field(self) + elif sig_format == 1: + # drop generics for now; may need multiple passes + raw = re.sub("<[^<]+?>", "", raw) + raw = re.sub("<[^<]+?>", "", raw) - for r in ["field", "volatile", "transient", "public", "protected", "static", "final", "deprecated"]: - while r in raw: raw.remove(r) + raw = raw.split() + self.split = list(raw) - self.typ = raw[0] - self.name = raw[1].strip(";") - if len(raw) >= 4 and raw[2] == "=": - self.value = raw[3].strip(';"') - else: - self.value = None - self.ident = ident(self.raw) + for r in ["field", "volatile", "transient", "public", "protected", "static", "final", "deprecated"]: + while r in raw: raw.remove(r) + + # ignore annotations for now + raw = [ r for r in raw if not r.startswith("@") ] + + self.typ = raw[0] + self.name = raw[1].strip(";") + if len(raw) >= 4 and raw[2] == "=": + self.value = raw[3].strip(';"') + else: + self.value = None + + self.ident = "-".join((self.typ, self.name, self.value or "")) def __hash__(self): return hash(self.raw) @@ -89,34 +88,55 @@ class Field(): def __repr__(self): return self.raw - class Method(): - def __init__(self, clazz, line, raw, blame): + def __init__(self, clazz, line, raw, blame, sig_format = 1): self.clazz = clazz self.line = line self.raw = raw.strip(" {;") self.blame = blame - # drop generics for now - raw = re.sub("<.+?>", "", raw) - - raw = re.split("[\s(),;]+", raw) - for r in ["", ";"]: - while r in raw: raw.remove(r) - self.split = list(raw) + if sig_format == 2: + V2LineParser(raw).parse_into_method(self) + elif sig_format == 1: + # drop generics for now; may need multiple passes + raw = re.sub("<[^<]+?>", "", raw) + raw = re.sub("<[^<]+?>", "", raw) + + # handle each clause differently + raw_prefix, raw_args, _, raw_throws = re.match(r"(.*?)\((.*?)\)( throws )?(.*?);$", raw).groups() + + # parse prefixes + raw = re.split("[\s]+", raw_prefix) + for r in ["", ";"]: + while r in raw: raw.remove(r) + self.split = list(raw) + + for r in ["method", "public", "protected", "static", "final", "deprecated", "abstract", "default", "operator", "synchronized"]: + while r in raw: raw.remove(r) + + self.typ = raw[0] + self.name = raw[1] + + # parse args + self.args = [] + for arg in re.split(",\s*", raw_args): + arg = re.split("\s", arg) + # ignore annotations for now + arg = [ a for a in arg if not a.startswith("@") ] + if len(arg[0]) > 0: + self.args.append(arg[0]) + + # parse throws + self.throws = [] + for throw in re.split(",\s*", raw_throws): + self.throws.append(throw) + else: + raise ValueError("Unknown signature format: " + sig_format) - for r in ["method", "public", "protected", "static", "final", "deprecated", "abstract", "default"]: - while r in raw: raw.remove(r) + self.ident = "-".join((self.typ, self.name, "-".join(self.args))) - self.typ = raw[0] - self.name = raw[1] - self.args = [] - self.throws = [] - target = self.args - for r in raw[2:]: - if r == "throws": target = self.throws - else: target.append(r) - self.ident = ident(self.raw) + def sig_matches(self, typ, name, args): + return typ == self.typ and name == self.name and args == self.args def __hash__(self): return hash(self.raw) @@ -126,7 +146,7 @@ class Method(): class Class(): - def __init__(self, pkg, line, raw, blame): + def __init__(self, pkg, line, raw, blame, sig_format = 1): self.pkg = pkg self.line = line self.raw = raw.strip(" {;") @@ -135,27 +155,51 @@ class Class(): self.fields = [] self.methods = [] - raw = raw.split() - self.split = list(raw) - if "class" in raw: - self.fullname = raw[raw.index("class")+1] - elif "interface" in raw: - self.fullname = raw[raw.index("interface")+1] - else: - raise ValueError("Funky class type %s" % (self.raw)) + if sig_format == 2: + V2LineParser(raw).parse_into_class(self) + elif sig_format == 1: + # drop generics for now; may need multiple passes + raw = re.sub("<[^<]+?>", "", raw) + raw = re.sub("<[^<]+?>", "", raw) + + raw = raw.split() + self.split = list(raw) + if "class" in raw: + self.fullname = raw[raw.index("class")+1] + elif "interface" in raw: + self.fullname = raw[raw.index("interface")+1] + elif "@interface" in raw: + self.fullname = raw[raw.index("@interface")+1] + else: + raise ValueError("Funky class type %s" % (self.raw)) - if "extends" in raw: - self.extends = raw[raw.index("extends")+1] - self.extends_path = self.extends.split(".") + if "extends" in raw: + self.extends = raw[raw.index("extends")+1] + else: + self.extends = None + + if "implements" in raw: + self.implements = raw[raw.index("implements")+1] + else: + self.implements = None else: - self.extends = None - self.extends_path = [] + raise ValueError("Unknown signature format: " + sig_format) self.fullname = self.pkg.name + "." + self.fullname self.fullname_path = self.fullname.split(".") + if self.extends is not None: + self.extends_path = self.extends.split(".") + else: + self.extends_path = [] + self.name = self.fullname[self.fullname.rindex(".")+1:] + def merge_from(self, other): + self.ctors.extend(other.ctors) + self.fields.extend(other.fields) + self.methods.extend(other.methods) + def __hash__(self): return hash((self.raw, tuple(self.ctors), tuple(self.fields), tuple(self.methods))) @@ -176,15 +220,386 @@ class Package(): def __repr__(self): return self.raw +class V2Tokenizer(object): + __slots__ = ["raw"] + + DELIMITER = re.compile(r'\s+|[()@<>;,={}/"!?]|\[\]|\.\.\.') + STRING_SPECIAL = re.compile(r'["\\]') + + def __init__(self, raw): + self.raw = raw + + def tokenize(self): + tokens = [] + current = 0 + raw = self.raw + length = len(raw) + + while current < length: + while current < length: + start = current + match = V2Tokenizer.DELIMITER.search(raw, start) + if match is not None: + match_start = match.start() + if match_start == current: + end = match.end() + else: + end = match_start + else: + end = length -def _parse_stream(f, clazz_cb=None): - line = 0 + token = raw[start:end] + current = end + + if token == "" or token[0] == " ": + continue + else: + break + + if token == "@": + if raw[start:start+11] == "@interface ": + current = start + 11 + tokens.append("@interface") + continue + elif token == '/': + if raw[start:start+2] == "//": + current = length + continue + elif token == '"': + current, string_token = self.tokenize_string(raw, length, current) + tokens.append(token + string_token) + continue + + tokens.append(token) + + return tokens + + def tokenize_string(self, raw, length, current): + start = current + end = length + while start < end: + match = V2Tokenizer.STRING_SPECIAL.search(raw, start) + if match: + if match.group() == '"': + end = match.end() + break + elif match.group() == '\\': + # ignore whatever is after the slash + start += 2 + else: + raise ValueError("Unexpected match: `%s`" % (match.group())) + else: + raise ValueError("Unexpected EOF tokenizing string: `%s`" % (raw[current - 1:],)) + + token = raw[current:end] + return end, token + +class V2LineParser(object): + __slots__ = ["tokenized", "current", "len"] + + FIELD_KINDS = ("field", "property", "enum_constant") + MODIFIERS = set("public protected internal private abstract default static final transient volatile synchronized native operator sealed strictfp infix inline suspend vararg".split()) + JAVA_LANG_TYPES = set("AbstractMethodError AbstractStringBuilder Appendable ArithmeticException ArrayIndexOutOfBoundsException ArrayStoreException AssertionError AutoCloseable Boolean BootstrapMethodError Byte Character CharSequence Class ClassCastException ClassCircularityError ClassFormatError ClassLoader ClassNotFoundException Cloneable CloneNotSupportedException Comparable Compiler Deprecated Double Enum EnumConstantNotPresentException Error Exception ExceptionInInitializerError Float FunctionalInterface IllegalAccessError IllegalAccessException IllegalArgumentException IllegalMonitorStateException IllegalStateException IllegalThreadStateException IncompatibleClassChangeError IndexOutOfBoundsException InheritableThreadLocal InstantiationError InstantiationException Integer InternalError InterruptedException Iterable LinkageError Long Math NegativeArraySizeException NoClassDefFoundError NoSuchFieldError NoSuchFieldException NoSuchMethodError NoSuchMethodException NullPointerException Number NumberFormatException Object OutOfMemoryError Override Package package-info.java Process ProcessBuilder ProcessEnvironment ProcessImpl Readable ReflectiveOperationException Runnable Runtime RuntimeException RuntimePermission SafeVarargs SecurityException SecurityManager Short StackOverflowError StackTraceElement StrictMath String StringBuffer StringBuilder StringIndexOutOfBoundsException SuppressWarnings System Thread ThreadDeath ThreadGroup ThreadLocal Throwable TypeNotPresentException UNIXProcess UnknownError UnsatisfiedLinkError UnsupportedClassVersionError UnsupportedOperationException VerifyError VirtualMachineError Void".split()) + + def __init__(self, raw): + self.tokenized = V2Tokenizer(raw).tokenize() + self.current = 0 + self.len = len(self.tokenized) + + def parse_into_method(self, method): + method.split = [] + kind = self.parse_one_of("ctor", "method") + method.split.append(kind) + annotations = self.parse_annotations() + method.split.extend(self.parse_modifiers()) + self.parse_matching_paren("<", ">") + if "@Deprecated" in annotations: + method.split.append("deprecated") + if kind == "ctor": + method.typ = "ctor" + else: + method.typ = self.parse_type() + method.split.append(method.typ) + method.name = self.parse_name() + method.split.append(method.name) + self.parse_token("(") + method.args = self.parse_args() + self.parse_token(")") + method.throws = self.parse_throws() + if "@interface" in method.clazz.split: + self.parse_annotation_default() + self.parse_token(";") + self.parse_eof() + + def parse_into_class(self, clazz): + clazz.split = [] + annotations = self.parse_annotations() + if "@Deprecated" in annotations: + clazz.split.append("deprecated") + clazz.split.extend(self.parse_modifiers()) + kind = self.parse_one_of("class", "interface", "@interface", "enum") + if kind == "enum": + # enums are implicitly final + clazz.split.append("final") + clazz.split.append(kind) + clazz.fullname = self.parse_name() + self.parse_matching_paren("<", ">") + extends = self.parse_extends() + clazz.extends = extends[0] if extends else None + implements = self.parse_implements() + clazz.implements = implements[0] if implements else None + # The checks assume that interfaces are always found in implements, which isn't true for + # subinterfaces. + if not implements and "interface" in clazz.split: + clazz.implements = clazz.extends + self.parse_token("{") + self.parse_eof() + + def parse_into_field(self, field): + kind = self.parse_one_of(*V2LineParser.FIELD_KINDS) + field.split = [kind] + annotations = self.parse_annotations() + if "@Deprecated" in annotations: + field.split.append("deprecated") + field.split.extend(self.parse_modifiers()) + field.typ = self.parse_type() + field.split.append(field.typ) + field.name = self.parse_name() + field.split.append(field.name) + if self.parse_if("="): + field.value = self.parse_value_stripped() + else: + field.value = None + + self.parse_token(";") + self.parse_eof() + + def lookahead(self): + return self.tokenized[self.current] + + def parse_one_of(self, *options): + found = self.lookahead() + if found not in options: + raise ValueError("Parsing failed, expected one of `%s` but found `%s` in %s" % (options, found, repr(self.tokenized))) + return self.parse_token() + + def parse_token(self, tok = None): + found = self.lookahead() + if tok is not None and found != tok: + raise ValueError("Parsing failed, expected `%s` but found `%s` in %s" % (tok, found, repr(self.tokenized))) + self.current += 1 + return found + + def eof(self): + return self.current == self.len + + def parse_eof(self): + if not self.eof(): + raise ValueError("Parsing failed, expected EOF, but %s has not been parsed in %s" % (self.tokenized[self.current:], self.tokenized)) + + def parse_if(self, tok): + if not self.eof() and self.lookahead() == tok: + self.parse_token() + return True + return False + + def parse_annotations(self): + ret = [] + while self.lookahead() == "@": + ret.append(self.parse_annotation()) + return ret + + def parse_annotation(self): + ret = self.parse_token("@") + self.parse_token() + self.parse_matching_paren("(", ")") + return ret + + def parse_matching_paren(self, open, close): + start = self.current + if not self.parse_if(open): + return + length = len(self.tokenized) + count = 1 + while count > 0: + if self.current == length: + raise ValueError("Unexpected EOF looking for closing paren: `%s`" % (self.tokenized[start:],)) + t = self.parse_token() + if t == open: + count += 1 + elif t == close: + count -= 1 + return self.tokenized[start:self.current] + + def parse_modifiers(self): + ret = [] + while self.lookahead() in V2LineParser.MODIFIERS: + ret.append(self.parse_token()) + return ret + + def parse_kotlin_nullability(self): + t = self.lookahead() + if t == "?" or t == "!": + return self.parse_token() + return None + + def parse_type(self): + self.parse_annotations() + type = self.parse_token() + if type[-1] == '.': + self.parse_annotations() + type += self.parse_token() + if type in V2LineParser.JAVA_LANG_TYPES: + type = "java.lang." + type + self.parse_matching_paren("<", ">") + while True: + t = self.lookahead() + if t == "@": + self.parse_annotation() + elif t == "[]": + type += self.parse_token() + elif self.parse_kotlin_nullability() is not None: + pass # discard nullability for now + else: + break + return type + + def parse_arg_type(self): + type = self.parse_type() + if self.parse_if("..."): + type += "..." + self.parse_kotlin_nullability() # discard nullability for now + return type + + def parse_name(self): + return self.parse_token() + + def parse_args(self): + args = [] + if self.lookahead() == ")": + return args + + while True: + args.append(self.parse_arg()) + if self.lookahead() == ")": + return args + self.parse_token(",") + + def parse_arg(self): + self.parse_if("vararg") # kotlin vararg + self.parse_annotations() + type = self.parse_arg_type() + l = self.lookahead() + if l != "," and l != ")": + if self.lookahead() != '=': + self.parse_token() # kotlin argument name + if self.parse_if('='): # kotlin default value + self.parse_expression() + return type + + def parse_expression(self): + while not self.lookahead() in [')', ',', ';']: + (self.parse_matching_paren('(', ')') or + self.parse_matching_paren('{', '}') or + self.parse_token()) + + def parse_throws(self): + ret = [] + if self.parse_if("throws"): + ret.append(self.parse_type()) + while self.parse_if(","): + ret.append(self.parse_type()) + return ret + + def parse_extends(self): + if self.parse_if("extends"): + return self.parse_space_delimited_type_list() + return [] + + def parse_implements(self): + if self.parse_if("implements"): + return self.parse_space_delimited_type_list() + return [] + + def parse_space_delimited_type_list(self, terminals = ["implements", "{"]): + types = [] + while True: + types.append(self.parse_type()) + if self.lookahead() in terminals: + return types + + def parse_annotation_default(self): + if self.parse_if("default"): + self.parse_expression() + + def parse_value(self): + if self.lookahead() == "{": + return " ".join(self.parse_matching_paren("{", "}")) + elif self.lookahead() == "(": + return " ".join(self.parse_matching_paren("(", ")")) + else: + return self.parse_token() + + def parse_value_stripped(self): + value = self.parse_value() + if value[0] == '"': + return value[1:-1] + return value + + +def _parse_stream(f, clazz_cb=None, base_f=None, out_classes_with_base=None, + in_classes_with_base=[]): api = {} + in_classes_with_base = _retry_iterator(in_classes_with_base) + + if base_f: + base_classes = _retry_iterator(_parse_stream_to_generator(base_f)) + else: + base_classes = [] + + def handle_class(clazz): + if clazz_cb: + clazz_cb(clazz) + else: # In callback mode, don't keep track of the full API + api[clazz.fullname] = clazz + + def handle_missed_classes_with_base(clazz): + for c in _yield_until_matching_class(in_classes_with_base, clazz): + base_class = _skip_to_matching_class(base_classes, c) + if base_class: + handle_class(base_class) + + for clazz in _parse_stream_to_generator(f): + # Before looking at clazz, let's see if there's some classes that were not present, but + # may have an entry in the base stream. + handle_missed_classes_with_base(clazz) + + base_class = _skip_to_matching_class(base_classes, clazz) + if base_class: + clazz.merge_from(base_class) + if out_classes_with_base is not None: + out_classes_with_base.append(clazz) + handle_class(clazz) + + handle_missed_classes_with_base(None) + + return api + +def _parse_stream_to_generator(f): + line = 0 pkg = None clazz = None blame = None + sig_format = 1 re_blame = re.compile("^([a-z0-9]{7,}) \(<([^>]+)>.+?\) (.+?)$") + + field_prefixes = map(lambda kind: " %s" % (kind,), V2LineParser.FIELD_KINDS) + def startsWithFieldPrefix(raw): + for prefix in field_prefixes: + if raw.startswith(prefix): + return True + return False + for raw in f: line += 1 raw = raw.rstrip() @@ -195,29 +610,72 @@ def _parse_stream(f, clazz_cb=None): else: blame = None - if raw.startswith("package"): + if line == 1 and raw == "// Signature format: 2.0": + sig_format = 2 + elif raw.startswith("package"): pkg = Package(line, raw, blame) elif raw.startswith(" ") and raw.endswith("{"): - # When provided with class callback, we treat as incremental - # parse and don't build up entire API - if clazz and clazz_cb: - clazz_cb(clazz) - clazz = Class(pkg, line, raw, blame) - if not clazz_cb: - api[clazz.fullname] = clazz + clazz = Class(pkg, line, raw, blame, sig_format=sig_format) elif raw.startswith(" ctor"): - clazz.ctors.append(Method(clazz, line, raw, blame)) + clazz.ctors.append(Method(clazz, line, raw, blame, sig_format=sig_format)) elif raw.startswith(" method"): - clazz.methods.append(Method(clazz, line, raw, blame)) - elif raw.startswith(" field"): - clazz.fields.append(Field(clazz, line, raw, blame)) - - # Handle last trailing class - if clazz and clazz_cb: - clazz_cb(clazz) - - return api - + clazz.methods.append(Method(clazz, line, raw, blame, sig_format=sig_format)) + elif startsWithFieldPrefix(raw): + clazz.fields.append(Field(clazz, line, raw, blame, sig_format=sig_format)) + elif raw.startswith(" }") and clazz: + yield clazz + +def _retry_iterator(it): + """Wraps an iterator, such that calling send(True) on it will redeliver the same element""" + for e in it: + while True: + retry = yield e + if not retry: + break + # send() was called, asking us to redeliver clazz on next(). Still need to yield + # a dummy value to the send() first though. + if (yield "Returning clazz on next()"): + raise TypeError("send() must be followed by next(), not send()") + +def _skip_to_matching_class(classes, needle): + """Takes a classes iterator and consumes entries until it returns the class we're looking for + + This relies on classes being sorted by package and class name.""" + + for clazz in classes: + if clazz.pkg.name < needle.pkg.name: + # We haven't reached the right package yet + continue + if clazz.pkg.name == needle.pkg.name and clazz.fullname < needle.fullname: + # We're in the right package, but not the right class yet + continue + if clazz.fullname == needle.fullname: + return clazz + # We ran past the right class. Send it back into the generator, then report failure. + classes.send(clazz) + return None + +def _yield_until_matching_class(classes, needle): + """Takes a class iterator and yields entries it until it reaches the class we're looking for. + + This relies on classes being sorted by package and class name.""" + + for clazz in classes: + if needle is None: + yield clazz + elif clazz.pkg.name < needle.pkg.name: + # We haven't reached the right package yet + yield clazz + elif clazz.pkg.name == needle.pkg.name and clazz.fullname < needle.fullname: + # We're in the right package, but not the right class yet + yield clazz + elif clazz.fullname == needle.fullname: + # Class found, abort. + return + else: + # We ran past the right class. Send it back into the iterator, then abort. + classes.send(clazz) + return class Failure(): def __init__(self, sig, clazz, detail, error, rule, msg): @@ -257,7 +715,7 @@ def _fail(clazz, detail, error, rule, msg): """Records an API failure to be processed later.""" global failures - sig = "%s-%s-%s" % (clazz.fullname, repr(detail), msg) + sig = "%s-%s-%s" % (clazz.fullname, detail.ident if detail else None, msg) sig = sig.replace(" deprecated ", " ") failures[sig] = Failure(sig, clazz, detail, error, rule, msg) @@ -298,7 +756,7 @@ def verify_constants(clazz): def verify_enums(clazz): """Enums are bad, mmkay?""" - if "extends java.lang.Enum" in clazz.raw: + if clazz.extends == "java.lang.Enum" or "enum" in clazz.split: error(clazz, None, "F5", "Enums are not allowed") @@ -357,7 +815,7 @@ def verify_listeners(clazz): interface OnFooListener { void onFoo() }""" if clazz.name.endswith("Listener"): - if " abstract class " in clazz.raw: + if "abstract" in clazz.split and "class" in clazz.split: error(clazz, None, "L1", "Listeners should be an interface, or otherwise renamed Callback") for m in clazz.methods: @@ -436,16 +894,16 @@ def verify_equals(clazz): eq = False hc = False for m in clazz.methods: - if " static " in m.raw: continue - if "boolean equals(java.lang.Object)" in m.raw: eq = True - if "int hashCode()" in m.raw: hc = True + if "static" in m.split: continue + if m.sig_matches("boolean", "equals", ["java.lang.Object"]): eq = True + if m.sig_matches("int", "hashCode", []): hc = True if eq != hc: error(clazz, None, "M8", "Must override both equals and hashCode; missing one") def verify_parcelable(clazz): """Verify that Parcelable objects aren't hiding required bits.""" - if "implements android.os.Parcelable" in clazz.raw: + if clazz.implements == "android.os.Parcelable": creator = [ i for i in clazz.fields if i.name == "CREATOR" ] write = [ i for i in clazz.methods if i.name == "writeToParcel" ] describe = [ i for i in clazz.methods if i.name == "describeContents" ] @@ -453,8 +911,7 @@ def verify_parcelable(clazz): if len(creator) == 0 or len(write) == 0 or len(describe) == 0: error(clazz, None, "FW3", "Parcelable requires CREATOR, writeToParcel, and describeContents; missing one") - if ((" final class " not in clazz.raw) and - (" final deprecated class " not in clazz.raw)): + if "final" not in clazz.split: error(clazz, None, "FW8", "Parcelable classes must be final") for c in clazz.ctors: @@ -465,6 +922,7 @@ def verify_parcelable(clazz): def verify_protected(clazz): """Verify that no protected methods or fields are allowed.""" for m in clazz.methods: + if m.name == "finalize": continue if "protected" in m.split: error(clazz, m, "M7", "Protected methods not allowed; must be public") for f in clazz.fields: @@ -505,7 +963,7 @@ def verify_fields(clazz): else: error(clazz, f, "F2", "Bare fields must be marked final, or add accessors if mutable") - if not "static" in f.split: + if "static" not in f.split and "property" not in f.split: if not re.match("[a-z]([a-zA-Z]+)?", f.name): error(clazz, f, "S1", "Non-static fields must be named using myField style") @@ -573,7 +1031,7 @@ def verify_helper_classes(clazz): """Verify that helper classes are named consistently with what they extend. All developer extendable methods should be named onFoo().""" test_methods = False - if "extends android.app.Service" in clazz.raw: + if clazz.extends == "android.app.Service": test_methods = True if not clazz.name.endswith("Service"): error(clazz, None, "CL4", "Inconsistent class name; should be FooService") @@ -585,7 +1043,7 @@ def verify_helper_classes(clazz): if f.value != clazz.fullname: error(clazz, f, "C4", "Inconsistent interface constant; expected '%s'" % (clazz.fullname)) - if "extends android.content.ContentProvider" in clazz.raw: + if clazz.extends == "android.content.ContentProvider": test_methods = True if not clazz.name.endswith("Provider"): error(clazz, None, "CL4", "Inconsistent class name; should be FooProvider") @@ -597,12 +1055,12 @@ def verify_helper_classes(clazz): if f.value != clazz.fullname: error(clazz, f, "C4", "Inconsistent interface constant; expected '%s'" % (clazz.fullname)) - if "extends android.content.BroadcastReceiver" in clazz.raw: + if clazz.extends == "android.content.BroadcastReceiver": test_methods = True if not clazz.name.endswith("Receiver"): error(clazz, None, "CL4", "Inconsistent class name; should be FooReceiver") - if "extends android.app.Activity" in clazz.raw: + if clazz.extends == "android.app.Activity": test_methods = True if not clazz.name.endswith("Activity"): error(clazz, None, "CL4", "Inconsistent class name; should be FooActivity") @@ -620,7 +1078,7 @@ def verify_helper_classes(clazz): def verify_builder(clazz): """Verify builder classes. Methods should return the builder to enable chaining.""" - if " extends " in clazz.raw: return + if clazz.extends: return if not clazz.name.endswith("Builder"): return if clazz.name != "Builder": @@ -648,7 +1106,7 @@ def verify_builder(clazz): def verify_aidl(clazz): """Catch people exposing raw AIDL.""" - if "extends android.os.Binder" in clazz.raw or "implements android.os.IInterface" in clazz.raw: + if clazz.extends == "android.os.Binder" or clazz.implements == "android.os.IInterface": error(clazz, None, None, "Raw AIDL interfaces must not be exposed") @@ -657,48 +1115,66 @@ def verify_internal(clazz): if clazz.pkg.name.startswith("com.android"): error(clazz, None, None, "Internal classes must not be exposed") +def layering_build_ranking(ranking_list): + r = {} + for rank, ps in enumerate(ranking_list): + if not isinstance(ps, list): + ps = [ps] + for p in ps: + rs = r + for n in p.split('.'): + if n not in rs: + rs[n] = {} + rs = rs[n] + rs['-rank'] = rank + return r + +LAYERING_PACKAGE_RANKING = layering_build_ranking([ + ["android.service","android.accessibilityservice","android.inputmethodservice","android.printservice","android.appwidget","android.webkit","android.preference","android.gesture","android.print"], + "android.app", + "android.widget", + "android.view", + "android.animation", + "android.provider", + ["android.content","android.graphics.drawable"], + "android.database", + "android.text", + "android.graphics", + "android.os", + "android.util" +]) def verify_layering(clazz): """Catch package layering violations. For example, something in android.os depending on android.app.""" - ranking = [ - ["android.service","android.accessibilityservice","android.inputmethodservice","android.printservice","android.appwidget","android.webkit","android.preference","android.gesture","android.print"], - "android.app", - "android.widget", - "android.view", - "android.animation", - "android.provider", - ["android.content","android.graphics.drawable"], - "android.database", - "android.graphics", - "android.text", - "android.os", - "android.util" - ] def rank(p): - for i in range(len(ranking)): - if isinstance(ranking[i], list): - for j in ranking[i]: - if p.startswith(j): return i + r = None + l = LAYERING_PACKAGE_RANKING + for n in p.split('.'): + if n in l: + l = l[n] + if '-rank' in l: + r = l['-rank'] else: - if p.startswith(ranking[i]): return i + break + return r cr = rank(clazz.pkg.name) if cr is None: return for f in clazz.fields: ir = rank(f.typ) - if ir and ir < cr: + if ir is not None and ir < cr: warn(clazz, f, "FW6", "Field type violates package layering") - for m in clazz.methods: + for m in itertools.chain(clazz.methods, clazz.ctors): ir = rank(m.typ) - if ir and ir < cr: + if ir is not None and ir < cr: warn(clazz, m, "FW6", "Method return type violates package layering") for arg in m.args: ir = rank(arg) - if ir and ir < cr: + if ir is not None and ir < cr: warn(clazz, m, "FW6", "Method argument type violates package layering") @@ -789,21 +1265,18 @@ def verify_exception(clazz): if len(m.args) == 0 and t in ["java.lang.IllegalArgumentException", "java.lang.NullPointerException"]: warn(clazz, m, "S1", "Methods taking no arguments should throw IllegalStateException") +GOOGLE_IGNORECASE = re.compile("google", re.IGNORECASE) def verify_google(clazz): """Verifies that APIs never reference Google.""" - if re.search("google", clazz.raw, re.IGNORECASE): + if GOOGLE_IGNORECASE.search(clazz.raw) is not None: error(clazz, None, None, "Must never reference Google") - test = [] - test.extend(clazz.ctors) - test.extend(clazz.fields) - test.extend(clazz.methods) - - for t in test: - if re.search("google", t.raw, re.IGNORECASE): - error(clazz, t, None, "Must never reference Google") + for test in clazz.ctors, clazz.fields, clazz.methods: + for t in test: + if GOOGLE_IGNORECASE.search(t.raw) is not None: + error(clazz, t, None, "Must never reference Google") def verify_bitset(clazz): @@ -998,6 +1471,10 @@ def verify_resource_names(clazz): # Resources defined by files are foo_bar_baz if clazz.name in ["anim","animator","color","dimen","drawable","interpolator","layout","transition","menu","mipmap","string","plurals","raw","xml"]: for f in clazz.fields: + if re.match("config_[a-z][a-zA-Z1-9]*$", f.name): continue + if f.name.startswith("config_"): + error(clazz, f, None, "Expected config name to be config_fooBarBaz style") + if re.match("[a-z1-9_]+$", f.name): continue error(clazz, f, None, "Expected resource name in this class to be foo_bar_baz style") @@ -1053,7 +1530,7 @@ def verify_abstract_inner(clazz): """Verifies that abstract inner classes are static.""" if re.match(".+?\.[A-Z][^\.]+\.[A-Z]", clazz.fullname): - if " abstract " in clazz.raw and " static " not in clazz.raw: + if "abstract" in clazz.split and "static" not in clazz.split: warn(clazz, None, None, "Abstract inner classes should be static to improve testability") @@ -1148,8 +1625,8 @@ def verify_units(clazz): def verify_closable(clazz): """Verifies that classes are AutoClosable.""" - if "implements java.lang.AutoCloseable" in clazz.raw: return - if "implements java.io.Closeable" in clazz.raw: return + if clazz.implements == "java.lang.AutoCloseable": return + if clazz.implements == "java.io.Closeable": return for m in clazz.methods: if len(m.args) > 0: continue @@ -1194,7 +1671,7 @@ def verify_method_name_not_kotlin_operator(clazz): binary.add(op) for m in clazz.methods: - if 'static' in m.split: + if 'static' in m.split or 'operator' in m.split: continue # https://kotlinlang.org/docs/reference/operator-overloading.html#unary-prefix-operators @@ -1235,6 +1712,9 @@ def verify_method_name_not_kotlin_operator(clazz): def verify_collections_over_arrays(clazz): """Warn that [] should be Collections.""" + if "@interface" in clazz.split: + return + safe = ["java.lang.String[]","byte[]","short[]","int[]","long[]","float[]","double[]","boolean[]","char[]"] for m in clazz.methods: if m.typ.endswith("[]") and m.typ not in safe: @@ -1253,10 +1733,19 @@ def verify_user_handle(clazz): if clazz.fullname == "android.os.UserManager": return for m in clazz.methods: - if m.name.endswith("AsUser") or m.name.endswith("ForUser"): continue if re.match("on[A-Z]+", m.name): continue - if "android.os.UserHandle" in m.args: - warn(clazz, m, None, "Method taking UserHandle should be named 'doFooAsUser' or 'queryFooForUser'") + + has_arg = "android.os.UserHandle" in m.args + has_name = m.name.endswith("AsUser") or m.name.endswith("ForUser") + + if clazz.fullname.endswith("Manager") and has_arg: + warn(clazz, m, None, "When a method overload is needed to target a specific " + "UserHandle, callers should be directed to use " + "Context.createPackageContextAsUser() and re-obtain the relevant " + "Manager, and no new API should be added") + elif has_arg and not has_name: + warn(clazz, m, None, "Method taking UserHandle should be named 'doFooAsUser' " + "or 'queryFooForUser'") def verify_params(clazz): @@ -1334,18 +1823,79 @@ def verify_clone(clazz): error(clazz, m, None, "Provide an explicit copy constructor instead of implementing clone()") +def verify_pfd(clazz): + """Verify that android APIs use PFD over FD.""" + examine = clazz.ctors + clazz.methods + for m in examine: + if m.typ == "java.io.FileDescriptor": + error(clazz, m, "FW11", "Must use ParcelFileDescriptor") + if m.typ == "int": + if "Fd" in m.name or "FD" in m.name or "FileDescriptor" in m.name: + error(clazz, m, "FW11", "Must use ParcelFileDescriptor") + for arg in m.args: + if arg == "java.io.FileDescriptor": + error(clazz, m, "FW11", "Must use ParcelFileDescriptor") + + for f in clazz.fields: + if f.typ == "java.io.FileDescriptor": + error(clazz, f, "FW11", "Must use ParcelFileDescriptor") + + +def verify_numbers(clazz): + """Discourage small numbers types like short and byte.""" + + discouraged = ["short","byte"] + + for c in clazz.ctors: + for arg in c.args: + if arg in discouraged: + warn(clazz, c, "FW12", "Should avoid odd sized primitives; use int instead") + + for f in clazz.fields: + if f.typ in discouraged: + warn(clazz, f, "FW12", "Should avoid odd sized primitives; use int instead") + + for m in clazz.methods: + if m.typ in discouraged: + warn(clazz, m, "FW12", "Should avoid odd sized primitives; use int instead") + for arg in m.args: + if arg in discouraged: + warn(clazz, m, "FW12", "Should avoid odd sized primitives; use int instead") + + +def verify_singleton(clazz): + """Catch singleton objects with constructors.""" + + singleton = False + for m in clazz.methods: + if m.name.startswith("get") and m.name.endswith("Instance") and " static " in m.raw: + singleton = True + + if singleton: + for c in clazz.ctors: + error(clazz, c, None, "Singleton classes should use getInstance() methods") + + + +def is_interesting(clazz): + """Test if given class is interesting from an Android PoV.""" + + if clazz.pkg.name.startswith("java"): return False + if clazz.pkg.name.startswith("junit"): return False + if clazz.pkg.name.startswith("org.apache"): return False + if clazz.pkg.name.startswith("org.xml"): return False + if clazz.pkg.name.startswith("org.json"): return False + if clazz.pkg.name.startswith("org.w3c"): return False + if clazz.pkg.name.startswith("android.icu."): return False + return True + + def examine_clazz(clazz): """Find all style issues in the given class.""" notice(clazz) - if clazz.pkg.name.startswith("java"): return - if clazz.pkg.name.startswith("junit"): return - if clazz.pkg.name.startswith("org.apache"): return - if clazz.pkg.name.startswith("org.xml"): return - if clazz.pkg.name.startswith("org.json"): return - if clazz.pkg.name.startswith("org.w3c"): return - if clazz.pkg.name.startswith("android.icu."): return + if not is_interesting(clazz): return verify_constants(clazz) verify_enums(clazz) @@ -1397,14 +1947,19 @@ def examine_clazz(clazz): verify_tense(clazz) verify_icu(clazz) verify_clone(clazz) + verify_pfd(clazz) + verify_numbers(clazz) + verify_singleton(clazz) -def examine_stream(stream): +def examine_stream(stream, base_stream=None, in_classes_with_base=[], out_classes_with_base=None): """Find all style issues in the given API stream.""" global failures, noticed failures = {} noticed = {} - _parse_stream(stream, examine_clazz) + _parse_stream(stream, examine_clazz, base_f=base_stream, + in_classes_with_base=in_classes_with_base, + out_classes_with_base=out_classes_with_base) return (failures, noticed) @@ -1479,6 +2034,7 @@ def show_deprecations_at_birth(cur, prev): # Remove all existing things so we're left with new for prev_clazz in prev.values(): cur_clazz = cur[prev_clazz.fullname] + if not is_interesting(cur_clazz): continue sigs = { i.ident: i for i in prev_clazz.ctors } cur_clazz.ctors = [ i for i in cur_clazz.ctors if i.ident not in sigs ] @@ -1492,11 +2048,11 @@ def show_deprecations_at_birth(cur, prev): del cur[prev_clazz.fullname] for clazz in cur.values(): - if " deprecated " in clazz.raw and not clazz.fullname in prev: + if "deprecated" in clazz.split and not clazz.fullname in prev: error(clazz, None, None, "Found API deprecation at birth") for i in clazz.ctors + clazz.methods + clazz.fields: - if " deprecated " in i.raw: + if "deprecated" in i.split: error(clazz, i, None, "Found API deprecation at birth") print "%s Deprecated at birth %s\n" % ((format(fg=WHITE, bg=BLUE, bold=True), @@ -1506,12 +2062,50 @@ def show_deprecations_at_birth(cur, prev): print +def show_stats(cur, prev): + """Show API stats.""" + + stats = collections.defaultdict(int) + for cur_clazz in cur.values(): + if not is_interesting(cur_clazz): continue + + if cur_clazz.fullname not in prev: + stats['new_classes'] += 1 + stats['new_ctors'] += len(cur_clazz.ctors) + stats['new_methods'] += len(cur_clazz.methods) + stats['new_fields'] += len(cur_clazz.fields) + else: + prev_clazz = prev[cur_clazz.fullname] + + sigs = { i.ident: i for i in prev_clazz.ctors } + ctors = len([ i for i in cur_clazz.ctors if i.ident not in sigs ]) + sigs = { i.ident: i for i in prev_clazz.methods } + methods = len([ i for i in cur_clazz.methods if i.ident not in sigs ]) + sigs = { i.ident: i for i in prev_clazz.fields } + fields = len([ i for i in cur_clazz.fields if i.ident not in sigs ]) + + if ctors + methods + fields > 0: + stats['extend_classes'] += 1 + stats['extend_ctors'] += ctors + stats['extend_methods'] += methods + stats['extend_fields'] += fields + + print "#", "".join([ k.ljust(20) for k in sorted(stats.keys()) ]) + print " ", "".join([ str(stats[k]).ljust(20) for k in sorted(stats.keys()) ]) + + if __name__ == "__main__": parser = argparse.ArgumentParser(description="Enforces common Android public API design \ patterns. It ignores lint messages from a previous API level, if provided.") parser.add_argument("current.txt", type=argparse.FileType('r'), help="current.txt") parser.add_argument("previous.txt", nargs='?', type=argparse.FileType('r'), default=None, help="previous.txt") + parser.add_argument("--base-current", nargs='?', type=argparse.FileType('r'), default=None, + help="The base current.txt to use when examining system-current.txt or" + " test-current.txt") + parser.add_argument("--base-previous", nargs='?', type=argparse.FileType('r'), default=None, + help="The base previous.txt to use when examining system-previous.txt or" + " test-previous.txt") parser.add_argument("--no-color", action='store_const', const=True, help="Disable terminal colors") parser.add_argument("--allow-google", action='store_const', const=True, @@ -1520,6 +2114,8 @@ if __name__ == "__main__": help="Show API changes noticed") parser.add_argument("--show-deprecations-at-birth", action='store_const', const=True, help="Show API deprecations at birth") + parser.add_argument("--show-stats", action='store_const', const=True, + help="Show API stats") args = vars(parser.parse_args()) if args['no_color']: @@ -1529,7 +2125,9 @@ if __name__ == "__main__": ALLOW_GOOGLE = True current_file = args['current.txt'] + base_current_file = args['base_current'] previous_file = args['previous.txt'] + base_previous_file = args['base_previous'] if args['show_deprecations_at_birth']: with current_file as f: @@ -1539,11 +2137,32 @@ if __name__ == "__main__": show_deprecations_at_birth(cur, prev) sys.exit() + if args['show_stats']: + with current_file as f: + cur = _parse_stream(f) + with previous_file as f: + prev = _parse_stream(f) + show_stats(cur, prev) + sys.exit() + + classes_with_base = [] + with current_file as f: - cur_fail, cur_noticed = examine_stream(f) + if base_current_file: + with base_current_file as base_f: + cur_fail, cur_noticed = examine_stream(f, base_f, + out_classes_with_base=classes_with_base) + else: + cur_fail, cur_noticed = examine_stream(f, out_classes_with_base=classes_with_base) + if not previous_file is None: with previous_file as f: - prev_fail, prev_noticed = examine_stream(f) + if base_previous_file: + with base_previous_file as base_f: + prev_fail, prev_noticed = examine_stream(f, base_f, + in_classes_with_base=classes_with_base) + else: + prev_fail, prev_noticed = examine_stream(f, in_classes_with_base=classes_with_base) # ignore errors from previous API level for p in prev_fail: diff --git a/tools/apilint/apilint_sha_system.sh b/tools/apilint/apilint_sha_system.sh new file mode 100755 index 000000000000..8538a3d904f5 --- /dev/null +++ b/tools/apilint/apilint_sha_system.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Copyright (C) 2018 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +if git show --name-only --pretty=format: $1 | grep api/ > /dev/null; then + python tools/apilint/apilint.py \ + --base-current <(git show $1:api/current.txt) \ + --base-previous <(git show $1^:api/current.txt) \ + <(git show $1:api/system-current.txt) \ + <(git show $1^:api/system-current.txt) +fi diff --git a/tools/apilint/apilint_stats.sh b/tools/apilint/apilint_stats.sh new file mode 100755 index 000000000000..052d9a5265fe --- /dev/null +++ b/tools/apilint/apilint_stats.sh @@ -0,0 +1,7 @@ +#!/bin/bash +API=28 +while [ $API -gt 14 ]; do + echo "# Changes in API $((API))" + python tools/apilint/apilint.py --show-stats ../../prebuilts/sdk/$((API))/public/api/android.txt ../../prebuilts/sdk/$((API-1))/public/api/android.txt + let API=API-1 +done diff --git a/tools/apilint/apilint_test.py b/tools/apilint/apilint_test.py new file mode 100644 index 000000000000..9c261d506dac --- /dev/null +++ b/tools/apilint/apilint_test.py @@ -0,0 +1,356 @@ +#!/usr/bin/env python + +# Copyright (C) 2018 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the 'License'); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an 'AS IS' BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import unittest + +import apilint + +def cls(pkg, name): + return apilint.Class(apilint.Package(999, "package %s {" % pkg, None), 999, + "public final class %s {" % name, None) + +_ri = apilint._retry_iterator + +c1 = cls("android.app", "ActivityManager") +c2 = cls("android.app", "Notification") +c3 = cls("android.app", "Notification.Action") +c4 = cls("android.graphics", "Bitmap") + +class UtilTests(unittest.TestCase): + def test_retry_iterator(self): + it = apilint._retry_iterator([1, 2, 3, 4]) + self.assertEqual(it.next(), 1) + self.assertEqual(it.next(), 2) + self.assertEqual(it.next(), 3) + it.send("retry") + self.assertEqual(it.next(), 3) + self.assertEqual(it.next(), 4) + with self.assertRaises(StopIteration): + it.next() + + def test_retry_iterator_one(self): + it = apilint._retry_iterator([1]) + self.assertEqual(it.next(), 1) + it.send("retry") + self.assertEqual(it.next(), 1) + with self.assertRaises(StopIteration): + it.next() + + def test_retry_iterator_one(self): + it = apilint._retry_iterator([1]) + self.assertEqual(it.next(), 1) + it.send("retry") + self.assertEqual(it.next(), 1) + with self.assertRaises(StopIteration): + it.next() + + def test_skip_to_matching_class_found(self): + it = _ri([c1, c2, c3, c4]) + self.assertEquals(apilint._skip_to_matching_class(it, c3), + c3) + self.assertEqual(it.next(), c4) + + def test_skip_to_matching_class_not_found(self): + it = _ri([c1, c2, c3, c4]) + self.assertEquals(apilint._skip_to_matching_class(it, cls("android.content", "ContentProvider")), + None) + self.assertEqual(it.next(), c4) + + def test_yield_until_matching_class_found(self): + it = _ri([c1, c2, c3, c4]) + self.assertEquals(list(apilint._yield_until_matching_class(it, c3)), + [c1, c2]) + self.assertEqual(it.next(), c4) + + def test_yield_until_matching_class_not_found(self): + it = _ri([c1, c2, c3, c4]) + self.assertEquals(list(apilint._yield_until_matching_class(it, cls("android.content", "ContentProvider"))), + [c1, c2, c3]) + self.assertEqual(it.next(), c4) + + def test_yield_until_matching_class_None(self): + it = _ri([c1, c2, c3, c4]) + self.assertEquals(list(apilint._yield_until_matching_class(it, None)), + [c1, c2, c3, c4]) + + +faulty_current_txt = """ +package android.app { + public final class Activity { + } + + public final class WallpaperColors implements android.os.Parcelable { + ctor public WallpaperColors(android.os.Parcel); + method public int describeContents(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.app.WallpaperColors> CREATOR; + } +} +""".split('\n') + +ok_current_txt = """ +package android.app { + public final class Activity { + } + + public final class WallpaperColors implements android.os.Parcelable { + ctor public WallpaperColors(); + method public int describeContents(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.app.WallpaperColors> CREATOR; + } +} +""".split('\n') + +system_current_txt = """ +package android.app { + public final class WallpaperColors implements android.os.Parcelable { + method public int getSomething(); + } +} +""".split('\n') + + + +class BaseFileTests(unittest.TestCase): + def test_base_file_avoids_errors(self): + failures, _ = apilint.examine_stream(system_current_txt, ok_current_txt) + self.assertEquals(failures, {}) + + def test_class_with_base_finds_same_errors(self): + failures_with_classes_with_base, _ = apilint.examine_stream("", faulty_current_txt, + in_classes_with_base=[cls("android.app", "WallpaperColors")]) + failures_with_system_txt, _ = apilint.examine_stream(system_current_txt, faulty_current_txt) + + self.assertEquals(failures_with_classes_with_base.keys(), failures_with_system_txt.keys()) + + def test_classes_with_base_is_emited(self): + classes_with_base = [] + _, _ = apilint.examine_stream(system_current_txt, faulty_current_txt, + out_classes_with_base=classes_with_base) + self.assertEquals(map(lambda x: x.fullname, classes_with_base), ["android.app.WallpaperColors"]) + +class ParseV2Stream(unittest.TestCase): + def test_field_kinds(self): + api = apilint._parse_stream(""" +// Signature format: 2.0 +package android { + public enum SomeEnum { + enum_constant public static final android.SomeEnum ENUM_CONST; + field public static final int FIELD_CONST; + property public final int someProperty; + ctor public SomeEnum(); + method public Object? getObject(); + } +} + """.strip().split('\n')) + + self.assertEquals(api['android.SomeEnum'].fields[0].split[0], 'enum_constant') + self.assertEquals(api['android.SomeEnum'].fields[1].split[0], 'field') + self.assertEquals(api['android.SomeEnum'].fields[2].split[0], 'property') + self.assertEquals(api['android.SomeEnum'].ctors[0].split[0], 'ctor') + self.assertEquals(api['android.SomeEnum'].methods[0].split[0], 'method') + +class V2TokenizerTests(unittest.TestCase): + def _test(self, raw, expected): + self.assertEquals(apilint.V2Tokenizer(raw).tokenize(), expected) + + def test_simple(self): + self._test(" method public some.Type someName(some.Argument arg, int arg);", + ['method', 'public', 'some.Type', 'someName', '(', 'some.Argument', + 'arg', ',', 'int', 'arg', ')', ';']) + self._test("class Some.Class extends SomeOther {", + ['class', 'Some.Class', 'extends', 'SomeOther', '{']) + + def test_varargs(self): + self._test("name(String...)", + ['name', '(', 'String', '...', ')']) + + def test_kotlin(self): + self._test("String? name(String!...)", + ['String', '?', 'name', '(', 'String', '!', '...', ')']) + + def test_annotation(self): + self._test("method @Nullable public void name();", + ['method', '@', 'Nullable', 'public', 'void', 'name', '(', ')', ';']) + + def test_annotation_args(self): + self._test("@Some(val=1, other=2) class Class {", + ['@', 'Some', '(', 'val', '=', '1', ',', 'other', '=', '2', ')', + 'class', 'Class', '{']) + def test_comment(self): + self._test("some //comment", ['some']) + + def test_strings(self): + self._test(r'"" "foo" "\"" "\\"', ['""', '"foo"', r'"\""', r'"\\"']) + + def test_at_interface(self): + self._test("public @interface Annotation {", + ['public', '@interface', 'Annotation', '{']) + + def test_array_type(self): + self._test("int[][]", ['int', '[]', '[]']) + + def test_generics(self): + self._test("<>foobar<A extends Object>", + ['<', '>', 'foobar', '<', 'A', 'extends', 'Object', '>']) + +class V2ParserTests(unittest.TestCase): + def _cls(self, raw): + pkg = apilint.Package(999, "package pkg {", None) + return apilint.Class(pkg, 1, raw, '', sig_format=2) + + def _method(self, raw, cls=None): + if not cls: + cls = self._cls("class Class {") + return apilint.Method(cls, 1, raw, '', sig_format=2) + + def _field(self, raw): + cls = self._cls("class Class {") + return apilint.Field(cls, 1, raw, '', sig_format=2) + + def test_class(self): + cls = self._cls("@Deprecated @IntRange(from=1, to=2) public static abstract class Some.Name extends Super<Class> implements Interface<Class> {") + self.assertTrue('deprecated' in cls.split) + self.assertTrue('static' in cls.split) + self.assertTrue('abstract' in cls.split) + self.assertTrue('class' in cls.split) + self.assertEquals('Super', cls.extends) + self.assertEquals('Interface', cls.implements) + self.assertEquals('pkg.Some.Name', cls.fullname) + + def test_enum(self): + cls = self._cls("public enum Some.Name {") + self._field("enum_constant public static final android.ValueType COLOR;") + + def test_interface(self): + cls = self._cls("@Deprecated @IntRange(from=1, to=2) public interface Some.Name extends Interface<Class> {") + self.assertTrue('deprecated' in cls.split) + self.assertTrue('interface' in cls.split) + self.assertEquals('Interface', cls.extends) + self.assertEquals('Interface', cls.implements) + self.assertEquals('pkg.Some.Name', cls.fullname) + + def test_at_interface(self): + cls = self._cls("@java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.FIELD, java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.PARAMETER, java.lang.annotation.ElementType.CONSTRUCTOR, java.lang.annotation.ElementType.LOCAL_VARIABLE}) @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.CLASS) public @interface SuppressLint {") + self.assertTrue('@interface' in cls.split) + self.assertEquals('pkg.SuppressLint', cls.fullname) + + def test_parse_method(self): + m = self._method("method @Deprecated public static native <T> Class<T>[][] name(" + + "Class<T[]>[][], Class<T[][][]>[][]...) throws Exception, T;") + self.assertTrue('static' in m.split) + self.assertTrue('public' in m.split) + self.assertTrue('method' in m.split) + self.assertTrue('native' in m.split) + self.assertTrue('deprecated' in m.split) + self.assertEquals('java.lang.Class[][]', m.typ) + self.assertEquals('name', m.name) + self.assertEquals(['java.lang.Class[][]', 'java.lang.Class[][]...'], m.args) + self.assertEquals(['java.lang.Exception', 'T'], m.throws) + + def test_ctor(self): + m = self._method("ctor @Deprecated <T> ClassName();") + self.assertTrue('ctor' in m.split) + self.assertTrue('deprecated' in m.split) + self.assertEquals('ctor', m.typ) + self.assertEquals('ClassName', m.name) + + def test_parse_annotation_method(self): + cls = self._cls("@interface Annotation {") + self._method('method abstract String category() default "";', cls=cls) + self._method('method abstract boolean deepExport() default false;', cls=cls) + self._method('method abstract ViewDebug.FlagToString[] flagMapping() default {};', cls=cls) + self._method('method abstract ViewDebug.FlagToString[] flagMapping() default (double)java.lang.Float.NEGATIVE_INFINITY;', cls=cls) + + def test_parse_string_field(self): + f = self._field('field @Deprecated public final String SOME_NAME = "value";') + self.assertTrue('field' in f.split) + self.assertTrue('deprecated' in f.split) + self.assertTrue('final' in f.split) + self.assertEquals('java.lang.String', f.typ) + self.assertEquals('SOME_NAME', f.name) + self.assertEquals('value', f.value) + + def test_parse_field(self): + f = self._field('field public Object SOME_NAME;') + self.assertTrue('field' in f.split) + self.assertEquals('java.lang.Object', f.typ) + self.assertEquals('SOME_NAME', f.name) + self.assertEquals(None, f.value) + + def test_parse_int_field(self): + f = self._field('field public int NAME = 123;') + self.assertTrue('field' in f.split) + self.assertEquals('int', f.typ) + self.assertEquals('NAME', f.name) + self.assertEquals('123', f.value) + + def test_parse_quotient_field(self): + f = self._field('field public int NAME = (0.0/0.0);') + self.assertTrue('field' in f.split) + self.assertEquals('int', f.typ) + self.assertEquals('NAME', f.name) + self.assertEquals('( 0.0 / 0.0 )', f.value) + + def test_kotlin_types(self): + self._field('field public List<Integer[]?[]!>?[]![]? NAME;') + self._method("method <T?> Class<T!>?[]![][]? name(Type!, Type argname," + + "Class<T?>[][]?[]!...!) throws Exception, T;") + self._method("method <T> T name(T a = 1, T b = A(1), Lambda f = { false }, N? n = null, " + + """double c = (1/0), float d = 1.0f, String s = "heyo", char c = 'a');""") + + def test_kotlin_operator(self): + self._method('method public operator void unaryPlus(androidx.navigation.NavDestination);') + self._method('method public static operator androidx.navigation.NavDestination get(androidx.navigation.NavGraph, @IdRes int id);') + self._method('method public static operator <T> T get(androidx.navigation.NavigatorProvider, kotlin.reflect.KClass<T> clazz);') + + def test_kotlin_property(self): + self._field('property public VM value;') + self._field('property public final String? action;') + + def test_kotlin_varargs(self): + self._method('method public void error(int p = "42", Integer int2 = "null", int p1 = "42", vararg String args);') + + def test_kotlin_default_values(self): + self._method('method public void foo(String! = null, String! = "Hello World", int = 42);') + self._method('method void method(String, String firstArg = "hello", int secondArg = "42", String thirdArg = "world");') + self._method('method void method(String, String firstArg = "hello", int secondArg = "42");') + self._method('method void method(String, String firstArg = "hello");') + self._method('method void edit(android.Type, boolean commit = false, Function1<? super Editor,kotlin.Unit> action);') + self._method('method <K, V> LruCache<K,V> lruCache(int maxSize, Function2<? super K,? super V,java.lang.Integer> sizeOf = { _, _ -> 1 }, Function1<? extends V> create = { (V)null }, Function4<kotlin.Unit> onEntryRemoved = { _, _, _, _ -> });') + self._method('method android.Bitmap? drawToBitmap(android.View, android.Config config = android.graphics.Bitmap.Config.ARGB_8888);') + self._method('method void emptyLambda(Function0<kotlin.Unit> sizeOf = {});') + self._method('method void method1(int p = 42, Integer? int2 = null, int p1 = 42, String str = "hello world", java.lang.String... args);') + self._method('method void method2(int p, int int2 = (2 * int) * some.other.pkg.Constants.Misc.SIZE);') + self._method('method void method3(String str, int p, int int2 = double(int) + str.length);') + self._method('method void print(test.pkg.Foo foo = test.pkg.Foo());') + + def test_type_use_annotation(self): + self._method('method public static int codePointAt(char @NonNull [], int);') + self._method('method @NonNull public java.util.Set<java.util.Map.@NonNull Entry<K,V>> entrySet();') + + m = self._method('method @NonNull public java.lang.annotation.@NonNull Annotation @NonNull [] getAnnotations();') + self.assertEquals('java.lang.annotation.Annotation[]', m.typ) + + m = self._method('method @NonNull public abstract java.lang.annotation.@NonNull Annotation @NonNull [] @NonNull [] getParameterAnnotations();') + self.assertEquals('java.lang.annotation.Annotation[][]', m.typ) + + m = self._method('method @NonNull public @NonNull String @NonNull [] split(@NonNull String, int);') + self.assertEquals('java.lang.String[]', m.typ) + +if __name__ == "__main__": + unittest.main() |