Merge "Make some SubscriptionManager APIs system APIs"
diff --git a/Android.bp b/Android.bp
index 151adf8..124f473 100644
--- a/Android.bp
+++ b/Android.bp
@@ -484,6 +484,8 @@
"telecomm/java/com/android/internal/telecom/IConnectionServiceAdapter.aidl",
"telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl",
"telecomm/java/com/android/internal/telecom/IInCallService.aidl",
+ "telecomm/java/com/android/internal/telecom/IPhoneAccountSuggestionCallback.aidl",
+ "telecomm/java/com/android/internal/telecom/IPhoneAccountSuggestionService.aidl",
"telecomm/java/com/android/internal/telecom/ITelecomService.aidl",
"telecomm/java/com/android/internal/telecom/RemoteServiceCallback.aidl",
"telephony/java/android/telephony/data/IDataService.aidl",
@@ -677,6 +679,7 @@
static_libs: [
"apex_aidl_interface-java",
+ "networkstack-aidl-interfaces-java",
"framework-protos",
"android.hidl.base-V1.0-java",
"android.hardware.cas-V1.0-java",
@@ -816,6 +819,16 @@
output_extension: "srcjar",
}
+// AIDL interfaces between the core system and the networking mainline module.
+aidl_interface {
+ name: "networkstack-aidl-interfaces",
+ local_include_dir: "core/java",
+ srcs: [
+ "core/java/android/net/INetworkStackConnector.aidl",
+ ],
+ api_dir: "aidl/networkstack",
+}
+
// Build ext.jar
// ============================================================
java_library {
@@ -1147,6 +1160,7 @@
metalava_framework_docs_args = "--manifest $(location core/res/AndroidManifest.xml) " +
"--hide-package com.android.okhttp " +
"--hide-package com.android.org.conscrypt --hide-package com.android.server " +
+ "--error UnhiddenSystemApi " +
"--hide RequiresPermission " +
"--hide MissingPermission --hide BroadcastBehavior " +
"--hide HiddenSuperclass --hide DeprecationMismatch --hide UnavailableSymbol " +
@@ -1563,6 +1577,7 @@
dex_mapping_filename: "dex-mapping.txt",
args: metalava_framework_docs_args +
" --hide ReferencesHidden " +
+ " --hide UnhiddenSystemApi " +
" --show-unannotated " +
" --show-annotation android.annotation.SystemApi " +
" --show-annotation android.annotation.TestApi "
diff --git a/api/current.txt b/api/current.txt
index 7b48a5b..89b14b8 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -27225,7 +27225,7 @@
method public void addDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
method public boolean bindProcessToNetwork(android.net.Network);
method public android.net.Network getActiveNetwork();
- method public android.net.NetworkInfo getActiveNetworkInfo();
+ method public deprecated android.net.NetworkInfo getActiveNetworkInfo();
method public deprecated android.net.NetworkInfo[] getAllNetworkInfo();
method public android.net.Network[] getAllNetworks();
method public deprecated boolean getBackgroundDataSetting();
@@ -27236,7 +27236,7 @@
method public int getMultipathPreference(android.net.Network);
method public android.net.NetworkCapabilities getNetworkCapabilities(android.net.Network);
method public deprecated android.net.NetworkInfo getNetworkInfo(int);
- method public android.net.NetworkInfo getNetworkInfo(android.net.Network);
+ method public deprecated android.net.NetworkInfo getNetworkInfo(android.net.Network);
method public deprecated int getNetworkPreference();
method public byte[] getNetworkWatchlistConfigHash();
method public static deprecated android.net.Network getProcessDefaultNetwork();
@@ -27270,14 +27270,14 @@
field public static final deprecated int DEFAULT_NETWORK_PREFERENCE = 1; // 0x1
field public static final java.lang.String EXTRA_CAPTIVE_PORTAL = "android.net.extra.CAPTIVE_PORTAL";
field public static final java.lang.String EXTRA_CAPTIVE_PORTAL_URL = "android.net.extra.CAPTIVE_PORTAL_URL";
- field public static final java.lang.String EXTRA_EXTRA_INFO = "extraInfo";
- field public static final java.lang.String EXTRA_IS_FAILOVER = "isFailover";
+ field public static final deprecated java.lang.String EXTRA_EXTRA_INFO = "extraInfo";
+ field public static final deprecated java.lang.String EXTRA_IS_FAILOVER = "isFailover";
field public static final java.lang.String EXTRA_NETWORK = "android.net.extra.NETWORK";
field public static final deprecated java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
field public static final java.lang.String EXTRA_NETWORK_REQUEST = "android.net.extra.NETWORK_REQUEST";
field public static final java.lang.String EXTRA_NETWORK_TYPE = "networkType";
field public static final java.lang.String EXTRA_NO_CONNECTIVITY = "noConnectivity";
- field public static final java.lang.String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
+ field public static final deprecated java.lang.String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
field public static final java.lang.String EXTRA_REASON = "reason";
field public static final int MULTIPATH_PREFERENCE_HANDOVER = 1; // 0x1
field public static final int MULTIPATH_PREFERENCE_PERFORMANCE = 4; // 0x4
@@ -27333,6 +27333,11 @@
field public int serverAddress;
}
+ public class InetAddresses {
+ method public static boolean isNumericAddress(java.lang.String);
+ method public static java.net.InetAddress parseNumericAddress(java.lang.String);
+ }
+
public final class IpPrefix implements android.os.Parcelable {
method public boolean contains(java.net.InetAddress);
method public int describeContents();
@@ -27424,6 +27429,7 @@
method public android.net.ProxyInfo getHttpProxy();
method public java.lang.String getInterfaceName();
method public java.util.List<android.net.LinkAddress> getLinkAddresses();
+ method public int getMtu();
method public java.lang.String getPrivateDnsServerName();
method public java.util.List<android.net.RouteInfo> getRoutes();
method public boolean isPrivateDnsActive();
@@ -27572,10 +27578,10 @@
field public static final int TRANSPORT_WIFI_AWARE = 5; // 0x5
}
- public class NetworkInfo implements android.os.Parcelable {
+ public deprecated class NetworkInfo implements android.os.Parcelable {
method public int describeContents();
method public deprecated android.net.NetworkInfo.DetailedState getDetailedState();
- method public java.lang.String getExtraInfo();
+ method public deprecated java.lang.String getExtraInfo();
method public deprecated java.lang.String getReason();
method public deprecated android.net.NetworkInfo.State getState();
method public deprecated int getSubtype();
@@ -27591,7 +27597,7 @@
field public static final android.os.Parcelable.Creator<android.net.NetworkInfo> CREATOR;
}
- public static final class NetworkInfo.DetailedState extends java.lang.Enum {
+ public static final deprecated class NetworkInfo.DetailedState extends java.lang.Enum {
method public static android.net.NetworkInfo.DetailedState valueOf(java.lang.String);
method public static final android.net.NetworkInfo.DetailedState[] values();
enum_constant public static final android.net.NetworkInfo.DetailedState AUTHENTICATING;
@@ -27609,7 +27615,7 @@
enum_constant public static final android.net.NetworkInfo.DetailedState VERIFYING_POOR_LINK;
}
- public static final class NetworkInfo.State extends java.lang.Enum {
+ public static final deprecated class NetworkInfo.State extends java.lang.Enum {
method public static android.net.NetworkInfo.State valueOf(java.lang.String);
method public static final android.net.NetworkInfo.State[] values();
enum_constant public static final android.net.NetworkInfo.State CONNECTED;
@@ -37330,10 +37336,13 @@
}
public static final class Telephony.CarrierId implements android.provider.BaseColumns {
+ method public static android.net.Uri getPreciseCarrierIdUriForSubscriptionId(int);
method public static android.net.Uri getUriForSubscriptionId(int);
field public static final java.lang.String CARRIER_ID = "carrier_id";
field public static final java.lang.String CARRIER_NAME = "carrier_name";
field public static final android.net.Uri CONTENT_URI;
+ field public static final java.lang.String PRECISE_CARRIER_ID = "precise_carrier_id";
+ field public static final java.lang.String PRECISE_CARRIER_ID_NAME = "precise_carrier_id_name";
}
public static final class Telephony.Carriers implements android.provider.BaseColumns {
@@ -37345,22 +37354,23 @@
field public static final android.net.Uri CONTENT_URI;
field public static final java.lang.String CURRENT = "current";
field public static final java.lang.String DEFAULT_SORT_ORDER = "name ASC";
- field public static final java.lang.String MCC = "mcc";
+ field public static final deprecated java.lang.String MCC = "mcc";
field public static final java.lang.String MMSC = "mmsc";
field public static final java.lang.String MMSPORT = "mmsport";
field public static final java.lang.String MMSPROXY = "mmsproxy";
- field public static final java.lang.String MNC = "mnc";
- field public static final java.lang.String MVNO_MATCH_DATA = "mvno_match_data";
- field public static final java.lang.String MVNO_TYPE = "mvno_type";
+ field public static final deprecated java.lang.String MNC = "mnc";
+ field public static final deprecated java.lang.String MVNO_MATCH_DATA = "mvno_match_data";
+ field public static final deprecated java.lang.String MVNO_TYPE = "mvno_type";
field public static final java.lang.String NAME = "name";
field public static final java.lang.String NETWORK_TYPE_BITMASK = "network_type_bitmask";
- field public static final java.lang.String NUMERIC = "numeric";
+ field public static final deprecated java.lang.String NUMERIC = "numeric";
field public static final java.lang.String PASSWORD = "password";
field public static final java.lang.String PORT = "port";
field public static final java.lang.String PROTOCOL = "protocol";
field public static final java.lang.String PROXY = "proxy";
field public static final java.lang.String ROAMING_PROTOCOL = "roaming_protocol";
field public static final java.lang.String SERVER = "server";
+ field public static final android.net.Uri SIM_APN_URI;
field public static final java.lang.String SUBSCRIPTION_ID = "sub_id";
field public static final java.lang.String TYPE = "type";
field public static final java.lang.String USER = "user";
@@ -39458,13 +39468,16 @@
public class CarrierIdentifier implements android.os.Parcelable {
ctor public CarrierIdentifier(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String);
+ ctor public CarrierIdentifier(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String, int, int);
ctor public CarrierIdentifier(byte[], java.lang.String, java.lang.String);
method public int describeContents();
+ method public int getCarrierId();
method public java.lang.String getGid1();
method public java.lang.String getGid2();
method public java.lang.String getImsi();
method public java.lang.String getMcc();
method public java.lang.String getMnc();
+ method public int getPreciseCarrierId();
method public java.lang.String getSpn();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.service.carrier.CarrierIdentifier> CREATOR;
@@ -40495,13 +40508,13 @@
method public static long sendfile(java.io.FileDescriptor, java.io.FileDescriptor, android.system.Int64Ref, long) throws android.system.ErrnoException;
method public static int sendto(java.io.FileDescriptor, java.nio.ByteBuffer, int, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
method public static int sendto(java.io.FileDescriptor, byte[], int, int, int, java.net.InetAddress, int) throws android.system.ErrnoException, java.net.SocketException;
- method public static void setegid(int) throws android.system.ErrnoException;
+ method public static deprecated void setegid(int) throws android.system.ErrnoException;
method public static void setenv(java.lang.String, java.lang.String, boolean) throws android.system.ErrnoException;
- method public static void seteuid(int) throws android.system.ErrnoException;
- method public static void setgid(int) throws android.system.ErrnoException;
+ method public static deprecated void seteuid(int) throws android.system.ErrnoException;
+ method public static deprecated void setgid(int) throws android.system.ErrnoException;
method public static int setsid() throws android.system.ErrnoException;
method public static void setsockoptInt(java.io.FileDescriptor, int, int, int) throws android.system.ErrnoException;
- method public static void setuid(int) throws android.system.ErrnoException;
+ method public static deprecated void setuid(int) throws android.system.ErrnoException;
method public static void setxattr(java.lang.String, java.lang.String, byte[], int) throws android.system.ErrnoException;
method public static void shutdown(java.io.FileDescriptor, int) throws android.system.ErrnoException;
method public static java.io.FileDescriptor socket(int, int, int) throws android.system.ErrnoException;
@@ -40855,7 +40868,9 @@
field public static final int SIOCGIFBRDADDR;
field public static final int SIOCGIFDSTADDR;
field public static final int SIOCGIFNETMASK;
+ field public static final int SOCK_CLOEXEC;
field public static final int SOCK_DGRAM;
+ field public static final int SOCK_NONBLOCK;
field public static final int SOCK_RAW;
field public static final int SOCK_SEQPACKET;
field public static final int SOCK_STREAM;
@@ -41934,9 +41949,12 @@
public static final class VideoProfile.CameraCapabilities implements android.os.Parcelable {
ctor public VideoProfile.CameraCapabilities(int, int);
+ ctor public VideoProfile.CameraCapabilities(int, int, boolean, float);
method public int describeContents();
method public int getHeight();
+ method public float getMaxZoom();
method public int getWidth();
+ method public boolean isZoomSupported();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.telecom.VideoProfile.CameraCapabilities> CREATOR;
}
@@ -42846,6 +42864,7 @@
public class SubscriptionInfo implements android.os.Parcelable {
method public android.graphics.Bitmap createIconBitmap(android.content.Context);
method public int describeContents();
+ method public int getCarrierId();
method public java.lang.CharSequence getCarrierName();
method public java.lang.String getCountryIso();
method public int getDataRoaming();
@@ -42885,12 +42904,14 @@
method public static int getSlotIndex(int);
method public int[] getSubscriptionIds(int);
method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int);
+ method public java.util.List<android.telephony.SubscriptionInfo> getSubscriptionsInGroup(int);
method public boolean isActiveSubscriptionId(int);
method public boolean isNetworkRoaming(int);
method public static boolean isUsableSubscriptionId(int);
method public static boolean isValidSubscriptionId(int);
method public void removeOnOpportunisticSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnOpportunisticSubscriptionsChangedListener);
method public void removeOnSubscriptionsChangedListener(android.telephony.SubscriptionManager.OnSubscriptionsChangedListener);
+ method public boolean removeSubscriptionsFromGroup(int[]);
method public java.lang.String setSubscriptionGroup(int[]);
method public void setSubscriptionOverrideCongested(int, boolean, long);
method public void setSubscriptionOverrideUnmetered(int, boolean, long);
@@ -42955,6 +42976,7 @@
method public java.util.List<android.telephony.CellInfo> getAllCellInfo();
method public int getCallState();
method public android.os.PersistableBundle getCarrierConfig();
+ method public int getCarrierIdFromSimMccMnc();
method public deprecated android.telephony.CellLocation getCellLocation();
method public java.util.Map<java.lang.Integer, java.util.List<android.telephony.emergency.EmergencyNumber>> getCurrentEmergencyNumberList();
method public java.util.Map<java.lang.Integer, java.util.List<android.telephony.emergency.EmergencyNumber>> getCurrentEmergencyNumberList(int);
@@ -42992,6 +43014,8 @@
method public java.lang.String getSimCountryIso();
method public java.lang.String getSimOperator();
method public java.lang.String getSimOperatorName();
+ method public int getSimPreciseCarrierId();
+ method public java.lang.CharSequence getSimPreciseCarrierIdName();
method public java.lang.String getSimSerialNumber();
method public int getSimState();
method public int getSimState(int);
@@ -43047,6 +43071,7 @@
field public static final java.lang.String ACTION_SECRET_CODE = "android.telephony.action.SECRET_CODE";
field public static final java.lang.String ACTION_SHOW_VOICEMAIL_NOTIFICATION = "android.telephony.action.SHOW_VOICEMAIL_NOTIFICATION";
field public static final java.lang.String ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED = "android.telephony.action.SUBSCRIPTION_CARRIER_IDENTITY_CHANGED";
+ field public static final java.lang.String ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED = "android.telephony.action.SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED";
field public static final int APPTYPE_CSIM = 4; // 0x4
field public static final int APPTYPE_ISIM = 5; // 0x5
field public static final int APPTYPE_RUIM = 3; // 0x3
@@ -43079,6 +43104,8 @@
field public static final java.lang.String EXTRA_LAUNCH_VOICEMAIL_SETTINGS_INTENT = "android.telephony.extra.LAUNCH_VOICEMAIL_SETTINGS_INTENT";
field public static final java.lang.String EXTRA_NOTIFICATION_COUNT = "android.telephony.extra.NOTIFICATION_COUNT";
field public static final java.lang.String EXTRA_PHONE_ACCOUNT_HANDLE = "android.telephony.extra.PHONE_ACCOUNT_HANDLE";
+ field public static final java.lang.String EXTRA_PRECISE_CARRIER_ID = "android.telephony.extra.PRECISE_CARRIER_ID";
+ field public static final java.lang.String EXTRA_PRECISE_CARRIER_NAME = "android.telephony.extra.PRECISE_CARRIER_NAME";
field public static final java.lang.String EXTRA_STATE = "state";
field public static final java.lang.String EXTRA_STATE_IDLE;
field public static final java.lang.String EXTRA_STATE_OFFHOOK;
diff --git a/api/system-current.txt b/api/system-current.txt
index a8f32a7..af902d4d3 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -23,6 +23,7 @@
field public static final java.lang.String BIND_KEYGUARD_APPWIDGET = "android.permission.BIND_KEYGUARD_APPWIDGET";
field public static final java.lang.String BIND_NETWORK_RECOMMENDATION_SERVICE = "android.permission.BIND_NETWORK_RECOMMENDATION_SERVICE";
field public static final java.lang.String BIND_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE";
+ field public static final java.lang.String BIND_PHONE_ACCOUNT_SUGGESTION_SERVICE = "android.permission.BIND_PHONE_ACCOUNT_SUGGESTION_SERVICE";
field public static final java.lang.String BIND_PRINT_RECOMMENDATION_SERVICE = "android.permission.BIND_PRINT_RECOMMENDATION_SERVICE";
field public static final java.lang.String BIND_RESOLVER_RANKER_SERVICE = "android.permission.BIND_RESOLVER_RANKER_SERVICE";
field public static final java.lang.String BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE = "android.permission.BIND_RUNTIME_PERMISSION_PRESENTER_SERVICE";
@@ -3044,7 +3045,20 @@
ctor public LinkAddress(java.lang.String);
}
+ public final class LinkProperties implements android.os.Parcelable {
+ ctor public LinkProperties();
+ method public boolean addRoute(android.net.RouteInfo);
+ method public void clear();
+ method public void setDnsServers(java.util.Collection<java.net.InetAddress>);
+ method public void setDomains(java.lang.String);
+ method public void setHttpProxy(android.net.ProxyInfo);
+ method public void setInterfaceName(java.lang.String);
+ method public void setLinkAddresses(java.util.Collection<android.net.LinkAddress>);
+ method public void setMtu(int);
+ }
+
public final class NetworkCapabilities implements android.os.Parcelable {
+ method public int getSignalStrength();
field public static final int NET_CAPABILITY_OEM_PAID = 22; // 0x16
}
@@ -3064,6 +3078,10 @@
method public abstract void onRequestScores(android.net.NetworkKey[]);
}
+ public static class NetworkRequest.Builder {
+ method public android.net.NetworkRequest.Builder setSignalStrength(int);
+ }
+
public class NetworkScoreManager {
method public boolean clearScores() throws java.lang.SecurityException;
method public void disableScoring() throws java.lang.SecurityException;
@@ -4942,6 +4960,14 @@
ctor public PhoneAccountSuggestion(android.telecom.PhoneAccountHandle, int, boolean);
}
+ public class PhoneAccountSuggestionService extends android.app.Service {
+ ctor public PhoneAccountSuggestionService();
+ method public void onAccountSuggestionRequest(java.lang.String);
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public final void suggestPhoneAccounts(java.lang.String, java.util.List<android.telecom.PhoneAccountSuggestion>);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.PhoneAccountSuggestionService";
+ }
+
public final class RemoteConference {
method public deprecated void setAudioState(android.telecom.AudioState);
}
@@ -5035,6 +5061,83 @@
field public static final java.lang.String KEY_CARRIER_SETUP_APP_STRING = "carrier_setup_app_string";
}
+ public class DisconnectCause {
+ field public static final int ALREADY_DIALING = 72; // 0x48
+ field public static final int ANSWERED_ELSEWHERE = 52; // 0x34
+ field public static final int BUSY = 4; // 0x4
+ field public static final int CALLING_DISABLED = 74; // 0x4a
+ field public static final int CALL_BARRED = 20; // 0x14
+ field public static final int CALL_PULLED = 51; // 0x33
+ field public static final int CANT_CALL_WHILE_RINGING = 73; // 0x49
+ field public static final int CDMA_ACCESS_BLOCKED = 35; // 0x23
+ field public static final int CDMA_ACCESS_FAILURE = 32; // 0x20
+ field public static final int CDMA_ALREADY_ACTIVATED = 49; // 0x31
+ field public static final int CDMA_DROP = 27; // 0x1b
+ field public static final int CDMA_INTERCEPT = 28; // 0x1c
+ field public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 26; // 0x1a
+ field public static final int CDMA_NOT_EMERGENCY = 34; // 0x22
+ field public static final int CDMA_PREEMPTED = 33; // 0x21
+ field public static final int CDMA_REORDER = 29; // 0x1d
+ field public static final int CDMA_RETRY_ORDER = 31; // 0x1f
+ field public static final int CDMA_SO_REJECT = 30; // 0x1e
+ field public static final int CONGESTION = 5; // 0x5
+ field public static final int CS_RESTRICTED = 22; // 0x16
+ field public static final int CS_RESTRICTED_EMERGENCY = 24; // 0x18
+ field public static final int CS_RESTRICTED_NORMAL = 23; // 0x17
+ field public static final int DATA_DISABLED = 54; // 0x36
+ field public static final int DATA_LIMIT_REACHED = 55; // 0x37
+ field public static final int DIALED_CALL_FORWARDING_WHILE_ROAMING = 57; // 0x39
+ field public static final int DIALED_MMI = 39; // 0x27
+ field public static final int DIAL_LOW_BATTERY = 62; // 0x3e
+ field public static final int DIAL_MODIFIED_TO_DIAL = 48; // 0x30
+ field public static final int DIAL_MODIFIED_TO_DIAL_VIDEO = 66; // 0x42
+ field public static final int DIAL_MODIFIED_TO_SS = 47; // 0x2f
+ field public static final int DIAL_MODIFIED_TO_USSD = 46; // 0x2e
+ field public static final int DIAL_VIDEO_MODIFIED_TO_DIAL = 69; // 0x45
+ field public static final int DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO = 70; // 0x46
+ field public static final int DIAL_VIDEO_MODIFIED_TO_SS = 67; // 0x43
+ field public static final int DIAL_VIDEO_MODIFIED_TO_USSD = 68; // 0x44
+ field public static final int EMERGENCY_PERM_FAILURE = 64; // 0x40
+ field public static final int EMERGENCY_TEMP_FAILURE = 63; // 0x3f
+ field public static final int ERROR_UNSPECIFIED = 36; // 0x24
+ field public static final int FDN_BLOCKED = 21; // 0x15
+ field public static final int ICC_ERROR = 19; // 0x13
+ field public static final int IMEI_NOT_ACCEPTED = 58; // 0x3a
+ field public static final int IMS_ACCESS_BLOCKED = 60; // 0x3c
+ field public static final int IMS_MERGED_SUCCESSFULLY = 45; // 0x2d
+ field public static final int IMS_SIP_ALTERNATE_EMERGENCY_CALL = 71; // 0x47
+ field public static final int INCOMING_MISSED = 1; // 0x1
+ field public static final int INCOMING_REJECTED = 16; // 0x10
+ field public static final int INVALID_CREDENTIALS = 10; // 0xa
+ field public static final int INVALID_NUMBER = 7; // 0x7
+ field public static final int LIMIT_EXCEEDED = 15; // 0xf
+ field public static final int LOCAL = 3; // 0x3
+ field public static final int LOST_SIGNAL = 14; // 0xe
+ field public static final int LOW_BATTERY = 61; // 0x3d
+ field public static final int MAXIMUM_NUMBER_OF_CALLS_REACHED = 53; // 0x35
+ field public static final int MMI = 6; // 0x6
+ field public static final int NORMAL = 2; // 0x2
+ field public static final int NORMAL_UNSPECIFIED = 65; // 0x41
+ field public static final int NOT_DISCONNECTED = 0; // 0x0
+ field public static final int NOT_VALID = -1; // 0xffffffff
+ field public static final int NO_PHONE_NUMBER_SUPPLIED = 38; // 0x26
+ field public static final int NUMBER_UNREACHABLE = 8; // 0x8
+ field public static final int OTASP_PROVISIONING_IN_PROCESS = 76; // 0x4c
+ field public static final int OUTGOING_CANCELED = 44; // 0x2c
+ field public static final int OUTGOING_FAILURE = 43; // 0x2b
+ field public static final int OUT_OF_NETWORK = 11; // 0xb
+ field public static final int OUT_OF_SERVICE = 18; // 0x12
+ field public static final int POWER_OFF = 17; // 0x11
+ field public static final int SERVER_ERROR = 12; // 0xc
+ field public static final int SERVER_UNREACHABLE = 9; // 0x9
+ field public static final int TIMED_OUT = 13; // 0xd
+ field public static final int TOO_MANY_ONGOING_CALLS = 75; // 0x4b
+ field public static final int UNOBTAINABLE_NUMBER = 25; // 0x19
+ field public static final int VIDEO_CALL_NOT_ALLOWED_WHILE_TTY_ENABLED = 50; // 0x32
+ field public static final int VOICEMAIL_NUMBER_MISSING = 40; // 0x28
+ field public static final int WIFI_LOST = 59; // 0x3b
+ }
+
public class MbmsDownloadSession implements java.lang.AutoCloseable {
field public static final java.lang.String MBMS_DOWNLOAD_SERVICE_ACTION = "android.telephony.action.EmbmsDownload";
}
@@ -5081,16 +5184,15 @@
public abstract class NetworkService extends android.app.Service {
ctor public NetworkService();
method protected abstract android.telephony.NetworkService.NetworkServiceProvider createNetworkServiceProvider(int);
- field public static final java.lang.String NETWORK_SERVICE_EXTRA_SLOT_ID = "android.telephony.extra.SLOT_ID";
field public static final java.lang.String NETWORK_SERVICE_INTERFACE = "android.telephony.NetworkService";
}
- public class NetworkService.NetworkServiceProvider {
+ public abstract class NetworkService.NetworkServiceProvider implements java.lang.AutoCloseable {
ctor public NetworkService.NetworkServiceProvider(int);
+ method public abstract void close();
method public void getNetworkRegistrationState(int, android.telephony.NetworkServiceCallback);
method public final int getSlotId();
method public final void notifyNetworkRegistrationStateChanged();
- method protected void onDestroy();
}
public class NetworkServiceCallback {
@@ -5124,14 +5226,134 @@
}
public class PhoneStateListener {
+ method public void onCallDisconnectCauseChanged(int, int);
+ method public void onPreciseCallStateChanged(android.telephony.PreciseCallState);
method public void onRadioPowerStateChanged(int);
method public void onSrvccStateChanged(int);
method public void onVoiceActivationStateChanged(int);
+ field public static final int LISTEN_CALL_DISCONNECT_CAUSES = 33554432; // 0x2000000
+ field public static final int LISTEN_PRECISE_CALL_STATE = 2048; // 0x800
field public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000
field public static final int LISTEN_SRVCC_STATE_CHANGED = 16384; // 0x4000
field public static final int LISTEN_VOICE_ACTIVATION_STATE = 131072; // 0x20000
}
+ public final class PreciseCallState implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getBackgroundCallState();
+ method public int getForegroundCallState();
+ method public int getRingingCallState();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.PreciseCallState> CREATOR;
+ field public static final int PRECISE_CALL_STATE_ACTIVE = 1; // 0x1
+ field public static final int PRECISE_CALL_STATE_ALERTING = 4; // 0x4
+ field public static final int PRECISE_CALL_STATE_DIALING = 3; // 0x3
+ field public static final int PRECISE_CALL_STATE_DISCONNECTED = 7; // 0x7
+ field public static final int PRECISE_CALL_STATE_DISCONNECTING = 8; // 0x8
+ field public static final int PRECISE_CALL_STATE_HOLDING = 2; // 0x2
+ field public static final int PRECISE_CALL_STATE_IDLE = 0; // 0x0
+ field public static final int PRECISE_CALL_STATE_INCOMING = 5; // 0x5
+ field public static final int PRECISE_CALL_STATE_NOT_VALID = -1; // 0xffffffff
+ field public static final int PRECISE_CALL_STATE_WAITING = 6; // 0x6
+ }
+
+ public class PreciseDisconnectCause {
+ field public static final int ACCESS_CLASS_BLOCKED = 260; // 0x104
+ field public static final int ACCESS_INFORMATION_DISCARDED = 43; // 0x2b
+ field public static final int ACM_LIMIT_EXCEEDED = 68; // 0x44
+ field public static final int BEARER_CAPABILITY_NOT_AUTHORIZED = 57; // 0x39
+ field public static final int BEARER_NOT_AVAIL = 58; // 0x3a
+ field public static final int BEARER_SERVICE_NOT_IMPLEMENTED = 65; // 0x41
+ field public static final int BUSY = 17; // 0x11
+ field public static final int CALL_BARRED = 240; // 0xf0
+ field public static final int CALL_REJECTED = 21; // 0x15
+ field public static final int CDMA_ACCESS_BLOCKED = 1009; // 0x3f1
+ field public static final int CDMA_ACCESS_FAILURE = 1006; // 0x3ee
+ field public static final int CDMA_DROP = 1001; // 0x3e9
+ field public static final int CDMA_INTERCEPT = 1002; // 0x3ea
+ field public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000; // 0x3e8
+ field public static final int CDMA_NOT_EMERGENCY = 1008; // 0x3f0
+ field public static final int CDMA_PREEMPTED = 1007; // 0x3ef
+ field public static final int CDMA_REORDER = 1003; // 0x3eb
+ field public static final int CDMA_RETRY_ORDER = 1005; // 0x3ed
+ field public static final int CDMA_SO_REJECT = 1004; // 0x3ec
+ field public static final int CHANNEL_NOT_AVAIL = 44; // 0x2c
+ field public static final int CHANNEL_UNACCEPTABLE = 6; // 0x6
+ field public static final int CONDITIONAL_IE_ERROR = 100; // 0x64
+ field public static final int DESTINATION_OUT_OF_ORDER = 27; // 0x1b
+ field public static final int ERROR_UNSPECIFIED = 65535; // 0xffff
+ field public static final int FACILITY_REJECTED = 29; // 0x1d
+ field public static final int FDN_BLOCKED = 241; // 0xf1
+ field public static final int IMEI_NOT_ACCEPTED = 243; // 0xf3
+ field public static final int IMSI_UNKNOWN_IN_VLR = 242; // 0xf2
+ field public static final int INCOMING_CALLS_BARRED_WITHIN_CUG = 55; // 0x37
+ field public static final int INCOMPATIBLE_DESTINATION = 88; // 0x58
+ field public static final int INFORMATION_ELEMENT_NON_EXISTENT = 99; // 0x63
+ field public static final int INTERWORKING_UNSPECIFIED = 127; // 0x7f
+ field public static final int INVALID_MANDATORY_INFORMATION = 96; // 0x60
+ field public static final int INVALID_NUMBER_FORMAT = 28; // 0x1c
+ field public static final int INVALID_TRANSACTION_IDENTIFIER = 81; // 0x51
+ field public static final int MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101; // 0x65
+ field public static final int MESSAGE_TYPE_NON_IMPLEMENTED = 97; // 0x61
+ field public static final int MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98; // 0x62
+ field public static final int NETWORK_DETACH = 261; // 0x105
+ field public static final int NETWORK_OUT_OF_ORDER = 38; // 0x26
+ field public static final int NETWORK_REJECT = 252; // 0xfc
+ field public static final int NETWORK_RESP_TIMEOUT = 251; // 0xfb
+ field public static final int NORMAL = 16; // 0x10
+ field public static final int NORMAL_UNSPECIFIED = 31; // 0x1f
+ field public static final int NOT_VALID = -1; // 0xffffffff
+ field public static final int NO_ANSWER_FROM_USER = 19; // 0x13
+ field public static final int NO_CIRCUIT_AVAIL = 34; // 0x22
+ field public static final int NO_DISCONNECT_CAUSE_AVAILABLE = 0; // 0x0
+ field public static final int NO_ROUTE_TO_DESTINATION = 3; // 0x3
+ field public static final int NO_USER_RESPONDING = 18; // 0x12
+ field public static final int NO_VALID_SIM = 249; // 0xf9
+ field public static final int NUMBER_CHANGED = 22; // 0x16
+ field public static final int OEM_CAUSE_1 = 61441; // 0xf001
+ field public static final int OEM_CAUSE_10 = 61450; // 0xf00a
+ field public static final int OEM_CAUSE_11 = 61451; // 0xf00b
+ field public static final int OEM_CAUSE_12 = 61452; // 0xf00c
+ field public static final int OEM_CAUSE_13 = 61453; // 0xf00d
+ field public static final int OEM_CAUSE_14 = 61454; // 0xf00e
+ field public static final int OEM_CAUSE_15 = 61455; // 0xf00f
+ field public static final int OEM_CAUSE_2 = 61442; // 0xf002
+ field public static final int OEM_CAUSE_3 = 61443; // 0xf003
+ field public static final int OEM_CAUSE_4 = 61444; // 0xf004
+ field public static final int OEM_CAUSE_5 = 61445; // 0xf005
+ field public static final int OEM_CAUSE_6 = 61446; // 0xf006
+ field public static final int OEM_CAUSE_7 = 61447; // 0xf007
+ field public static final int OEM_CAUSE_8 = 61448; // 0xf008
+ field public static final int OEM_CAUSE_9 = 61449; // 0xf009
+ field public static final int ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE = 70; // 0x46
+ field public static final int OPERATOR_DETERMINED_BARRING = 8; // 0x8
+ field public static final int OUT_OF_SRV = 248; // 0xf8
+ field public static final int PREEMPTION = 25; // 0x19
+ field public static final int PROTOCOL_ERROR_UNSPECIFIED = 111; // 0x6f
+ field public static final int QOS_NOT_AVAIL = 49; // 0x31
+ field public static final int RADIO_ACCESS_FAILURE = 253; // 0xfd
+ field public static final int RADIO_INTERNAL_ERROR = 250; // 0xfa
+ field public static final int RADIO_LINK_FAILURE = 254; // 0xfe
+ field public static final int RADIO_LINK_LOST = 255; // 0xff
+ field public static final int RADIO_OFF = 247; // 0xf7
+ field public static final int RADIO_RELEASE_ABNORMAL = 259; // 0x103
+ field public static final int RADIO_RELEASE_NORMAL = 258; // 0x102
+ field public static final int RADIO_SETUP_FAILURE = 257; // 0x101
+ field public static final int RADIO_UPLINK_FAILURE = 256; // 0x100
+ field public static final int RECOVERY_ON_TIMER_EXPIRED = 102; // 0x66
+ field public static final int REQUESTED_FACILITY_NOT_IMPLEMENTED = 69; // 0x45
+ field public static final int REQUESTED_FACILITY_NOT_SUBSCRIBED = 50; // 0x32
+ field public static final int RESOURCES_UNAVAILABLE_OR_UNSPECIFIED = 47; // 0x2f
+ field public static final int SEMANTICALLY_INCORRECT_MESSAGE = 95; // 0x5f
+ field public static final int SERVICE_OPTION_NOT_AVAILABLE = 63; // 0x3f
+ field public static final int SERVICE_OR_OPTION_NOT_IMPLEMENTED = 79; // 0x4f
+ field public static final int STATUS_ENQUIRY = 30; // 0x1e
+ field public static final int SWITCHING_CONGESTION = 42; // 0x2a
+ field public static final int TEMPORARY_FAILURE = 41; // 0x29
+ field public static final int UNOBTAINABLE_NUMBER = 1; // 0x1
+ field public static final int USER_NOT_MEMBER_OF_CUG = 87; // 0x57
+ }
+
public class ServiceState implements android.os.Parcelable {
method public android.telephony.NetworkRegistrationState getNetworkRegistrationState(int, int);
method public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStates();
@@ -5169,6 +5391,7 @@
public class SubscriptionInfo implements android.os.Parcelable {
method public java.util.List<android.telephony.UiccAccessRule> getAccessRules();
+ method public int getCardId();
}
public class SubscriptionManager {
@@ -5241,6 +5464,7 @@
method public int getSimCardState();
method public int getSupportedRadioAccessFamily();
method public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms();
+ method public android.telephony.UiccCardInfo[] getUiccCardsInfo();
method public android.telephony.UiccSlotInfo[] getUiccSlotsInfo();
method public android.os.Bundle getVisualVoicemailSettings();
method public int getVoiceActivationState();
@@ -5358,6 +5582,18 @@
field public static final android.os.Parcelable.Creator<android.telephony.UiccAccessRule> CREATOR;
}
+ public class UiccCardInfo implements android.os.Parcelable {
+ ctor public UiccCardInfo(boolean, int, java.lang.String, java.lang.String, int);
+ method public int describeContents();
+ method public int getCardId();
+ method public java.lang.String getEid();
+ method public java.lang.String getIccId();
+ method public int getSlotIndex();
+ method public boolean isEuicc();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.UiccCardInfo> CREATOR;
+ }
+
public class UiccSlotInfo implements android.os.Parcelable {
ctor public UiccSlotInfo(boolean, boolean, java.lang.String, int, int, boolean);
method public int describeContents();
@@ -5429,20 +5665,19 @@
public abstract class DataService extends android.app.Service {
ctor public DataService();
method public abstract android.telephony.data.DataService.DataServiceProvider createDataServiceProvider(int);
- field public static final java.lang.String DATA_SERVICE_EXTRA_SLOT_ID = "android.telephony.data.extra.SLOT_ID";
field public static final java.lang.String DATA_SERVICE_INTERFACE = "android.telephony.data.DataService";
field public static final int REQUEST_REASON_HANDOVER = 3; // 0x3
field public static final int REQUEST_REASON_NORMAL = 1; // 0x1
field public static final int REQUEST_REASON_SHUTDOWN = 2; // 0x2
}
- public class DataService.DataServiceProvider {
+ public abstract class DataService.DataServiceProvider implements java.lang.AutoCloseable {
ctor public DataService.DataServiceProvider(int);
+ method public abstract void close();
method public void deactivateDataCall(int, int, android.telephony.data.DataServiceCallback);
method public void getDataCallList(android.telephony.data.DataServiceCallback);
method public final int getSlotId();
method public final void notifyDataCallListChanged(java.util.List<android.telephony.data.DataCallResponse>);
- method protected void onDestroy();
method public void setDataProfile(java.util.List<android.telephony.data.DataProfile>, boolean, android.telephony.data.DataServiceCallback);
method public void setInitialAttachApn(android.telephony.data.DataProfile, boolean, android.telephony.data.DataServiceCallback);
method public void setupDataCall(int, android.telephony.data.DataProfile, boolean, boolean, int, android.net.LinkProperties, android.telephony.data.DataServiceCallback);
@@ -5907,6 +6142,7 @@
field public static final int CODE_RADIO_SETUP_FAILURE = 1509; // 0x5e5
field public static final int CODE_RADIO_UPLINK_FAILURE = 1508; // 0x5e4
field public static final int CODE_REGISTRATION_ERROR = 1000; // 0x3e8
+ field public static final int CODE_REJECTED_ELSEWHERE = 1017; // 0x3f9
field public static final int CODE_REJECT_1X_COLLISION = 1603; // 0x643
field public static final int CODE_REJECT_CALL_ON_OTHER_SUB = 1602; // 0x642
field public static final int CODE_REJECT_CALL_TYPE_NOT_ALLOWED = 1605; // 0x645
@@ -5930,26 +6166,39 @@
field public static final int CODE_REJECT_VT_AVPF_NOT_ALLOWED = 1619; // 0x653
field public static final int CODE_REJECT_VT_TTY_NOT_ALLOWED = 1615; // 0x64f
field public static final int CODE_REMOTE_CALL_DECLINE = 1404; // 0x57c
+ field public static final int CODE_SESSION_MODIFICATION_FAILED = 1517; // 0x5ed
field public static final int CODE_SIP_ALTERNATE_EMERGENCY_CALL = 1514; // 0x5ea
+ field public static final int CODE_SIP_AMBIGUOUS = 376; // 0x178
field public static final int CODE_SIP_BAD_ADDRESS = 337; // 0x151
field public static final int CODE_SIP_BAD_REQUEST = 331; // 0x14b
field public static final int CODE_SIP_BUSY = 338; // 0x152
+ field public static final int CODE_SIP_CALL_OR_TRANS_DOES_NOT_EXIST = 372; // 0x174
field public static final int CODE_SIP_CLIENT_ERROR = 342; // 0x156
+ field public static final int CODE_SIP_EXTENSION_REQUIRED = 370; // 0x172
field public static final int CODE_SIP_FORBIDDEN = 332; // 0x14c
field public static final int CODE_SIP_GLOBAL_ERROR = 362; // 0x16a
+ field public static final int CODE_SIP_INTERVAL_TOO_BRIEF = 371; // 0x173
+ field public static final int CODE_SIP_LOOP_DETECTED = 373; // 0x175
+ field public static final int CODE_SIP_METHOD_NOT_ALLOWED = 366; // 0x16e
field public static final int CODE_SIP_NOT_ACCEPTABLE = 340; // 0x154
field public static final int CODE_SIP_NOT_FOUND = 333; // 0x14d
field public static final int CODE_SIP_NOT_REACHABLE = 341; // 0x155
field public static final int CODE_SIP_NOT_SUPPORTED = 334; // 0x14e
+ field public static final int CODE_SIP_PROXY_AUTHENTICATION_REQUIRED = 367; // 0x16f
field public static final int CODE_SIP_REDIRECTED = 321; // 0x141
field public static final int CODE_SIP_REQUEST_CANCELLED = 339; // 0x153
+ field public static final int CODE_SIP_REQUEST_ENTITY_TOO_LARGE = 368; // 0x170
+ field public static final int CODE_SIP_REQUEST_PENDING = 377; // 0x179
field public static final int CODE_SIP_REQUEST_TIMEOUT = 335; // 0x14f
+ field public static final int CODE_SIP_REQUEST_URI_TOO_LARGE = 369; // 0x171
field public static final int CODE_SIP_SERVER_ERROR = 354; // 0x162
field public static final int CODE_SIP_SERVER_INTERNAL_ERROR = 351; // 0x15f
field public static final int CODE_SIP_SERVER_TIMEOUT = 353; // 0x161
field public static final int CODE_SIP_SERVICE_UNAVAILABLE = 352; // 0x160
field public static final int CODE_SIP_TEMPRARILY_UNAVAILABLE = 336; // 0x150
+ field public static final int CODE_SIP_TOO_MANY_HOPS = 374; // 0x176
field public static final int CODE_SIP_TRANSACTION_DOES_NOT_EXIST = 343; // 0x157
+ field public static final int CODE_SIP_UNDECIPHERABLE = 378; // 0x17a
field public static final int CODE_SIP_USER_MARKED_UNWANTED = 365; // 0x16d
field public static final int CODE_SIP_USER_REJECTED = 361; // 0x169
field public static final int CODE_SUPP_SVC_CANCELLED = 1202; // 0x4b2
@@ -5959,9 +6208,11 @@
field public static final int CODE_TIMEOUT_NO_ANSWER = 202; // 0xca
field public static final int CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE = 203; // 0xcb
field public static final int CODE_UNSPECIFIED = 0; // 0x0
+ field public static final int CODE_USER_CANCELLED_SESSION_MODIFICATION = 512; // 0x200
field public static final int CODE_USER_DECLINE = 504; // 0x1f8
field public static final int CODE_USER_IGNORE = 503; // 0x1f7
field public static final int CODE_USER_NOANSWER = 502; // 0x1f6
+ field public static final int CODE_USER_REJECTED_SESSION_MODIFICATION = 511; // 0x1ff
field public static final int CODE_USER_TERMINATED = 501; // 0x1f5
field public static final int CODE_USER_TERMINATED_BY_REMOTE = 510; // 0x1fe
field public static final int CODE_UT_CB_PASSWORD_MISMATCH = 821; // 0x335
diff --git a/api/test-current.txt b/api/test-current.txt
index b5b128a..dfa1c16 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -967,6 +967,14 @@
ctor public PhoneAccountSuggestion(android.telecom.PhoneAccountHandle, int, boolean);
}
+ public class PhoneAccountSuggestionService extends android.app.Service {
+ ctor public PhoneAccountSuggestionService();
+ method public void onAccountSuggestionRequest(java.lang.String);
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public final void suggestPhoneAccounts(java.lang.String, java.util.List<android.telecom.PhoneAccountSuggestion>);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.telecom.PhoneAccountSuggestionService";
+ }
+
}
package android.telephony {
diff --git a/cmds/incident_helper/src/TextParserBase.h b/cmds/incident_helper/src/TextParserBase.h
index 784c181..a6074e7 100644
--- a/cmds/incident_helper/src/TextParserBase.h
+++ b/cmds/incident_helper/src/TextParserBase.h
@@ -30,7 +30,7 @@
public:
String8 name;
- TextParserBase(String8 name) : name(name) {};
+ explicit TextParserBase(String8 name) : name(name) {};
virtual ~TextParserBase() {};
virtual status_t Parse(const int in, const int out) const = 0;
diff --git a/cmds/incident_helper/src/ih_util.h b/cmds/incident_helper/src/ih_util.h
index c02a349..09dc8e6 100644
--- a/cmds/incident_helper/src/ih_util.h
+++ b/cmds/incident_helper/src/ih_util.h
@@ -109,7 +109,7 @@
class Reader
{
public:
- Reader(const int fd);
+ explicit Reader(const int fd);
~Reader();
bool readLine(std::string* line);
@@ -162,7 +162,7 @@
class Message
{
public:
- Message(Table* table);
+ explicit Message(Table* table);
~Message();
// Reconstructs the typical proto message by adding its message fields.
diff --git a/cmds/incidentd/src/IncidentService.h b/cmds/incidentd/src/IncidentService.h
index e176bfd..140484b 100644
--- a/cmds/incidentd/src/IncidentService.h
+++ b/cmds/incidentd/src/IncidentService.h
@@ -97,7 +97,7 @@
// ================================================================================
class IncidentService : public BnIncidentManager {
public:
- IncidentService(const sp<Looper>& handlerLooper);
+ explicit IncidentService(const sp<Looper>& handlerLooper);
virtual ~IncidentService();
virtual Status reportIncident(const IncidentReportArgs& args);
diff --git a/cmds/incidentd/src/Privacy.h b/cmds/incidentd/src/Privacy.h
index a3df490..a0159d9 100644
--- a/cmds/incidentd/src/Privacy.h
+++ b/cmds/incidentd/src/Privacy.h
@@ -83,7 +83,7 @@
static PrivacySpec new_spec(int dest);
private:
- PrivacySpec(uint8_t dest) : dest(dest) {}
+ explicit PrivacySpec(uint8_t dest) : dest(dest) {}
};
} // namespace incidentd
diff --git a/cmds/incidentd/src/Reporter.h b/cmds/incidentd/src/Reporter.h
index 45fd944..2a3abd7 100644
--- a/cmds/incidentd/src/Reporter.h
+++ b/cmds/incidentd/src/Reporter.h
@@ -89,7 +89,7 @@
ReportRequestSet batch;
Reporter(); // PROD must use this constructor.
- Reporter(const char* directory); // For testing purpose only.
+ explicit Reporter(const char* directory); // For testing purpose only.
virtual ~Reporter();
// Run the report as described in the batch and args parameters.
diff --git a/cmds/incidentd/src/Section.cpp b/cmds/incidentd/src/Section.cpp
index 72a4103..bb5221c 100644
--- a/cmds/incidentd/src/Section.cpp
+++ b/cmds/incidentd/src/Section.cpp
@@ -410,7 +410,7 @@
bool workerDone;
status_t workerError;
- WorkerThreadData(const WorkerThreadSection* section);
+ explicit WorkerThreadData(const WorkerThreadSection* section);
virtual ~WorkerThreadData();
};
diff --git a/cmds/statsd/src/anomaly/AlarmMonitor.h b/cmds/statsd/src/anomaly/AlarmMonitor.h
index 3badb1f..bca858e 100644
--- a/cmds/statsd/src/anomaly/AlarmMonitor.h
+++ b/cmds/statsd/src/anomaly/AlarmMonitor.h
@@ -42,7 +42,7 @@
* Timestamps are in seconds since epoch in a uint32, so will fail in year 2106.
*/
struct InternalAlarm : public RefBase {
- InternalAlarm(uint32_t timestampSec) : timestampSec(timestampSec) {
+ explicit InternalAlarm(uint32_t timestampSec) : timestampSec(timestampSec) {
}
const uint32_t timestampSec;
diff --git a/cmds/statsd/src/atom_field_options.proto b/cmds/statsd/src/atom_field_options.proto
index a2a03b1..7dfe7d6 100644
--- a/cmds/statsd/src/atom_field_options.proto
+++ b/cmds/statsd/src/atom_field_options.proto
@@ -64,10 +64,22 @@
optional StateField option = 1 [default = STATE_FIELD_UNSET];
}
+// Used to generate StatsLog.write APIs.
+enum LogMode {
+ MODE_UNSET = 0;
+ // Log fields as their actual types e.g., all primary data types.
+ // Or fields that are hardcoded in stats_log_api_gen tool e.g., AttributionNode
+ MODE_AUTOMATIC = 1;
+ // Log fields in their proto binary format. These fields will not be parsed in statsd
+ MODE_BYTES = 2;
+}
+
extend google.protobuf.FieldOptions {
// Flags to decorate an atom that presents a state change.
optional StateAtomFieldOption stateFieldOption = 50000;
// Flags to decorate the uid fields in an atom.
optional bool is_uid = 50001 [default = false];
+
+ optional LogMode log_mode = 50002 [default = MODE_AUTOMATIC];
}
\ No newline at end of file
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 281f900..d9fa0f1 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -26,6 +26,7 @@
import "frameworks/base/core/proto/android/bluetooth/enums.proto";
import "frameworks/base/core/proto/android/os/enums.proto";
import "frameworks/base/core/proto/android/server/enums.proto";
+import "frameworks/base/core/proto/android/stats/launcher/launcher.proto";
import "frameworks/base/core/proto/android/telecomm/enums.proto";
import "frameworks/base/core/proto/android/telephony/enums.proto";
import "frameworks/base/core/proto/android/view/enums.proto";
@@ -59,7 +60,8 @@
LongPartialWakelockStateChanged long_partial_wakelock_state_changed = 11;
MobileRadioPowerStateChanged mobile_radio_power_state_changed = 12;
WifiRadioPowerStateChanged wifi_radio_power_state_changed = 13;
- // 14 - 19 are available
+ // 14 - 18 are available
+ LauncherUIChanged launcher_event = 19;
BatterySaverModeStateChanged battery_saver_mode_state_changed = 20;
DeviceIdleModeStateChanged device_idle_mode_state_changed = 21;
DeviceIdlingModeStateChanged device_idling_mode_state_changed = 22;
@@ -1166,6 +1168,14 @@
optional State state = 1;
}
+message LauncherUIChanged {
+ optional android.stats.launcher.LauncherAction action = 1;
+ optional android.stats.launcher.LauncherState src_state = 2;
+ optional android.stats.launcher.LauncherState dst_state = 3;
+ optional android.stats.launcher.LauncherExtension extension = 4 [(log_mode) = MODE_BYTES];
+ optional bool is_swipe_up_enabled = 5;
+}
+
/**
* Logs that a setting was updated.
* Logged from:
diff --git a/cmds/statsd/src/condition/ConditionWizard.h b/cmds/statsd/src/condition/ConditionWizard.h
index a6f88af..2c88147 100644
--- a/cmds/statsd/src/condition/ConditionWizard.h
+++ b/cmds/statsd/src/condition/ConditionWizard.h
@@ -29,7 +29,7 @@
class ConditionWizard : public virtual android::RefBase {
public:
ConditionWizard(){}; // for testing
- ConditionWizard(std::vector<sp<ConditionTracker>>& conditionTrackers)
+ explicit ConditionWizard(std::vector<sp<ConditionTracker>>& conditionTrackers)
: mAllConditions(conditionTrackers){};
virtual ~ConditionWizard(){};
diff --git a/cmds/statsd/src/config/ConfigKey.h b/cmds/statsd/src/config/ConfigKey.h
index dc79519..4cc9393 100644
--- a/cmds/statsd/src/config/ConfigKey.h
+++ b/cmds/statsd/src/config/ConfigKey.h
@@ -33,7 +33,7 @@
class ConfigKey {
public:
ConfigKey();
- explicit ConfigKey(const ConfigKey& that);
+ ConfigKey(const ConfigKey& that);
ConfigKey(int uid, const int64_t& id);
~ConfigKey();
diff --git a/cmds/statsd/src/config/ConfigManager.cpp b/cmds/statsd/src/config/ConfigManager.cpp
index 16b7e79..5fea90b 100644
--- a/cmds/statsd/src/config/ConfigManager.cpp
+++ b/cmds/statsd/src/config/ConfigManager.cpp
@@ -106,14 +106,14 @@
// Add to set.
mConfigs[key.GetUid()].insert(key);
- for (sp<ConfigListener> listener : mListeners) {
+ for (const sp<ConfigListener>& listener : mListeners) {
broadcastList.push_back(listener);
}
}
const int64_t timestampNs = getElapsedRealtimeNs();
// Tell everyone
- for (sp<ConfigListener> listener : broadcastList) {
+ for (const sp<ConfigListener>& listener : broadcastList) {
listener->OnConfigUpdated(timestampNs, key, config);
}
}
@@ -137,7 +137,7 @@
if (uidIt != mConfigs.end() && uidIt->second.find(key) != uidIt->second.end()) {
// Remove from map
uidIt->second.erase(key);
- for (sp<ConfigListener> listener : mListeners) {
+ for (const sp<ConfigListener>& listener : mListeners) {
broadcastList.push_back(listener);
}
}
@@ -153,7 +153,7 @@
remove_saved_configs(key);
}
- for (sp<ConfigListener> listener:broadcastList) {
+ for (const sp<ConfigListener>& listener:broadcastList) {
listener->OnConfigRemoved(key);
}
}
@@ -183,7 +183,7 @@
mConfigs.erase(uidIt);
- for (sp<ConfigListener> listener : mListeners) {
+ for (const sp<ConfigListener>& listener : mListeners) {
broadcastList.push_back(listener);
}
}
@@ -191,7 +191,7 @@
// Remove separately so if they do anything in the callback they can't mess up our iteration.
for (auto& key : removed) {
// Tell everyone
- for (sp<ConfigListener> listener:broadcastList) {
+ for (const sp<ConfigListener>& listener:broadcastList) {
listener->OnConfigRemoved(key);
}
}
@@ -213,7 +213,7 @@
}
mConfigReceivers.clear();
- for (sp<ConfigListener> listener : mListeners) {
+ for (const sp<ConfigListener>& listener : mListeners) {
broadcastList.push_back(listener);
}
}
@@ -221,7 +221,7 @@
// Remove separately so if they do anything in the callback they can't mess up our iteration.
for (auto& key : removed) {
// Tell everyone
- for (sp<ConfigListener> listener:broadcastList) {
+ for (const sp<ConfigListener>& listener:broadcastList) {
listener->OnConfigRemoved(key);
}
}
diff --git a/cmds/statsd/src/external/ResourceHealthManagerPuller.h b/cmds/statsd/src/external/ResourceHealthManagerPuller.h
index 9b238eaf5..ba6e6c3 100644
--- a/cmds/statsd/src/external/ResourceHealthManagerPuller.h
+++ b/cmds/statsd/src/external/ResourceHealthManagerPuller.h
@@ -28,7 +28,7 @@
*/
class ResourceHealthManagerPuller : public StatsPuller {
public:
- ResourceHealthManagerPuller(int tagId);
+ explicit ResourceHealthManagerPuller(int tagId);
bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override;
};
diff --git a/cmds/statsd/src/external/StatsCompanionServicePuller.h b/cmds/statsd/src/external/StatsCompanionServicePuller.h
index 0a49732..a16baf0 100644
--- a/cmds/statsd/src/external/StatsCompanionServicePuller.h
+++ b/cmds/statsd/src/external/StatsCompanionServicePuller.h
@@ -25,7 +25,7 @@
class StatsCompanionServicePuller : public StatsPuller {
public:
- StatsCompanionServicePuller(int tagId);
+ explicit StatsCompanionServicePuller(int tagId);
bool PullInternal(vector<std::shared_ptr<LogEvent> >* data) override;
void SetStatsCompanionService(sp<IStatsCompanionService> statsCompanionService) override;
diff --git a/cmds/statsd/src/external/StatsPuller.h b/cmds/statsd/src/external/StatsPuller.h
index caac677..35be12b 100644
--- a/cmds/statsd/src/external/StatsPuller.h
+++ b/cmds/statsd/src/external/StatsPuller.h
@@ -33,7 +33,7 @@
class StatsPuller : public virtual RefBase {
public:
- StatsPuller(const int tagId);
+ explicit StatsPuller(const int tagId);
virtual ~StatsPuller() {}
diff --git a/cmds/statsd/src/external/SubsystemSleepStatePuller.cpp b/cmds/statsd/src/external/SubsystemSleepStatePuller.cpp
index 4501b64..2713d327 100644
--- a/cmds/statsd/src/external/SubsystemSleepStatePuller.cpp
+++ b/cmds/statsd/src/external/SubsystemSleepStatePuller.cpp
@@ -111,7 +111,7 @@
(long long)state.residencyInMsecSinceBoot,
(long long)state.totalTransitions,
state.supportedOnlyInSuspend ? 1 : 0);
- for (auto voter : state.voters) {
+ for (const auto& voter : state.voters) {
auto voterPtr = make_shared<LogEvent>(
android::util::SUBSYSTEM_SLEEP_STATE,
wallClockTimestampNs, elapsedTimestampNs);
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index 4e4f146..5d6d02b 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -379,7 +379,7 @@
string LogEvent::ToString() const {
string result;
- result += StringPrintf("{ %lld %lld (%d)", (long long)mLogdTimestampNs,
+ result += StringPrintf("{ uid(%d) %lld %lld (%d)", mLogUid, (long long)mLogdTimestampNs,
(long long)mElapsedTimestampNs, mTagId);
for (const auto& value : mValues) {
result +=
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
index 24d624d..8a03ac4 100644
--- a/cmds/statsd/src/logd/LogEvent.h
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -158,7 +158,7 @@
* Don't copy, it's slower. If we really need this we can add it but let's try to
* avoid it.
*/
- explicit LogEvent(const LogEvent&);
+ LogEvent(const LogEvent&);
/**
* Parses a log_msg into a LogEvent object.
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index 4fac0e1..a6c7f3a 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -395,7 +395,7 @@
// Returns the total byte size of all metrics managed by a single config source.
size_t MetricsManager::byteSize() {
size_t totalSize = 0;
- for (auto metricProducer : mAllMetricProducers) {
+ for (const auto& metricProducer : mAllMetricProducers) {
totalSize += metricProducer->byteSize();
}
return totalSize;
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
index 811a00e..a1c80b8 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -537,7 +537,7 @@
}
noReportMetricIds.insert(no_report_metric);
}
- for (auto it : allMetricProducers) {
+ for (const auto& it : allMetricProducers) {
uidMap.addListener(it);
}
return true;
diff --git a/cmds/statsd/src/packages/UidMap.cpp b/cmds/statsd/src/packages/UidMap.cpp
index 73ac968..88957df 100644
--- a/cmds/statsd/src/packages/UidMap.cpp
+++ b/cmds/statsd/src/packages/UidMap.cpp
@@ -141,7 +141,7 @@
// listener removes itself before we call it. It's then the listener's job to handle it (expect
// the callback to be called after listener is removed, and the listener should properly
// ignore it).
- for (auto weakPtr : broadcastList) {
+ for (const auto& weakPtr : broadcastList) {
auto strongPtr = weakPtr.promote();
if (strongPtr != NULL) {
strongPtr->onUidMapReceived(timestamp);
@@ -181,7 +181,7 @@
StatsdStats::getInstance().setUidMapChanges(mChanges.size());
}
- for (auto weakPtr : broadcastList) {
+ for (const auto& weakPtr : broadcastList) {
auto strongPtr = weakPtr.promote();
if (strongPtr != NULL) {
strongPtr->notifyAppUpgrade(timestamp, appName, uid, versionCode);
@@ -248,7 +248,7 @@
getListenerListCopyLocked(&broadcastList);
}
- for (auto weakPtr : broadcastList) {
+ for (const auto& weakPtr : broadcastList) {
auto strongPtr = weakPtr.promote();
if (strongPtr != NULL) {
strongPtr->notifyAppRemoved(timestamp, app, uid);
diff --git a/cmds/statsd/src/socket/StatsSocketListener.h b/cmds/statsd/src/socket/StatsSocketListener.h
index 73e4d33..b8185d2 100644
--- a/cmds/statsd/src/socket/StatsSocketListener.h
+++ b/cmds/statsd/src/socket/StatsSocketListener.h
@@ -35,7 +35,7 @@
class StatsSocketListener : public SocketListener, public virtual android::RefBase {
public:
- StatsSocketListener(const sp<LogListener>& listener);
+ explicit StatsSocketListener(const sp<LogListener>& listener);
virtual ~StatsSocketListener();
@@ -51,4 +51,4 @@
};
} // namespace statsd
} // namespace os
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index a0ab3e4..11ce717 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -25,15 +25,16 @@
#include <utils/Log.h>
#include <utils/SystemClock.h>
+using android::util::AtomsInfo;
using android::util::FIELD_COUNT_REPEATED;
using android::util::FIELD_TYPE_BOOL;
+using android::util::FIELD_TYPE_FIXED64;
using android::util::FIELD_TYPE_FLOAT;
using android::util::FIELD_TYPE_INT32;
using android::util::FIELD_TYPE_INT64;
-using android::util::FIELD_TYPE_UINT64;
-using android::util::FIELD_TYPE_FIXED64;
using android::util::FIELD_TYPE_MESSAGE;
using android::util::FIELD_TYPE_STRING;
+using android::util::FIELD_TYPE_UINT64;
using android::util::ProtoOutputStream;
namespace android {
@@ -294,8 +295,9 @@
// }
//
//
-void writeFieldValueTreeToStreamHelper(const std::vector<FieldValue>& dims, size_t* index,
- int depth, int prefix, ProtoOutputStream* protoOutput) {
+void writeFieldValueTreeToStreamHelper(int tagId, const std::vector<FieldValue>& dims,
+ size_t* index, int depth, int prefix,
+ ProtoOutputStream* protoOutput) {
size_t count = dims.size();
while (*index < count) {
const auto& dim = dims[*index];
@@ -319,9 +321,33 @@
case FLOAT:
protoOutput->write(FIELD_TYPE_FLOAT | fieldNum, dim.mValue.float_value);
break;
- case STRING:
- protoOutput->write(FIELD_TYPE_STRING | fieldNum, dim.mValue.str_value);
+ case STRING: {
+ bool isBytesField = false;
+ // Bytes field is logged via string format in log_msg format. So here we check
+ // if this string field is a byte field.
+ std::map<int, std::vector<int>>::const_iterator itr;
+ if (depth == 0 && (itr = AtomsInfo::kBytesFieldAtoms.find(tagId)) !=
+ AtomsInfo::kBytesFieldAtoms.end()) {
+ const std::vector<int>& bytesFields = itr->second;
+ for (int bytesField : bytesFields) {
+ if (bytesField == fieldNum) {
+ // This is a bytes field
+ isBytesField = true;
+ break;
+ }
+ }
+ }
+ if (isBytesField) {
+ if (dim.mValue.str_value.length() > 0) {
+ protoOutput->write(FIELD_TYPE_MESSAGE | fieldNum,
+ (const char*)dim.mValue.str_value.c_str(),
+ dim.mValue.str_value.length());
+ }
+ } else {
+ protoOutput->write(FIELD_TYPE_STRING | fieldNum, dim.mValue.str_value);
+ }
break;
+ }
default:
break;
}
@@ -337,7 +363,7 @@
}
// Directly jump to the leaf value because the repeated position field is implied
// by the position of the sub msg in the parent field.
- writeFieldValueTreeToStreamHelper(dims, index, valueDepth,
+ writeFieldValueTreeToStreamHelper(tagId, dims, index, valueDepth,
dim.mField.getPrefix(valueDepth), protoOutput);
if (msg_token != 0) {
protoOutput->end(msg_token);
@@ -354,7 +380,7 @@
uint64_t atomToken = protoOutput->start(FIELD_TYPE_MESSAGE | tagId);
size_t index = 0;
- writeFieldValueTreeToStreamHelper(values, &index, 0, 0, protoOutput);
+ writeFieldValueTreeToStreamHelper(tagId, values, &index, 0, 0, protoOutput);
protoOutput->end(atomToken);
}
diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp
index 2fcde29..b29de53 100644
--- a/cmds/statsd/tests/LogEvent_test.cpp
+++ b/cmds/statsd/tests/LogEvent_test.cpp
@@ -12,9 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "src/logd/LogEvent.h"
#include <gtest/gtest.h>
#include <log/log_event_list.h>
-#include "src/logd/LogEvent.h"
+#include "frameworks/base/cmds/statsd/src/atoms.pb.h"
+#include "frameworks/base/core/proto/android/stats/launcher/launcher.pb.h"
#ifdef __ANDROID__
@@ -22,6 +24,9 @@
namespace os {
namespace statsd {
+using std::string;
+using util::ProtoOutputStream;
+
TEST(LogEventTest, TestLogParsing) {
LogEvent event1(1, 2000);
@@ -159,6 +164,94 @@
}
+TEST(LogEventTest, TestBinaryFieldAtom) {
+ Atom launcherAtom;
+ auto launcher_event = launcherAtom.mutable_launcher_event();
+ launcher_event->set_action(stats::launcher::LauncherAction::LONGPRESS);
+ launcher_event->set_src_state(stats::launcher::LauncherState::OVERVIEW);
+ launcher_event->set_dst_state(stats::launcher::LauncherState::ALLAPPS);
+
+ auto extension = launcher_event->mutable_extension();
+
+ auto src_target = extension->add_src_target();
+ src_target->set_type(stats::launcher::LauncherTarget_Type_ITEM_TYPE);
+ src_target->set_item(stats::launcher::LauncherTarget_Item_FOLDER_ICON);
+
+ auto dst_target = extension->add_dst_target();
+ dst_target->set_type(stats::launcher::LauncherTarget_Type_ITEM_TYPE);
+ dst_target->set_item(stats::launcher::LauncherTarget_Item_WIDGET);
+
+ string extension_str;
+ extension->SerializeToString(&extension_str);
+
+ LogEvent event1(Atom::kLauncherEventFieldNumber, 1000);
+
+ event1.write((int32_t)stats::launcher::LauncherAction::LONGPRESS);
+ event1.write((int32_t)stats::launcher::LauncherState::OVERVIEW);
+ event1.write((int64_t)stats::launcher::LauncherState::ALLAPPS);
+ event1.write(extension_str);
+ event1.init();
+
+ ProtoOutputStream proto;
+ event1.ToProto(proto);
+
+ std::vector<uint8_t> outData;
+ outData.resize(proto.size());
+ size_t pos = 0;
+ auto iter = proto.data();
+ while (iter.readBuffer() != NULL) {
+ size_t toRead = iter.currentToRead();
+ std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
+ pos += toRead;
+ iter.rp()->move(toRead);
+ }
+
+ std::string result_str(outData.begin(), outData.end());
+ std::string orig_str;
+ launcherAtom.SerializeToString(&orig_str);
+
+ EXPECT_EQ(orig_str, result_str);
+}
+
+TEST(LogEventTest, TestBinaryFieldAtom_empty) {
+ Atom launcherAtom;
+ auto launcher_event = launcherAtom.mutable_launcher_event();
+ launcher_event->set_action(stats::launcher::LauncherAction::LONGPRESS);
+ launcher_event->set_src_state(stats::launcher::LauncherState::OVERVIEW);
+ launcher_event->set_dst_state(stats::launcher::LauncherState::ALLAPPS);
+
+ // empty string.
+ string extension_str;
+
+ LogEvent event1(Atom::kLauncherEventFieldNumber, 1000);
+
+ event1.write((int32_t)stats::launcher::LauncherAction::LONGPRESS);
+ event1.write((int32_t)stats::launcher::LauncherState::OVERVIEW);
+ event1.write((int64_t)stats::launcher::LauncherState::ALLAPPS);
+ event1.write(extension_str);
+ event1.init();
+
+ ProtoOutputStream proto;
+ event1.ToProto(proto);
+
+ std::vector<uint8_t> outData;
+ outData.resize(proto.size());
+ size_t pos = 0;
+ auto iter = proto.data();
+ while (iter.readBuffer() != NULL) {
+ size_t toRead = iter.currentToRead();
+ std::memcpy(&(outData[pos]), iter.readBuffer(), toRead);
+ pos += toRead;
+ iter.rp()->move(toRead);
+ }
+
+ std::string result_str(outData.begin(), outData.end());
+ std::string orig_str;
+ launcherAtom.SerializeToString(&orig_str);
+
+ EXPECT_EQ(orig_str, result_str);
+}
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
index 218d52a..e125887 100644
--- a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
+++ b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp
@@ -71,12 +71,12 @@
const std::shared_ptr<DimToValMap>& currentBucket,
const std::set<const MetricDimensionKey>& trueList,
const std::set<const MetricDimensionKey>& falseList) {
- for (MetricDimensionKey key : trueList) {
+ for (const MetricDimensionKey& key : trueList) {
if (!tracker.detectAnomaly(bucketNum, key, getBucketValue(currentBucket, key))) {
return false;
}
}
- for (MetricDimensionKey key : falseList) {
+ for (const MetricDimensionKey& key : falseList) {
if (tracker.detectAnomaly(bucketNum, key, getBucketValue(currentBucket, key))) {
return false;
}
diff --git a/cmds/telecom/src/com/android/commands/telecom/Telecom.java b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
index a39f5e3..4174ad7 100644
--- a/cmds/telecom/src/com/android/commands/telecom/Telecom.java
+++ b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
@@ -51,6 +51,8 @@
private static final String COMMAND_ADD_OR_REMOVE_CALL_COMPANION_APP =
"add-or-remove-call-companion-app";
private static final String COMMAND_SET_TEST_AUTO_MODE_APP = "set-test-auto-mode-app";
+ private static final String COMMAND_SET_PHONE_ACCOUNT_SUGGESTION_COMPONENT =
+ "set-phone-acct-suggestion-component";
private static final String COMMAND_UNREGISTER_PHONE_ACCOUNT = "unregister-phone-account";
private static final String COMMAND_SET_DEFAULT_DIALER = "set-default-dialer";
private static final String COMMAND_GET_DEFAULT_DIALER = "get-default-dialer";
@@ -64,36 +66,37 @@
@Override
public void onShowUsage(PrintStream out) {
- out.println(
- "usage: telecom [subcommand] [options]\n" +
- "usage: telecom set-phone-account-enabled <COMPONENT> <ID> <USER_SN>\n" +
- "usage: telecom set-phone-account-disabled <COMPONENT> <ID> <USER_SN>\n" +
- "usage: telecom register-phone-account <COMPONENT> <ID> <USER_SN> <LABEL>\n" +
- "usage: telecom set-test-call-redirection-app <PACKAGE>\n" +
- "usage: telecom set-test-call-screening-app <PACKAGE>\n" +
- "usage: telecom set-test-auto-mode-app <PACKAGE>\n" +
- "usage: telecom add-or-remove-call-companion-app <PACKAGE> <1/0>\n" +
- "usage: telecom register-sim-phone-account <COMPONENT> <ID> <USER_SN> <LABEL> <ADDRESS>\n" +
- "usage: telecom unregister-phone-account <COMPONENT> <ID> <USER_SN>\n" +
- "usage: telecom set-default-dialer <PACKAGE>\n" +
- "usage: telecom get-default-dialer\n" +
- "usage: telecom get-system-dialer\n" +
- "usage: telecom wait-on-handlers\n" +
- "\n" +
- "telecom set-phone-account-enabled: Enables the given phone account, if it has \n" +
- " already been registered with Telecom.\n" +
- "\n" +
- "telecom set-phone-account-disabled: Disables the given phone account, if it \n" +
- " has already been registered with telecom.\n" +
- "\n" +
- "telecom set-default-dialer: Sets the default dialer to the given component. \n" +
- "\n" +
- "telecom get-default-dialer: Displays the current default dialer. \n" +
- "\n" +
- "telecom get-system-dialer: Displays the current system dialer. \n" +
- "\n" +
- "telecom wait-on-handlers: Wait until all handlers finish their work. \n"
- );
+ out.println("usage: telecom [subcommand] [options]\n"
+ + "usage: telecom set-phone-account-enabled <COMPONENT> <ID> <USER_SN>\n"
+ + "usage: telecom set-phone-account-disabled <COMPONENT> <ID> <USER_SN>\n"
+ + "usage: telecom register-phone-account <COMPONENT> <ID> <USER_SN> <LABEL>\n"
+ + "usage: telecom set-test-call-redirection-app <PACKAGE>\n"
+ + "usage: telecom set-test-call-screening-app <PACKAGE>\n"
+ + "usage: telecom set-test-auto-mode-app <PACKAGE>\n"
+ + "usage: telecom set-phone-acct-suggestion-component <COMPONENT>\n"
+ + "usage: telecom add-or-remove-call-companion-app <PACKAGE> <1/0>\n"
+ + "usage: telecom register-sim-phone-account <COMPONENT> <ID> <USER_SN>"
+ + " <LABEL> <ADDRESS>\n"
+ + "usage: telecom unregister-phone-account <COMPONENT> <ID> <USER_SN>\n"
+ + "usage: telecom set-default-dialer <PACKAGE>\n"
+ + "usage: telecom get-default-dialer\n"
+ + "usage: telecom get-system-dialer\n"
+ + "usage: telecom wait-on-handlers\n"
+ + "\n"
+ + "telecom set-phone-account-enabled: Enables the given phone account, if it has \n"
+ + " already been registered with Telecom.\n"
+ + "\n"
+ + "telecom set-phone-account-disabled: Disables the given phone account, if it \n"
+ + " has already been registered with telecom.\n"
+ + "\n"
+ + "telecom set-default-dialer: Sets the default dialer to the given component. \n"
+ + "\n"
+ + "telecom get-default-dialer: Displays the current default dialer. \n"
+ + "\n"
+ + "telecom get-system-dialer: Displays the current system dialer. \n"
+ + "\n"
+ + "telecom wait-on-handlers: Wait until all handlers finish their work. \n"
+ );
}
@Override
@@ -134,6 +137,9 @@
case COMMAND_SET_TEST_AUTO_MODE_APP:
runSetTestAutoModeApp();
break;
+ case COMMAND_SET_PHONE_ACCOUNT_SUGGESTION_COMPONENT:
+ runSetTestPhoneAcctSuggestionComponent();
+ break;
case COMMAND_REGISTER_SIM_PHONE_ACCOUNT:
runRegisterSimPhoneAccount();
break;
@@ -216,6 +222,11 @@
mTelecomService.setTestAutoModeApp(packageName);
}
+ private void runSetTestPhoneAcctSuggestionComponent() throws RemoteException {
+ final String componentName = nextArg();
+ mTelecomService.setTestPhoneAcctSuggestionComponent(componentName);
+ }
+
private void runUnregisterPhoneAccount() throws RemoteException {
final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs();
mTelecomService.unregisterPhoneAccount(handle);
diff --git a/config/dirty-image-objects b/config/dirty-image-objects
index 9b4d199..9e2230b 100644
--- a/config/dirty-image-objects
+++ b/config/dirty-image-objects
@@ -44,7 +44,6 @@
sun.misc.FormattedFloatingDecimal
java.util.stream.IntStream
android.icu.util.TimeZone
-libcore.io.DropBox
org.apache.harmony.luni.internal.util.TimezoneGetter
dalvik.system.SocketTagger
dalvik.system.CloseGuard
@@ -137,7 +136,6 @@
android.icu.util.ULocale
dalvik.system.BaseDexClassLoader
android.icu.text.BreakIterator
-libcore.io.EventLogger
libcore.net.NetworkSecurityPolicy
android.icu.text.UnicodeSet
com.android.org.conscrypt.TrustedCertificateStore$PreloadHolder
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index 2aeb431..648ff27 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -2938,7 +2938,6 @@
Lcom/android/internal/telephony/dataconnection/DataConnection;->mActiveState:Lcom/android/internal/telephony/dataconnection/DataConnection$DcActiveState;
Lcom/android/internal/telephony/dataconnection/DataConnection;->mConnectionParams:Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;
Lcom/android/internal/telephony/dataconnection/DataConnection;->mDataRegState:I
-Lcom/android/internal/telephony/dataconnection/DataConnection;->mDcFailCause:Lcom/android/internal/telephony/dataconnection/DcFailCause;
Lcom/android/internal/telephony/dataconnection/DataConnection;->mDct:Lcom/android/internal/telephony/dataconnection/DcTracker;
Lcom/android/internal/telephony/dataconnection/DataConnection;->mDisconnectingErrorCreatingConnection:Lcom/android/internal/telephony/dataconnection/DataConnection$DcDisconnectionErrorCreatingConnection;
Lcom/android/internal/telephony/dataconnection/DataConnection;->mDisconnectingState:Lcom/android/internal/telephony/dataconnection/DataConnection$DcDisconnectingState;
@@ -2949,10 +2948,8 @@
Lcom/android/internal/telephony/dataconnection/DataConnection;->mNetworkInfo:Landroid/net/NetworkInfo;
Lcom/android/internal/telephony/dataconnection/DataConnection;->mPhone:Lcom/android/internal/telephony/Phone;
Lcom/android/internal/telephony/dataconnection/DataConnection;->mRilRat:I
-Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyAllDisconnectCompleted(Lcom/android/internal/telephony/dataconnection/DcFailCause;)V
Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyAllOfConnected(Ljava/lang/String;)V
Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyAllOfDisconnectDcRetrying(Ljava/lang/String;)V
-Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyConnectCompleted(Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;Lcom/android/internal/telephony/dataconnection/DcFailCause;Z)V
Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyDisconnectCompleted(Lcom/android/internal/telephony/dataconnection/DataConnection$DisconnectParams;Z)V
Lcom/android/internal/telephony/dataconnection/DataConnection;->onConnect(Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;)V
Lcom/android/internal/telephony/dataconnection/DataConnection;->tearDownData(Ljava/lang/Object;)V
@@ -2961,22 +2958,6 @@
Lcom/android/internal/telephony/dataconnection/DcController;->mDcListActiveByCid:Ljava/util/HashMap;
Lcom/android/internal/telephony/dataconnection/DcController;->mDct:Lcom/android/internal/telephony/dataconnection/DcTracker;
Lcom/android/internal/telephony/dataconnection/DcController;->mDcTesterDeactivateAll:Lcom/android/internal/telephony/dataconnection/DcTesterDeactivateAll;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->ACTIVATION_REJECT_GGSN:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->ACTIVATION_REJECT_UNSPECIFIED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->APN_TYPE_CONFLICT:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->INSUFFICIENT_RESOURCES:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->MISSING_UNKNOWN_APN:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->NSAPI_IN_USE:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->ONLY_IPV4_ALLOWED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->ONLY_IPV6_ALLOWED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->ONLY_SINGLE_BEARER_ALLOWED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->OPERATOR_BARRED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->PROTOCOL_ERRORS:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->SERVICE_OPTION_NOT_SUBSCRIBED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->SERVICE_OPTION_NOT_SUPPORTED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->SERVICE_OPTION_OUT_OF_ORDER:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->UNKNOWN_PDP_ADDRESS_TYPE:Lcom/android/internal/telephony/dataconnection/DcFailCause;
-Lcom/android/internal/telephony/dataconnection/DcFailCause;->USER_AUTHENTICATION:Lcom/android/internal/telephony/dataconnection/DcFailCause;
Lcom/android/internal/telephony/dataconnection/DcTracker$RecoveryAction;->isAggressiveRecovery(I)Z
Lcom/android/internal/telephony/dataconnection/DcTracker;->cancelReconnectAlarm(Lcom/android/internal/telephony/dataconnection/ApnContext;)V
Lcom/android/internal/telephony/dataconnection/DcTracker;->cleanUpAllConnections(Ljava/lang/String;)V
@@ -3011,7 +2992,6 @@
Lcom/android/internal/telephony/dataconnection/DcTracker;->onActionIntentDataStallAlarm(Landroid/content/Intent;)V
Lcom/android/internal/telephony/dataconnection/DcTracker;->onActionIntentProvisioningApnAlarm(Landroid/content/Intent;)V
Lcom/android/internal/telephony/dataconnection/DcTracker;->onRecordsLoadedOrSubIdChanged()V
-Lcom/android/internal/telephony/dataconnection/DcTracker;->onSetUserDataEnabled(Z)V
Lcom/android/internal/telephony/dataconnection/DcTracker;->onTrySetupData(Lcom/android/internal/telephony/dataconnection/ApnContext;)Z
Lcom/android/internal/telephony/dataconnection/DcTracker;->onTrySetupData(Ljava/lang/String;)Z
Lcom/android/internal/telephony/dataconnection/DcTracker;->registerSettingsObserver()V
diff --git a/config/preloaded-classes b/config/preloaded-classes
index 495615b..fafcc6b 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -6124,12 +6124,6 @@
libcore.io.ClassPathURLStreamHandler
libcore.io.ClassPathURLStreamHandler$ClassPathURLConnection
libcore.io.ClassPathURLStreamHandler$ClassPathURLConnection$1
-libcore.io.DropBox
-libcore.io.DropBox$DefaultReporter
-libcore.io.DropBox$Reporter
-libcore.io.EventLogger
-libcore.io.EventLogger$DefaultReporter
-libcore.io.EventLogger$Reporter
libcore.io.ForwardingOs
libcore.io.IoBridge
libcore.io.IoTracker
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 47fddfe..15af8a9 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -81,7 +81,6 @@
import android.os.Build;
import android.os.Bundle;
import android.os.Debug;
-import android.os.DropBoxManager;
import android.os.Environment;
import android.os.GraphicsEnvironment;
import android.os.Handler;
@@ -157,8 +156,6 @@
import dalvik.system.VMDebug;
import dalvik.system.VMRuntime;
-import libcore.io.DropBox;
-import libcore.io.EventLogger;
import libcore.io.IoUtils;
import libcore.net.event.NetworkEventDispatcher;
@@ -6680,9 +6677,6 @@
}
}
- // add dropbox logging to libcore
- DropBox.setReporter(new DropBoxReporter());
-
ViewRootImpl.ConfigChangedCallback configChangedCallback
= (Configuration globalConfig) -> {
synchronized (mResourcesManager) {
@@ -6736,38 +6730,6 @@
}
}
- private static class EventLoggingReporter implements EventLogger.Reporter {
- @Override
- public void report (int code, Object... list) {
- EventLog.writeEvent(code, list);
- }
- }
-
- private class DropBoxReporter implements DropBox.Reporter {
-
- private DropBoxManager dropBox;
-
- public DropBoxReporter() {}
-
- @Override
- public void addData(String tag, byte[] data, int flags) {
- ensureInitialized();
- dropBox.addData(tag, data, flags);
- }
-
- @Override
- public void addText(String tag, String data) {
- ensureInitialized();
- dropBox.addText(tag, data);
- }
-
- private synchronized void ensureInitialized() {
- if (dropBox == null) {
- dropBox = (DropBoxManager) getSystemContext().getSystemService(Context.DROPBOX_SERVICE);
- }
- }
- }
-
public static void main(String[] args) {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
@@ -6778,9 +6740,6 @@
Environment.initForCurrentUser();
- // Set the reporter for event logging in libcore
- EventLogger.setReporter(new EventLoggingReporter());
-
// Make sure TrustedCertificateStore looks in the right place for CA certificates
final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
TrustedCertificateStore.setDefaultUserDirectory(configDir);
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index b976d3f..15005d0 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -87,6 +87,7 @@
import android.net.IpSecManager;
import android.net.NetworkPolicyManager;
import android.net.NetworkScoreManager;
+import android.net.NetworkStack;
import android.net.NetworkWatchlistManager;
import android.net.lowpan.ILowpanManager;
import android.net.lowpan.LowpanManager;
@@ -283,6 +284,13 @@
return new ConnectivityManager(context, service);
}});
+ registerService(Context.NETWORK_STACK_SERVICE, NetworkStack.class,
+ new StaticServiceFetcher<NetworkStack>() {
+ @Override
+ public NetworkStack createService() {
+ return new NetworkStack();
+ }});
+
registerService(Context.IPSEC_SERVICE, IpSecManager.class,
new CachedServiceFetcher<IpSecManager>() {
@Override
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 72795cf..81e72cc 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -49,6 +49,7 @@
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
+import android.net.NetworkStack;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@@ -3504,6 +3505,15 @@
/**
* Use with {@link #getSystemService(String)} to retrieve a
+ * {@link NetworkStack} for communicating with the network stack
+ * @hide
+ * @see #getSystemService(String)
+ * @see NetworkStack
+ */
+ public static final String NETWORK_STACK_SERVICE = "network_stack";
+
+ /**
+ * Use with {@link #getSystemService(String)} to retrieve a
* {@link android.net.IpSecManager} for encrypting Sockets or Networks with
* IPSec.
*
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 4714587..49c3dc6 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -187,13 +187,19 @@
* is for a network to which the connectivity manager was failing over
* following a disconnect on another network.
* Retrieve it with {@link android.content.Intent#getBooleanExtra(String,boolean)}.
+ *
+ * @deprecated See {@link NetworkInfo}.
*/
+ @Deprecated
public static final String EXTRA_IS_FAILOVER = "isFailover";
/**
* The lookup key for a {@link NetworkInfo} object. This is supplied when
* there is another network that it may be possible to connect to. Retrieve with
* {@link android.content.Intent#getParcelableExtra(String)}.
+ *
+ * @deprecated See {@link NetworkInfo}.
*/
+ @Deprecated
public static final String EXTRA_OTHER_NETWORK_INFO = "otherNetwork";
/**
* The lookup key for a boolean that indicates whether there is a
@@ -214,7 +220,10 @@
* may be passed up from the lower networking layers, and its
* meaning may be specific to a particular network type. Retrieve
* it with {@link android.content.Intent#getStringExtra(String)}.
+ *
+ * @deprecated See {@link NetworkInfo#getExtraInfo()}.
*/
+ @Deprecated
public static final String EXTRA_EXTRA_INFO = "extraInfo";
/**
* The lookup key for an int that provides information about
@@ -895,7 +904,9 @@
*
* @return a {@link NetworkInfo} object for the current default network
* or {@code null} if no default network is currently active
+ * @deprecated See {@link NetworkInfo}.
*/
+ @Deprecated
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
public NetworkInfo getActiveNetworkInfo() {
try {
@@ -1079,7 +1090,9 @@
* @return a {@link NetworkInfo} object for the requested
* network or {@code null} if the {@code Network}
* is not valid.
+ * @deprecated See {@link NetworkInfo}.
*/
+ @Deprecated
@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
public NetworkInfo getNetworkInfo(Network network) {
return getNetworkInfoForUid(network, Process.myUid(), false);
diff --git a/core/java/android/net/INetdEventCallback.aidl b/core/java/android/net/INetdEventCallback.aidl
index 4b1a08d..0877a1a4 100644
--- a/core/java/android/net/INetdEventCallback.aidl
+++ b/core/java/android/net/INetdEventCallback.aidl
@@ -45,6 +45,20 @@
in String[] ipAddresses, int ipAddressesCount, long timestamp, int uid);
/**
+ * Represents adding or removing a NAT64 prefix.
+ * This method must not block or perform long-running operations.
+ *
+ * @param netId the ID of the network the prefix was performed on.
+ * @param added true if the NAT64 prefix was added, or false if the NAT64 prefix was removed.
+ * There is only one prefix at a time for each netId. If a prefix is added, it replaces
+ * the previous-added prefix.
+ * @param prefixString the detected NAT64 prefix as a string literal.
+ * @param prefixLength the prefix length associated with this NAT64 prefix.
+ */
+ void onNat64PrefixEvent(int netId, boolean added, @utf8InCpp String prefixString,
+ int prefixLength);
+
+ /**
* Represents a private DNS validation success or failure.
* This method must not block or perform long-running operations.
*
diff --git a/core/java/android/net/INetworkStackConnector.aidl b/core/java/android/net/INetworkStackConnector.aidl
new file mode 100644
index 0000000..29f8828
--- /dev/null
+++ b/core/java/android/net/INetworkStackConnector.aidl
@@ -0,0 +1,21 @@
+/**
+ * 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 perNmissions and
+ * limitations under the License.
+ */
+package android.net;
+
+/** @hide */
+oneway interface INetworkStackConnector {
+ // TODO: requestDhcpServer(), etc. will go here
+}
\ No newline at end of file
diff --git a/core/java/android/net/InetAddresses.java b/core/java/android/net/InetAddresses.java
new file mode 100644
index 0000000..8e6c69a
--- /dev/null
+++ b/core/java/android/net/InetAddresses.java
@@ -0,0 +1,63 @@
+/*
+ * 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.
+ */
+
+package android.net;
+
+import libcore.net.InetAddressUtils;
+
+import java.net.InetAddress;
+
+/**
+ * Utility methods for {@link InetAddress} implementations.
+ */
+public class InetAddresses {
+
+ private InetAddresses() {}
+
+ /**
+ * Checks to see if the {@code address} is a numeric address (such as {@code "192.0.2.1"} or
+ * {@code "2001:db8::1:2"}).
+ *
+ * <p>A numeric address is either an IPv4 address containing exactly 4 decimal numbers or an
+ * IPv6 numeric address. IPv4 addresses that consist of either hexadecimal or octal digits or
+ * do not have exactly 4 numbers are not treated as numeric.
+ *
+ * <p>This method will never do a DNS lookup.
+ *
+ * @param address the address to parse.
+ * @return true if the supplied address is numeric, false otherwise.
+ */
+ public static boolean isNumericAddress(String address) {
+ return InetAddressUtils.isNumericAddress(address);
+ }
+
+ /**
+ * Returns an InetAddress corresponding to the given numeric address (such
+ * as {@code "192.168.0.1"} or {@code "2001:4860:800d::68"}).
+ *
+ * <p>See {@link #isNumericAddress(String)} (String)} for a definition as to what constitutes a
+ * numeric address.
+ *
+ * <p>This method will never do a DNS lookup.
+ *
+ * @param address the address to parse, must be numeric.
+ * @return an {@link InetAddress} instance corresponding to the address.
+ * @throws IllegalArgumentException if {@code address} is not a numeric address.
+ */
+ public static InetAddress parseNumericAddress(String address) {
+ return InetAddressUtils.parseNumericAddress(address);
+ }
+}
diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java
index 1b9a66c..80517ce 100644
--- a/core/java/android/net/LinkProperties.java
+++ b/core/java/android/net/LinkProperties.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -161,7 +162,7 @@
/**
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public LinkProperties() {
}
@@ -195,7 +196,7 @@
* @param iface The name of the network interface used for this link.
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public void setInterfaceName(String iface) {
mIfaceName = iface;
ArrayList<RouteInfo> newRoutes = new ArrayList<>(mRoutes.size());
@@ -346,7 +347,7 @@
* object.
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public void setLinkAddresses(Collection<LinkAddress> addresses) {
mLinkAddresses.clear();
for (LinkAddress address: addresses) {
@@ -392,7 +393,7 @@
* @param dnsServers The {@link Collection} of DNS servers to set in this object.
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public void setDnsServers(Collection<InetAddress> dnsServers) {
mDnses.clear();
for (InetAddress dnsServer: dnsServers) {
@@ -529,7 +530,7 @@
* domains to search when resolving host names on this link.
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public void setDomains(String domains) {
mDomains = domains;
}
@@ -552,7 +553,7 @@
* @param mtu The MTU to use for this link.
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public void setMtu(int mtu) {
mMtu = mtu;
}
@@ -562,9 +563,7 @@
* this will return 0.
*
* @return The mtu value set for this link.
- * @hide
*/
- @UnsupportedAppUsage
public int getMtu() {
return mMtu;
}
@@ -613,7 +612,7 @@
*
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public boolean addRoute(RouteInfo route) {
if (route != null) {
String routeIface = route.getInterface();
@@ -688,7 +687,7 @@
* @param proxy A {@link ProxyInfo} defining the HTTP Proxy to use on this link.
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public void setHttpProxy(ProxyInfo proxy) {
mHttpProxy = proxy;
}
@@ -760,7 +759,7 @@
* Clears this object to its initial state.
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public void clear() {
mIfaceName = null;
mLinkAddresses.clear();
diff --git a/core/java/android/net/NetworkCapabilities.java b/core/java/android/net/NetworkCapabilities.java
index 8a5f43d..1b44c92 100644
--- a/core/java/android/net/NetworkCapabilities.java
+++ b/core/java/android/net/NetworkCapabilities.java
@@ -1017,7 +1017,7 @@
* @return The bearer-specific signal strength.
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public int getSignalStrength() {
return mSignalStrength;
}
@@ -1467,7 +1467,7 @@
appendStringRepresentationOfBitMaskToStringBuilder(sb, mNetworkCapabilities,
NetworkCapabilities::capabilityNameOf, "&");
}
- if (0 != mNetworkCapabilities) {
+ if (0 != mUnwantedNetworkCapabilities) {
sb.append(" Unwanted: ");
appendStringRepresentationOfBitMaskToStringBuilder(sb, mUnwantedNetworkCapabilities,
NetworkCapabilities::capabilityNameOf, "&");
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index 1a1d2d334..89d9961 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -28,7 +28,20 @@
* Describes the status of a network interface.
* <p>Use {@link ConnectivityManager#getActiveNetworkInfo()} to get an instance that represents
* the current network connection.
+ *
+ * @deprecated Callers should instead use the {@link ConnectivityManager.NetworkCallback} API to
+ * learn about connectivity changes, or switch to use
+ * {@link ConnectivityManager#getNetworkCapabilities} or
+ * {@link ConnectivityManager#getLinkProperties} to get information synchronously. Keep
+ * in mind that while callbacks are guaranteed to be called for every event in order,
+ * synchronous calls have no such constraints, and as such it is unadvisable to use the
+ * synchronous methods inside the callbacks as they will often not offer a view of
+ * networking that is consistent (that is: they may return a past or a future state with
+ * respect to the event being processed by the callback). Instead, callers are advised
+ * to only use the arguments of the callbacks, possibly memorizing the specific bits of
+ * information they need to keep from one callback to another.
*/
+@Deprecated
public class NetworkInfo implements Parcelable {
/**
@@ -52,7 +65,10 @@
* <tr><td><code>FAILED</code></td><td><code>DISCONNECTED</code></td></tr>
* <tr><td><code>BLOCKED</code></td><td><code>DISCONNECTED</code></td></tr>
* </table>
+ *
+ * @deprecated See {@link NetworkInfo}.
*/
+ @Deprecated
public enum State {
CONNECTING, CONNECTED, SUSPENDED, DISCONNECTING, DISCONNECTED, UNKNOWN
}
@@ -61,7 +77,10 @@
* The fine-grained state of a network connection. This level of detail
* is probably of interest to few applications. Most should use
* {@link android.net.NetworkInfo.State State} instead.
+ *
+ * @deprecated See {@link NetworkInfo}.
*/
+ @Deprecated
public enum DetailedState {
/** Ready to start data connection setup. */
IDLE,
@@ -463,8 +482,10 @@
* Set the extraInfo field.
* @param extraInfo an optional {@code String} providing addditional network state
* information passed up from the lower networking layers.
+ * @deprecated See {@link NetworkInfo#getExtraInfo}.
* @hide
*/
+ @Deprecated
public void setExtraInfo(String extraInfo) {
synchronized (this) {
this.mExtraInfo = extraInfo;
@@ -488,7 +509,10 @@
* Report the extra information about the network state, if any was
* provided by the lower networking layers.
* @return the extra information, or null if not available
+ * @deprecated Use other services e.g. WifiManager to get additional information passed up from
+ * the lower networking layers.
*/
+ @Deprecated
public String getExtraInfo() {
synchronized (this) {
return mExtraInfo;
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index 04b6b44..3b01b03 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -17,6 +17,7 @@
package android.net;
import android.annotation.NonNull;
+import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.net.NetworkCapabilities.NetCapability;
import android.net.NetworkCapabilities.Transport;
@@ -344,7 +345,7 @@
* @param signalStrength the bearer-specific signal strength.
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public Builder setSignalStrength(int signalStrength) {
mNetworkCapabilities.setSignalStrength(signalStrength);
return this;
diff --git a/core/java/android/net/NetworkStack.java b/core/java/android/net/NetworkStack.java
new file mode 100644
index 0000000..82a4e31
--- /dev/null
+++ b/core/java/android/net/NetworkStack.java
@@ -0,0 +1,156 @@
+/*
+ * 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.
+ */
+package android.net;
+
+import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
+import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemService;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Process;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+
+/**
+ * Service used to communicate with the network stack, which is running in a separate module.
+ * @hide
+ */
+@SystemService(Context.NETWORK_STACK_SERVICE)
+public class NetworkStack {
+ private static final String TAG = NetworkStack.class.getSimpleName();
+
+ @NonNull
+ @GuardedBy("mPendingNetStackRequests")
+ private final ArrayList<NetworkStackRequest> mPendingNetStackRequests = new ArrayList<>();
+ @Nullable
+ @GuardedBy("mPendingNetStackRequests")
+ private INetworkStackConnector mConnector;
+
+ private interface NetworkStackRequest {
+ void onNetworkStackConnected(INetworkStackConnector connector);
+ }
+
+ public NetworkStack() { }
+
+ private class NetworkStackConnection implements ServiceConnection {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ registerNetworkStackService(service);
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ // TODO: crash/reboot the system ?
+ Slog.wtf(TAG, "Lost network stack connector");
+ }
+ };
+
+ private void registerNetworkStackService(@NonNull IBinder service) {
+ final INetworkStackConnector connector = INetworkStackConnector.Stub.asInterface(service);
+
+ ServiceManager.addService(Context.NETWORK_STACK_SERVICE, service, false /* allowIsolated */,
+ DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL);
+
+ final ArrayList<NetworkStackRequest> requests;
+ synchronized (mPendingNetStackRequests) {
+ requests = new ArrayList<>(mPendingNetStackRequests);
+ mPendingNetStackRequests.clear();
+ mConnector = connector;
+ }
+
+ for (NetworkStackRequest r : requests) {
+ r.onNetworkStackConnected(connector);
+ }
+ }
+
+ /**
+ * Start the network stack. Should be called only once on device startup.
+ *
+ * <p>This method will start the network stack either in the network stack process, or inside
+ * the system server on devices that do not support the network stack module. The network stack
+ * connector will then be delivered asynchronously to clients that requested it before it was
+ * started.
+ */
+ public void start(Context context) {
+ // Try to bind in-process if the library is available
+ IBinder connector = null;
+ try {
+ final Class service = Class.forName(
+ "com.android.server.NetworkStackService",
+ true /* initialize */,
+ context.getClassLoader());
+ connector = (IBinder) service.getMethod("makeConnector").invoke(null);
+ } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
+ Slog.wtf(TAG, "Could not create network stack connector from NetworkStackService");
+ // TODO: crash/reboot system here ?
+ return;
+ } catch (ClassNotFoundException e) {
+ // Normal behavior if stack is provided by the app: fall through
+ }
+
+ // In-process network stack. Add the service to the service manager here.
+ if (connector != null) {
+ registerNetworkStackService(connector);
+ return;
+ }
+ // Start the network stack process. The service will be added to the service manager in
+ // NetworkStackConnection.onServiceConnected().
+ final Intent intent = new Intent(INetworkStackConnector.class.getName());
+ final ComponentName comp = intent.resolveSystemService(context.getPackageManager(), 0);
+ intent.setComponent(comp);
+
+ if (comp == null || !context.bindServiceAsUser(intent, new NetworkStackConnection(),
+ Context.BIND_AUTO_CREATE | Context.BIND_IMPORTANT, UserHandle.SYSTEM)) {
+ Slog.wtf(TAG,
+ "Could not bind to network stack in-process, or in app with " + intent);
+ // TODO: crash/reboot system server if no network stack after a timeout ?
+ }
+ }
+
+ // TODO: use this method to obtain the connector when implementing network stack operations
+ private void requestConnector(@NonNull NetworkStackRequest request) {
+ // TODO: PID check.
+ if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+ // Don't even attempt to obtain the connector and give a nice error message
+ throw new SecurityException(
+ "Only the system server should try to bind to the network stack.");
+ }
+
+ final INetworkStackConnector connector;
+ synchronized (mPendingNetStackRequests) {
+ connector = mConnector;
+ if (connector == null) {
+ mPendingNetStackRequests.add(request);
+ return;
+ }
+ }
+
+ request.onNetworkStackConnected(connector);
+ }
+}
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 34e9476..c0aa4a6 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -17,6 +17,7 @@
package android.net;
import android.annotation.UnsupportedAppUsage;
+import android.os.Build;
import android.os.Parcel;
import android.util.Log;
import android.util.Pair;
@@ -294,8 +295,10 @@
* @param addrString
* @return the InetAddress
* @hide
+ * @deprecated Use {@link InetAddresses#parseNumericAddress(String)}, if possible.
*/
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
+ @Deprecated
public static InetAddress numericToInetAddress(String addrString)
throws IllegalArgumentException {
return InetAddress.parseNumericAddress(addrString);
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index be8cf0e..fdd7488 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -390,7 +390,7 @@
/**
* Setup a new VPN.
*/
- void createVirtualNetwork(int netId, boolean hasDNS, boolean secure);
+ void createVirtualNetwork(int netId, boolean secure);
/**
* Remove a network.
diff --git a/core/java/android/os/NativeHandle.java b/core/java/android/os/NativeHandle.java
index fbecc8e..f7ffc37 100644
--- a/core/java/android/os/NativeHandle.java
+++ b/core/java/android/os/NativeHandle.java
@@ -16,6 +16,8 @@
package android.os;
+import static android.system.OsConstants.F_DUPFD_CLOEXEC;
+
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.system.ErrnoException;
@@ -108,7 +110,10 @@
FileDescriptor[] fds = new FileDescriptor[mFds.length];
try {
for (int i = 0; i < mFds.length; i++) {
- fds[i] = Os.dup(mFds[i]);
+ FileDescriptor newFd = new FileDescriptor();
+ int fdint = Os.fcntlInt(mFds[i], F_DUPFD_CLOEXEC, 0);
+ newFd.setInt$(fdint);
+ fds[i] = newFd;
}
} catch (ErrnoException e) {
e.rethrowAsIOException();
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index d0cdf6e..f2837ecb 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -174,6 +174,12 @@
*/
public static final int SE_UID = 1068;
+ /**
+ * Defines the UID/GID for the NetworkStack app.
+ * @hide
+ */
+ public static final int NETWORK_STACK_UID = 1073;
+
/** {@hide} */
public static final int NOBODY_UID = 9999;
diff --git a/core/java/android/service/carrier/CarrierIdentifier.java b/core/java/android/service/carrier/CarrierIdentifier.java
index e930f40..568ca0f 100644
--- a/core/java/android/service/carrier/CarrierIdentifier.java
+++ b/core/java/android/service/carrier/CarrierIdentifier.java
@@ -71,10 +71,8 @@
* @param gid2 group id level 2
* @param carrierid carrier unique identifier {@link TelephonyManager#getSimCarrierId()}, used
* to uniquely identify the carrier and look up the carrier configurations.
- * @param preciseCarrierId precise carrier identifier {@link TelephonyManager#getSimPreciseCarrierId()}
- * @hide
- *
- * TODO: expose this to public API
+ * @param preciseCarrierId precise carrier identifier
+ * {@link TelephonyManager#getSimPreciseCarrierId()}
*/
public CarrierIdentifier(String mcc, String mnc, @Nullable String spn,
@Nullable String imsi, @Nullable String gid1, @Nullable String gid2,
@@ -155,16 +153,16 @@
}
/**
- * Get the carrier id {@link TelephonyManager#getSimCarrierId() }
- * @hide
+ * Returns the carrier id.
+ * @see TelephonyManager#getSimCarrierId()
*/
public int getCarrierId() {
return mCarrierId;
}
/**
- * Get the precise carrier id {@link TelephonyManager#getSimPreciseCarrierId()}
- * @hide
+ * Returns the precise carrier id.
+ * @see TelephonyManager#getSimPreciseCarrierId()
*/
public int getPreciseCarrierId() {
return mPreciseCarrierId;
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 2e98d03..1dbe166 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -268,6 +268,13 @@
public static final int FX_SURFACE_DIM = 0x00020000;
/**
+ * Surface creation flag: Creates a container surface.
+ * This surface will have no buffers and will only be used
+ * as a container for other surfaces, or for its InputInfo.
+ */
+ public static final int FX_SURFACE_CONTAINER = 0x00080000;
+
+ /**
* Mask used for FX values above.
*
*/
@@ -523,14 +530,39 @@
*/
public Builder setColorLayer(boolean isColorLayer) {
if (isColorLayer) {
- mFlags |= FX_SURFACE_DIM;
+ setFlags(FX_SURFACE_DIM, FX_SURFACE_MASK);
} else {
- mFlags &= ~FX_SURFACE_DIM;
+ setBufferLayer();
}
return this;
}
/**
+ * Indicates whether a 'ContainerLayer' is to be constructed.
+ *
+ * Container layers will not be rendered in any fashion and instead are used
+ * as a parent of renderable layers.
+ *
+ * @param isContainerLayer Whether to create a container layer.
+ */
+ public Builder setContainerLayer(boolean isContainerLayer) {
+ if (isContainerLayer) {
+ setFlags(FX_SURFACE_CONTAINER, FX_SURFACE_MASK);
+ } else {
+ setBufferLayer();
+ }
+ return this;
+ }
+
+ /**
+ * Indicates whether a buffer layer is to be constructed.
+ *
+ */
+ public Builder setBufferLayer() {
+ return setFlags(FX_SURFACE_NORMAL, FX_SURFACE_MASK);
+ }
+
+ /**
* Set 'Surface creation flags' such as {@link HIDDEN}, {@link SECURE}.
*
* TODO: Finish conversion to individual builder methods?
@@ -540,6 +572,11 @@
mFlags = flags;
return this;
}
+
+ private Builder setFlags(int flags, int mask) {
+ mFlags = (mFlags & ~mask) | flags;
+ return this;
+ }
}
/**
diff --git a/core/java/android/webkit/WebSyncManager.java b/core/java/android/webkit/WebSyncManager.java
index 3fa1b01..e44d6eb 100644
--- a/core/java/android/webkit/WebSyncManager.java
+++ b/core/java/android/webkit/WebSyncManager.java
@@ -26,6 +26,7 @@
abstract class WebSyncManager implements Runnable {
protected static final java.lang.String LOGTAG = "websync";
protected android.webkit.WebViewDatabase mDataBase;
+ @UnsupportedAppUsage
protected android.os.Handler mHandler;
protected WebSyncManager(Context context, String name) {
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 8bdb000..c2c6ae6 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -536,9 +536,11 @@
static ClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
String libraryPath = System.getProperty("java.library.path");
+ // We use the boot class loader, that's what the runtime expects at AOT.
+ ClassLoader parent = ClassLoader.getSystemClassLoader().getParent();
+
return ClassLoaderFactory.createClassLoader(classPath, libraryPath, libraryPath,
- ClassLoader.getSystemClassLoader(), targetSdkVersion, true /* isNamespaceShared */,
- null /* classLoaderName */);
+ parent, targetSdkVersion, true /* isNamespaceShared */, null /* classLoaderName */);
}
/**
diff --git a/core/java/com/android/internal/widget/NumericTextView.java b/core/java/com/android/internal/widget/NumericTextView.java
index 27c5834..d215670 100644
--- a/core/java/com/android/internal/widget/NumericTextView.java
+++ b/core/java/com/android/internal/widget/NumericTextView.java
@@ -16,6 +16,7 @@
package com.android.internal.widget;
+import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
@@ -53,6 +54,7 @@
private OnValueChangedListener mListener;
+ @UnsupportedAppUsage
public NumericTextView(Context context, AttributeSet attrs) {
super(context, attrs);
diff --git a/core/java/com/android/server/net/BaseNetdEventCallback.java b/core/java/com/android/server/net/BaseNetdEventCallback.java
index 97247aa..a65214a 100644
--- a/core/java/com/android/server/net/BaseNetdEventCallback.java
+++ b/core/java/com/android/server/net/BaseNetdEventCallback.java
@@ -32,6 +32,12 @@
}
@Override
+ public void onNat64PrefixEvent(int netId, boolean added, String prefixString,
+ int prefixLength) {
+ // default no-op
+ }
+
+ @Override
public void onPrivateDnsValidationEvent(int netId, String ipAddress,
String hostname, boolean validated) {
// default no-op
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index b5860d8..c81a77d 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -264,7 +264,7 @@
"libhardware",
"libhardware_legacy",
"libselinux",
- "libicuuc",
+ "libandroidicu",
"libmedia",
"libmediametrics",
"libaudioclient",
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 5a74a24..b085bc9 100755
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -48,7 +48,7 @@
class BitmapWrapper {
public:
- BitmapWrapper(Bitmap* bitmap)
+ explicit BitmapWrapper(Bitmap* bitmap)
: mBitmap(bitmap) { }
void freePixels() {
diff --git a/core/jni/android/graphics/FontUtils.h b/core/jni/android/graphics/FontUtils.h
index 9eaaa49..30fdf24 100644
--- a/core/jni/android/graphics/FontUtils.h
+++ b/core/jni/android/graphics/FontUtils.h
@@ -27,7 +27,7 @@
namespace android {
struct FontFamilyWrapper {
- FontFamilyWrapper(std::shared_ptr<minikin::FontFamily>&& family) : family(family) {}
+ explicit FontFamilyWrapper(std::shared_ptr<minikin::FontFamily>&& family) : family(family) {}
std::shared_ptr<minikin::FontFamily> family;
};
diff --git a/core/jni/android/graphics/GIFMovie.cpp b/core/jni/android/graphics/GIFMovie.cpp
index dd99b37..f84a4bd 100644
--- a/core/jni/android/graphics/GIFMovie.cpp
+++ b/core/jni/android/graphics/GIFMovie.cpp
@@ -21,7 +21,7 @@
class GIFMovie : public Movie {
public:
- GIFMovie(SkStream* stream);
+ explicit GIFMovie(SkStream* stream);
virtual ~GIFMovie();
protected:
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 6c9f463..9963a45 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -20,7 +20,6 @@
#include "android_media_AudioTrack.h"
#include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
#include "core_jni_helpers.h"
#include <utils/Log.h>
diff --git a/core/jni/android_media_DeviceCallback.cpp b/core/jni/android_media_DeviceCallback.cpp
index 108fa00..a1a0351 100644
--- a/core/jni/android_media_DeviceCallback.cpp
+++ b/core/jni/android_media_DeviceCallback.cpp
@@ -20,7 +20,6 @@
#include <utils/Log.h>
#include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
#include "core_jni_helpers.h"
#include <media/AudioSystem.h>
diff --git a/core/jni/android_os_SharedMemory.cpp b/core/jni/android_os_SharedMemory.cpp
index f6e5c7a..c33405d 100644
--- a/core/jni/android_os_SharedMemory.cpp
+++ b/core/jni/android_os_SharedMemory.cpp
@@ -20,8 +20,9 @@
#include <cutils/ashmem.h>
#include <utils/Log.h>
+
+#include <nativehelper/jni_macros.h>
#include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
#include <nativehelper/ScopedLocalRef.h>
#include <algorithm>
@@ -31,10 +32,10 @@
namespace {
-static void throwErrnoException(JNIEnv* env, const char* functionName, int error) {
- static jmethodID ctor = env->GetMethodID(JniConstants::errnoExceptionClass,
- "<init>", "(Ljava/lang/String;I)V");
+jclass errnoExceptionClass;
+jmethodID errnoExceptionCtor; // MethodID for ErrnoException.<init>(String,I)
+void throwErrnoException(JNIEnv* env, const char* functionName, int error) {
ScopedLocalRef<jstring> detailMessage(env, env->NewStringUTF(functionName));
if (detailMessage.get() == NULL) {
// Not really much we can do here. We're probably dead in the water,
@@ -42,12 +43,14 @@
env->ExceptionClear();
}
- jobject exception = env->NewObject(JniConstants::errnoExceptionClass, ctor,
- detailMessage.get(), error);
+ jobject exception = env->NewObject(errnoExceptionClass,
+ errnoExceptionCtor,
+ detailMessage.get(),
+ error);
env->Throw(reinterpret_cast<jthrowable>(exception));
}
-static jobject SharedMemory_create(JNIEnv* env, jobject, jstring jname, jint size) {
+jobject SharedMemory_nCreate(JNIEnv* env, jobject, jstring jname, jint size) {
// Name is optional so we can't use ScopedUtfChars for this as it throws NPE on null
const char* name = jname ? env->GetStringUTFChars(jname, nullptr) : nullptr;
@@ -69,7 +72,7 @@
return jniCreateFileDescriptor(env, fd);
}
-static jint SharedMemory_getSize(JNIEnv* env, jobject, jobject fileDescriptor) {
+jint SharedMemory_nGetSize(JNIEnv* env, jobject, jobject fileDescriptor) {
int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
if (!ashmem_valid(fd)) {
return -1;
@@ -78,7 +81,7 @@
return static_cast<jint>(std::min(size, static_cast<size_t>(std::numeric_limits<jint>::max())));
}
-static jint SharedMemory_setProt(JNIEnv* env, jobject, jobject fileDescriptor, jint prot) {
+jint SharedMemory_nSetProt(JNIEnv* env, jobject, jobject fileDescriptor, jint prot) {
int fd = jniGetFDFromFileDescriptor(env, fileDescriptor);
int err = 0;
if (ashmem_set_prot_region(fd, prot)) {
@@ -87,18 +90,21 @@
return err;
}
-static const JNINativeMethod methods[] = {
- {"nCreate", "(Ljava/lang/String;I)Ljava/io/FileDescriptor;", (void*)SharedMemory_create},
- {"nGetSize", "(Ljava/io/FileDescriptor;)I", (void*)SharedMemory_getSize},
- {"nSetProt", "(Ljava/io/FileDescriptor;I)I", (void*)SharedMemory_setProt},
+const JNINativeMethod methods[] = {
+ NATIVE_METHOD(SharedMemory, nCreate, "(Ljava/lang/String;I)Ljava/io/FileDescriptor;"),
+ NATIVE_METHOD(SharedMemory, nGetSize, "(Ljava/io/FileDescriptor;)I"),
+ NATIVE_METHOD(SharedMemory, nSetProt, "(Ljava/io/FileDescriptor;I)I")
};
} // anonymous namespace
namespace android {
-int register_android_os_SharedMemory(JNIEnv* env)
-{
+int register_android_os_SharedMemory(JNIEnv* env) {
+ errnoExceptionClass =
+ MakeGlobalRefOrDie(env, FindClassOrDie(env, "android/system/ErrnoException"));
+ errnoExceptionCtor =
+ GetMethodIDOrDie(env, errnoExceptionClass, "<init>", "(Ljava/lang/String;I)V");
return RegisterMethodsOrDie(env, "android/os/SharedMemory", methods, NELEM(methods));
}
diff --git a/core/jni/android_util_jar_StrictJarFile.cpp b/core/jni/android_util_jar_StrictJarFile.cpp
index 4ab8db4..182a621 100644
--- a/core/jni/android_util_jar_StrictJarFile.cpp
+++ b/core/jni/android_util_jar_StrictJarFile.cpp
@@ -22,24 +22,26 @@
#include <log/log.h>
+#include <nativehelper/jni_macros.h>
#include <nativehelper/JNIHelp.h>
-#include <nativehelper/JniConstants.h>
#include <nativehelper/ScopedLocalRef.h>
#include <nativehelper/ScopedUtfChars.h>
-#include "jni.h"
+
+#include "core_jni_helpers.h"
#include "ziparchive/zip_archive.h"
-namespace android {
+namespace {
+jclass zipEntryClass;
// The method ID for ZipEntry.<init>(String,String,JJJIII[BJJ)
-static jmethodID zipEntryCtor;
+jmethodID zipEntryCtor;
-static void throwIoException(JNIEnv* env, const int32_t errorCode) {
+void throwIoException(JNIEnv* env, const int32_t errorCode) {
jniThrowException(env, "java/io/IOException", ErrorCodeString(errorCode));
}
-static jobject newZipEntry(JNIEnv* env, const ZipEntry& entry, jstring entryName) {
- return env->NewObject(JniConstants::zipEntryClass,
+jobject newZipEntry(JNIEnv* env, const ZipEntry& entry, jstring entryName) {
+ return env->NewObject(zipEntryClass,
zipEntryCtor,
entryName,
NULL, // comment
@@ -52,7 +54,7 @@
static_cast<jlong>(entry.offset));
}
-static jlong StrictJarFile_nativeOpenJarFile(JNIEnv* env, jobject, jstring name, jint fd) {
+jlong StrictJarFile_nativeOpenJarFile(JNIEnv* env, jobject, jstring name, jint fd) {
// Name argument is used for logging, and can be any string.
ScopedUtfChars nameChars(env, name);
if (nameChars.c_str() == NULL) {
@@ -90,7 +92,7 @@
};
-static jlong StrictJarFile_nativeStartIteration(JNIEnv* env, jobject, jlong nativeHandle,
+jlong StrictJarFile_nativeStartIteration(JNIEnv* env, jobject, jlong nativeHandle,
jstring prefix) {
ScopedUtfChars prefixChars(env, prefix);
if (prefixChars.c_str() == NULL) {
@@ -116,7 +118,7 @@
return reinterpret_cast<jlong>(handle);
}
-static jobject StrictJarFile_nativeNextEntry(JNIEnv* env, jobject, jlong iterationHandle) {
+jobject StrictJarFile_nativeNextEntry(JNIEnv* env, jobject, jlong iterationHandle) {
ZipEntry data;
ZipString entryName;
@@ -135,7 +137,7 @@
return newZipEntry(env, data, entryNameString.get());
}
-static jobject StrictJarFile_nativeFindEntry(JNIEnv* env, jobject, jlong nativeHandle,
+jobject StrictJarFile_nativeFindEntry(JNIEnv* env, jobject, jlong nativeHandle,
jstring entryName) {
ScopedUtfChars entryNameChars(env, entryName);
if (entryNameChars.c_str() == NULL) {
@@ -152,11 +154,11 @@
return newZipEntry(env, data, entryName);
}
-static void StrictJarFile_nativeClose(JNIEnv*, jobject, jlong nativeHandle) {
+void StrictJarFile_nativeClose(JNIEnv*, jobject, jlong nativeHandle) {
CloseArchive(reinterpret_cast<ZipArchiveHandle>(nativeHandle));
}
-static JNINativeMethod gMethods[] = {
+JNINativeMethod gMethods[] = {
NATIVE_METHOD(StrictJarFile, nativeOpenJarFile, "(Ljava/lang/String;I)J"),
NATIVE_METHOD(StrictJarFile, nativeStartIteration, "(JLjava/lang/String;)J"),
NATIVE_METHOD(StrictJarFile, nativeNextEntry, "(J)Ljava/util/zip/ZipEntry;"),
@@ -164,14 +166,15 @@
NATIVE_METHOD(StrictJarFile, nativeClose, "(J)V"),
};
+} // namespace
+
+namespace android {
+
int register_android_util_jar_StrictJarFile(JNIEnv* env) {
- jniRegisterNativeMethods(env, "android/util/jar/StrictJarFile", gMethods, NELEM(gMethods));
-
- zipEntryCtor = env->GetMethodID(JniConstants::zipEntryClass, "<init>",
- "(Ljava/lang/String;Ljava/lang/String;JJJII[BJ)V");
- LOG_ALWAYS_FATAL_IF(zipEntryCtor == NULL, "Unable to find ZipEntry.<init>");
-
- return 0;
+ zipEntryClass = MakeGlobalRefOrDie(env, FindClassOrDie(env, "java/util/zip/ZipEntry"));
+ zipEntryCtor = GetMethodIDOrDie(env, zipEntryClass, "<init>",
+ "(Ljava/lang/String;Ljava/lang/String;JJJII[BJ)V");
+ return jniRegisterNativeMethods(env, "android/util/jar/StrictJarFile", gMethods, NELEM(gMethods));
}
}; // namespace android
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 01105ba..d4fe1ed 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -414,7 +414,7 @@
}
endmntent(fp);
- for (auto path : toUnmount) {
+ for (const auto& path : toUnmount) {
if (umount2(path.c_str(), MNT_DETACH)) {
ALOGW("Failed to unmount %s: %s", path.c_str(), strerror(errno));
}
@@ -917,6 +917,13 @@
capabilities |= (1LL << CAP_SYS_NICE);
}
+ if (multiuser_get_app_id(uid) == AID_NETWORK_STACK) {
+ capabilities |= (1LL << CAP_NET_ADMIN);
+ capabilities |= (1LL << CAP_NET_BROADCAST);
+ capabilities |= (1LL << CAP_NET_BIND_SERVICE);
+ capabilities |= (1LL << CAP_NET_RAW);
+ }
+
/*
* Grant CAP_BLOCK_SUSPEND to processes that belong to GID "wakelock"
*/
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index d457a1b..d8d919d 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -148,7 +148,7 @@
const bool is_sock;
private:
- FileDescriptorInfo(int fd);
+ explicit FileDescriptorInfo(int fd);
FileDescriptorInfo(struct stat stat, const std::string& file_path, int fd, int open_flags,
int fd_flags, int fs_flags, off_t offset);
@@ -327,11 +327,13 @@
return false;
}
- if (TEMP_FAILURE_RETRY(dup2(new_fd, fd)) == -1) {
+ int dupFlags = (fd_flags & FD_CLOEXEC) ? O_CLOEXEC : 0;
+ if (TEMP_FAILURE_RETRY(dup3(new_fd, fd, dupFlags)) == -1) {
close(new_fd);
- *error_msg = android::base::StringPrintf("Failed dup2(%d, %d) (%s): %s",
+ *error_msg = android::base::StringPrintf("Failed dup3(%d, %d, %d) (%s): %s",
fd,
new_fd,
+ dupFlags,
file_path.c_str(),
strerror(errno));
return false;
diff --git a/core/jni/fd_utils.h b/core/jni/fd_utils.h
index a3570d7..09022a2 100644
--- a/core/jni/fd_utils.h
+++ b/core/jni/fd_utils.h
@@ -86,7 +86,7 @@
bool ReopenOrDetach(std::string* error_msg);
private:
- FileDescriptorTable(const std::unordered_map<int, FileDescriptorInfo*>& map);
+ explicit FileDescriptorTable(const std::unordered_map<int, FileDescriptorInfo*>& map);
bool RestatInternal(std::set<int>& open_fds, std::string* error_msg);
diff --git a/core/proto/android/stats/launcher/launcher.proto b/core/proto/android/stats/launcher/launcher.proto
new file mode 100644
index 0000000..dbd0e03
--- /dev/null
+++ b/core/proto/android/stats/launcher/launcher.proto
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+
+syntax = "proto2";
+package android.stats.launcher;
+option java_multiple_files = true;
+
+enum LauncherAction {
+ DEFAULT_ACTION = 0;
+ LAUNCH_APP = 1;
+ LAUNCH_TASK = 2;
+ DISMISS_TASK = 3;
+ LONGPRESS = 4;
+ DRAGDROP = 5;
+ SWIPE_UP = 6;
+ SWIPE_DOWN = 7;
+ SWIPE_LEFT = 8;
+ SWIPE_RIGHT = 9;
+}
+
+enum LauncherState {
+ BACKGROUND = 0;
+ HOME = 1;
+ OVERVIEW = 2;
+ ALLAPPS = 3;
+}
+
+message LauncherTarget {
+ enum Type {
+ NONE = 0;
+ ITEM_TYPE = 1;
+ CONTROL_TYPE = 2;
+ CONTAINER_TYPE = 3;
+ }
+ enum Item {
+ DEFAULT_ITEM = 0;
+ APP_ICON = 1;
+ SHORTCUT = 2;
+ WIDGET = 3;
+ FOLDER_ICON = 4;
+ DEEPSHORTCUT = 5;
+ SEARCHBOX = 6;
+ EDITTEXT = 7;
+ NOTIFICATION = 8;
+ TASK = 9;
+ }
+ enum Container {
+ DEFAULT_CONTAINER = 0;
+ HOTSEAT = 1;
+ FOLDER = 2;
+ PREDICTION = 3;
+ SEARCHRESULT = 4;
+ }
+ enum Control {
+ DEFAULT_CONTROL = 0;
+ MENU = 1;
+ UNINSTALL = 2;
+ REMOVE = 3;
+ }
+ optional Type type = 1;
+ optional Item item = 2;
+ optional Container container = 3;
+ optional Control control = 4;
+ optional string launch_component = 5;
+ optional int32 page_id = 6;
+ optional int32 grid_x = 7;
+ optional int32 grid_y = 8;
+}
+
+message LauncherExtension {
+ repeated LauncherTarget src_target = 1;
+ repeated LauncherTarget dst_target = 2;
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 5154de0..344b74c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1832,6 +1832,15 @@
<permission android:name="android.permission.BIND_SCREENING_SERVICE"
android:protectionLevel="signature|privileged" />
+ <!-- Must be required by a {@link android.telecom.PhoneAccountSuggestionService},
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature|privileged
+ @SystemApi
+ @hide
+ -->
+ <permission android:name="android.permission.BIND_PHONE_ACCOUNT_SUGGESTION_SERVICE"
+ android:protectionLevel="signature|privileged" />
+
<!-- Must be required by a {@link android.telecom.CallRedirectionService},
to ensure that only the system can bind to it.
<p>Protection level: signature|privileged
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 0082f4b..c8bd847 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -33,6 +33,10 @@
<permission name="android.permission.CRYPT_KEEPER"/>
</privapp-permissions>
+ <privapp-permissions package="com.android.carrierconfig">
+ <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
+ </privapp-permissions>
+
<privapp-permissions package="com.android.cellbroadcastreceiver">
<permission name="android.permission.INTERACT_ACROSS_USERS"/>
<permission name="android.permission.MANAGE_USERS"/>
@@ -315,6 +319,8 @@
<permission name="android.permission.PACKAGE_USAGE_STATS" />
<permission name="android.permission.READ_FRAME_BUFFER"/>
<permission name="android.permission.READ_LOWPAN_CREDENTIAL"/>
+ <!-- Needed for test only -->
+ <permission name="android.permission.READ_PRECISE_PHONE_STATE" />
<permission name="android.permission.REAL_GET_TASKS"/>
<permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
<permission name="android.permission.REGISTER_CALL_PROVIDER"/>
diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java
index 6ac52d1..36b7e37 100644
--- a/keystore/java/android/security/KeyStore.java
+++ b/keystore/java/android/security/KeyStore.java
@@ -54,6 +54,7 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@@ -303,13 +304,14 @@
}
/**
- * List uids of all keys that are auth bound to the current user.
+ * List uids of all keys that are auth bound to the current user.
* Only system is allowed to call this method.
*/
@UnsupportedAppUsage
public int[] listUidsOfAuthBoundKeys() {
- final int MAX_RESULT_SIZE = 100;
- int[] uidsOut = new int[MAX_RESULT_SIZE];
+ // uids are returned as a list of strings because list of integers
+ // as an output parameter is not supported by aidl-cpp.
+ List<String> uidsOut = new ArrayList<>();
try {
int rc = mBinder.listUidsOfAuthBoundKeys(uidsOut);
if (rc != NO_ERROR) {
@@ -323,8 +325,8 @@
Log.w(TAG, "KeyStore exception", e);
return null;
}
- // Remove any 0 entries
- return Arrays.stream(uidsOut).filter(x -> x > 0).toArray();
+ // Turn list of strings into an array of uid integers.
+ return uidsOut.stream().mapToInt(Integer::parseInt).toArray();
}
public String[] list(String prefix) {
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
index 953cef7d..aa29174 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java
@@ -210,6 +210,10 @@
throw new InvalidAlgorithmParameterException(
"HMAC key size must be at least 64 bits.");
}
+ if (mKeySizeBits > 512 && spec.isStrongBoxBacked()) {
+ throw new InvalidAlgorithmParameterException(
+ "StrongBox HMAC key size must be smaller than 512 bits.");
+ }
// JCA HMAC key algorithm implies a digest (e.g., HmacSHA256 key algorithm
// implies SHA-256 digest). Because keymaster HMAC key is authorized only for
diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
index 5fc742a..d44c894 100644
--- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
+++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java
@@ -303,7 +303,7 @@
if (mKeySizeBits == -1) {
mKeySizeBits = getDefaultKeySize(keymasterAlgorithm);
}
- checkValidKeySize(keymasterAlgorithm, mKeySizeBits);
+ checkValidKeySize(keymasterAlgorithm, mKeySizeBits, mSpec.isStrongBoxBacked());
if (spec.getKeystoreAlias() == null) {
throw new InvalidAlgorithmParameterException("KeyStore entry alias not provided");
@@ -724,10 +724,18 @@
}
}
- private static void checkValidKeySize(int keymasterAlgorithm, int keySize)
+ private static void checkValidKeySize(
+ int keymasterAlgorithm,
+ int keySize,
+ boolean isStrongBoxBacked)
throws InvalidAlgorithmParameterException {
switch (keymasterAlgorithm) {
case KeymasterDefs.KM_ALGORITHM_EC:
+ if (isStrongBoxBacked && keySize != 256) {
+ throw new InvalidAlgorithmParameterException(
+ "Unsupported StrongBox EC key size: "
+ + keySize + " bits. Supported: 256");
+ }
if (!SUPPORTED_EC_NIST_CURVE_SIZES.contains(keySize)) {
throw new InvalidAlgorithmParameterException("Unsupported EC key size: "
+ keySize + " bits. Supported: " + SUPPORTED_EC_NIST_CURVE_SIZES);
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h
index 38ad9c0..e9fba3a 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.h
@@ -30,7 +30,7 @@
class SkiaPipeline : public renderthread::IRenderPipeline {
public:
- SkiaPipeline(renderthread::RenderThread& thread);
+ explicit SkiaPipeline(renderthread::RenderThread& thread);
virtual ~SkiaPipeline();
TaskManager* getTaskManager() override;
diff --git a/libs/hwui/pipeline/skia/SkiaProfileRenderer.h b/libs/hwui/pipeline/skia/SkiaProfileRenderer.h
index 5ae7d6b..3233c8d 100644
--- a/libs/hwui/pipeline/skia/SkiaProfileRenderer.h
+++ b/libs/hwui/pipeline/skia/SkiaProfileRenderer.h
@@ -23,7 +23,7 @@
class SkiaProfileRenderer : public IProfileRenderer {
public:
- SkiaProfileRenderer(SkCanvas* canvas) : mCanvas(canvas) {}
+ explicit SkiaProfileRenderer(SkCanvas* canvas) : mCanvas(canvas) {}
void drawRect(float left, float top, float right, float bottom, const SkPaint& paint) override;
void drawRects(const float* rects, int count, const SkPaint& paint) override;
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
index 03b4c79..3d00386 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
@@ -25,7 +25,7 @@
class SkiaVulkanPipeline : public SkiaPipeline {
public:
- SkiaVulkanPipeline(renderthread::RenderThread& thread);
+ explicit SkiaVulkanPipeline(renderthread::RenderThread& thread);
virtual ~SkiaVulkanPipeline() {}
renderthread::MakeCurrentResult makeCurrent() override;
diff --git a/libs/hwui/pipeline/skia/VectorDrawableAtlas.h b/libs/hwui/pipeline/skia/VectorDrawableAtlas.h
index 74e48ce..5e892aa 100644
--- a/libs/hwui/pipeline/skia/VectorDrawableAtlas.h
+++ b/libs/hwui/pipeline/skia/VectorDrawableAtlas.h
@@ -62,8 +62,8 @@
public:
enum class StorageMode { allowSharedSurface, disallowSharedSurface };
- VectorDrawableAtlas(size_t surfaceArea,
- StorageMode storageMode = StorageMode::allowSharedSurface);
+ explicit VectorDrawableAtlas(size_t surfaceArea,
+ StorageMode storageMode = StorageMode::allowSharedSurface);
/**
* "prepareForDraw" may allocate a new surface if needed. It may schedule to repack the
diff --git a/libs/hwui/renderthread/CacheManager.h b/libs/hwui/renderthread/CacheManager.h
index 7d73352..78d2539 100644
--- a/libs/hwui/renderthread/CacheManager.h
+++ b/libs/hwui/renderthread/CacheManager.h
@@ -59,7 +59,7 @@
private:
friend class RenderThread;
- CacheManager(const DisplayInfo& display);
+ explicit CacheManager(const DisplayInfo& display);
void reset(sk_sp<GrContext> grContext);
void destroy();
diff --git a/libs/hwui/renderthread/VulkanManager.h b/libs/hwui/renderthread/VulkanManager.h
index c319c9e..ea69704 100644
--- a/libs/hwui/renderthread/VulkanManager.h
+++ b/libs/hwui/renderthread/VulkanManager.h
@@ -127,6 +127,7 @@
fPtr = ptr;
return *this;
}
+ // NOLINTNEXTLINE(google-explicit-constructor)
operator FNPTR_TYPE() const { return fPtr; }
private:
diff --git a/libs/hwui/tests/common/scenes/ShapeAnimation.cpp b/libs/hwui/tests/common/scenes/ShapeAnimation.cpp
index 0d87776..d189a93 100644
--- a/libs/hwui/tests/common/scenes/ShapeAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/ShapeAnimation.cpp
@@ -76,7 +76,7 @@
paint.setStrokeWidth(strokeWidth);
// fill column with each op
int middleCount = canvas.save(SaveFlags::MatrixClip);
- for (auto op : ops) {
+ for (const auto& op : ops) {
int innerCount = canvas.save(SaveFlags::MatrixClip);
canvas.clipRect(0, 0, cellSize, cellSize, SkClipOp::kIntersect);
canvas.drawColor(Color::White, SkBlendMode::kSrcOver);
diff --git a/libs/hwui/tests/unit/VectorDrawableTests.cpp b/libs/hwui/tests/unit/VectorDrawableTests.cpp
index 02f740c..4f299e3 100644
--- a/libs/hwui/tests/unit/VectorDrawableTests.cpp
+++ b/libs/hwui/tests/unit/VectorDrawableTests.cpp
@@ -251,7 +251,7 @@
}
TEST(PathParser, parseStringForData) {
- for (TestData testData : sTestDataSet) {
+ for (const TestData& testData : sTestDataSet) {
PathParser::ParseResult result;
// Test generated path data against the given data.
PathData pathData;
@@ -271,7 +271,7 @@
}
TEST(VectorDrawableUtils, createSkPathFromPathData) {
- for (TestData testData : sTestDataSet) {
+ for (const TestData& testData : sTestDataSet) {
SkPath expectedPath;
testData.skPathLamda(&expectedPath);
SkPath actualPath;
@@ -281,7 +281,7 @@
}
TEST(PathParser, parseAsciiStringForSkPath) {
- for (TestData testData : sTestDataSet) {
+ for (const TestData& testData : sTestDataSet) {
PathParser::ParseResult result;
size_t length = strlen(testData.pathString);
// Check the return value as well as the SkPath generated.
@@ -304,8 +304,8 @@
}
TEST(VectorDrawableUtils, morphPathData) {
- for (TestData fromData : sTestDataSet) {
- for (TestData toData : sTestDataSet) {
+ for (const TestData& fromData : sTestDataSet) {
+ for (const TestData& toData : sTestDataSet) {
bool canMorph = VectorDrawableUtils::canMorph(fromData.pathData, toData.pathData);
if (fromData.pathData == toData.pathData) {
EXPECT_TRUE(canMorph);
@@ -319,8 +319,8 @@
TEST(VectorDrawableUtils, interpolatePathData) {
// Interpolate path data with itself and every other path data
- for (TestData fromData : sTestDataSet) {
- for (TestData toData : sTestDataSet) {
+ for (const TestData& fromData : sTestDataSet) {
+ for (const TestData& toData : sTestDataSet) {
PathData outData;
bool success = VectorDrawableUtils::interpolatePathData(&outData, fromData.pathData,
toData.pathData, 0.5);
@@ -331,7 +331,7 @@
float fractions[] = {0, 0.00001, 0.28, 0.5, 0.7777, 0.9999999, 1};
// Now try to interpolate with a slightly modified version of self and expect success
- for (TestData fromData : sTestDataSet) {
+ for (const TestData& fromData : sTestDataSet) {
PathData toPathData = fromData.pathData;
for (size_t i = 0; i < toPathData.points.size(); i++) {
toPathData.points[i]++;
diff --git a/libs/incident/include/android/os/IncidentReportArgs.h b/libs/incident/include/android/os/IncidentReportArgs.h
index c56f689..ee1e33c 100644
--- a/libs/incident/include/android/os/IncidentReportArgs.h
+++ b/libs/incident/include/android/os/IncidentReportArgs.h
@@ -40,7 +40,7 @@
class IncidentReportArgs : public Parcelable {
public:
IncidentReportArgs();
- explicit IncidentReportArgs(const IncidentReportArgs& that);
+ IncidentReportArgs(const IncidentReportArgs& that);
virtual ~IncidentReportArgs();
virtual status_t writeToParcel(Parcel* out) const;
diff --git a/native/android/net.c b/native/android/net.c
index e32b787..4cac371 100644
--- a/native/android/net.c
+++ b/native/android/net.c
@@ -84,8 +84,7 @@
return android_getaddrinfofornet(node, service, hints, netid, 0, res);
}
-int android_res_nquery(net_handle_t network,
- const char *dname, int ns_class, int ns_type) {
+int android_res_nquery(net_handle_t network, const char *dname, int ns_class, int ns_type) {
unsigned netid;
if (!getnetidfromhandle(network, &netid)) {
return -ENONET;
@@ -94,12 +93,11 @@
return resNetworkQuery(netid, dname, ns_class, ns_type);
}
-int android_res_nresult(int fd, int *rcode, unsigned char *answer, int anslen) {
+int android_res_nresult(int fd, int *rcode, uint8_t *answer, size_t anslen) {
return resNetworkResult(fd, rcode, answer, anslen);
}
-int android_res_nsend(net_handle_t network,
- const unsigned char *msg, int msglen) {
+int android_res_nsend(net_handle_t network, const uint8_t *msg, size_t msglen) {
unsigned netid;
if (!getnetidfromhandle(network, &netid)) {
return -ENONET;
diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp
new file mode 100644
index 0000000..55bb517
--- /dev/null
+++ b/packages/NetworkStack/Android.bp
@@ -0,0 +1,37 @@
+//
+// 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.
+//
+
+// Library including the network stack, used to compile the network stack app, or linked into the
+// system server on devices that run the stack there
+java_library {
+ name: "NetworkStackLib",
+ installable: true,
+ srcs: [
+ "src/**/*.java",
+ ],
+}
+
+// Updatable network stack packaged as an application
+android_app {
+ name: "NetworkStack",
+ platform_apis: true,
+ certificate: "platform",
+ privileged: true,
+ static_libs: [
+ "NetworkStackLib"
+ ],
+ manifest: "AndroidManifest.xml",
+}
\ No newline at end of file
diff --git a/packages/NetworkStack/AndroidManifest.xml b/packages/NetworkStack/AndroidManifest.xml
new file mode 100644
index 0000000..d1c5cb6
--- /dev/null
+++ b/packages/NetworkStack/AndroidManifest.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright (C) 2014 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.
+ */
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.google.android.networkstack"
+ android:sharedUserId="android.uid.networkstack">
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+ <!-- Launch captive portal app as specific user -->
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
+ <application
+ android:label="NetworkStack"
+ android:defaultToDeviceProtectedStorage="true"
+ android:directBootAware="true"
+ android:usesCleartextTraffic="true">
+ <service android:name="com.android.server.NetworkStackService">
+ <intent-filter>
+ <action android:name="android.net.INetworkStackConnector"/>
+ </intent-filter>
+ </service>
+ </application>
+</manifest>
diff --git a/packages/NetworkStack/src/com/android/server/NetworkStackService.java b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
new file mode 100644
index 0000000..5afaf58
--- /dev/null
+++ b/packages/NetworkStack/src/com/android/server/NetworkStackService.java
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+package com.android.server;
+
+import static android.os.Binder.getCallingUid;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.Service;
+import android.content.Intent;
+import android.net.INetworkStackConnector;
+import android.os.IBinder;
+import android.os.Process;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
+/**
+ * Android service used to start the network stack when bound to via an intent.
+ *
+ * <p>The service returns a binder for the system server to communicate with the network stack.
+ */
+public class NetworkStackService extends Service {
+ private static final String TAG = NetworkStackService.class.getSimpleName();
+
+ /**
+ * Create a binder connector for the system server to communicate with the network stack.
+ *
+ * <p>On platforms where the network stack runs in the system server process, this method may
+ * be called directly instead of obtaining the connector by binding to the service.
+ */
+ public static IBinder makeConnector() {
+ return new NetworkStackConnector();
+ }
+
+ @NonNull
+ @Override
+ public IBinder onBind(Intent intent) {
+ return makeConnector();
+ }
+
+ private static class NetworkStackConnector extends INetworkStackConnector.Stub {
+ // TODO: makeDhcpServer(), etc. will go here.
+
+ @Override
+ protected void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter fout,
+ @Nullable String[] args) {
+ checkCaller();
+ fout.println("NetworkStack logs:");
+ // TODO: dump logs here
+ }
+ }
+
+ private static void checkCaller() {
+ // TODO: check that the calling PID is the system server.
+ if (getCallingUid() != Process.SYSTEM_UID && getCallingUid() != Process.ROOT_UID) {
+ throw new SecurityException("Invalid caller: " + getCallingUid());
+ }
+ }
+}
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java b/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java
index 4c45a75..cb2a088 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java
@@ -25,9 +25,9 @@
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
-import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
+import android.sysprop.CarProperties;
import android.util.Log;
import com.android.internal.util.UserIcons;
@@ -43,7 +43,6 @@
@Deprecated
public final class UserManagerHelper {
private static final String TAG = "UserManagerHelper";
- private static final String HEADLESS_SYSTEM_USER = "android.car.systemuser.headless";
private final Context mContext;
private final UserManager mUserManager;
private final ActivityManager mActivityManager;
@@ -84,7 +83,7 @@
* @return {@boolean true} if headless system user.
*/
public boolean isHeadlessSystemUser() {
- return SystemProperties.getBoolean(HEADLESS_SYSTEM_USER, false);
+ return CarProperties.headless_system_user().orElse(false);
}
/**
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index adeff5d..9306219 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -26,6 +26,7 @@
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
+ <uses-permission android:name="android.permission.READ_PRECISE_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index 83021ca..be46d2c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -19,7 +19,7 @@
import android.app.ActivityManager;
import android.graphics.PixelFormat;
import android.graphics.drawable.Drawable;
-import android.os.SystemProperties;
+import android.sysprop.CarProperties;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
@@ -56,7 +56,7 @@
CarBatteryController.BatteryViewHandler {
private static final String TAG = "CarStatusBar";
public static final boolean ENABLE_HVAC_CONNECTION
- = !SystemProperties.getBoolean("android.car.hvac.demo", true);
+ = !CarProperties.hvac_demo().orElse(true);
private TaskStackListenerImpl mTaskStackListener;
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 49de4b1..555e899 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -76,6 +76,7 @@
import java.util.LinkedList;
import java.util.Locale;
import java.util.Map;
+import java.util.NoSuchElementException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -1279,7 +1280,11 @@
if (mService == null) {
return;
}
- mService.unlinkToDeath(this, 0);
+ try {
+ mService.unlinkToDeath(this, 0);
+ } catch (NoSuchElementException e) {
+ Log.e(TAG, "error unlinking to death", e);
+ }
mService = null;
mClassName = null;
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 89194e4..66ceae4 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -5714,7 +5714,6 @@
// This should never fail. Specifying an already in use NetID will cause failure.
if (networkAgent.isVPN()) {
mNMS.createVirtualNetwork(networkAgent.network.netId,
- !networkAgent.linkProperties.getDnsServers().isEmpty(),
(networkAgent.networkMisc == null ||
!networkAgent.networkMisc.allowBypass));
} else {
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index d0e8b47..00b1320 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -163,8 +163,6 @@
private static final int MAX_UID_RANGES_PER_COMMAND = 10;
- private static final String[] EMPTY_STRING_ARRAY = new String[0];
-
/**
* Name representing {@link #setGlobalAlert(long)} limit when delivered to
* {@link INetworkManagementEventObserver#limitReached(String, String)}.
@@ -954,8 +952,7 @@
public String[] listInterfaces() {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
- final List<String> result = mNetdService.interfaceGetList();
- return result.toArray(EMPTY_STRING_ARRAY);
+ return mNetdService.interfaceGetList();
} catch (RemoteException | ServiceSpecificException e) {
throw new IllegalStateException(e);
}
@@ -1247,8 +1244,7 @@
public String[] listTetheredInterfaces() {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
- final List<String> result = mNetdService.tetherInterfaceList();
- return result.toArray(EMPTY_STRING_ARRAY);
+ return mNetdService.tetherInterfaceList();
} catch (RemoteException | ServiceSpecificException e) {
throw new IllegalStateException(e);
}
@@ -1271,8 +1267,7 @@
public String[] getDnsForwarders() {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
- final List<String> result = mNetdService.tetherDnsList();
- return result.toArray(EMPTY_STRING_ARRAY);
+ return mNetdService.tetherDnsList();
} catch (RemoteException | ServiceSpecificException e) {
throw new IllegalStateException(e);
}
@@ -2313,11 +2308,11 @@
}
@Override
- public void createVirtualNetwork(int netId, boolean hasDNS, boolean secure) {
+ public void createVirtualNetwork(int netId, boolean secure) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
try {
- mNetdService.networkCreateVpn(netId, hasDNS, secure);
+ mNetdService.networkCreateVpn(netId, secure);
} catch (RemoteException | ServiceSpecificException e) {
throw new IllegalStateException(e);
}
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 66ae47c..7b29fe5 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -210,6 +210,10 @@
private PreciseCallState mPreciseCallState = new PreciseCallState();
+ private int mCallDisconnectCause = DisconnectCause.NOT_VALID;
+
+ private int mCallPreciseDisconnectCause = PreciseDisconnectCause.NOT_VALID;
+
private boolean mCarrierNetworkChangeState = false;
private PhoneCapability mPhoneCapability = null;
@@ -708,6 +712,14 @@
remove(r.binder);
}
}
+ if ((events & PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES) != 0) {
+ try {
+ r.callback.onCallDisconnectCauseChanged(mCallDisconnectCause,
+ mCallPreciseDisconnectCause);
+ } catch (RemoteException ex) {
+ remove(r.binder);
+ }
+ }
if ((events & PhoneStateListener.LISTEN_PRECISE_DATA_CONNECTION_STATE) != 0) {
try {
r.callback.onPreciseDataConnectionStateChanged(
@@ -1478,9 +1490,8 @@
}
handleRemoveListLocked();
}
- broadcastPreciseCallStateChanged(ringingCallState, foregroundCallState, backgroundCallState,
- DisconnectCause.NOT_VALID,
- PreciseDisconnectCause.NOT_VALID);
+ broadcastPreciseCallStateChanged(ringingCallState, foregroundCallState,
+ backgroundCallState);
}
public void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause) {
@@ -1488,12 +1499,14 @@
return;
}
synchronized (mRecords) {
- mPreciseCallState = new PreciseCallState(mRingingCallState, mForegroundCallState,
- mBackgroundCallState, disconnectCause, preciseDisconnectCause);
+ mCallDisconnectCause = disconnectCause;
+ mCallPreciseDisconnectCause = preciseDisconnectCause;
for (Record r : mRecords) {
- if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_PRECISE_CALL_STATE)) {
+ if (r.matchPhoneStateListenerEvent(PhoneStateListener
+ .LISTEN_CALL_DISCONNECT_CAUSES)) {
try {
- r.callback.onPreciseCallStateChanged(mPreciseCallState);
+ r.callback.onCallDisconnectCauseChanged(mCallDisconnectCause,
+ mCallPreciseDisconnectCause);
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
}
@@ -1501,8 +1514,6 @@
}
handleRemoveListLocked();
}
- broadcastPreciseCallStateChanged(mRingingCallState, mForegroundCallState,
- mBackgroundCallState, disconnectCause, preciseDisconnectCause);
}
public void notifyPreciseDataConnectionFailed(String reason, String apnType,
@@ -1703,6 +1714,8 @@
}
pw.println("mPreciseDataConnectionState=" + mPreciseDataConnectionState);
pw.println("mPreciseCallState=" + mPreciseCallState);
+ pw.println("mCallDisconnectCause=" + mCallDisconnectCause);
+ pw.println("mCallPreciseDisconnectCause=" + mCallPreciseDisconnectCause);
pw.println("mCarrierNetworkChangeState=" + mCarrierNetworkChangeState);
pw.println("mRingingCallState=" + mRingingCallState);
pw.println("mForegroundCallState=" + mForegroundCallState);
@@ -1877,13 +1890,11 @@
}
private void broadcastPreciseCallStateChanged(int ringingCallState, int foregroundCallState,
- int backgroundCallState, int disconnectCause, int preciseDisconnectCause) {
+ int backgroundCallState) {
Intent intent = new Intent(TelephonyManager.ACTION_PRECISE_CALL_STATE_CHANGED);
intent.putExtra(TelephonyManager.EXTRA_RINGING_CALL_STATE, ringingCallState);
intent.putExtra(TelephonyManager.EXTRA_FOREGROUND_CALL_STATE, foregroundCallState);
intent.putExtra(TelephonyManager.EXTRA_BACKGROUND_CALL_STATE, backgroundCallState);
- intent.putExtra(TelephonyManager.EXTRA_DISCONNECT_CAUSE, disconnectCause);
- intent.putExtra(TelephonyManager.EXTRA_PRECISE_DISCONNECT_CAUSE, preciseDisconnectCause);
mContext.sendBroadcastAsUser(intent, UserHandle.ALL,
android.Manifest.permission.READ_PRECISE_PHONE_STATE);
}
@@ -1964,6 +1975,11 @@
}
+ if ((events & PhoneStateListener.LISTEN_CALL_DISCONNECT_CAUSES) != 0) {
+ mContext.enforceCallingOrSelfPermission(
+ android.Manifest.permission.READ_PRECISE_PHONE_STATE, null);
+ }
+
return true;
}
diff --git a/services/core/java/com/android/server/am/OWNERS b/services/core/java/com/android/server/am/OWNERS
index 79c98e5..2649807 100644
--- a/services/core/java/com/android/server/am/OWNERS
+++ b/services/core/java/com/android/server/am/OWNERS
@@ -15,7 +15,7 @@
jjaggi@google.com
racarr@google.com
chaviw@google.com
-brycelee@google.com
+vishnun@google.com
akulian@google.com
roosa@google.com
diff --git a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
index 422f556..e40949b 100644
--- a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
+++ b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java
@@ -217,6 +217,19 @@
@Override
// Called concurrently by multiple binder threads.
// This method must not block or perform long-running operations.
+ public synchronized void onNat64PrefixEvent(int netId,
+ boolean added, String prefixString, int prefixLength)
+ throws RemoteException {
+ for (INetdEventCallback callback : mNetdEventCallbackList) {
+ if (callback != null) {
+ callback.onNat64PrefixEvent(netId, added, prefixString, prefixLength);
+ }
+ }
+ }
+
+ @Override
+ // Called concurrently by multiple binder threads.
+ // This method must not block or perform long-running operations.
public synchronized void onPrivateDnsValidationEvent(int netId,
String ipAddress, String hostname, boolean validated)
throws RemoteException {
diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
index bf95210..9684f4c 100644
--- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java
+++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java
@@ -944,6 +944,10 @@
private class WaitingForNextProbeState extends State {
@Override
public void enter() {
+ scheduleNextProbe();
+ }
+
+ private void scheduleNextProbe() {
final Message msg = obtainMessage(CMD_REEVALUATE, ++mReevaluateToken, 0);
sendMessageDelayed(msg, mReevaluateDelayMs);
mReevaluateDelayMs *= 2;
diff --git a/services/core/java/com/android/server/connectivity/PacManager.java b/services/core/java/com/android/server/connectivity/PacManager.java
index c370959..3ea9810 100644
--- a/services/core/java/com/android/server/connectivity/PacManager.java
+++ b/services/core/java/com/android/server/connectivity/PacManager.java
@@ -43,8 +43,6 @@
import com.android.net.IProxyPortListener;
import com.android.net.IProxyService;
-import libcore.io.Streams;
-
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
@@ -71,6 +69,11 @@
private static final int DELAY_LONG = 4;
private static final long MAX_PAC_SIZE = 20 * 1000 * 1000;
+ // Return values for #setCurrentProxyScriptUrl
+ enum ToSendOrNotToSendBroadcast {
+ DONT_SEND_BROADCAST, DO_SEND_BROADCAST
+ }
+
private String mCurrentPac;
@GuardedBy("mProxyLock")
private volatile Uri mPacUrl = Uri.EMPTY;
@@ -171,13 +174,13 @@
* PacManager will trigger a new broadcast when it is ready.
*
* @param proxy Proxy information that is about to be broadcast.
- * @return Returns true when the broadcast should not be sent
+ * @return Returns whether the broadcast should be sent : either DO_ or DONT_SEND_BROADCAST
*/
- synchronized boolean setCurrentProxyScriptUrl(ProxyInfo proxy) {
+ synchronized ToSendOrNotToSendBroadcast setCurrentProxyScriptUrl(ProxyInfo proxy) {
if (!Uri.EMPTY.equals(proxy.getPacFileUrl())) {
if (proxy.getPacFileUrl().equals(mPacUrl) && (proxy.getPort() > 0)) {
// Allow to send broadcast, nothing to do.
- return false;
+ return ToSendOrNotToSendBroadcast.DO_SEND_BROADCAST;
}
mPacUrl = proxy.getPacFileUrl();
mCurrentDelay = DELAY_1;
@@ -185,7 +188,7 @@
mHasDownloaded = false;
getAlarmManager().cancel(mPacRefreshIntent);
bind();
- return true;
+ return ToSendOrNotToSendBroadcast.DONT_SEND_BROADCAST;
} else {
getAlarmManager().cancel(mPacRefreshIntent);
synchronized (mProxyLock) {
@@ -201,7 +204,7 @@
}
}
}
- return false;
+ return ToSendOrNotToSendBroadcast.DO_SEND_BROADCAST;
}
}
@@ -296,7 +299,7 @@
Intent intent = new Intent();
intent.setClassName(PAC_PACKAGE, PAC_SERVICE);
if ((mProxyConnection != null) && (mConnection != null)) {
- // Already bound no need to bind again, just download the new file.
+ // Already bound: no need to bind again, just download the new file.
mNetThreadHandler.post(mPacDownloader);
return;
}
diff --git a/services/core/java/com/android/server/connectivity/ProxyTracker.java b/services/core/java/com/android/server/connectivity/ProxyTracker.java
index 15468ff..fdddccd 100644
--- a/services/core/java/com/android/server/connectivity/ProxyTracker.java
+++ b/services/core/java/com/android/server/connectivity/ProxyTracker.java
@@ -208,7 +208,10 @@
public void sendProxyBroadcast() {
final ProxyInfo defaultProxy = getDefaultProxy();
final ProxyInfo proxyInfo = null != defaultProxy ? defaultProxy : new ProxyInfo("", 0, "");
- if (mPacManager.setCurrentProxyScriptUrl(proxyInfo)) return;
+ if (mPacManager.setCurrentProxyScriptUrl(proxyInfo)
+ == PacManager.ToSendOrNotToSendBroadcast.DONT_SEND_BROADCAST) {
+ return;
+ }
if (DBG) Slog.d(TAG, "sending Proxy Broadcast for " + proxyInfo);
Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING |
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 268e844..0120dc3 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -80,8 +80,10 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Locale;
+import java.util.Map;
import libcore.util.EmptyArray;
/**
@@ -93,6 +95,31 @@
private final Locale HONG_KONG = new Locale("zh", "HK");
private final Locale MACAU = new Locale("zh", "MO");
+ private static final Map<String, String> mTerminologyToBibliographicMap;
+ static {
+ mTerminologyToBibliographicMap = new HashMap<>();
+ // NOTE: (TERMINOLOGY_CODE, BIBLIOGRAPHIC_CODE)
+ mTerminologyToBibliographicMap.put("sqi", "alb"); // Albanian
+ mTerminologyToBibliographicMap.put("hye", "arm"); // Armenian
+ mTerminologyToBibliographicMap.put("eus", "baq"); // Basque
+ mTerminologyToBibliographicMap.put("mya", "bur"); // Burmese
+ mTerminologyToBibliographicMap.put("ces", "cze"); // Czech
+ mTerminologyToBibliographicMap.put("nld", "dut"); // Dutch
+ mTerminologyToBibliographicMap.put("kat", "geo"); // Georgian
+ mTerminologyToBibliographicMap.put("deu", "ger"); // German
+ mTerminologyToBibliographicMap.put("ell", "gre"); // Greek
+ mTerminologyToBibliographicMap.put("fra", "fre"); // French
+ mTerminologyToBibliographicMap.put("isl", "ice"); // Icelandic
+ mTerminologyToBibliographicMap.put("mkd", "mac"); // Macedonian
+ mTerminologyToBibliographicMap.put("mri", "mao"); // Maori
+ mTerminologyToBibliographicMap.put("msa", "may"); // Malay
+ mTerminologyToBibliographicMap.put("fas", "per"); // Persian
+ mTerminologyToBibliographicMap.put("ron", "rum"); // Romanian
+ mTerminologyToBibliographicMap.put("slk", "slo"); // Slovak
+ mTerminologyToBibliographicMap.put("bod", "tib"); // Tibetan
+ mTerminologyToBibliographicMap.put("cym", "wel"); // Welsh
+ }
+
static final String PERMISSION = "android.permission.HDMI_CEC";
// The reason code to initiate intializeCec().
@@ -176,7 +203,18 @@
// Chinese used in Taiwan/Hong Kong/Macau.
return "chi";
} else {
- return locale.getISO3Language();
+ String language = locale.getISO3Language();
+
+ // locale.getISO3Language() returns terminology code and need to
+ // send it as bibliographic code instead since the Bibliographic
+ // codes of ISO/FDIS 639-2 shall be used.
+ // NOTE: Chinese also has terminology/bibliographic code "zho" and "chi"
+ // But, as it depends on the locale, is not handled here.
+ if (mTerminologyToBibliographicMap.containsKey(language)) {
+ language = mTerminologyToBibliographicMap.get(language);
+ }
+
+ return language;
}
}
}
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index cc640f0..5e1ed03 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -404,12 +404,17 @@
+ " dexoptFlags=" + printDexoptFlags(dexoptFlags)
+ " target-filter=" + compilerFilter);
- // TODO(calin): b/64530081 b/66984396. Use SKIP_SHARED_LIBRARY_CHECK for the context
- // (instead of dexUseInfo.getClassLoaderContext()) in order to compile secondary dex files
- // in isolation (and avoid to extract/verify the main apk if it's in the class path).
- // Note this trades correctness for performance since the resulting slow down is
- // unacceptable in some cases until b/64530081 is fixed.
- String classLoaderContext = SKIP_SHARED_LIBRARY_CHECK;
+ String classLoaderContext;
+ if (dexUseInfo.isUnknownClassLoaderContext() || dexUseInfo.isVariableClassLoaderContext()) {
+ // If we have an unknown (not yet set), or a variable class loader chain, compile
+ // without a context and mark the oat file with SKIP_SHARED_LIBRARY_CHECK. Note that
+ // this might lead to a incorrect compilation.
+ // TODO(calin): We should just extract in this case.
+ classLoaderContext = SKIP_SHARED_LIBRARY_CHECK;
+ } else {
+ classLoaderContext = dexUseInfo.getClassLoaderContext();
+ }
+
int reason = options.getCompilationReason();
try {
for (String isa : dexUseInfo.getLoaderIsas()) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 9345ad1..f4673a8 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -456,6 +456,7 @@
private static final int BLUETOOTH_UID = Process.BLUETOOTH_UID;
private static final int SHELL_UID = Process.SHELL_UID;
private static final int SE_UID = Process.SE_UID;
+ private static final int NETWORKSTACK_UID = Process.NETWORK_STACK_UID;
// Suffix used during package installation when copying/moving
// package apks to install directory.
@@ -2469,6 +2470,8 @@
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
mSettings.addSharedUserLPw("android.uid.se", SE_UID,
ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
+ mSettings.addSharedUserLPw("android.uid.networkstack", NETWORKSTACK_UID,
+ ApplicationInfo.FLAG_SYSTEM, ApplicationInfo.PRIVATE_FLAG_PRIVILEGED);
String separateProcesses = SystemProperties.get("debug.separate_processes");
if (separateProcesses != null && separateProcesses.length() > 0) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 7856bcf..e5b9030 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -627,9 +627,13 @@
pw.print("=");
}
pw.print(info.packageName);
- if (showVersionCode && !isApex) {
+ if (showVersionCode) {
pw.print(" versionCode:");
- pw.print(info.applicationInfo.versionCode);
+ if (info.applicationInfo != null) {
+ pw.print(info.applicationInfo.versionCode);
+ } else {
+ pw.print(info.versionCode);
+ }
}
if (listInstaller && !isApex) {
pw.print(" installer=");
@@ -2701,7 +2705,7 @@
pw.println(" Prints all system libraries.");
pw.println("");
pw.println(" list packages [-f] [-d] [-e] [-s] [-3] [-i] [-l] [-u] [-U] ");
- pw.println(" [--apex-only] [--uid UID] [--user USER_ID] [FILTER]");
+ pw.println(" [--show-versioncode] [--apex-only] [--uid UID] [--user USER_ID] [FILTER]");
pw.println(" Prints all packages; optionally only those whose name contains");
pw.println(" the text in FILTER. Options are:");
pw.println(" -f: see their associated file");
@@ -2714,6 +2718,7 @@
pw.println(" -l: ignored (used for compatibility with older releases)");
pw.println(" -U: also show the package UID");
pw.println(" -u: also include uninstalled packages");
+ pw.println(" --show-versioncode: also show the version code");
pw.println(" --apex-only: only show APEX packages");
pw.println(" --uid UID: filter to only show packages with the given UID");
pw.println(" --user USER_ID: only list packages belonging to the given user");
diff --git a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
index 519a20d..a194f57 100644
--- a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
+++ b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
@@ -863,15 +863,13 @@
public String getClassLoaderContext() { return mClassLoaderContext; }
- @VisibleForTesting
- /* package */ boolean isUnknownClassLoaderContext() {
+ public boolean isUnknownClassLoaderContext() {
// The class loader context may be unknown if we loaded the data from a previous version
// which didn't save the context.
return UNKNOWN_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext);
}
- @VisibleForTesting
- /* package */ boolean isVariableClassLoaderContext() {
+ public boolean isVariableClassLoaderContext() {
return VARIABLE_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext);
}
}
diff --git a/services/core/java/com/android/server/wm/AppWindowThumbnail.java b/services/core/java/com/android/server/wm/AppWindowThumbnail.java
index ad92f81..bef974a 100644
--- a/services/core/java/com/android/server/wm/AppWindowThumbnail.java
+++ b/services/core/java/com/android/server/wm/AppWindowThumbnail.java
@@ -69,6 +69,7 @@
.setFormat(PixelFormat.TRANSLUCENT)
.setMetadata(appToken.windowType,
window != null ? window.mOwnerUid : Binder.getCallingUid())
+ .setBufferLayer()
.build();
if (SHOW_TRANSACTIONS) {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 2941e93..6700a12 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -773,7 +773,8 @@
final SurfaceControl.Builder b = mService.makeSurfaceBuilder(mSession)
.setSize(mSurfaceSize, mSurfaceSize)
- .setOpaque(true);
+ .setOpaque(true)
+ .setContainerLayer(true);
mWindowingLayer = b.setName("Display Root").build();
mOverlayLayer = b.setName("Display Overlays").build();
@@ -3890,7 +3891,7 @@
SurfaceSession s = child != null ? child.getSession() : getSession();
final SurfaceControl.Builder b = mService.makeSurfaceBuilder(s);
b.setSize(mSurfaceSize, mSurfaceSize);
-
+ b.setContainerLayer(true);
if (child == null) {
return b;
}
diff --git a/services/core/java/com/android/server/wm/OWNERS b/services/core/java/com/android/server/wm/OWNERS
index fff42c5..8dda485 100644
--- a/services/core/java/com/android/server/wm/OWNERS
+++ b/services/core/java/com/android/server/wm/OWNERS
@@ -2,6 +2,6 @@
jjaggi@google.com
racarr@google.com
chaviw@google.com
-brycelee@google.com
+vishnun@google.com
akulian@google.com
roosa@google.com
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index 66c8cca..4548cec 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -104,6 +104,7 @@
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "new SurfaceControl");
final SurfaceControl.Builder b = win.makeSurface()
+ .setBufferLayer()
.setParent(win.getSurfaceControl())
.setName(name)
.setSize(w, h)
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 4decd4f..2d07fd6 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1204,6 +1204,16 @@
}
traceEnd();
+ traceBeginAndSlog("StartNetworkStack");
+ try {
+ final android.net.NetworkStack networkStack =
+ context.getSystemService(android.net.NetworkStack.class);
+ networkStack.start(context);
+ } catch (Throwable e) {
+ reportWtf("starting Network Stack", e);
+ }
+ traceEnd();
+
traceBeginAndSlog("StartNsdService");
try {
serviceDiscovery = NsdService.create(context);
diff --git a/services/net/java/android/net/apf/ApfFilter.java b/services/net/java/android/net/apf/ApfFilter.java
index b9cc372..f037905 100644
--- a/services/net/java/android/net/apf/ApfFilter.java
+++ b/services/net/java/android/net/apf/ApfFilter.java
@@ -139,7 +139,8 @@
DROPPED_IPV6_MULTICAST_PING,
DROPPED_IPV6_NON_ICMP_MULTICAST,
DROPPED_802_3_FRAME,
- DROPPED_ETHERTYPE_BLACKLISTED;
+ DROPPED_ETHERTYPE_BLACKLISTED,
+ DROPPED_ARP_REPLY_SPA_NO_HOST;
// Returns the negative byte offset from the end of the APF data segment for
// a given counter.
@@ -156,7 +157,7 @@
/**
* When APFv4 is supported, loads R1 with the offset of the specified counter.
*/
- private void maybeSetCounter(ApfGenerator gen, Counter c) {
+ private void maybeSetupCounter(ApfGenerator gen, Counter c) {
if (mApfCapabilities.hasDataAccess()) {
gen.addLoadImmediate(Register.R1, c.offset());
}
@@ -288,16 +289,18 @@
private static final int DHCP_CLIENT_MAC_OFFSET = ETH_HEADER_LEN + UDP_HEADER_LEN + 28;
private static final int ARP_HEADER_OFFSET = ETH_HEADER_LEN;
- private static final int ARP_OPCODE_OFFSET = ARP_HEADER_OFFSET + 6;
- private static final short ARP_OPCODE_REQUEST = 1;
- private static final short ARP_OPCODE_REPLY = 2;
private static final byte[] ARP_IPV4_HEADER = {
0, 1, // Hardware type: Ethernet (1)
8, 0, // Protocol type: IP (0x0800)
6, // Hardware size: 6
4, // Protocol size: 4
};
- private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ETH_HEADER_LEN + 24;
+ private static final int ARP_OPCODE_OFFSET = ARP_HEADER_OFFSET + 6;
+ // Opcode: ARP request (0x0001), ARP reply (0x0002)
+ private static final short ARP_OPCODE_REQUEST = 1;
+ private static final short ARP_OPCODE_REPLY = 2;
+ private static final int ARP_SOURCE_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 14;
+ private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 24;
// Do not log ApfProgramEvents whose actual lifetimes was less than this.
private static final int APF_PROGRAM_EVENT_LIFETIME_THRESHOLD = 2;
// Limit on the Black List size to cap on program usage for this
@@ -816,7 +819,7 @@
gen.addJumpIfR0LessThan(filterLifetime, nextFilterLabel);
}
}
- maybeSetCounter(gen, Counter.DROPPED_RA);
+ maybeSetupCounter(gen, Counter.DROPPED_RA);
gen.addJump(mCountAndDropLabel);
gen.defineLabel(nextFilterLabel);
return filterLifetime;
@@ -883,6 +886,8 @@
// pass
// if not ARP IPv4 reply or request
// pass
+ // if ARP reply source ip is 0.0.0.0
+ // drop
// if unicast ARP reply
// pass
// if interface has no IPv4 address
@@ -897,18 +902,23 @@
// Pass if not ARP IPv4.
gen.addLoadImmediate(Register.R0, ARP_HEADER_OFFSET);
- maybeSetCounter(gen, Counter.PASSED_ARP_NON_IPV4);
+ maybeSetupCounter(gen, Counter.PASSED_ARP_NON_IPV4);
gen.addJumpIfBytesNotEqual(Register.R0, ARP_IPV4_HEADER, mCountAndPassLabel);
// Pass if unknown ARP opcode.
gen.addLoad16(Register.R0, ARP_OPCODE_OFFSET);
gen.addJumpIfR0Equals(ARP_OPCODE_REQUEST, checkTargetIPv4); // Skip to unicast check
- maybeSetCounter(gen, Counter.PASSED_ARP_UNKNOWN);
+ maybeSetupCounter(gen, Counter.PASSED_ARP_UNKNOWN);
gen.addJumpIfR0NotEquals(ARP_OPCODE_REPLY, mCountAndPassLabel);
+ // Drop if ARP reply source IP is 0.0.0.0
+ gen.addLoad32(Register.R0, ARP_SOURCE_IP_ADDRESS_OFFSET);
+ maybeSetupCounter(gen, Counter.DROPPED_ARP_REPLY_SPA_NO_HOST);
+ gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, mCountAndDropLabel);
+
// Pass if unicast reply.
gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
- maybeSetCounter(gen, Counter.PASSED_ARP_UNICAST_REPLY);
+ maybeSetupCounter(gen, Counter.PASSED_ARP_UNICAST_REPLY);
gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
// Either a unicast request, a unicast reply, or a broadcast reply.
@@ -916,17 +926,17 @@
if (mIPv4Address == null) {
// When there is no IPv4 address, drop GARP replies (b/29404209).
gen.addLoad32(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET);
- maybeSetCounter(gen, Counter.DROPPED_GARP_REPLY);
+ maybeSetupCounter(gen, Counter.DROPPED_GARP_REPLY);
gen.addJumpIfR0Equals(IPV4_ANY_HOST_ADDRESS, mCountAndDropLabel);
} else {
// When there is an IPv4 address, drop unicast/broadcast requests
// and broadcast replies with a different target IPv4 address.
gen.addLoadImmediate(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET);
- maybeSetCounter(gen, Counter.DROPPED_ARP_OTHER_HOST);
+ maybeSetupCounter(gen, Counter.DROPPED_ARP_OTHER_HOST);
gen.addJumpIfBytesNotEqual(Register.R0, mIPv4Address, mCountAndDropLabel);
}
- maybeSetCounter(gen, Counter.PASSED_ARP);
+ maybeSetupCounter(gen, Counter.PASSED_ARP);
gen.addJump(mCountAndPassLabel);
}
@@ -970,7 +980,7 @@
// NOTE: Relies on R1 containing IPv4 header offset.
gen.addAddR1();
gen.addJumpIfBytesNotEqual(Register.R0, mHardwareAddress, skipDhcpv4Filter);
- maybeSetCounter(gen, Counter.PASSED_DHCP);
+ maybeSetupCounter(gen, Counter.PASSED_DHCP);
gen.addJump(mCountAndPassLabel);
// Drop all multicasts/broadcasts.
@@ -979,30 +989,30 @@
// If IPv4 destination address is in multicast range, drop.
gen.addLoad8(Register.R0, IPV4_DEST_ADDR_OFFSET);
gen.addAnd(0xf0);
- maybeSetCounter(gen, Counter.DROPPED_IPV4_MULTICAST);
+ maybeSetupCounter(gen, Counter.DROPPED_IPV4_MULTICAST);
gen.addJumpIfR0Equals(0xe0, mCountAndDropLabel);
// If IPv4 broadcast packet, drop regardless of L2 (b/30231088).
- maybeSetCounter(gen, Counter.DROPPED_IPV4_BROADCAST_ADDR);
+ maybeSetupCounter(gen, Counter.DROPPED_IPV4_BROADCAST_ADDR);
gen.addLoad32(Register.R0, IPV4_DEST_ADDR_OFFSET);
gen.addJumpIfR0Equals(IPV4_BROADCAST_ADDRESS, mCountAndDropLabel);
if (mIPv4Address != null && mIPv4PrefixLength < 31) {
- maybeSetCounter(gen, Counter.DROPPED_IPV4_BROADCAST_NET);
+ maybeSetupCounter(gen, Counter.DROPPED_IPV4_BROADCAST_NET);
int broadcastAddr = ipv4BroadcastAddress(mIPv4Address, mIPv4PrefixLength);
gen.addJumpIfR0Equals(broadcastAddr, mCountAndDropLabel);
}
// If L2 broadcast packet, drop.
// TODO: can we invert this condition to fall through to the common pass case below?
- maybeSetCounter(gen, Counter.PASSED_IPV4_UNICAST);
+ maybeSetupCounter(gen, Counter.PASSED_IPV4_UNICAST);
gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
- maybeSetCounter(gen, Counter.DROPPED_IPV4_L2_BROADCAST);
+ maybeSetupCounter(gen, Counter.DROPPED_IPV4_L2_BROADCAST);
gen.addJump(mCountAndDropLabel);
}
// Otherwise, pass
- maybeSetCounter(gen, Counter.PASSED_IPV4);
+ maybeSetupCounter(gen, Counter.PASSED_IPV4);
gen.addJump(mCountAndPassLabel);
}
@@ -1050,16 +1060,16 @@
// Drop all other packets sent to ff00::/8 (multicast prefix).
gen.defineLabel(dropAllIPv6MulticastsLabel);
- maybeSetCounter(gen, Counter.DROPPED_IPV6_NON_ICMP_MULTICAST);
+ maybeSetupCounter(gen, Counter.DROPPED_IPV6_NON_ICMP_MULTICAST);
gen.addLoad8(Register.R0, IPV6_DEST_ADDR_OFFSET);
gen.addJumpIfR0Equals(0xff, mCountAndDropLabel);
// Not multicast. Pass.
- maybeSetCounter(gen, Counter.PASSED_IPV6_UNICAST_NON_ICMP);
+ maybeSetupCounter(gen, Counter.PASSED_IPV6_UNICAST_NON_ICMP);
gen.addJump(mCountAndPassLabel);
gen.defineLabel(skipIPv6MulticastFilterLabel);
} else {
// If not ICMPv6, pass.
- maybeSetCounter(gen, Counter.PASSED_IPV6_NON_ICMP);
+ maybeSetupCounter(gen, Counter.PASSED_IPV6_NON_ICMP);
gen.addJumpIfR0NotEquals(IPPROTO_ICMPV6, mCountAndPassLabel);
}
@@ -1069,7 +1079,7 @@
String skipUnsolicitedMulticastNALabel = "skipUnsolicitedMulticastNA";
gen.addLoad8(Register.R0, ICMP6_TYPE_OFFSET);
// Drop all router solicitations (b/32833400)
- maybeSetCounter(gen, Counter.DROPPED_IPV6_ROUTER_SOLICITATION);
+ maybeSetupCounter(gen, Counter.DROPPED_IPV6_ROUTER_SOLICITATION);
gen.addJumpIfR0Equals(ICMPV6_ROUTER_SOLICITATION, mCountAndDropLabel);
// If not neighbor announcements, skip filter.
gen.addJumpIfR0NotEquals(ICMPV6_NEIGHBOR_ADVERTISEMENT, skipUnsolicitedMulticastNALabel);
@@ -1078,7 +1088,7 @@
gen.addLoadImmediate(Register.R0, IPV6_DEST_ADDR_OFFSET);
gen.addJumpIfBytesNotEqual(Register.R0, IPV6_ALL_NODES_ADDRESS,
skipUnsolicitedMulticastNALabel);
- maybeSetCounter(gen, Counter.DROPPED_IPV6_MULTICAST_NA);
+ maybeSetupCounter(gen, Counter.DROPPED_IPV6_MULTICAST_NA);
gen.addJump(mCountAndDropLabel);
gen.defineLabel(skipUnsolicitedMulticastNALabel);
}
@@ -1108,7 +1118,7 @@
if (mApfCapabilities.hasDataAccess()) {
// Increment TOTAL_PACKETS
- maybeSetCounter(gen, Counter.TOTAL_PACKETS);
+ maybeSetupCounter(gen, Counter.TOTAL_PACKETS);
gen.addLoadData(Register.R0, 0); // load counter
gen.addAdd(1);
gen.addStoreData(Register.R0, 0); // write-back counter
@@ -1134,12 +1144,12 @@
if (mDrop802_3Frames) {
// drop 802.3 frames (ethtype < 0x0600)
- maybeSetCounter(gen, Counter.DROPPED_802_3_FRAME);
+ maybeSetupCounter(gen, Counter.DROPPED_802_3_FRAME);
gen.addJumpIfR0LessThan(ETH_TYPE_MIN, mCountAndDropLabel);
}
// Handle ether-type black list
- maybeSetCounter(gen, Counter.DROPPED_ETHERTYPE_BLACKLISTED);
+ maybeSetupCounter(gen, Counter.DROPPED_ETHERTYPE_BLACKLISTED);
for (int p : mEthTypeBlackList) {
gen.addJumpIfR0Equals(p, mCountAndDropLabel);
}
@@ -1168,9 +1178,9 @@
// Drop non-IP non-ARP broadcasts, pass the rest
gen.addLoadImmediate(Register.R0, ETH_DEST_ADDR_OFFSET);
- maybeSetCounter(gen, Counter.PASSED_NON_IP_UNICAST);
+ maybeSetupCounter(gen, Counter.PASSED_NON_IP_UNICAST);
gen.addJumpIfBytesNotEqual(Register.R0, ETH_BROADCAST_MAC_ADDRESS, mCountAndPassLabel);
- maybeSetCounter(gen, Counter.DROPPED_ETH_BROADCAST);
+ maybeSetupCounter(gen, Counter.DROPPED_ETH_BROADCAST);
gen.addJump(mCountAndDropLabel);
// Add IPv6 filters:
@@ -1193,7 +1203,7 @@
// Execution will reach the bottom of the program if none of the filters match,
// which will pass the packet to the application processor.
- maybeSetCounter(gen, Counter.PASSED_IPV6_ICMP);
+ maybeSetupCounter(gen, Counter.PASSED_IPV6_ICMP);
// Append the count & pass trampoline, which increments the counter at the data address
// pointed to by R1, then jumps to the pass label. This saves a few bytes over inserting
diff --git a/services/net/java/android/net/dhcp/DhcpServer.java b/services/net/java/android/net/dhcp/DhcpServer.java
index cee6fa9..35d29e7 100644
--- a/services/net/java/android/net/dhcp/DhcpServer.java
+++ b/services/net/java/android/net/dhcp/DhcpServer.java
@@ -39,7 +39,6 @@
import android.net.MacAddress;
import android.net.NetworkUtils;
import android.net.TrafficStats;
-import android.net.util.InterfaceParams;
import android.net.util.SharedLog;
import android.os.Handler;
import android.os.Looper;
@@ -85,7 +84,7 @@
@NonNull
private final ServerHandler mHandler;
@NonNull
- private final InterfaceParams mIface;
+ private final String mIfName;
@NonNull
private final DhcpLeaseRepository mLeaseRepo;
@NonNull
@@ -161,20 +160,20 @@
}
}
- public DhcpServer(@NonNull Looper looper, @NonNull InterfaceParams iface,
+ public DhcpServer(@NonNull Looper looper, @NonNull String ifName,
@NonNull DhcpServingParams params, @NonNull SharedLog log) {
- this(looper, iface, params, log, null);
+ this(looper, ifName, params, log, null);
}
@VisibleForTesting
- DhcpServer(@NonNull Looper looper, @NonNull InterfaceParams iface,
+ DhcpServer(@NonNull Looper looper, @NonNull String ifName,
@NonNull DhcpServingParams params, @NonNull SharedLog log,
@Nullable Dependencies deps) {
if (deps == null) {
deps = new DependenciesImpl();
}
mHandler = new ServerHandler(looper);
- mIface = iface;
+ mIfName = ifName;
mServingParams = params;
mLog = log;
mDeps = deps;
@@ -444,7 +443,7 @@
private boolean addArpEntry(@NonNull MacAddress macAddr, @NonNull Inet4Address inetAddr) {
try {
- mDeps.addArpEntry(inetAddr, macAddr, mIface.name, mSocket);
+ mDeps.addArpEntry(inetAddr, macAddr, mIfName, mSocket);
return true;
} catch (IOException e) {
mLog.e("Error adding client to ARP table", e);
@@ -526,7 +525,7 @@
// 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, mIface.name);
+ 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);
diff --git a/services/net/java/android/net/ip/IpServer.java b/services/net/java/android/net/ip/IpServer.java
index 823c0a1..493350d 100644
--- a/services/net/java/android/net/ip/IpServer.java
+++ b/services/net/java/android/net/ip/IpServer.java
@@ -138,9 +138,9 @@
return NetdService.getInstance();
}
- public DhcpServer makeDhcpServer(Looper looper, InterfaceParams iface,
+ public DhcpServer makeDhcpServer(Looper looper, String ifName,
DhcpServingParams params, SharedLog log) {
- return new DhcpServer(looper, iface, params, log);
+ return new DhcpServer(looper, ifName, params, log);
}
}
@@ -256,12 +256,6 @@
if (mUsingLegacyDhcp) {
return true;
}
-
- final InterfaceParams ifaceParams = mDeps.getInterfaceParams(mIfaceName);
- if (ifaceParams == null) {
- Log.e(TAG, "Failed to find interface params for DHCPv4");
- return false;
- }
final DhcpServingParams params;
try {
params = new DhcpServingParams.Builder()
@@ -277,7 +271,7 @@
return false;
}
- mDhcpServer = mDeps.makeDhcpServer(getHandler().getLooper(), ifaceParams, params,
+ mDhcpServer = mDeps.makeDhcpServer(getHandler().getLooper(), mIfaceName, params,
mLog.forSubComponent("DHCP"));
mDhcpServer.start();
return true;
diff --git a/startop/view_compiler/Android.bp b/startop/view_compiler/Android.bp
index de40e0d..91cec554 100644
--- a/startop/view_compiler/Android.bp
+++ b/startop/view_compiler/Android.bp
@@ -24,6 +24,9 @@
"libdexfile",
"slicer",
],
+ static_libs: [
+ "libtinyxml2",
+ ],
}
cc_library_host_static {
@@ -32,7 +35,9 @@
srcs: [
"dex_builder.cc",
"java_lang_builder.cc",
+ "tinyxml_layout_parser.cc",
"util.cc",
+ "layout_validation.cc",
],
}
@@ -43,7 +48,6 @@
"main.cc",
],
static_libs: [
- "libtinyxml2",
"libgflags",
"libviewcompiler",
],
@@ -54,6 +58,7 @@
defaults: ["viewcompiler_defaults"],
srcs: [
"dex_builder_test.cc",
+ "layout_validation_test.cc",
"util_test.cc",
],
static_libs: [
diff --git a/startop/view_compiler/dex_builder.cc b/startop/view_compiler/dex_builder.cc
index 906d64c..a78f7d5 100644
--- a/startop/view_compiler/dex_builder.cc
+++ b/startop/view_compiler/dex_builder.cc
@@ -61,18 +61,49 @@
case Instruction::Op::kInvokeDirect:
out << "kInvokeDirect";
return out;
+ case Instruction::Op::kInvokeStatic:
+ out << "kInvokeStatic";
+ return out;
+ case Instruction::Op::kInvokeInterface:
+ out << "kInvokeInterface";
+ return out;
case Instruction::Op::kBindLabel:
out << "kBindLabel";
return out;
case Instruction::Op::kBranchEqz:
out << "kBranchEqz";
return out;
+ case Instruction::Op::kBranchNEqz:
+ out << "kBranchNEqz";
+ return out;
case Instruction::Op::kNew:
out << "kNew";
return out;
+ case Instruction::Op::kCheckCast:
+ out << "kCheckCast";
+ return out;
}
}
+std::ostream& operator<<(std::ostream& out, const Value& value) {
+ if (value.is_register()) {
+ out << "Register(" << value.value() << ")";
+ } else if (value.is_parameter()) {
+ out << "Parameter(" << value.value() << ")";
+ } else if (value.is_immediate()) {
+ out << "Immediate(" << value.value() << ")";
+ } else if (value.is_string()) {
+ out << "String(" << value.value() << ")";
+ } else if (value.is_label()) {
+ out << "Label(" << value.value() << ")";
+ } else if (value.is_type()) {
+ out << "Type(" << value.value() << ")";
+ } else {
+ out << "UnknownValue";
+ }
+ return out;
+}
+
void* TrackingAllocator::Allocate(size_t size) {
std::unique_ptr<uint8_t[]> buffer = std::make_unique<uint8_t[]>(size);
void* raw_buffer = buffer.get();
@@ -289,12 +320,20 @@
return EncodeInvoke(instruction, art::Instruction::INVOKE_VIRTUAL);
case Instruction::Op::kInvokeDirect:
return EncodeInvoke(instruction, art::Instruction::INVOKE_DIRECT);
+ case Instruction::Op::kInvokeStatic:
+ return EncodeInvoke(instruction, art::Instruction::INVOKE_STATIC);
+ case Instruction::Op::kInvokeInterface:
+ return EncodeInvoke(instruction, art::Instruction::INVOKE_INTERFACE);
case Instruction::Op::kBindLabel:
return BindLabel(instruction.args()[0]);
case Instruction::Op::kBranchEqz:
return EncodeBranch(art::Instruction::IF_EQZ, instruction);
+ case Instruction::Op::kBranchNEqz:
+ return EncodeBranch(art::Instruction::IF_NEZ, instruction);
case Instruction::Op::kNew:
return EncodeNew(instruction);
+ case Instruction::Op::kCheckCast:
+ return EncodeCast(instruction);
}
}
@@ -353,7 +392,9 @@
// If there is a return value, add a move-result instruction
if (instruction.dest().has_value()) {
- Encode11x(art::Instruction::MOVE_RESULT, RegisterValue(*instruction.dest()));
+ Encode11x(instruction.result_is_object() ? art::Instruction::MOVE_RESULT_OBJECT
+ : art::Instruction::MOVE_RESULT,
+ RegisterValue(*instruction.dest()));
}
max_args_ = std::max(max_args_, instruction.args().size());
@@ -386,6 +427,18 @@
Encode21c(::art::Instruction::NEW_INSTANCE, RegisterValue(*instruction.dest()), type.value());
}
+void MethodBuilder::EncodeCast(const Instruction& instruction) {
+ DCHECK_EQ(Instruction::Op::kCheckCast, instruction.opcode());
+ DCHECK(instruction.dest().has_value());
+ DCHECK(instruction.dest()->is_variable());
+ DCHECK_EQ(1, instruction.args().size());
+
+ const Value& type = instruction.args()[0];
+ DCHECK_LT(RegisterValue(*instruction.dest()), 256);
+ DCHECK(type.is_type());
+ Encode21c(::art::Instruction::CHECK_CAST, RegisterValue(*instruction.dest()), type.value());
+}
+
size_t MethodBuilder::RegisterValue(const Value& value) const {
if (value.is_register()) {
return value.value();
@@ -447,7 +500,7 @@
auto& ir_node = dex_file_->methods_map[new_index];
SLICER_CHECK(ir_node == nullptr);
ir_node = decl;
- decl->orig_index = new_index;
+ decl->orig_index = decl->index = new_index;
entry = {id, decl};
}
diff --git a/startop/view_compiler/dex_builder.h b/startop/view_compiler/dex_builder.h
index adf82bf..757d863 100644
--- a/startop/view_compiler/dex_builder.h
+++ b/startop/view_compiler/dex_builder.h
@@ -73,7 +73,7 @@
bool operator<(const TypeDescriptor& rhs) const { return descriptor_ < rhs.descriptor_; }
private:
- TypeDescriptor(std::string descriptor) : descriptor_{descriptor} {}
+ explicit TypeDescriptor(std::string descriptor) : descriptor_{descriptor} {}
const std::string descriptor_;
};
@@ -83,7 +83,7 @@
class Prototype {
public:
template <typename... TypeDescriptors>
- Prototype(TypeDescriptor return_type, TypeDescriptors... param_types)
+ explicit Prototype(TypeDescriptor return_type, TypeDescriptors... param_types)
: return_type_{return_type}, param_types_{param_types...} {}
// Encode this prototype into the dex file.
@@ -142,14 +142,18 @@
// The operation performed by this instruction. These are virtual instructions that do not
// correspond exactly to DEX instructions.
enum class Op {
- kReturn,
- kReturnObject,
- kMove,
- kInvokeVirtual,
- kInvokeDirect,
kBindLabel,
kBranchEqz,
- kNew
+ kBranchNEqz,
+ kCheckCast,
+ kInvokeDirect,
+ kInvokeInterface,
+ kInvokeStatic,
+ kInvokeVirtual,
+ kMove,
+ kNew,
+ kReturn,
+ kReturnObject,
};
////////////////////////
@@ -163,19 +167,60 @@
// For most instructions, which take some number of arguments and have an optional return value.
template <typename... T>
static inline Instruction OpWithArgs(Op opcode, std::optional<const Value> dest, T... args) {
- return Instruction{opcode, /*method_id*/ 0, dest, args...};
+ return Instruction{opcode, /*method_id=*/0, /*result_is_object=*/false, dest, args...};
}
+
+ // A cast instruction. Basically, `(type)val`
+ static inline Instruction Cast(Value val, Value type) {
+ DCHECK(type.is_type());
+ return OpWithArgs(Op::kCheckCast, val, type);
+ }
+
// For method calls.
template <typename... T>
static inline Instruction InvokeVirtual(size_t method_id, std::optional<const Value> dest,
Value this_arg, T... args) {
- return Instruction{Op::kInvokeVirtual, method_id, dest, this_arg, args...};
+ return Instruction{
+ Op::kInvokeVirtual, method_id, /*result_is_object=*/false, dest, this_arg, args...};
+ }
+ // Returns an object
+ template <typename... T>
+ static inline Instruction InvokeVirtualObject(size_t method_id, std::optional<const Value> dest,
+ Value this_arg, T... args) {
+ return Instruction{
+ Op::kInvokeVirtual, method_id, /*result_is_object=*/true, dest, this_arg, args...};
}
// For direct calls (basically, constructors).
template <typename... T>
static inline Instruction InvokeDirect(size_t method_id, std::optional<const Value> dest,
Value this_arg, T... args) {
- return Instruction{Op::kInvokeDirect, method_id, dest, this_arg, args...};
+ return Instruction{
+ Op::kInvokeDirect, method_id, /*result_is_object=*/false, dest, this_arg, args...};
+ }
+ // Returns an object
+ template <typename... T>
+ static inline Instruction InvokeDirectObject(size_t method_id, std::optional<const Value> dest,
+ Value this_arg, T... args) {
+ return Instruction{
+ Op::kInvokeDirect, method_id, /*result_is_object=*/true, dest, this_arg, args...};
+ }
+ // For static calls.
+ template <typename... T>
+ static inline Instruction InvokeStatic(size_t method_id, std::optional<const Value> dest,
+ T... args) {
+ return Instruction{Op::kInvokeStatic, method_id, /*result_is_object=*/false, dest, args...};
+ }
+ // Returns an object
+ template <typename... T>
+ static inline Instruction InvokeStaticObject(size_t method_id, std::optional<const Value> dest,
+ T... args) {
+ return Instruction{Op::kInvokeStatic, method_id, /*result_is_object=*/true, dest, args...};
+ }
+ // For static calls.
+ template <typename... T>
+ static inline Instruction InvokeInterface(size_t method_id, std::optional<const Value> dest,
+ T... args) {
+ return Instruction{Op::kInvokeInterface, method_id, /*result_is_object=*/false, dest, args...};
}
///////////////
@@ -184,21 +229,27 @@
Op opcode() const { return opcode_; }
size_t method_id() const { return method_id_; }
+ bool result_is_object() const { return result_is_object_; }
const std::optional<const Value>& dest() const { return dest_; }
const std::vector<const Value>& args() const { return args_; }
private:
inline Instruction(Op opcode, size_t method_id, std::optional<const Value> dest)
- : opcode_{opcode}, method_id_{method_id}, dest_{dest}, args_{} {}
+ : opcode_{opcode}, method_id_{method_id}, result_is_object_{false}, dest_{dest}, args_{} {}
template <typename... T>
- inline constexpr Instruction(Op opcode, size_t method_id, std::optional<const Value> dest,
- T... args)
- : opcode_{opcode}, method_id_{method_id}, dest_{dest}, args_{args...} {}
+ inline constexpr Instruction(Op opcode, size_t method_id, bool result_is_object,
+ std::optional<const Value> dest, T... args)
+ : opcode_{opcode},
+ method_id_{method_id},
+ result_is_object_{result_is_object},
+ dest_{dest},
+ args_{args...} {}
const Op opcode_;
// The index of the method to invoke, for kInvokeVirtual and similar opcodes.
const size_t method_id_{0};
+ const bool result_is_object_;
const std::optional<const Value> dest_;
const std::vector<const Value> args_;
};
@@ -244,6 +295,8 @@
// TODO: add builders for more instructions
+ DexBuilder* dex_file() const { return dex_; }
+
private:
void EncodeInstructions();
void EncodeInstruction(const Instruction& instruction);
@@ -257,6 +310,7 @@
void EncodeInvoke(const Instruction& instruction, ::art::Instruction::Code opcode);
void EncodeBranch(art::Instruction::Code op, const Instruction& instruction);
void EncodeNew(const Instruction& instruction);
+ void EncodeCast(const Instruction& instruction);
// Low-level instruction format encoding. See
// https://source.android.com/devices/tech/dalvik/instruction-formats for documentation of
diff --git a/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java b/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
index e20f3a9..42d4161 100644
--- a/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
+++ b/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java
@@ -20,6 +20,7 @@
import dalvik.system.InMemoryDexClassLoader;
import dalvik.system.PathClassLoader;
import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import org.junit.Assert;
@@ -84,6 +85,15 @@
}
@Test
+ public void returnIfNotZero() throws Exception {
+ ClassLoader loader = loadDexFile("simple.dex");
+ Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
+ Method method = clazz.getMethod("returnIfNotZero", int.class);
+ Assert.assertEquals(3, method.invoke(null, 0));
+ Assert.assertEquals(5, method.invoke(null, 17));
+ }
+
+ @Test
public void backwardsBranch() throws Exception {
ClassLoader loader = loadDexFile("simple.dex");
Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
@@ -124,4 +134,41 @@
Assert.assertEquals("b", method.invoke(null, 0));
Assert.assertEquals("a", method.invoke(null, 1));
}
+
+ @Test
+ public void invokeStaticReturnObject() throws Exception {
+ ClassLoader loader = loadDexFile("simple.dex");
+ Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
+ Method method = clazz.getMethod("invokeStaticReturnObject", int.class, int.class);
+ Assert.assertEquals("10", method.invoke(null, 10, 10));
+ Assert.assertEquals("a", method.invoke(null, 10, 16));
+ Assert.assertEquals("5", method.invoke(null, 5, 16));
+ }
+
+ @Test
+ public void invokeVirtualReturnObject() throws Exception {
+ ClassLoader loader = loadDexFile("simple.dex");
+ Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
+ Method method = clazz.getMethod("invokeVirtualReturnObject", String.class, int.class);
+ Assert.assertEquals("bc", method.invoke(null, "abc", 1));
+ }
+
+ @Test
+ public void castObjectToString() throws Exception {
+ ClassLoader loader = loadDexFile("simple.dex");
+ Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests");
+ Method method = clazz.getMethod("castObjectToString", Object.class);
+ Assert.assertEquals("abc", method.invoke(null, "abc"));
+ boolean castFailed = false;
+ try {
+ method.invoke(null, 5);
+ } catch (InvocationTargetException e) {
+ if (e.getCause() instanceof ClassCastException) {
+ castFailed = true;
+ } else {
+ throw e;
+ }
+ }
+ Assert.assertTrue(castFailed);
+ }
}
diff --git a/startop/view_compiler/dex_testcase_generator.cc b/startop/view_compiler/dex_testcase_generator.cc
index e2bf43bc..f62ec5dd 100644
--- a/startop/view_compiler/dex_testcase_generator.cc
+++ b/startop/view_compiler/dex_testcase_generator.cc
@@ -108,6 +108,27 @@
}
returnIfZero.Encode();
+ // int returnIfNotZero(int x) { if (x != 0) { return 5; } else { return 3; } }
+ MethodBuilder returnIfNotZero{cbuilder.CreateMethod(
+ "returnIfNotZero", Prototype{TypeDescriptor::Int(), TypeDescriptor::Int()})};
+ {
+ Value resultIfNotZero{returnIfNotZero.MakeRegister()};
+ Value else_target{returnIfNotZero.MakeLabel()};
+ returnIfNotZero.AddInstruction(Instruction::OpWithArgs(
+ Instruction::Op::kBranchNEqz, /*dest=*/{}, Value::Parameter(0), else_target));
+ // else branch
+ returnIfNotZero.BuildConst4(resultIfNotZero, 3);
+ returnIfNotZero.AddInstruction(
+ Instruction::OpWithArgs(Instruction::Op::kReturn, /*dest=*/{}, resultIfNotZero));
+ // then branch
+ returnIfNotZero.AddInstruction(
+ Instruction::OpWithArgs(Instruction::Op::kBindLabel, /*dest=*/{}, else_target));
+ returnIfNotZero.BuildConst4(resultIfNotZero, 5);
+ returnIfNotZero.AddInstruction(
+ Instruction::OpWithArgs(Instruction::Op::kReturn, /*dest=*/{}, resultIfNotZero));
+ }
+ returnIfNotZero.Encode();
+
// Make sure backwards branches work too.
//
// Pseudo code for test:
@@ -216,6 +237,51 @@
method.Encode();
}(returnStringIfZeroBA);
+ // Make sure we can invoke static methods that return an object
+ // String invokeStaticReturnObject(int n, int radix) { return java.lang.Integer.toString(n,
+ // radix); }
+ MethodBuilder invokeStaticReturnObject{
+ cbuilder.CreateMethod("invokeStaticReturnObject",
+ Prototype{string_type, TypeDescriptor::Int(), TypeDescriptor::Int()})};
+ [&](MethodBuilder& method) {
+ Value result{method.MakeRegister()};
+ MethodDeclData to_string{dex_file.GetOrDeclareMethod(
+ TypeDescriptor::FromClassname("java.lang.Integer"),
+ "toString",
+ Prototype{string_type, TypeDescriptor::Int(), TypeDescriptor::Int()})};
+ method.AddInstruction(Instruction::InvokeStaticObject(
+ to_string.id, result, Value::Parameter(0), Value::Parameter(1)));
+ method.BuildReturn(result, /*is_object=*/true);
+ method.Encode();
+ }(invokeStaticReturnObject);
+
+ // Make sure we can invoke virtual methods that return an object
+ // String invokeVirtualReturnObject(String s, int n) { return s.substring(n); }
+ MethodBuilder invokeVirtualReturnObject{cbuilder.CreateMethod(
+ "invokeVirtualReturnObject", Prototype{string_type, string_type, TypeDescriptor::Int()})};
+ [&](MethodBuilder& method) {
+ Value result{method.MakeRegister()};
+ MethodDeclData substring{dex_file.GetOrDeclareMethod(
+ string_type, "substring", Prototype{string_type, TypeDescriptor::Int()})};
+ method.AddInstruction(Instruction::InvokeVirtualObject(
+ substring.id, result, Value::Parameter(0), Value::Parameter(1)));
+ method.BuildReturn(result, /*is_object=*/true);
+ method.Encode();
+ }(invokeVirtualReturnObject);
+
+ // Make sure we can cast objects
+ // String castObjectToString(Object o) { return (String)o; }
+ MethodBuilder castObjectToString{cbuilder.CreateMethod(
+ "castObjectToString",
+ Prototype{string_type, TypeDescriptor::FromClassname("java.lang.Object")})};
+ [&](MethodBuilder& method) {
+ const ir::Type* type_def = dex_file.GetOrAddType(string_type.descriptor());
+ method.AddInstruction(
+ Instruction::Cast(Value::Parameter(0), Value::Type(type_def->orig_index)));
+ method.BuildReturn(Value::Parameter(0), /*is_object=*/true);
+ method.Encode();
+ }(castObjectToString);
+
slicer::MemView image{dex_file.CreateImage()};
std::ofstream out_file(outdir + "/simple.dex");
out_file.write(image.ptr<const char>(), image.size());
diff --git a/startop/view_compiler/layout_validation.cc b/startop/view_compiler/layout_validation.cc
new file mode 100644
index 0000000..8c77377
--- /dev/null
+++ b/startop/view_compiler/layout_validation.cc
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+#include "layout_validation.h"
+
+#include "android-base/stringprintf.h"
+
+namespace startop {
+
+void LayoutValidationVisitor::VisitStartTag(const std::u16string& name) {
+ if (0 == name.compare(u"merge")) {
+ message_ = "Merge tags are not supported";
+ can_compile_ = false;
+ }
+ if (0 == name.compare(u"include")) {
+ message_ = "Include tags are not supported";
+ can_compile_ = false;
+ }
+ if (0 == name.compare(u"view")) {
+ message_ = "View tags are not supported";
+ can_compile_ = false;
+ }
+ if (0 == name.compare(u"fragment")) {
+ message_ = "Fragment tags are not supported";
+ can_compile_ = false;
+ }
+}
+
+} // namespace startop
\ No newline at end of file
diff --git a/startop/view_compiler/layout_validation.h b/startop/view_compiler/layout_validation.h
new file mode 100644
index 0000000..bed34bb
--- /dev/null
+++ b/startop/view_compiler/layout_validation.h
@@ -0,0 +1,46 @@
+/*
+ * 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.
+ */
+
+#ifndef LAYOUT_VALIDATION_H_
+#define LAYOUT_VALIDATION_H_
+
+#include "dex_builder.h"
+
+#include <string>
+
+namespace startop {
+
+// This visitor determines whether a layout can be compiled. Since we do not currently support all
+// features, such as includes and merges, we need to pre-validate the layout before we start
+// compiling.
+class LayoutValidationVisitor {
+ public:
+ void VisitStartDocument() const {}
+ void VisitEndDocument() const {}
+ void VisitStartTag(const std::u16string& name);
+ void VisitEndTag() const {}
+
+ const std::string& message() const { return message_; }
+ bool can_compile() const { return can_compile_; }
+
+ private:
+ std::string message_{"Okay"};
+ bool can_compile_{true};
+};
+
+} // namespace startop
+
+#endif // LAYOUT_VALIDATION_H_
diff --git a/startop/view_compiler/layout_validation_test.cc b/startop/view_compiler/layout_validation_test.cc
new file mode 100644
index 0000000..b74cdae
--- /dev/null
+++ b/startop/view_compiler/layout_validation_test.cc
@@ -0,0 +1,163 @@
+/*
+ * 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.
+ */
+#include "tinyxml_layout_parser.h"
+
+#include "gtest/gtest.h"
+
+using startop::CanCompileLayout;
+using std::string;
+
+namespace {
+void ValidateXmlText(const string& xml, bool expected) {
+ tinyxml2::XMLDocument doc;
+ doc.Parse(xml.c_str());
+ EXPECT_EQ(CanCompileLayout(doc), expected);
+}
+} // namespace
+
+TEST(LayoutValidationTest, SingleButtonLayout) {
+ const string xml = R"(<?xml version="1.0" encoding="utf-8"?>
+<Button xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:text="Hello, World!">
+
+</Button>)";
+ ValidateXmlText(xml, /*expected=*/true);
+}
+
+TEST(LayoutValidationTest, SmallConstraintLayout) {
+ const string xml = R"(<?xml version="1.0" encoding="utf-8"?>
+<android.support.constraint.ConstraintLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <Button
+ android:id="@+id/button6"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="16dp"
+ android:layout_marginBottom="16dp"
+ android:text="Button"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent" />
+
+ <Button
+ android:id="@+id/button7"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="8dp"
+ android:layout_marginBottom="16dp"
+ android:text="Button2"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toStartOf="@+id/button6" />
+
+ <Button
+ android:id="@+id/button8"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginEnd="8dp"
+ android:layout_marginBottom="16dp"
+ android:text="Button1"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toStartOf="@+id/button7" />
+</android.support.constraint.ConstraintLayout>)";
+ ValidateXmlText(xml, /*expected=*/true);
+}
+
+TEST(LayoutValidationTest, MergeNode) {
+ const string xml = R"(<?xml version="1.0" encoding="utf-8"?>
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+
+ <TextView
+ android:id="@+id/textView3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="TextView" />
+
+ <Button
+ android:id="@+id/button9"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Button" />
+</merge>)";
+ ValidateXmlText(xml, /*expected=*/false);
+}
+
+TEST(LayoutValidationTest, IncludeLayout) {
+ const string xml = R"(<?xml version="1.0" encoding="utf-8"?>
+<android.support.constraint.ConstraintLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <include
+ layout="@layout/single_button_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
+</android.support.constraint.ConstraintLayout>)";
+ ValidateXmlText(xml, /*expected=*/false);
+}
+
+TEST(LayoutValidationTest, ViewNode) {
+ const string xml = R"(<?xml version="1.0" encoding="utf-8"?>
+<android.support.constraint.ConstraintLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <view
+ class="android.support.design.button.MaterialButton"
+ id="@+id/view"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
+</android.support.constraint.ConstraintLayout>)";
+ ValidateXmlText(xml, /*expected=*/false);
+}
+
+TEST(LayoutValidationTest, FragmentNode) {
+ // This test case is from https://developer.android.com/guide/components/fragments
+ const string xml = R"(<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <fragment android:name="com.example.news.ArticleListFragment"
+ android:id="@+id/list"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="match_parent" />
+ <fragment android:name="com.example.news.ArticleReaderFragment"
+ android:id="@+id/viewer"
+ android:layout_weight="2"
+ android:layout_width="0dp"
+ android:layout_height="match_parent" />
+</LinearLayout>)";
+ ValidateXmlText(xml, /*expected=*/false);
+}
diff --git a/startop/view_compiler/main.cc b/startop/view_compiler/main.cc
index 7d791c2..55bfdc7 100644
--- a/startop/view_compiler/main.cc
+++ b/startop/view_compiler/main.cc
@@ -18,6 +18,7 @@
#include "dex_builder.h"
#include "java_lang_builder.h"
+#include "tinyxml_layout_parser.h"
#include "util.h"
#include "tinyxml2.h"
@@ -41,7 +42,7 @@
class ViewCompilerXmlVisitor : public XMLVisitor {
public:
- ViewCompilerXmlVisitor(JavaLangViewBuilder* builder) : builder_(builder) {}
+ explicit ViewCompilerXmlVisitor(JavaLangViewBuilder* builder) : builder_(builder) {}
bool VisitEnter(const XMLDocument& /*doc*/) override {
builder_->Start();
@@ -100,6 +101,12 @@
XMLDocument xml;
xml.LoadFile(filename);
+ string message{};
+ if (!startop::CanCompileLayout(xml, &message)) {
+ LOG(ERROR) << "Layout not supported: " << message;
+ return 1;
+ }
+
std::ofstream outfile;
if (FLAGS_out != kStdoutFilename) {
outfile.open(FLAGS_out);
diff --git a/startop/view_compiler/tinyxml_layout_parser.cc b/startop/view_compiler/tinyxml_layout_parser.cc
new file mode 100644
index 0000000..1b3a81f
--- /dev/null
+++ b/startop/view_compiler/tinyxml_layout_parser.cc
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+#include "tinyxml_layout_parser.h"
+
+#include "layout_validation.h"
+
+namespace startop {
+
+bool CanCompileLayout(const tinyxml2::XMLDocument& xml, std::string* message) {
+ LayoutValidationVisitor validator;
+ TinyXmlVisitorAdapter adapter{&validator};
+ xml.Accept(&adapter);
+
+ if (message != nullptr) {
+ *message = validator.message();
+ }
+
+ return validator.can_compile();
+}
+
+} // namespace startop
diff --git a/startop/view_compiler/tinyxml_layout_parser.h b/startop/view_compiler/tinyxml_layout_parser.h
new file mode 100644
index 0000000..8f714a2
--- /dev/null
+++ b/startop/view_compiler/tinyxml_layout_parser.h
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+#ifndef TINYXML_LAYOUT_PARSER_H_
+#define TINYXML_LAYOUT_PARSER_H_
+
+#include "tinyxml2.h"
+
+#include <codecvt>
+#include <locale>
+#include <string>
+
+namespace startop {
+
+template <typename Visitor>
+class TinyXmlVisitorAdapter : public tinyxml2::XMLVisitor {
+ public:
+ explicit TinyXmlVisitorAdapter(Visitor* visitor) : visitor_{visitor} {}
+
+ bool VisitEnter(const tinyxml2::XMLDocument& /*doc*/) override {
+ visitor_->VisitStartDocument();
+ return true;
+ }
+
+ bool VisitExit(const tinyxml2::XMLDocument& /*doc*/) override {
+ visitor_->VisitEndDocument();
+ return true;
+ }
+
+ bool VisitEnter(const tinyxml2::XMLElement& element,
+ const tinyxml2::XMLAttribute* /*firstAttribute*/) override {
+ visitor_->VisitStartTag(
+ std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>{}.from_bytes(
+ element.Name()));
+ return true;
+ }
+
+ bool VisitExit(const tinyxml2::XMLElement& /*element*/) override {
+ visitor_->VisitEndTag();
+ return true;
+ }
+
+ private:
+ Visitor* visitor_;
+};
+
+// Returns whether a layout resource represented by a TinyXML document is supported by the layout
+// compiler.
+bool CanCompileLayout(const tinyxml2::XMLDocument& xml, std::string* message = nullptr);
+
+} // namespace startop
+
+#endif // TINYXML_LAYOUT_PARSER_H_
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index bf0ffb9..36d0188 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -29,7 +29,6 @@
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
-import java.lang.String;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.nio.charset.StandardCharsets;
@@ -919,10 +918,16 @@
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
- sb.append("[pa: ");
+ sb.append("[id: ");
+ sb.append(mTelecomCallId);
+ sb.append(", pa: ");
sb.append(mAccountHandle);
sb.append(", hdl: ");
- sb.append(Log.pii(mHandle));
+ sb.append(Log.piiHandle(mHandle));
+ sb.append(", hdlPres: ");
+ sb.append(mHandlePresentation);
+ sb.append(", videoState: ");
+ sb.append(VideoProfile.videoStateToString(mVideoState));
sb.append(", caps: ");
sb.append(capabilitiesToString(mCallCapabilities));
sb.append(", props: ");
diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java
index 7db6940..6628743 100644
--- a/telecomm/java/android/telecom/CallScreeningService.java
+++ b/telecomm/java/android/telecom/CallScreeningService.java
@@ -27,8 +27,8 @@
import android.os.RemoteException;
import com.android.internal.os.SomeArgs;
-import com.android.internal.telecom.ICallScreeningService;
import com.android.internal.telecom.ICallScreeningAdapter;
+import com.android.internal.telecom.ICallScreeningService;
/**
* This service can be implemented by the default dialer (see
@@ -147,7 +147,7 @@
private boolean mShouldSkipCallLog;
private boolean mShouldSkipNotification;
- /*
+ /**
* Sets whether the incoming call should be blocked.
*/
public Builder setDisallowCall(boolean shouldDisallowCall) {
@@ -155,7 +155,7 @@
return this;
}
- /*
+ /**
* Sets whether the incoming call should be disconnected as if the user had manually
* rejected it. This property should only be set to true if the call is disallowed.
*/
@@ -164,16 +164,20 @@
return this;
}
- /*
+ /**
* Sets whether the incoming call should not be displayed in the call log. This property
* should only be set to true if the call is disallowed.
+ * <p>
+ * Note: Calls will still be logged with type
+ * {@link android.provider.CallLog.Calls#BLOCKED_TYPE}, regardless of how this property
+ * is set.
*/
public Builder setSkipCallLog(boolean shouldSkipCallLog) {
mShouldSkipCallLog = shouldSkipCallLog;
return this;
}
- /*
+ /**
* Sets whether a missed call notification should not be shown for the incoming call.
* This property should only be set to true if the call is disallowed.
*/
@@ -211,6 +215,17 @@
* Called when a new incoming call is added.
* {@link CallScreeningService#respondToCall(Call.Details, CallScreeningService.CallResponse)}
* should be called to allow or disallow the call.
+ * <p>
+ * Note: The {@link Call.Details} instance provided to a call screening service will only have
+ * the following properties set. The rest of the {@link Call.Details} properties will be set to
+ * their default value or {@code null}.
+ * <ul>
+ * <li>{@link Call.Details#getState()}</li>
+ * <li>{@link Call.Details#getConnectTimeMillis()}</li>
+ * <li>{@link Call.Details#getCreationTimeMillis()}</li>
+ * <li>{@link Call.Details#getHandle()}</li>
+ * <li>{@link Call.Details#getHandlePresentation()}</li>
+ * </ul>
*
* @param callDetails Information about a new incoming call, see {@link Call.Details}.
*/
diff --git a/telecomm/java/android/telecom/PhoneAccountSuggestion.aidl b/telecomm/java/android/telecom/PhoneAccountSuggestion.aidl
new file mode 100644
index 0000000..e2fa7e4
--- /dev/null
+++ b/telecomm/java/android/telecom/PhoneAccountSuggestion.aidl
@@ -0,0 +1,22 @@
+/*
+ * 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.
+ */
+
+package android.telecom;
+
+/**
+ * {@hide}
+ */
+parcelable PhoneAccountSuggestion;
\ No newline at end of file
diff --git a/telecomm/java/android/telecom/PhoneAccountSuggestion.java b/telecomm/java/android/telecom/PhoneAccountSuggestion.java
index 4e6a178..b401bcf 100644
--- a/telecomm/java/android/telecom/PhoneAccountSuggestion.java
+++ b/telecomm/java/android/telecom/PhoneAccountSuggestion.java
@@ -24,6 +24,7 @@
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
public final class PhoneAccountSuggestion implements Parcelable {
@@ -132,4 +133,19 @@
dest.writeInt(mReason);
dest.writeByte((byte) (mShouldAutoSelect ? 1 : 0));
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ PhoneAccountSuggestion that = (PhoneAccountSuggestion) o;
+ return mReason == that.mReason
+ && mShouldAutoSelect == that.mShouldAutoSelect
+ && Objects.equals(mHandle, that.mHandle);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mHandle, mReason, mShouldAutoSelect);
+ }
}
diff --git a/telecomm/java/android/telecom/PhoneAccountSuggestionService.java b/telecomm/java/android/telecom/PhoneAccountSuggestionService.java
new file mode 100644
index 0000000..ba3822c
--- /dev/null
+++ b/telecomm/java/android/telecom/PhoneAccountSuggestionService.java
@@ -0,0 +1,123 @@
+/*
+ * 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.
+ */
+
+package android.telecom;
+
+import android.annotation.NonNull;
+import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.RemoteException;
+
+import com.android.internal.telecom.IPhoneAccountSuggestionCallback;
+import com.android.internal.telecom.IPhoneAccountSuggestionService;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Base class for service that allows system apps to suggest phone accounts for outgoing calls.
+ *
+ * Phone account suggestions allow OEMs to intelligently select phone accounts based on knowledge
+ * about the user's past behavior, carrier billing patterns, or other factors unknown to the AOSP
+ * Telecom system.
+ * OEMs who wish to provide a phone account suggestion service on their device should implement this
+ * service in an app that resides in the /system/priv-app/ directory on their device. For security
+ * reasons, the service's entry {@code AndroidManifest.xml} file must declare the
+ * {@link android.Manifest.permission.BIND_PHONE_ACCOUNT_SUGGESTION_SERVICE} permission:
+ * <pre>
+ * {@code
+ * <service android:name="your.package.YourServiceName"
+ * android:permission="android.permission.BIND_PHONE_ACCOUNT_SUGGESTION_SERVICE">
+ * <intent-filter>
+ * <action android:name="android.telecom.PhoneAccountSuggestionService"/>
+ * </intent-filter>
+ * </service>
+ * }
+ * </pre>
+ * Only one system app on each device may implement this service. If multiple system apps implement
+ * this service, none of them will be queried for suggestions.
+ * @hide
+ */
+@SystemApi
+@TestApi
+public class PhoneAccountSuggestionService extends Service {
+ /**
+ * The {@link Intent} that must be declared in the {@code intent-filter} element of the
+ * service's manifest entry.
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+ public static final String SERVICE_INTERFACE = "android.telecom.PhoneAccountSuggestionService";
+
+ private IPhoneAccountSuggestionService mInterface = new IPhoneAccountSuggestionService.Stub() {
+ @Override
+ public void onAccountSuggestionRequest(IPhoneAccountSuggestionCallback callback,
+ String number) {
+ mCallbackMap.put(number, callback);
+ PhoneAccountSuggestionService.this.onAccountSuggestionRequest(number);
+ }
+ };
+
+ private final Map<String, IPhoneAccountSuggestionCallback> mCallbackMap =
+ new HashMap<>();
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mInterface.asBinder();
+ }
+
+ /**
+ * The system calls this method during the outgoing call flow if it needs account suggestions.
+ *
+ * The implementer of this service must override this method to implement its account suggestion
+ * logic. After preparing the suggestions, the implementation of the service must call
+ * {@link #suggestPhoneAccounts(String, List)} to deliver the suggestions back to the system.
+ *
+ * Note that the system will suspend the outgoing call process after it calls this method until
+ * this service calls {@link #suggestPhoneAccounts}.
+ *
+ * @param number The phone number to provide suggestions for.
+ */
+ public void onAccountSuggestionRequest(@NonNull String number) {}
+
+ /**
+ * The implementation of this service calls this method to deliver suggestions to the system.
+ *
+ * The implementation of this service must call this method after receiving a call to
+ * {@link #onAccountSuggestionRequest(String)}. If no suggestions are available, pass an empty
+ * list as the {@code suggestions} argument.
+ *
+ * @param number The phone number to provide suggestions for.
+ * @param suggestions The list of suggestions.
+ */
+ public final void suggestPhoneAccounts(@NonNull String number,
+ @NonNull List<PhoneAccountSuggestion> suggestions) {
+ IPhoneAccountSuggestionCallback callback = mCallbackMap.remove(number);
+ if (callback == null) {
+ Log.w(this, "No suggestions requested for the number %s", Log.pii(number));
+ return;
+ }
+ try {
+ callback.suggestPhoneAccounts(number, suggestions);
+ } catch (RemoteException e) {
+ Log.w(this, "Remote exception calling suggestPhoneAccounts");
+ }
+ }
+}
diff --git a/telecomm/java/android/telecom/VideoProfile.java b/telecomm/java/android/telecom/VideoProfile.java
index bbac8eb..7b23061 100644
--- a/telecomm/java/android/telecom/VideoProfile.java
+++ b/telecomm/java/android/telecom/VideoProfile.java
@@ -369,16 +369,13 @@
}
/**
- * Create a call camera capabilities instance that optionally
- * supports zoom.
+ * Create a call camera capabilities instance that optionally supports zoom.
*
* @param width The width of the camera video (in pixels).
* @param height The height of the camera video (in pixels).
* @param zoomSupported True when camera supports zoom.
* @param maxZoom Maximum zoom supported by camera.
- * @hide
*/
- @UnsupportedAppUsage
public CameraCapabilities(int width, int height, boolean zoomSupported, float maxZoom) {
mWidth = width;
mHeight = height;
@@ -455,16 +452,14 @@
}
/**
- * Whether the camera supports zoom.
- * @hide
+ * Returns {@code true} is zoom is supported, {@code false} otherwise.
*/
public boolean isZoomSupported() {
return mZoomSupported;
}
/**
- * The maximum zoom supported by the camera.
- * @hide
+ * Returns the maximum zoom supported by the camera.
*/
public float getMaxZoom() {
return mMaxZoom;
diff --git a/telecomm/java/com/android/internal/telecom/IPhoneAccountSuggestionCallback.aidl b/telecomm/java/com/android/internal/telecom/IPhoneAccountSuggestionCallback.aidl
new file mode 100644
index 0000000..cb14241
--- /dev/null
+++ b/telecomm/java/com/android/internal/telecom/IPhoneAccountSuggestionCallback.aidl
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+package com.android.internal.telecom;
+
+import android.telecom.PhoneAccountSuggestion;
+/**
+ * Internal remote callback interface for a phone acct suggestion service.
+ * @hide
+ */
+oneway interface IPhoneAccountSuggestionCallback{
+ void suggestPhoneAccounts(in String number, in List<PhoneAccountSuggestion> suggestions);
+}
diff --git a/telecomm/java/com/android/internal/telecom/IPhoneAccountSuggestionService.aidl b/telecomm/java/com/android/internal/telecom/IPhoneAccountSuggestionService.aidl
new file mode 100644
index 0000000..0ffab93
--- /dev/null
+++ b/telecomm/java/com/android/internal/telecom/IPhoneAccountSuggestionService.aidl
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+package com.android.internal.telecom;
+
+import com.android.internal.telecom.IPhoneAccountSuggestionCallback;
+
+/**
+ * Internal remote interface for a phone acct suggestion service.
+ * @hide
+ */
+oneway interface IPhoneAccountSuggestionService {
+ void onAccountSuggestionRequest(in IPhoneAccountSuggestionCallback callback,
+ in String number);
+}
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index d64efea..6f1b66a 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -307,6 +307,8 @@
void setTestDefaultCallRedirectionApp(String packageName);
+ void setTestPhoneAcctSuggestionComponent(String flattenedComponentName);
+
void setTestDefaultCallScreeningApp(String packageName);
void addOrRemoveTestCallCompanionApp(String packageName, boolean isAdded);
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 0b5aa14..3e4482e 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -2668,10 +2668,26 @@
/**
* The {@code content://} style URL for this table.
+ * For MSIM, this will return APNs for the default subscription
+ * {@link SubscriptionManager#getDefaultSubscriptionId()}. To specify subId for MSIM,
+ * use {@link Uri#withAppendedPath(Uri, String)} to append with subscription id.
*/
public static final Uri CONTENT_URI = Uri.parse("content://telephony/carriers");
/**
+ * The {@code content://} style URL for this table. Used for APN query based on current
+ * subscription. Instead of specifying carrier matching information in the selection,
+ * this API will return all matching APNs from current subscription carrier and queries
+ * will be applied on top of that. If there is no match for MVNO (Mobile Virtual Network
+ * Operator) APNs, return APNs from its MNO (based on mccmnc) instead. For MSIM, this will
+ * return APNs for the default subscription
+ * {@link SubscriptionManager#getDefaultSubscriptionId()}. To specify subId for MSIM,
+ * use {@link Uri#withAppendedPath(Uri, String)} to append with subscription id.
+ */
+ public static final Uri SIM_APN_URI = Uri.parse(
+ "content://telephony/carriers/sim_apn_list");
+
+ /**
* The {@code content://} style URL to be called from DevicePolicyManagerService,
* can manage DPC-owned APNs.
* @hide
@@ -2681,7 +2697,9 @@
/**
* The {@code content://} style URL to be called from Telephony to query APNs.
* When DPC-owned APNs are enforced, only DPC-owned APNs are returned, otherwise only
- * non-DPC-owned APNs are returned.
+ * non-DPC-owned APNs are returned. For MSIM, this will return APNs for the default
+ * subscription {@link SubscriptionManager#getDefaultSubscriptionId()}. To specify subId
+ * for MSIM, use {@link Uri#withAppendedPath(Uri, String)} to append with subscription id.
* @hide
*/
public static final Uri FILTERED_URI = Uri.parse("content://telephony/carriers/filtered");
@@ -2695,13 +2713,6 @@
"content://telephony/carriers/enforce_managed");
/**
- * The {@code content://} style URL to be called from Telephony to query current APNs.
- * @hide
- */
- public static final Uri SIM_APN_LIST = Uri.parse(
- "content://telephony/carriers/sim_apn_list");
-
- /**
* The column name for ENFORCE_MANAGED_URI, indicates whether DPC-owned APNs are enforced.
* @hide
*/
@@ -2775,18 +2786,30 @@
/**
* Mobile Country Code (MCC).
* <P>Type: TEXT</P>
+ * @deprecated Use {@link #SIM_APN_URI} to query APN instead, this API will return
+ * matching APNs based on current subscription carrier, thus no need to specify MCC and
+ * other carrier matching information. In the future, Android will not support MCC for
+ * APN query.
*/
public static final String MCC = "mcc";
/**
* Mobile Network Code (MNC).
* <P>Type: TEXT</P>
+ * @deprecated Use {@link #SIM_APN_URI} to query APN instead, this API will return
+ * matching APNs based on current subscription carrier, thus no need to specify MNC and
+ * other carrier matching information. In the future, Android will not support MNC for
+ * APN query.
*/
public static final String MNC = "mnc";
/**
* Numeric operator ID (as String). Usually {@code MCC + MNC}.
* <P>Type: TEXT</P>
+ * @deprecated Use {@link #SIM_APN_URI} to query APN instead, this API will return
+ * matching APNs based on current subscription carrier, thus no need to specify Numeric
+ * and other carrier matching information. In the future, Android will not support Numeric
+ * for APN query.
*/
public static final String NUMERIC = "numeric";
@@ -2867,6 +2890,10 @@
* MVNO type:
* {@code SPN (Service Provider Name), IMSI, GID (Group Identifier Level 1)}.
* <P>Type: TEXT</P>
+ * @deprecated Use {@link #SIM_APN_URI} to query APN instead, this API will return
+ * matching APNs based on current subscription carrier, thus no need to specify MVNO_TYPE
+ * and other carrier matching information. In the future, Android will not support MVNO_TYPE
+ * for APN query.
*/
public static final String MVNO_TYPE = "mvno_type";
@@ -2879,6 +2906,10 @@
* <li>GID: 4E, 33, ...</li>
* </ul>
* <P>Type: TEXT</P>
+ * @deprecated Use {@link #SIM_APN_URI} to query APN instead, this API will return
+ * matching APNs based on current subscription carrier, thus no need to specify
+ * MVNO_MATCH_DATA and other carrier matching information. In the future, Android will not
+ * support MVNO_MATCH_DATA for APN query.
*/
public static final String MVNO_MATCH_DATA = "mvno_match_data";
@@ -3087,7 +3118,6 @@
})
@Retention(RetentionPolicy.SOURCE)
public @interface EditStatus {}
-
}
/**
@@ -3577,8 +3607,9 @@
/**
* Generates a content {@link Uri} used to receive updates on precise carrier identity
- * change on the given subscriptionId
- * {@link TelephonyManager#ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED}.
+ * change on the given subscriptionId returned by
+ * {@link TelephonyManager#getSimPreciseCarrierId()}.
+ * @see TelephonyManager#ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED
* <p>
* Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the
* precise carrier identity {@link TelephonyManager#getSimPreciseCarrierId()}
@@ -3589,7 +3620,6 @@
*
* @param subscriptionId the subscriptionId to receive updates on
* @return the Uri used to observe precise carrier identity changes
- * @hide
*/
public static Uri getPreciseCarrierIdUriForSubscriptionId(int subscriptionId) {
return Uri.withAppendedPath(Uri.withAppendedPath(CONTENT_URI, "precise"),
@@ -3611,24 +3641,22 @@
public static final String CARRIER_ID = "carrier_id";
/**
- * A user facing carrier name for precise carrier id.
- * @see TelephonyManager#getSimPreciseCarrierIdName()
- * This is not a database column, only used to notify content observers for
- * {@link #getPreciseCarrierIdUriForSubscriptionId(int)}
- * @hide
- */
- public static final String PRECISE_CARRIER_ID_NAME = "precise_carrier_id_name";
-
- /**
* A fine-grained carrier id.
* @see TelephonyManager#getSimPreciseCarrierId()
* This is not a database column, only used to notify content observers for
* {@link #getPreciseCarrierIdUriForSubscriptionId(int)}
- * @hide
*/
public static final String PRECISE_CARRIER_ID = "precise_carrier_id";
/**
+ * A user facing carrier name for precise carrier id {@link #PRECISE_CARRIER_ID}.
+ * @see TelephonyManager#getSimPreciseCarrierIdName()
+ * This is not a database column, only used to notify content observers for
+ * {@link #getPreciseCarrierIdUriForSubscriptionId(int)}
+ */
+ public static final String PRECISE_CARRIER_ID_NAME = "precise_carrier_id_name";
+
+ /**
* A unique parent carrier id. The parent-child
* relationship can be used to further differentiate a single carrier by different networks,
* by prepaid v.s. postpaid or even by 4G v.s. 3G plan. It's an optional field.
@@ -3640,18 +3668,6 @@
public static final String PARENT_CARRIER_ID = "parent_carrier_id";
/**
- * A unique mno carrier id. mno carrier shares the same {@link All#MCCMNC} as carrier id
- * and can be solely identified by {@link All#MCCMNC} only. If there is no such mno
- * carrier, then mno carrier id equals to {@link #CARRIER_ID carrier id}.
- *
- * <p>mno carrier id can be used as fallback id. When the exact carrier id configurations
- * are not found, usually fall back to its mno carrier id.
- * <P>Type: INTEGER </P>
- * @hide
- */
- public static final String MNO_CARRIER_ID = "mno_carrier_id";
-
- /**
* Contains mappings between matching rules with carrier id for all carriers.
* @hide
*/
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 14e0909..4561ea3 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -68,7 +68,13 @@
* This intent is broadcast by the system when carrier config changes. An int is specified in
* {@link #EXTRA_SLOT_INDEX} to indicate the slot index that this is for. An optional int extra
* {@link #EXTRA_SUBSCRIPTION_INDEX} is included to indicate the subscription index if a valid
- * one is available for the slot index.
+ * one is available for the slot index. An optional int extra
+ * {@link TelephonyManager#EXTRA_CARRIER_ID} is included to indicate the carrier id for the
+ * changed carrier configuration. An optional int extra
+ * {@link TelephonyManager#EXTRA_PRECISE_CARRIER_ID} is included to indicate the precise
+ * carrier id for the changed carrier configuration.
+ * @see TelephonyManager#getSimCarrierId()
+ * @see TelephonyManager#getSimPreciseCarrierId()
*/
public static final String
ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED";
@@ -1392,9 +1398,9 @@
* Example: "default"
*
* {@code ERROR_CODE_1} is an integer defined in
- * {@link com.android.internal.telephony.dataconnection.DcFailCause DcFailure}
+ * {@link DataFailCause DcFailure}
* Example:
- * {@link com.android.internal.telephony.dataconnection.DcFailCause#MISSING_UNKNOWN_APN}
+ * {@link DataFailCause#MISSING_UNKNOWN_APN}
*
* {@code CARRIER_ACTION_IDX_1} is an integer defined in
* {@link com.android.carrierdefaultapp.CarrierActionUtils CarrierActionUtils}
@@ -1994,6 +2000,8 @@
* Determine whether to use only RSRP for the number of LTE signal bars.
* @hide
*/
+ // FIXME: this key and related keys must not be exposed without a consistent philosophy for
+ // all RATs.
public static final String KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL =
"use_only_rsrp_for_lte_signal_bar_bool";
@@ -2237,6 +2245,8 @@
* Currently this only supports the value "rscp"
* @hide
*/
+ // FIXME: this key and related keys must not be exposed without a consistent philosophy for
+ // all RATs.
public static final String KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING =
"wcdma_default_signal_strength_measurement_string";
diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java
index 598f567..fa19867 100644
--- a/telephony/java/android/telephony/CellIdentityCdma.java
+++ b/telephony/java/android/telephony/CellIdentityCdma.java
@@ -16,7 +16,6 @@
package android.telephony;
-import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.telephony.cdma.CdmaCellLocation;
@@ -71,30 +70,13 @@
* to 2592000
* @param lat Latitude is a decimal number ranges from -1296000
* to 1296000
- *
- * @hide
- */
- @UnsupportedAppUsage
- public CellIdentityCdma(int nid, int sid, int bid, int lon, int lat) {
- this(nid, sid, bid, lon, lat, null, null);
- }
-
- /**
- * public constructor
- * @param nid Network Id 0..65535
- * @param sid CDMA System Id 0..32767
- * @param bid Base Station Id 0..65535
- * @param lon Longitude is a decimal number ranges from -2592000
- * to 2592000
- * @param lat Latitude is a decimal number ranges from -1296000
- * to 1296000
* @param alphal long alpha Operator Name String or Enhanced Operator Name String
* @param alphas short alpha Operator Name String or Enhanced Operator Name String
*
* @hide
*/
- public CellIdentityCdma(int nid, int sid, int bid, int lon, int lat, String alphal,
- String alphas) {
+ public CellIdentityCdma(
+ int nid, int sid, int bid, int lon, int lat, String alphal, String alphas) {
super(TAG, CellInfo.TYPE_CDMA, null, null, alphal, alphas);
mNetworkId = nid;
mSystemId = sid;
@@ -107,6 +89,17 @@
}
}
+ /** @hide */
+ public CellIdentityCdma(android.hardware.radio.V1_0.CellIdentityCdma cid) {
+ this(cid.networkId, cid.systemId, cid.baseStationId, cid.longitude, cid.latitude, "", "");
+ }
+
+ /** @hide */
+ public CellIdentityCdma(android.hardware.radio.V1_2.CellIdentityCdma cid) {
+ this(cid.base.networkId, cid.base.systemId, cid.base.baseStationId, cid.base.longitude,
+ cid.base.latitude, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort);
+ }
+
private CellIdentityCdma(CellIdentityCdma cid) {
this(cid.mNetworkId, cid.mSystemId, cid.mBasestationId, cid.mLongitude, cid.mLatitude,
cid.mAlphaLong, cid.mAlphaShort);
diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java
index 04c28e5..9a24e47 100644
--- a/telephony/java/android/telephony/CellIdentityGsm.java
+++ b/telephony/java/android/telephony/CellIdentityGsm.java
@@ -16,6 +16,7 @@
package android.telephony;
+import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.telephony.gsm.GsmCellLocation;
@@ -35,10 +36,8 @@
// 16-bit GSM Cell Identity described in TS 27.007, 0..65535
private final int mCid;
// 16-bit GSM Absolute RF Channel Number
- @UnsupportedAppUsage
private final int mArfcn;
// 6-bit Base Station Identity Code
- @UnsupportedAppUsage
private final int mBsic;
/**
@@ -52,34 +51,6 @@
mArfcn = CellInfo.UNAVAILABLE;
mBsic = CellInfo.UNAVAILABLE;
}
- /**
- * public constructor
- * @param mcc 3-digit Mobile Country Code, 0..999
- * @param mnc 2 or 3-digit Mobile Network Code, 0..999
- * @param lac 16-bit Location Area Code, 0..65535
- * @param cid 16-bit GSM Cell Identity or 28-bit UMTS Cell Identity
- *
- * @hide
- */
- public CellIdentityGsm(int mcc, int mnc, int lac, int cid) {
- this(lac, cid, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
- String.valueOf(mcc), String.valueOf(mnc), null, null);
- }
-
- /**
- * public constructor
- * @param mcc 3-digit Mobile Country Code, 0..999
- * @param mnc 2 or 3-digit Mobile Network Code, 0..999
- * @param lac 16-bit Location Area Code, 0..65535
- * @param cid 16-bit GSM Cell Identity or 28-bit UMTS Cell Identity
- * @param arfcn 16-bit GSM Absolute RF Channel Number
- * @param bsic 6-bit Base Station Identity Code
- *
- * @hide
- */
- public CellIdentityGsm(int mcc, int mnc, int lac, int cid, int arfcn, int bsic) {
- this(lac, cid, arfcn, bsic, String.valueOf(mcc), String.valueOf(mnc), null, null);
- }
/**
* public constructor
@@ -100,9 +71,21 @@
mLac = lac;
mCid = cid;
mArfcn = arfcn;
- // In RIL BSIC is a UINT8, so 0xFF is the 'INVALID' designator
- // for inbound parcels
- mBsic = (bsic == 0xFF) ? CellInfo.UNAVAILABLE : bsic;
+ mBsic = bsic;
+ }
+
+ /** @hide */
+ public CellIdentityGsm(android.hardware.radio.V1_0.CellIdentityGsm cid) {
+ this(cid.lac, cid.cid, cid.arfcn,
+ cid.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : cid.bsic,
+ cid.mcc, cid.mnc, "", "");
+ }
+
+ /** @hide */
+ public CellIdentityGsm(android.hardware.radio.V1_2.CellIdentityGsm cid) {
+ this(cid.base.lac, cid.base.cid, cid.base.arfcn,
+ cid.base.bsic == (byte) 0xFF ? CellInfo.UNAVAILABLE : cid.base.bsic, cid.base.mcc,
+ cid.base.mnc, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort);
}
private CellIdentityGsm(CellIdentityGsm cid) {
@@ -169,6 +152,7 @@
/**
* @return a 5 or 6 character string (MCC+MNC), null if any field is unknown.
*/
+ @Nullable
public String getMobileNetworkOperator() {
return (mMccStr == null || mMncStr == null) ? null : mMccStr + mMncStr;
}
diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java
index 04b6a6c..d957d07 100644
--- a/telephony/java/android/telephony/CellIdentityLte.java
+++ b/telephony/java/android/telephony/CellIdentityLte.java
@@ -16,6 +16,7 @@
package android.telephony;
+import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.telephony.gsm.GsmCellLocation;
@@ -37,7 +38,6 @@
// 16-bit tracking area code
private final int mTac;
// 18-bit Absolute RF Channel Number
- @UnsupportedAppUsage
private final int mEarfcn;
// cell bandwidth, in kHz
private final int mBandwidth;
@@ -73,22 +73,6 @@
/**
*
- * @param mcc 3-digit Mobile Country Code, 0..999
- * @param mnc 2 or 3-digit Mobile Network Code, 0..999
- * @param ci 28-bit Cell Identity
- * @param pci Physical Cell Id 0..503
- * @param tac 16-bit Tracking Area Code
- * @param earfcn 18-bit LTE Absolute RF Channel Number
- *
- * @hide
- */
- public CellIdentityLte(int mcc, int mnc, int ci, int pci, int tac, int earfcn) {
- this(ci, pci, tac, earfcn, CellInfo.UNAVAILABLE, String.valueOf(mcc), String.valueOf(mnc),
- null, null);
- }
-
- /**
- *
* @param ci 28-bit Cell Identity
* @param pci Physical Cell Id 0..503
* @param tac 16-bit Tracking Area Code
@@ -111,6 +95,18 @@
mBandwidth = bandwidth;
}
+ /** @hide */
+ public CellIdentityLte(android.hardware.radio.V1_0.CellIdentityLte cid) {
+ this(cid.ci, cid.pci, cid.tac, cid.earfcn, CellInfo.UNAVAILABLE, cid.mcc, cid.mnc, "", "");
+ }
+
+ /** @hide */
+ public CellIdentityLte(android.hardware.radio.V1_2.CellIdentityLte cid) {
+ this(cid.base.ci, cid.base.pci, cid.base.tac, cid.base.earfcn, cid.bandwidth,
+ cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong,
+ cid.operatorNames.alphaShort);
+ }
+
private CellIdentityLte(CellIdentityLte cid) {
this(cid.mCi, cid.mPci, cid.mTac, cid.mEarfcn, cid.mBandwidth, cid.mMccStr,
cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort);
@@ -197,6 +193,7 @@
/**
* @return a 5 or 6 character string (MCC+MNC), null if any field is unknown.
*/
+ @Nullable
public String getMobileNetworkOperator() {
return (mMccStr == null || mMncStr == null) ? null : mMccStr + mMncStr;
}
diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java
index 8b1c1b9..3814333 100644
--- a/telephony/java/android/telephony/CellIdentityTdscdma.java
+++ b/telephony/java/android/telephony/CellIdentityTdscdma.java
@@ -16,6 +16,7 @@
package android.telephony;
+import android.annotation.Nullable;
import android.os.Parcel;
import android.telephony.gsm.GsmCellLocation;
@@ -50,22 +51,6 @@
}
/**
- * @param mcc 3-digit Mobile Country Code, 0..999
- * @param mnc 2 or 3-digit Mobile Network Code, 0..999
- * @param lac 16-bit Location Area Code, 0..65535, CellInfo.UNAVAILABLE if unknown
- * @param cid 28-bit UMTS Cell Identity described in TS 25.331, 0..268435455, CellInfo.
- * UNAVAILABLE if unknown
- * @param cpid 8-bit Cell Parameters ID described in TS 25.331, 0..127, CellInfo.UNAVAILABLE
- * if unknown
- * @param uarfcn 16-bit UMTS Absolute RF Channel Number described in TS 25.101 sec. 5.4.3
- *
- * @hide
- */
- public CellIdentityTdscdma(int mcc, int mnc, int lac, int cid, int cpid, int uarfcn) {
- this(String.valueOf(mcc), String.valueOf(mnc), lac, cid, cpid, uarfcn, null, null);
- }
-
- /**
* @param mcc 3-digit Mobile Country Code in string format
* @param mnc 2 or 3-digit Mobile Network Code in string format
* @param lac 16-bit Location Area Code, 0..65535, CellInfo.UNAVAILABLE if unknown
@@ -93,6 +78,17 @@
cid.mCpid, cid.mUarfcn, cid.mAlphaLong, cid.mAlphaShort);
}
+ /** @hide */
+ public CellIdentityTdscdma(android.hardware.radio.V1_0.CellIdentityTdscdma cid) {
+ this(cid.mcc, cid.mnc, cid.lac, cid.cid, cid.cpid, CellInfo.UNAVAILABLE, "", "");
+ }
+
+ /** @hide */
+ public CellIdentityTdscdma(android.hardware.radio.V1_2.CellIdentityTdscdma cid) {
+ this(cid.base.mcc, cid.base.mnc, cid.base.lac, cid.base.cid, cid.base.cpid,
+ cid.uarfcn, cid.operatorNames.alphaLong, cid.operatorNames.alphaShort);
+ }
+
CellIdentityTdscdma copy() {
return new CellIdentityTdscdma(this);
}
@@ -116,6 +112,7 @@
/**
* @return a 5 or 6 character string (MCC+MNC), null if any field is unknown
*/
+ @Nullable
public String getMobileNetworkOperator() {
return (mMccStr == null || mMncStr == null) ? null : mMccStr + mMncStr;
}
diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java
index 3416ffe..6e09784 100644
--- a/telephony/java/android/telephony/CellIdentityWcdma.java
+++ b/telephony/java/android/telephony/CellIdentityWcdma.java
@@ -16,6 +16,7 @@
package android.telephony;
+import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.telephony.gsm.GsmCellLocation;
@@ -50,35 +51,6 @@
mPsc = CellInfo.UNAVAILABLE;
mUarfcn = CellInfo.UNAVAILABLE;
}
- /**
- * public constructor
- * @param mcc 3-digit Mobile Country Code, 0..999
- * @param mnc 2 or 3-digit Mobile Network Code, 0..999
- * @param lac 16-bit Location Area Code, 0..65535
- * @param cid 28-bit UMTS Cell Identity
- * @param psc 9-bit UMTS Primary Scrambling Code
- *
- * @hide
- */
- public CellIdentityWcdma (int mcc, int mnc, int lac, int cid, int psc) {
- this(lac, cid, psc, CellInfo.UNAVAILABLE, String.valueOf(mcc), String.valueOf(mnc),
- null, null);
- }
-
- /**
- * public constructor
- * @param mcc 3-digit Mobile Country Code, 0..999
- * @param mnc 2 or 3-digit Mobile Network Code, 0..999
- * @param lac 16-bit Location Area Code, 0..65535
- * @param cid 28-bit UMTS Cell Identity
- * @param psc 9-bit UMTS Primary Scrambling Code
- * @param uarfcn 16-bit UMTS Absolute RF Channel Number described in TS 25.101 sec. 5.4.3
- *
- * @hide
- */
- public CellIdentityWcdma (int mcc, int mnc, int lac, int cid, int psc, int uarfcn) {
- this(lac, cid, psc, uarfcn, String.valueOf(mcc), String.valueOf(mnc), null, null);
- }
/**
* public constructor
@@ -102,6 +74,18 @@
mUarfcn = uarfcn;
}
+ /** @hide */
+ public CellIdentityWcdma(android.hardware.radio.V1_0.CellIdentityWcdma cid) {
+ this(cid.lac, cid.cid, cid.psc, cid.uarfcn, cid.mcc, cid.mnc, "", "");
+ }
+
+ /** @hide */
+ public CellIdentityWcdma(android.hardware.radio.V1_2.CellIdentityWcdma cid) {
+ this(cid.base.lac, cid.base.cid, cid.base.psc, cid.base.uarfcn,
+ cid.base.mcc, cid.base.mnc, cid.operatorNames.alphaLong,
+ cid.operatorNames.alphaShort);
+ }
+
private CellIdentityWcdma(CellIdentityWcdma cid) {
this(cid.mLac, cid.mCid, cid.mPsc, cid.mUarfcn, cid.mMccStr,
cid.mMncStr, cid.mAlphaLong, cid.mAlphaShort);
@@ -173,6 +157,7 @@
/**
* @return a 5 or 6 character string (MCC+MNC), null if any field is unknown
*/
+ @Nullable
public String getMobileNetworkOperator() {
return (mMccStr == null || mMncStr == null) ? null : mMccStr + mMncStr;
}
diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java
index d0b2687..b761bd7 100644
--- a/telephony/java/android/telephony/CellInfo.java
+++ b/telephony/java/android/telephony/CellInfo.java
@@ -132,7 +132,8 @@
/** Connection status is unknown. */
public static final int CONNECTION_UNKNOWN = Integer.MAX_VALUE;
- private int mCellConnectionStatus = CONNECTION_NONE;
+ /** A cell connection status */
+ private int mCellConnectionStatus;
// True if device is mRegistered to the mobile network
private boolean mRegistered;
@@ -144,6 +145,7 @@
protected CellInfo() {
this.mRegistered = false;
this.mTimeStamp = Long.MAX_VALUE;
+ mCellConnectionStatus = CONNECTION_NONE;
}
/** @hide */
@@ -300,4 +302,44 @@
return new CellInfo[size];
}
};
+
+ /** @hide */
+ protected CellInfo(android.hardware.radio.V1_0.CellInfo ci) {
+ this.mRegistered = ci.registered;
+ this.mTimeStamp = ci.timeStamp;
+ this.mCellConnectionStatus = CONNECTION_UNKNOWN;
+ }
+
+ /** @hide */
+ protected CellInfo(android.hardware.radio.V1_2.CellInfo ci) {
+ this.mRegistered = ci.registered;
+ this.mTimeStamp = ci.timeStamp;
+ this.mCellConnectionStatus = ci.connectionStatus;
+ }
+
+ /** @hide */
+ public static CellInfo create(android.hardware.radio.V1_0.CellInfo ci) {
+ if (ci == null) return null;
+ switch(ci.cellInfoType) {
+ case android.hardware.radio.V1_0.CellInfoType.GSM: return new CellInfoGsm(ci);
+ case android.hardware.radio.V1_0.CellInfoType.CDMA: return new CellInfoCdma(ci);
+ case android.hardware.radio.V1_0.CellInfoType.LTE: return new CellInfoLte(ci);
+ case android.hardware.radio.V1_0.CellInfoType.WCDMA: return new CellInfoWcdma(ci);
+ case android.hardware.radio.V1_0.CellInfoType.TD_SCDMA: return new CellInfoTdscdma(ci);
+ default: return null;
+ }
+ }
+
+ /** @hide */
+ public static CellInfo create(android.hardware.radio.V1_2.CellInfo ci) {
+ if (ci == null) return null;
+ switch(ci.cellInfoType) {
+ case android.hardware.radio.V1_0.CellInfoType.GSM: return new CellInfoGsm(ci);
+ case android.hardware.radio.V1_0.CellInfoType.CDMA: return new CellInfoCdma(ci);
+ case android.hardware.radio.V1_0.CellInfoType.LTE: return new CellInfoLte(ci);
+ case android.hardware.radio.V1_0.CellInfoType.WCDMA: return new CellInfoWcdma(ci);
+ case android.hardware.radio.V1_0.CellInfoType.TD_SCDMA: return new CellInfoTdscdma(ci);
+ default: return null;
+ }
+ }
}
diff --git a/telephony/java/android/telephony/CellInfoCdma.java b/telephony/java/android/telephony/CellInfoCdma.java
index f67733d..8c76eae 100644
--- a/telephony/java/android/telephony/CellInfoCdma.java
+++ b/telephony/java/android/telephony/CellInfoCdma.java
@@ -48,6 +48,24 @@
this.mCellSignalStrengthCdma = ci.mCellSignalStrengthCdma.copy();
}
+ /** @hide */
+ public CellInfoCdma(android.hardware.radio.V1_0.CellInfo ci) {
+ super(ci);
+ final android.hardware.radio.V1_0.CellInfoCdma cic = ci.cdma.get(0);
+ mCellIdentityCdma = new CellIdentityCdma(cic.cellIdentityCdma);
+ mCellSignalStrengthCdma =
+ new CellSignalStrengthCdma(cic.signalStrengthCdma, cic.signalStrengthEvdo);
+ }
+
+ /** @hide */
+ public CellInfoCdma(android.hardware.radio.V1_2.CellInfo ci) {
+ super(ci);
+ final android.hardware.radio.V1_2.CellInfoCdma cic = ci.cdma.get(0);
+ mCellIdentityCdma = new CellIdentityCdma(cic.cellIdentityCdma);
+ mCellSignalStrengthCdma =
+ new CellSignalStrengthCdma(cic.signalStrengthCdma, cic.signalStrengthEvdo);
+ }
+
@Override
public CellIdentityCdma getCellIdentity() {
return mCellIdentityCdma;
diff --git a/telephony/java/android/telephony/CellInfoGsm.java b/telephony/java/android/telephony/CellInfoGsm.java
index 7211de1..ad16dfa 100644
--- a/telephony/java/android/telephony/CellInfoGsm.java
+++ b/telephony/java/android/telephony/CellInfoGsm.java
@@ -43,8 +43,24 @@
/** @hide */
public CellInfoGsm(CellInfoGsm ci) {
super(ci);
- this.mCellIdentityGsm = ci.mCellIdentityGsm.copy();
- this.mCellSignalStrengthGsm = ci.mCellSignalStrengthGsm.copy();
+ mCellIdentityGsm = ci.mCellIdentityGsm.copy();
+ mCellSignalStrengthGsm = ci.mCellSignalStrengthGsm.copy();
+ }
+
+ /** @hide */
+ public CellInfoGsm(android.hardware.radio.V1_0.CellInfo ci) {
+ super(ci);
+ final android.hardware.radio.V1_0.CellInfoGsm cig = ci.gsm.get(0);
+ mCellIdentityGsm = new CellIdentityGsm(cig.cellIdentityGsm);
+ mCellSignalStrengthGsm = new CellSignalStrengthGsm(cig.signalStrengthGsm);
+ }
+
+ /** @hide */
+ public CellInfoGsm(android.hardware.radio.V1_2.CellInfo ci) {
+ super(ci);
+ final android.hardware.radio.V1_2.CellInfoGsm cig = ci.gsm.get(0);
+ mCellIdentityGsm = new CellIdentityGsm(cig.cellIdentityGsm);
+ mCellSignalStrengthGsm = new CellSignalStrengthGsm(cig.signalStrengthGsm);
}
@Override
diff --git a/telephony/java/android/telephony/CellInfoLte.java b/telephony/java/android/telephony/CellInfoLte.java
index 7d5388b..8ca6a1a 100644
--- a/telephony/java/android/telephony/CellInfoLte.java
+++ b/telephony/java/android/telephony/CellInfoLte.java
@@ -51,6 +51,24 @@
this.mCellConfig = new CellConfigLte(ci.mCellConfig);
}
+ /** @hide */
+ public CellInfoLte(android.hardware.radio.V1_0.CellInfo ci) {
+ super(ci);
+ final android.hardware.radio.V1_0.CellInfoLte cil = ci.lte.get(0);
+ mCellIdentityLte = new CellIdentityLte(cil.cellIdentityLte);
+ mCellSignalStrengthLte = new CellSignalStrengthLte(cil.signalStrengthLte);
+ mCellConfig = new CellConfigLte();
+ }
+
+ /** @hide */
+ public CellInfoLte(android.hardware.radio.V1_2.CellInfo ci) {
+ super(ci);
+ final android.hardware.radio.V1_2.CellInfoLte cil = ci.lte.get(0);
+ mCellIdentityLte = new CellIdentityLte(cil.cellIdentityLte);
+ mCellSignalStrengthLte = new CellSignalStrengthLte(cil.signalStrengthLte);
+ mCellConfig = new CellConfigLte();
+ }
+
@Override
public CellIdentityLte getCellIdentity() {
if (DBG) log("getCellIdentity: " + mCellIdentityLte);
diff --git a/telephony/java/android/telephony/CellInfoTdscdma.java b/telephony/java/android/telephony/CellInfoTdscdma.java
index 40cadde..a8c49b7 100644
--- a/telephony/java/android/telephony/CellInfoTdscdma.java
+++ b/telephony/java/android/telephony/CellInfoTdscdma.java
@@ -48,8 +48,23 @@
this.mCellSignalStrengthTdscdma = ci.mCellSignalStrengthTdscdma.copy();
}
- @Override
- public CellIdentityTdscdma getCellIdentity() {
+ /** @hide */
+ public CellInfoTdscdma(android.hardware.radio.V1_0.CellInfo ci) {
+ super(ci);
+ final android.hardware.radio.V1_0.CellInfoTdscdma cit = ci.tdscdma.get(0);
+ mCellIdentityTdscdma = new CellIdentityTdscdma(cit.cellIdentityTdscdma);
+ mCellSignalStrengthTdscdma = new CellSignalStrengthTdscdma(cit.signalStrengthTdscdma);
+ }
+
+ /** @hide */
+ public CellInfoTdscdma(android.hardware.radio.V1_2.CellInfo ci) {
+ super(ci);
+ final android.hardware.radio.V1_2.CellInfoTdscdma cit = ci.tdscdma.get(0);
+ mCellIdentityTdscdma = new CellIdentityTdscdma(cit.cellIdentityTdscdma);
+ mCellSignalStrengthTdscdma = new CellSignalStrengthTdscdma(cit.signalStrengthTdscdma);
+ }
+
+ @Override public CellIdentityTdscdma getCellIdentity() {
return mCellIdentityTdscdma;
}
/** @hide */
diff --git a/telephony/java/android/telephony/CellInfoWcdma.java b/telephony/java/android/telephony/CellInfoWcdma.java
index 4f9dcb1..a427e80 100644
--- a/telephony/java/android/telephony/CellInfoWcdma.java
+++ b/telephony/java/android/telephony/CellInfoWcdma.java
@@ -47,6 +47,22 @@
this.mCellSignalStrengthWcdma = ci.mCellSignalStrengthWcdma.copy();
}
+ /** @hide */
+ public CellInfoWcdma(android.hardware.radio.V1_0.CellInfo ci) {
+ super(ci);
+ final android.hardware.radio.V1_0.CellInfoWcdma ciw = ci.wcdma.get(0);
+ mCellIdentityWcdma = new CellIdentityWcdma(ciw.cellIdentityWcdma);
+ mCellSignalStrengthWcdma = new CellSignalStrengthWcdma(ciw.signalStrengthWcdma);
+ }
+
+ /** @hide */
+ public CellInfoWcdma(android.hardware.radio.V1_2.CellInfo ci) {
+ super(ci);
+ final android.hardware.radio.V1_2.CellInfoWcdma ciw = ci.wcdma.get(0);
+ mCellIdentityWcdma = new CellIdentityWcdma(ciw.cellIdentityWcdma);
+ mCellSignalStrengthWcdma = new CellSignalStrengthWcdma(ciw.signalStrengthWcdma);
+ }
+
@Override
public CellIdentityWcdma getCellIdentity() {
return mCellIdentityWcdma;
diff --git a/telephony/java/android/telephony/CellSignalStrength.java b/telephony/java/android/telephony/CellSignalStrength.java
index afa4922..a18275f 100644
--- a/telephony/java/android/telephony/CellSignalStrength.java
+++ b/telephony/java/android/telephony/CellSignalStrength.java
@@ -16,6 +16,8 @@
package android.telephony;
+import android.os.PersistableBundle;
+
/**
* Abstract base class for cell phone signal strength related information.
*/
@@ -80,9 +82,74 @@
*/
public abstract CellSignalStrength copy();
+ /**
+ * Checks and returns whether there are any non-default values in this CellSignalStrength.
+ *
+ * Checks all the values in the subclass of CellSignalStrength and returns true if any of them
+ * have been set to a value other than their default.
+ *
+ * @hide
+ */
+ public abstract boolean isValid();
+
@Override
public abstract int hashCode();
@Override
public abstract boolean equals (Object o);
+
+ /**
+ * Calculate and set the carrier-influenced values such as the signal "Level".
+ *
+ * @hide
+ */
+ public abstract void updateLevel(PersistableBundle cc, ServiceState ss);
+
+ // Range for RSSI in ASU (0-31, 99) as defined in TS 27.007 8.69
+ /** @hide */
+ protected static final int getRssiDbmFromAsu(int asu) {
+ if (asu > 31 || asu < 0) return CellInfo.UNAVAILABLE;
+ return -113 + (2 * asu);
+ }
+
+ // Range for RSSI in ASU (0-31, 99) as defined in TS 27.007 8.69
+ /** @hide */
+ protected static final int getAsuFromRssiDbm(int dbm) {
+ if (dbm == CellInfo.UNAVAILABLE) return 99;
+ return (dbm / 2) + 113;
+ }
+
+ // Range for RSCP in ASU (0-96, 255) as defined in TS 27.007 8.69
+ /** @hide */
+ protected static final int getRscpDbmFromAsu(int asu) {
+ if (asu > 96 || asu < 0) return CellInfo.UNAVAILABLE;
+ return asu - 120;
+ }
+
+ // Range for RSCP in ASU (0-96, 255) as defined in TS 27.007 8.69
+ /** @hide */
+ protected static final int getAsuFromRscpDbm(int dbm) {
+ if (dbm == CellInfo.UNAVAILABLE) return 255;
+ return dbm + 120;
+ }
+
+ // Range for SNR in ASU (0-49, 255) as defined in TS 27.007 8.69
+ /** @hide */
+ protected static final int getEcNoDbFromAsu(int asu) {
+ if (asu > 49 || asu < 0) return CellInfo.UNAVAILABLE;
+ return -24 + (asu / 2);
+ }
+
+ /** @hide */
+ protected static final int inRangeOrUnavailable(int value, int rangeMin, int rangeMax) {
+ if (value < rangeMin || value > rangeMax) return CellInfo.UNAVAILABLE;
+ return value;
+ }
+
+ /** @hide */
+ protected static final int inRangeOrUnavailable(
+ int value, int rangeMin, int rangeMax, int special) {
+ if ((value < rangeMin || value > rangeMax) && value != special) return CellInfo.UNAVAILABLE;
+ return value;
+ }
}
diff --git a/telephony/java/android/telephony/CellSignalStrengthCdma.java b/telephony/java/android/telephony/CellSignalStrengthCdma.java
index 5123052..47faf1e 100644
--- a/telephony/java/android/telephony/CellSignalStrengthCdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthCdma.java
@@ -18,6 +18,7 @@
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.PersistableBundle;
import android.telephony.Rlog;
import java.util.Objects;
@@ -35,6 +36,7 @@
private int mEvdoDbm; // This value is the EVDO RSSI value
private int mEvdoEcio; // This value is the EVDO Ec/Io
private int mEvdoSnr; // Valid values are 0-8. 8 is the highest signal to noise ratio
+ private int mLevel;
/** @hide */
public CellSignalStrengthCdma() {
@@ -55,23 +57,29 @@
* rather than left as -1, which is a departure from SignalStrength, which is stuck with the
* values it currently reports.
*
- * @param cdmaDbm negative of the CDMA signal strength value or -1 if invalid.
- * @param cdmaEcio negative of the CDMA pilot/noise ratio or -1 if invalid.
- * @param evdoDbm negative of the EvDO signal strength value or -1 if invalid.
- * @param evdoEcio negative of the EvDO pilot/noise ratio or -1 if invalid.
- * @param evdoSnr an SNR value 0..8 or -1 if invalid.
+ * @param cdmaDbm CDMA signal strength value or CellInfo.UNAVAILABLE if invalid.
+ * @param cdmaEcio CDMA pilot/noise ratio or CellInfo.UNAVAILABLE if invalid.
+ * @param evdoDbm negative of the EvDO signal strength value or CellInfo.UNAVAILABLE if invalid.
+ * @param evdoEcio negative of the EvDO pilot/noise ratio or CellInfo.UNAVAILABLE if invalid.
+ * @param evdoSnr an SNR value 0..8 or CellInfo.UNVAILABLE if invalid.
* @hide
*/
public CellSignalStrengthCdma(int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio,
int evdoSnr) {
- // The values here were lifted from SignalStrength.validateInput()
- // FIXME: Combine all checking and setting logic between this and SignalStrength.
- mCdmaDbm = ((cdmaDbm > 0) && (cdmaDbm < 120)) ? -cdmaDbm : CellInfo.UNAVAILABLE;
- mCdmaEcio = ((cdmaEcio > 0) && (cdmaEcio < 160)) ? -cdmaEcio : CellInfo.UNAVAILABLE;
+ mCdmaDbm = inRangeOrUnavailable(cdmaDbm, -120, 0);
+ mCdmaEcio = inRangeOrUnavailable(cdmaEcio, -160, 0);
+ mEvdoDbm = inRangeOrUnavailable(evdoDbm, -120, 0);
+ mEvdoEcio = inRangeOrUnavailable(evdoEcio, -160, 0);
+ mEvdoSnr = inRangeOrUnavailable(evdoSnr, 0, 8);
- mEvdoDbm = ((evdoDbm > 0) && (evdoDbm < 120)) ? -evdoDbm : CellInfo.UNAVAILABLE;
- mEvdoEcio = ((evdoEcio > 0) && (evdoEcio < 160)) ? -evdoEcio : CellInfo.UNAVAILABLE;
- mEvdoSnr = ((evdoSnr > 0) && (evdoSnr <= 8)) ? evdoSnr : CellInfo.UNAVAILABLE;
+ updateLevel(null, null);
+ }
+
+ /** @hide */
+ public CellSignalStrengthCdma(android.hardware.radio.V1_0.CdmaSignalStrength cdma,
+ android.hardware.radio.V1_0.EvdoSignalStrength evdo) {
+ // Convert from HAL values as part of construction.
+ this(-cdma.dbm, -cdma.ecio, -evdo.dbm, -evdo.ecio, evdo.signalNoiseRatio);
}
/** @hide */
@@ -86,6 +94,7 @@
mEvdoDbm = s.mEvdoDbm;
mEvdoEcio = s.mEvdoEcio;
mEvdoSnr = s.mEvdoSnr;
+ mLevel = s.mLevel;
}
/** @hide */
@@ -102,6 +111,7 @@
mEvdoDbm = CellInfo.UNAVAILABLE;
mEvdoEcio = CellInfo.UNAVAILABLE;
mEvdoSnr = CellInfo.UNAVAILABLE;
+ mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
}
/**
@@ -112,26 +122,54 @@
*/
@Override
public int getLevel() {
- int level;
+ return mLevel;
+ }
+ /** @hide */
+ @Override
+ public void updateLevel(PersistableBundle cc, ServiceState ss) {
int cdmaLevel = getCdmaLevel();
int evdoLevel = getEvdoLevel();
if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
/* We don't know evdo, use cdma */
- level = getCdmaLevel();
+ mLevel = getCdmaLevel();
} else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
/* We don't know cdma, use evdo */
- level = getEvdoLevel();
+ mLevel = getEvdoLevel();
} else {
/* We know both, use the lowest level */
- level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
+ mLevel = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
}
- if (DBG) log("getLevel=" + level);
- return level;
}
/**
- * Get the signal level as an asu value between 0..97, 99 is unknown
+ * Get the 1xRTT Level in (Android) ASU.
+ *
+ * There is no standard definition of ASU for CDMA; however, Android defines it as the
+ * the lesser of the following two results (for 1xRTT):
+ * <table>
+ * <thead><tr><th>RSSI Range (dBm)</th><th>ASU Value</th></tr><thead>
+ * <tbody>
+ * <tr><td>-75..</td><td>16</td></tr>
+ * <tr><td>-82..-76</td><td>8</td></tr>
+ * <tr><td>-90..-83</td><td>4</td></tr>
+ * <tr><td>-95..-91</td><td>2</td></tr>
+ * <tr><td>-100..-96</td><td>1</td></tr>
+ * <tr><td>..-101</td><td>99</td></tr>
+ * </tbody>
+ * </table>
+ * <table>
+ * <thead><tr><th>Ec/Io Range (dB)</th><th>ASU Value</th></tr><thead>
+ * <tbody>
+ * <tr><td>-90..</td><td>16</td></tr>
+ * <tr><td>-100..-91</td><td>8</td></tr>
+ * <tr><td>-115..-101</td><td>4</td></tr>
+ * <tr><td>-130..-116</td><td>2</td></tr>
+ * <tr><td>--150..-131</td><td>1</td></tr>
+ * <tr><td>..-151</td><td>99</td></tr>
+ * </tbody>
+ * </table>
+ * @return 1xRTT Level in Android ASU {1,2,4,8,16,99}
*/
@Override
public int getAsuLevel() {
@@ -220,6 +258,63 @@
}
/**
+ * Get the EVDO Level in (Android) ASU.
+ *
+ * There is no standard definition of ASU for CDMA; however, Android defines it as the
+ * the lesser of the following two results (for EVDO):
+ * <table>
+ * <thead><tr><th>RSSI Range (dBm)</th><th>ASU Value</th></tr><thead>
+ * <tbody>
+ * <tr><td>-65..</td><td>16</td></tr>
+ * <tr><td>-75..-66</td><td>8</td></tr>
+ * <tr><td>-85..-76</td><td>4</td></tr>
+ * <tr><td>-95..-86</td><td>2</td></tr>
+ * <tr><td>-105..-96</td><td>1</td></tr>
+ * <tr><td>..-106</td><td>99</td></tr>
+ * </tbody>
+ * </table>
+ * <table>
+ * <thead><tr><th>SNR Range (unitless)</th><th>ASU Value</th></tr><thead>
+ * <tbody>
+ * <tr><td>7..</td><td>16</td></tr>
+ * <tr><td>6</td><td>8</td></tr>
+ * <tr><td>5</td><td>4</td></tr>
+ * <tr><td>3..4</td><td>2</td></tr>
+ * <tr><td>1..2</td><td>1</td></tr>
+ * <tr><td>0</td><td>99</td></tr>
+ * </tbody>
+ * </table>
+ *
+ * @return EVDO Level in Android ASU {1,2,4,8,16,99}
+ *
+ * @hide
+ */
+ public int getEvdoAsuLevel() {
+ int evdoDbm = getEvdoDbm();
+ int evdoSnr = getEvdoSnr();
+ int levelEvdoDbm;
+ int levelEvdoSnr;
+
+ if (evdoDbm >= -65) levelEvdoDbm = 16;
+ else if (evdoDbm >= -75) levelEvdoDbm = 8;
+ else if (evdoDbm >= -85) levelEvdoDbm = 4;
+ else if (evdoDbm >= -95) levelEvdoDbm = 2;
+ else if (evdoDbm >= -105) levelEvdoDbm = 1;
+ else levelEvdoDbm = 99;
+
+ if (evdoSnr >= 7) levelEvdoSnr = 16;
+ else if (evdoSnr >= 6) levelEvdoSnr = 8;
+ else if (evdoSnr >= 5) levelEvdoSnr = 4;
+ else if (evdoSnr >= 3) levelEvdoSnr = 2;
+ else if (evdoSnr >= 1) levelEvdoSnr = 1;
+ else levelEvdoSnr = 99;
+
+ int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
+ if (DBG) log("getEvdoAsuLevel=" + level);
+ return level;
+ }
+
+ /**
* Get the signal strength as dBm
*/
@Override
@@ -237,6 +332,7 @@
public int getCdmaDbm() {
return mCdmaDbm;
}
+
/** @hide */
public void setCdmaDbm(int cdmaDbm) {
mCdmaDbm = cdmaDbm;
@@ -248,6 +344,7 @@
public int getCdmaEcio() {
return mCdmaEcio;
}
+
/** @hide */
public void setCdmaEcio(int cdmaEcio) {
mCdmaEcio = cdmaEcio;
@@ -259,6 +356,7 @@
public int getEvdoDbm() {
return mEvdoDbm;
}
+
/** @hide */
public void setEvdoDbm(int evdoDbm) {
mEvdoDbm = evdoDbm;
@@ -270,6 +368,7 @@
public int getEvdoEcio() {
return mEvdoEcio;
}
+
/** @hide */
public void setEvdoEcio(int evdoEcio) {
mEvdoEcio = evdoEcio;
@@ -281,6 +380,7 @@
public int getEvdoSnr() {
return mEvdoSnr;
}
+
/** @hide */
public void setEvdoSnr(int evdoSnr) {
mEvdoSnr = evdoSnr;
@@ -288,28 +388,29 @@
@Override
public int hashCode() {
- return Objects.hash(mCdmaDbm, mCdmaEcio, mEvdoDbm, mEvdoEcio, mEvdoSnr);
+ return Objects.hash(mCdmaDbm, mCdmaEcio, mEvdoDbm, mEvdoEcio, mEvdoSnr, mLevel);
+ }
+
+ private static final CellSignalStrengthCdma sInvalid = new CellSignalStrengthCdma();
+
+ /** @hide */
+ @Override
+ public boolean isValid() {
+ return !this.equals(sInvalid);
}
@Override
public boolean equals (Object o) {
CellSignalStrengthCdma s;
-
- try {
- s = (CellSignalStrengthCdma) o;
- } catch (ClassCastException ex) {
- return false;
- }
-
- if (o == null) {
- return false;
- }
+ if (!(o instanceof CellSignalStrengthCdma)) return false;
+ s = (CellSignalStrengthCdma) o;
return mCdmaDbm == s.mCdmaDbm
&& mCdmaEcio == s.mCdmaEcio
&& mEvdoDbm == s.mEvdoDbm
&& mEvdoEcio == s.mEvdoEcio
- && mEvdoSnr == s.mEvdoSnr;
+ && mEvdoSnr == s.mEvdoSnr
+ && mLevel == s.mLevel;
}
/**
@@ -322,7 +423,8 @@
+ " cdmaEcio=" + mCdmaEcio
+ " evdoDbm=" + mEvdoDbm
+ " evdoEcio=" + mEvdoEcio
- + " evdoSnr=" + mEvdoSnr;
+ + " evdoSnr=" + mEvdoSnr
+ + " level=" + mLevel;
}
/** Implement the Parcelable interface */
@@ -334,6 +436,7 @@
dest.writeInt(mEvdoDbm);
dest.writeInt(mEvdoEcio);
dest.writeInt(mEvdoSnr);
+ dest.writeInt(mLevel);
}
/**
@@ -349,6 +452,7 @@
mEvdoDbm = in.readInt();
mEvdoEcio = in.readInt();
mEvdoSnr = in.readInt();
+ mLevel = in.readInt();
if (DBG) log("CellSignalStrengthCdma(Parcel): " + toString());
}
diff --git a/telephony/java/android/telephony/CellSignalStrengthGsm.java b/telephony/java/android/telephony/CellSignalStrengthGsm.java
index e906f46..7b29f69 100644
--- a/telephony/java/android/telephony/CellSignalStrengthGsm.java
+++ b/telephony/java/android/telephony/CellSignalStrengthGsm.java
@@ -19,6 +19,7 @@
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.PersistableBundle;
import android.telephony.Rlog;
import java.util.Objects;
@@ -31,16 +32,18 @@
private static final String LOG_TAG = "CellSignalStrengthGsm";
private static final boolean DBG = false;
- private static final int GSM_SIGNAL_STRENGTH_GREAT = 12;
- private static final int GSM_SIGNAL_STRENGTH_GOOD = 8;
- private static final int GSM_SIGNAL_STRENGTH_MODERATE = 5;
+ private static final int GSM_RSSI_MAX = -51;
+ private static final int GSM_RSSI_GREAT = -89;
+ private static final int GSM_RSSI_GOOD = -97;
+ private static final int GSM_RSSI_MODERATE = -103;
+ private static final int GSM_RSSI_POOR = -107;
+ private int mRssi; // in dBm [-113, -51] or UNAVAILABLE
@UnsupportedAppUsage
- private int mSignalStrength; // in ASU; Valid values are (0-31, 99) as defined in TS 27.007 8.5
- @UnsupportedAppUsage
- private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5
- @UnsupportedAppUsage
+ private int mBitErrorRate; // bit error rate (0-7, 99) TS 27.007 8.5 or UNAVAILABLE
+ @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.O)
private int mTimingAdvance; // range from 0-219 or CellInfo.UNAVAILABLE if unknown
+ private int mLevel;
/** @hide */
@UnsupportedAppUsage
@@ -49,15 +52,17 @@
}
/** @hide */
- public CellSignalStrengthGsm(int ss, int ber) {
- this(ss, ber, CellInfo.UNAVAILABLE);
+ public CellSignalStrengthGsm(int rssi, int ber, int ta) {
+ mRssi = inRangeOrUnavailable(rssi, -113, -51);
+ mBitErrorRate = inRangeOrUnavailable(ber, 0, 7, 99);
+ mTimingAdvance = inRangeOrUnavailable(ta, 0, 219);
+ updateLevel(null, null);
}
/** @hide */
- public CellSignalStrengthGsm(int ss, int ber, int ta) {
- mSignalStrength = ss;
- mBitErrorRate = ber;
- mTimingAdvance = ta;
+ public CellSignalStrengthGsm(android.hardware.radio.V1_0.GsmSignalStrength gsm) {
+ // Convert from HAL values as part of construction.
+ this(getRssiDbmFromAsu(gsm.signalStrength), gsm.bitErrorRate, gsm.timingAdvance);
}
/** @hide */
@@ -67,9 +72,10 @@
/** @hide */
protected void copyFrom(CellSignalStrengthGsm s) {
- mSignalStrength = s.mSignalStrength;
+ mRssi = s.mRssi;
mBitErrorRate = s.mBitErrorRate;
mTimingAdvance = s.mTimingAdvance;
+ mLevel = s.mLevel;
}
/** @hide */
@@ -81,9 +87,10 @@
/** @hide */
@Override
public void setDefaultValues() {
- mSignalStrength = CellInfo.UNAVAILABLE;
+ mRssi = CellInfo.UNAVAILABLE;
mBitErrorRate = CellInfo.UNAVAILABLE;
mTimingAdvance = CellInfo.UNAVAILABLE;
+ mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
}
/**
@@ -94,20 +101,18 @@
*/
@Override
public int getLevel() {
- int level;
+ return mLevel;
+ }
- // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
- // asu = 0 (-113dB or less) is very weak
- // signal, its better to show 0 bars to the user in such cases.
- // asu = 99 is a special case, where the signal strength is unknown.
- int asu = mSignalStrength;
- if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- else if (asu >= GSM_SIGNAL_STRENGTH_GREAT) level = SIGNAL_STRENGTH_GREAT;
- else if (asu >= GSM_SIGNAL_STRENGTH_GOOD) level = SIGNAL_STRENGTH_GOOD;
- else if (asu >= GSM_SIGNAL_STRENGTH_MODERATE) level = SIGNAL_STRENGTH_MODERATE;
- else level = SIGNAL_STRENGTH_POOR;
- if (DBG) log("getLevel=" + level);
- return level;
+ /** @hide */
+ @Override
+ public void updateLevel(PersistableBundle cc, ServiceState ss) {
+ if (mRssi > GSM_RSSI_MAX) mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ else if (mRssi >= GSM_RSSI_GREAT) mLevel = SIGNAL_STRENGTH_GREAT;
+ else if (mRssi >= GSM_RSSI_GOOD) mLevel = SIGNAL_STRENGTH_GOOD;
+ else if (mRssi >= GSM_RSSI_MODERATE) mLevel = SIGNAL_STRENGTH_MODERATE;
+ else if (mRssi >= GSM_RSSI_POOR) mLevel = SIGNAL_STRENGTH_POOR;
+ else mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
}
/**
@@ -126,55 +131,52 @@
*/
@Override
public int getDbm() {
- int dBm;
-
- int level = mSignalStrength;
- int asu = (level == 99 ? CellInfo.UNAVAILABLE : level);
- if (asu != CellInfo.UNAVAILABLE) {
- dBm = -113 + (2 * asu);
- } else {
- dBm = CellInfo.UNAVAILABLE;
- }
- if (DBG) log("getDbm=" + dBm);
- return dBm;
+ return mRssi;
}
/**
- * Get the signal level as an asu value between 0..31, 99 is unknown
+ * Get the RSSI in ASU.
+ *
* Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
+ *
+ * @return RSSI in ASU 0..31, 99, or UNAVAILABLE
*/
@Override
public int getAsuLevel() {
- // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
- // asu = 0 (-113dB or less) is very weak
- // signal, its better to show 0 bars to the user in such cases.
- // asu = 99 is a special case, where the signal strength is unknown.
- int level = mSignalStrength;
- if (DBG) log("getAsuLevel=" + level);
- return level;
+ return getAsuFromRssiDbm(mRssi);
+ }
+
+ /**
+ * Return the Bit Error Rate
+ * @returns the bit error rate (0-7, 99) as defined in TS 27.007 8.5 or UNAVAILABLE.
+ * @hide
+ */
+ public int getBitErrorRate() {
+ return mBitErrorRate;
}
@Override
public int hashCode() {
- return Objects.hash(mSignalStrength, mBitErrorRate, mTimingAdvance);
+ return Objects.hash(mRssi, mBitErrorRate, mTimingAdvance);
+ }
+
+ private static final CellSignalStrengthGsm sInvalid = new CellSignalStrengthGsm();
+
+ /** @hide */
+ @Override
+ public boolean isValid() {
+ return !this.equals(sInvalid);
}
@Override
- public boolean equals (Object o) {
- CellSignalStrengthGsm s;
+ public boolean equals(Object o) {
+ if (!(o instanceof CellSignalStrengthGsm)) return false;
+ CellSignalStrengthGsm s = (CellSignalStrengthGsm) o;
- try {
- s = (CellSignalStrengthGsm) o;
- } catch (ClassCastException ex) {
- return false;
- }
-
- if (o == null) {
- return false;
- }
-
- return mSignalStrength == s.mSignalStrength && mBitErrorRate == s.mBitErrorRate &&
- s.mTimingAdvance == mTimingAdvance;
+ return mRssi == s.mRssi
+ && mBitErrorRate == s.mBitErrorRate
+ && mTimingAdvance == s.mTimingAdvance
+ && mLevel == s.mLevel;
}
/**
@@ -183,18 +185,20 @@
@Override
public String toString() {
return "CellSignalStrengthGsm:"
- + " ss=" + mSignalStrength
+ + " rssi=" + mRssi
+ " ber=" + mBitErrorRate
- + " mTa=" + mTimingAdvance;
+ + " mTa=" + mTimingAdvance
+ + " mLevel=" + mLevel;
}
/** Implement the Parcelable interface */
@Override
public void writeToParcel(Parcel dest, int flags) {
if (DBG) log("writeToParcel(Parcel, int): " + toString());
- dest.writeInt(mSignalStrength);
+ dest.writeInt(mRssi);
dest.writeInt(mBitErrorRate);
dest.writeInt(mTimingAdvance);
+ dest.writeInt(mLevel);
}
/**
@@ -202,9 +206,10 @@
* where the token is already been processed.
*/
private CellSignalStrengthGsm(Parcel in) {
- mSignalStrength = in.readInt();
+ mRssi = in.readInt();
mBitErrorRate = in.readInt();
mTimingAdvance = in.readInt();
+ mLevel = in.readInt();
if (DBG) log("CellSignalStrengthGsm(Parcel): " + toString());
}
diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java
index d075394..893dbe3 100644
--- a/telephony/java/android/telephony/CellSignalStrengthLte.java
+++ b/telephony/java/android/telephony/CellSignalStrengthLte.java
@@ -19,7 +19,9 @@
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.PersistableBundle;
+import java.util.Arrays;
import java.util.Objects;
/**
@@ -28,7 +30,7 @@
public final class CellSignalStrengthLte extends CellSignalStrength implements Parcelable {
private static final String LOG_TAG = "CellSignalStrengthLte";
- private static final boolean DBG = false;
+ private static final boolean DBG = true;
/**
* Indicates the unknown or undetectable RSSI value in ASU.
@@ -49,18 +51,23 @@
*/
private static final int SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE = 0;
- @UnsupportedAppUsage
- private int mSignalStrength;
- @UnsupportedAppUsage
+ private static final int MAX_LTE_RSRP = -44;
+ private static final int MIN_LTE_RSRP = -140;
+
+ @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.P)
+ private int mSignalStrength; // To be removed
+ private int mRssi;
+ @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.O)
private int mRsrp;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.O)
private int mRsrq;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.O)
private int mRssnr;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.O)
private int mCqi;
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(maxTargetSdk = android.os.Build.VERSION_CODES.O)
private int mTimingAdvance;
+ private int mLevel;
/** @hide */
@UnsupportedAppUsage
@@ -68,15 +75,38 @@
setDefaultValues();
}
+ /**
+ * Construct a cell signal strength
+ *
+ * @param rssi in dBm [-113,-51], UNKNOWN
+ * @param rsrp in dBm [-140,-43], UNKNOWN
+ * @param rsrq in dB [-20,-3], UNKNOWN
+ * @param rssnr in 10*dB [-200, +300], UNKNOWN
+ * @param cqi [0, 15], UNKNOWN
+ * @param timingAdvance [0, 1282], UNKNOWN
+ *
+ */
/** @hide */
- public CellSignalStrengthLte(int signalStrength, int rsrp, int rsrq, int rssnr, int cqi,
+ public CellSignalStrengthLte(int rssi, int rsrp, int rsrq, int rssnr, int cqi,
int timingAdvance) {
- mSignalStrength = signalStrength;
- mRsrp = rsrp;
- mRsrq = rsrq;
- mRssnr = rssnr;
- mCqi = cqi;
- mTimingAdvance = timingAdvance;
+
+ mRssi = inRangeOrUnavailable(rssi, -113, -51);
+ mSignalStrength = mRssi;
+ mRsrp = inRangeOrUnavailable(rsrp, -140, -43);
+ mRsrq = inRangeOrUnavailable(rsrq, -20, -3);
+ mRssnr = inRangeOrUnavailable(rssnr, -200, 300);
+ mCqi = inRangeOrUnavailable(cqi, 0, 15);
+ mTimingAdvance = inRangeOrUnavailable(timingAdvance, 0, 1282);
+ updateLevel(null, null);
+ }
+
+ /** @hide */
+ public CellSignalStrengthLte(android.hardware.radio.V1_0.LteSignalStrength lte) {
+ // Convert from HAL values as part of construction.
+ this(convertRssiAsuToDBm(lte.signalStrength),
+ lte.rsrp != CellInfo.UNAVAILABLE ? -lte.rsrp : lte.rsrp,
+ lte.rsrq != CellInfo.UNAVAILABLE ? -lte.rsrq : lte.rsrq,
+ lte.rssnr, lte.cqi, lte.timingAdvance);
}
/** @hide */
@@ -87,11 +117,13 @@
/** @hide */
protected void copyFrom(CellSignalStrengthLte s) {
mSignalStrength = s.mSignalStrength;
+ mRssi = s.mRssi;
mRsrp = s.mRsrp;
mRsrq = s.mRsrq;
mRssnr = s.mRssnr;
mCqi = s.mCqi;
mTimingAdvance = s.mTimingAdvance;
+ mLevel = s.mLevel;
}
/** @hide */
@@ -104,11 +136,13 @@
@Override
public void setDefaultValues() {
mSignalStrength = CellInfo.UNAVAILABLE;
+ mRssi = CellInfo.UNAVAILABLE;
mRsrp = CellInfo.UNAVAILABLE;
mRsrq = CellInfo.UNAVAILABLE;
mRssnr = CellInfo.UNAVAILABLE;
mCqi = CellInfo.UNAVAILABLE;
mTimingAdvance = CellInfo.UNAVAILABLE;
+ mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
}
/**
@@ -119,34 +153,106 @@
*/
@Override
public int getLevel() {
- int levelRsrp = 0;
- int levelRssnr = 0;
+ return mLevel;
+ }
- if (mRsrp == CellInfo.UNAVAILABLE) levelRsrp = 0;
- else if (mRsrp >= -95) levelRsrp = SIGNAL_STRENGTH_GREAT;
- else if (mRsrp >= -105) levelRsrp = SIGNAL_STRENGTH_GOOD;
- else if (mRsrp >= -115) levelRsrp = SIGNAL_STRENGTH_MODERATE;
- else levelRsrp = SIGNAL_STRENGTH_POOR;
+ // Lifted from Default carrier configs and max range of RSRP
+ private static final int[] sThresholds = new int[]{-115, -105, -95, -85};
+ private static final int sRsrpBoost = 0;
- // See RIL_LTE_SignalStrength in ril.h
- if (mRssnr == CellInfo.UNAVAILABLE) levelRssnr = 0;
- else if (mRssnr >= 45) levelRssnr = SIGNAL_STRENGTH_GREAT;
- else if (mRssnr >= 10) levelRssnr = SIGNAL_STRENGTH_GOOD;
- else if (mRssnr >= -30) levelRssnr = SIGNAL_STRENGTH_MODERATE;
- else levelRssnr = SIGNAL_STRENGTH_POOR;
-
- int level;
- if (mRsrp == CellInfo.UNAVAILABLE) {
- level = levelRssnr;
- } else if (mRssnr == CellInfo.UNAVAILABLE) {
- level = levelRsrp;
+ /** @hide */
+ @Override
+ public void updateLevel(PersistableBundle cc, ServiceState ss) {
+ int[] thresholds;
+ boolean rsrpOnly;
+ if (cc == null) {
+ thresholds = sThresholds;
+ rsrpOnly = false;
} else {
- level = (levelRssnr < levelRsrp) ? levelRssnr : levelRsrp;
+ rsrpOnly = cc.getBoolean(
+ CarrierConfigManager.KEY_USE_ONLY_RSRP_FOR_LTE_SIGNAL_BAR_BOOL, false);
+ thresholds = cc.getIntArray(
+ CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY);
+ if (thresholds == null) thresholds = sThresholds;
+ if (DBG) log("updateLevel() carrierconfig - rsrpOnly="
+ + rsrpOnly + ", thresholds=" + Arrays.toString(thresholds));
}
- if (DBG) log("Lte rsrp level: " + levelRsrp
- + " snr level: " + levelRssnr + " level: " + level);
- return level;
+
+ int rsrpBoost = 0;
+ if (ss != null) {
+ rsrpBoost = ss.getLteEarfcnRsrpBoost();
+ }
+
+ int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ int rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ int snrIconLevel = -1;
+
+ int rsrp = mRsrp + rsrpBoost;
+
+ if (rsrp < MIN_LTE_RSRP || rsrp > MAX_LTE_RSRP) {
+ rsrpIconLevel = -1;
+ } else {
+ rsrpIconLevel = thresholds.length;
+ while (rsrpIconLevel > 0 && rsrp < thresholds[rsrpIconLevel - 1]) rsrpIconLevel--;
+ }
+
+ if (rsrpOnly) {
+ if (DBG) log("updateLevel() - rsrp = " + rsrpIconLevel);
+ if (rsrpIconLevel != -1) {
+ mLevel = rsrpIconLevel;
+ return;
+ }
+ }
+
+ /*
+ * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5
+ * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars
+ * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna
+ * Icon Only
+ */
+ if (mRssnr > 300) snrIconLevel = -1;
+ else if (mRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT;
+ else if (mRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD;
+ else if (mRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE;
+ else if (mRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR;
+ else if (mRssnr >= -200)
+ snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+
+ if (DBG) log("updateLevel() - rsrp:" + mRsrp + " snr:" + mRssnr + " rsrpIconLevel:"
+ + rsrpIconLevel + " snrIconLevel:" + snrIconLevel
+ + " lteRsrpBoost:" + sRsrpBoost);
+
+ /* Choose a measurement type to use for notification */
+ if (snrIconLevel != -1 && rsrpIconLevel != -1) {
+ /*
+ * The number of bars displayed shall be the smaller of the bars
+ * associated with LTE RSRP and the bars associated with the LTE
+ * RS_SNR
+ */
+ mLevel = (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel);
+ return;
+ }
+
+ if (snrIconLevel != -1) {
+ mLevel = snrIconLevel;
+ return;
+ }
+
+ if (rsrpIconLevel != -1) {
+ mLevel = rsrpIconLevel;
+ return;
+ }
+
+ if (mRssi > -51) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ else if (mRssi >= -89) rssiIconLevel = SIGNAL_STRENGTH_GREAT;
+ else if (mRssi >= -97) rssiIconLevel = SIGNAL_STRENGTH_GOOD;
+ else if (mRssi >= -103) rssiIconLevel = SIGNAL_STRENGTH_MODERATE;
+ else if (mRssi >= -113) rssiIconLevel = SIGNAL_STRENGTH_POOR;
+ else rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ if (DBG) log("getLteLevel - rssi:" + mRssi + " rssiIconLevel:"
+ + rssiIconLevel);
+ mLevel = rssiIconLevel;
}
/**
@@ -169,7 +275,7 @@
* @return the RSSI if available or {@link CellInfo#UNAVAILABLE} if unavailable.
*/
public int getRssi() {
- return convertRssiAsuToDBm(mSignalStrength);
+ return mRssi;
}
/**
@@ -212,13 +318,16 @@
}
/**
- * Get the LTE signal level as an asu value between 0..97, 99 is unknown
+ * Get the RSRP in ASU.
+ *
* Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
+ *
+ * @return RSCP in ASU 0..97, 255, or UNAVAILABLE
*/
@Override
public int getAsuLevel() {
int lteAsuLevel = 99;
- int lteDbm = getDbm();
+ int lteDbm = mRsrp;
if (lteDbm == CellInfo.UNAVAILABLE) lteAsuLevel = 99;
else if (lteDbm <= -140) lteAsuLevel = 0;
else if (lteDbm >= -43) lteAsuLevel = 97;
@@ -241,29 +350,31 @@
@Override
public int hashCode() {
- return Objects.hash(mSignalStrength, mRsrp, mRsrq, mRssnr, mCqi, mTimingAdvance);
+ return Objects.hash(mRssi, mRsrp, mRsrq, mRssnr, mCqi, mTimingAdvance, mLevel);
+ }
+
+ private static final CellSignalStrengthLte sInvalid = new CellSignalStrengthLte();
+
+ /** @hide */
+ @Override
+ public boolean isValid() {
+ return !this.equals(sInvalid);
}
@Override
public boolean equals (Object o) {
CellSignalStrengthLte s;
- try {
- s = (CellSignalStrengthLte) o;
- } catch (ClassCastException ex) {
- return false;
- }
+ if (!(o instanceof CellSignalStrengthLte)) return false;
+ s = (CellSignalStrengthLte) o;
- if (o == null) {
- return false;
- }
-
- return mSignalStrength == s.mSignalStrength
+ return mRssi == s.mRssi
&& mRsrp == s.mRsrp
&& mRsrq == s.mRsrq
&& mRssnr == s.mRssnr
&& mCqi == s.mCqi
- && mTimingAdvance == s.mTimingAdvance;
+ && mTimingAdvance == s.mTimingAdvance
+ && mLevel == s.mLevel;
}
/**
@@ -272,27 +383,29 @@
@Override
public String toString() {
return "CellSignalStrengthLte:"
- + " ss=" + mSignalStrength
+ + " rssi=" + mRssi
+ " rsrp=" + mRsrp
+ " rsrq=" + mRsrq
+ " rssnr=" + mRssnr
+ " cqi=" + mCqi
- + " ta=" + mTimingAdvance;
+ + " ta=" + mTimingAdvance
+ + " level=" + mLevel;
}
/** Implement the Parcelable interface */
@Override
public void writeToParcel(Parcel dest, int flags) {
if (DBG) log("writeToParcel(Parcel, int): " + toString());
- dest.writeInt(mSignalStrength);
+ dest.writeInt(mRssi);
// Need to multiply rsrp and rsrq by -1
// to ensure consistency when reading values written here
// unless the values are invalid
- dest.writeInt(mRsrp * (mRsrp != CellInfo.UNAVAILABLE ? -1 : 1));
- dest.writeInt(mRsrq * (mRsrq != CellInfo.UNAVAILABLE ? -1 : 1));
+ dest.writeInt(mRsrp);
+ dest.writeInt(mRsrq);
dest.writeInt(mRssnr);
dest.writeInt(mCqi);
dest.writeInt(mTimingAdvance);
+ dest.writeInt(mLevel);
}
/**
@@ -300,16 +413,14 @@
* where the token is already been processed.
*/
private CellSignalStrengthLte(Parcel in) {
- mSignalStrength = in.readInt();
- // rsrp and rsrq are written into the parcel as positive values.
- // Need to convert into negative values unless the values are invalid
+ mRssi = in.readInt();
+ mSignalStrength = mRssi;
mRsrp = in.readInt();
- if (mRsrp != CellInfo.UNAVAILABLE) mRsrp *= -1;
mRsrq = in.readInt();
- if (mRsrq != CellInfo.UNAVAILABLE) mRsrq *= -1;
mRssnr = in.readInt();
mCqi = in.readInt();
mTimingAdvance = in.readInt();
+ mLevel = in.readInt();
if (DBG) log("CellSignalStrengthLte(Parcel): " + toString());
}
@@ -342,13 +453,12 @@
}
private static int convertRssiAsuToDBm(int rssiAsu) {
- if (rssiAsu != SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN
- && (rssiAsu < SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE
- || rssiAsu > SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MAX_VALUE)) {
- Rlog.e(LOG_TAG, "convertRssiAsuToDBm: invalid RSSI in ASU=" + rssiAsu);
+ if (rssiAsu == SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN) {
return CellInfo.UNAVAILABLE;
}
- if (rssiAsu == SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN) {
+ if ((rssiAsu < SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE
+ || rssiAsu > SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MAX_VALUE)) {
+ Rlog.e(LOG_TAG, "convertRssiAsuToDBm: invalid RSSI in ASU=" + rssiAsu);
return CellInfo.UNAVAILABLE;
}
return -113 + (2 * rssiAsu);
diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java
index 8079242..061cd4b 100644
--- a/telephony/java/android/telephony/CellSignalStrengthNr.java
+++ b/telephony/java/android/telephony/CellSignalStrengthNr.java
@@ -18,6 +18,7 @@
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.PersistableBundle;
import java.util.Objects;
@@ -48,6 +49,12 @@
private int mSsRsrp;
private int mSsRsrq;
private int mSsSinr;
+ private int mLevel;
+
+ /** @hide */
+ public CellSignalStrengthNr() {
+ setDefaultValues();
+ }
/**
* @param csiRsrp CSI reference signal received power.
@@ -60,12 +67,13 @@
*/
public CellSignalStrengthNr(
int csiRsrp, int csiRsrq, int csiSinr, int ssRsrp, int ssRsrq, int ssSinr) {
- mCsiRsrp = csiRsrp;
- mCsiRsrq = csiRsrq;
- mCsiSinr = csiSinr;
- mSsRsrp = ssRsrp;
- mSsRsrq = ssRsrq;
- mSsSinr = ssSinr;
+ mCsiRsrp = inRangeOrUnavailable(csiRsrp, -140, -44);
+ mCsiRsrq = inRangeOrUnavailable(csiRsrq, -20, -3);
+ mCsiSinr = inRangeOrUnavailable(csiSinr, -23, 23);
+ mSsRsrp = inRangeOrUnavailable(ssRsrp, -140, -44);
+ mSsRsrq = inRangeOrUnavailable(ssRsrq, -20, -3);
+ mSsSinr = inRangeOrUnavailable(ssSinr, -23, 40);
+ updateLevel(null, null);
}
/**
@@ -142,6 +150,7 @@
dest.writeInt(mSsRsrp);
dest.writeInt(mSsRsrq);
dest.writeInt(mSsSinr);
+ dest.writeInt(mLevel);
}
private CellSignalStrengthNr(Parcel in) {
@@ -151,6 +160,7 @@
mSsRsrp = in.readInt();
mSsRsrq = in.readInt();
mSsSinr = in.readInt();
+ mLevel = in.readInt();
}
/** @hide */
@@ -162,27 +172,36 @@
mSsRsrp = CellInfo.UNAVAILABLE;
mSsRsrq = CellInfo.UNAVAILABLE;
mSsSinr = CellInfo.UNAVAILABLE;
+ mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
}
@Override
public int getLevel() {
+ return mLevel;
+ }
+
+ /** @hide */
+ @Override
+ public void updateLevel(PersistableBundle cc, ServiceState ss) {
if (mCsiRsrp == CellInfo.UNAVAILABLE) {
- return SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
} else if (mCsiRsrp >= SIGNAL_GREAT_THRESHOLD) {
- return SIGNAL_STRENGTH_GREAT;
+ mLevel = SIGNAL_STRENGTH_GREAT;
} else if (mCsiRsrp >= SIGNAL_GOOD_THRESHOLD) {
- return SIGNAL_STRENGTH_GOOD;
+ mLevel = SIGNAL_STRENGTH_GOOD;
} else if (mCsiRsrp >= SIGNAL_MODERATE_THRESHOLD) {
- return SIGNAL_STRENGTH_MODERATE;
+ mLevel = SIGNAL_STRENGTH_MODERATE;
} else {
- return SIGNAL_STRENGTH_POOR;
+ mLevel = SIGNAL_STRENGTH_POOR;
}
}
/**
- * Calculates the NR signal as an asu value between 0..97, 99 is unknown.
- * Asu is calculated based on 3GPP RSRP, refer to 3GPP TS 27.007 section 8.69.
- * @return an integer represent the asu level of the signal strength.
+ * Get the RSRP in ASU.
+ *
+ * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
+ *
+ * @return RSCP in ASU 0..97, 255, or UNAVAILABLE
*/
@Override
public int getAsuLevel() {
@@ -206,15 +225,33 @@
}
/** @hide */
+ public CellSignalStrengthNr(CellSignalStrengthNr s) {
+ mCsiRsrp = s.mCsiRsrp;
+ mCsiRsrq = s.mCsiRsrq;
+ mCsiSinr = s.mCsiSinr;
+ mSsRsrp = s.mSsRsrp;
+ mSsRsrq = s.mSsRsrq;
+ mSsSinr = s.mSsSinr;
+ mLevel = s.mLevel;
+ }
+
+ /** @hide */
@Override
- public CellSignalStrength copy() {
- return new CellSignalStrengthNr(
- mCsiRsrp, mCsiRsrq, mCsiSinr, mSsRsrp, mSsRsrq, mSsSinr);
+ public CellSignalStrengthNr copy() {
+ return new CellSignalStrengthNr(this);
}
@Override
public int hashCode() {
- return Objects.hash(mCsiRsrp, mCsiRsrq, mCsiSinr, mSsRsrp, mSsRsrq, mSsSinr);
+ return Objects.hash(mCsiRsrp, mCsiRsrq, mCsiSinr, mSsRsrp, mSsRsrq, mSsSinr, mLevel);
+ }
+
+ private static final CellSignalStrengthNr sInvalid = new CellSignalStrengthNr();
+
+ /** @hide */
+ @Override
+ public boolean isValid() {
+ return !this.equals(sInvalid);
}
@Override
@@ -222,7 +259,8 @@
if (obj instanceof CellSignalStrengthNr) {
CellSignalStrengthNr o = (CellSignalStrengthNr) obj;
return mCsiRsrp == o.mCsiRsrp && mCsiRsrq == o.mCsiRsrq && mCsiSinr == o.mCsiSinr
- && mSsRsrp == o.mSsRsrp && mSsRsrq == o.mSsRsrq && mSsSinr == o.mSsSinr;
+ && mSsRsrp == o.mSsRsrp && mSsRsrq == o.mSsRsrq && mSsSinr == o.mSsSinr
+ && mLevel == o.mLevel;
}
return false;
}
@@ -237,6 +275,7 @@
.append(" ssRsrp = " + mSsRsrp)
.append(" ssRsrq = " + mSsRsrq)
.append(" ssSinr = " + mSsSinr)
+ .append(" level = " + mLevel)
.append(" }")
.toString();
}
diff --git a/telephony/java/android/telephony/CellSignalStrengthTdscdma.java b/telephony/java/android/telephony/CellSignalStrengthTdscdma.java
index 4d040cc..6f52b85 100644
--- a/telephony/java/android/telephony/CellSignalStrengthTdscdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthTdscdma.java
@@ -18,6 +18,7 @@
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.PersistableBundle;
import java.util.Objects;
@@ -31,27 +32,53 @@
private static final String LOG_TAG = "CellSignalStrengthTdscdma";
private static final boolean DBG = false;
- private static final int TDSCDMA_SIGNAL_STRENGTH_GREAT = 12;
- private static final int TDSCDMA_SIGNAL_STRENGTH_GOOD = 8;
- private static final int TDSCDMA_SIGNAL_STRENGTH_MODERATE = 5;
+ private static final int TDSCDMA_RSSI_MAX = -51;
+ private static final int TDSCDMA_RSSI_GREAT = -77;
+ private static final int TDSCDMA_RSSI_GOOD = -87;
+ private static final int TDSCDMA_RSSI_MODERATE = -97;
+ private static final int TDSCDMA_RSSI_POOR = -107;
- private int mSignalStrength; // in ASU; Valid values are (0-31, 99) as defined in TS 27.007 8.5
- // or CellInfo.UNAVAILABLE if unknown
+ private static final int TDSCDMA_RSCP_MIN = -120;
+ private static final int TDSCDMA_RSCP_MAX = -24;
+
+ private int mRssi; // in dBm [-113, -51], CellInfo.UNAVAILABLE
+
private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 or
// CellInfo.UNAVAILABLE if unknown
- private int mRscp; // Pilot power (0-96, 255) as defined in TS 27.007 8.69 or
+ private int mRscp; // Pilot Power in dBm [-120, -24] or CellInfo.UNAVAILABLE
// CellInfo.UNAVAILABLE if unknown
+ private int mLevel;
+
/** @hide */
public CellSignalStrengthTdscdma() {
setDefaultValues();
}
+ /**
+ * @param rssi in dBm [-113, -51] or UNAVAILABLE
+ * @param ber [0-7], 99 or UNAVAILABLE
+ * @param rscp in dBm [-120, -24] or UNAVAILABLE
+ * @hide */
+ public CellSignalStrengthTdscdma(int rssi, int ber, int rscp) {
+ mRssi = inRangeOrUnavailable(rssi, -113, -51);
+ mBitErrorRate = inRangeOrUnavailable(ber, 0, 7, 99);
+ mRscp = inRangeOrUnavailable(rscp, -120, -24);
+ updateLevel(null, null);
+ }
+
/** @hide */
- public CellSignalStrengthTdscdma(int ss, int ber, int rscp) {
- mSignalStrength = ss;
- mBitErrorRate = ber;
- mRscp = rscp;
+ public CellSignalStrengthTdscdma(android.hardware.radio.V1_0.TdScdmaSignalStrength tdscdma) {
+ // Convert from HAL values as part of construction.
+ this(CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE,
+ tdscdma.rscp != CellInfo.UNAVAILABLE ? -tdscdma.rscp : tdscdma.rscp);
+ }
+
+ /** @hide */
+ public CellSignalStrengthTdscdma(android.hardware.radio.V1_2.TdscdmaSignalStrength tdscdma) {
+ // Convert from HAL values as part of construction.
+ this(getRssiDbmFromAsu(tdscdma.signalStrength),
+ tdscdma.bitErrorRate, getRscpDbmFromAsu(tdscdma.rscp));
}
/** @hide */
@@ -61,9 +88,10 @@
/** @hide */
protected void copyFrom(CellSignalStrengthTdscdma s) {
- mSignalStrength = s.mSignalStrength;
+ mRssi = s.mRssi;
mBitErrorRate = s.mBitErrorRate;
mRscp = s.mRscp;
+ mLevel = s.mLevel;
}
/** @hide */
@@ -75,9 +103,10 @@
/** @hide */
@Override
public void setDefaultValues() {
- mSignalStrength = CellInfo.UNAVAILABLE;
+ mRssi = CellInfo.UNAVAILABLE;
mBitErrorRate = CellInfo.UNAVAILABLE;
mRscp = CellInfo.UNAVAILABLE;
+ mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
}
/**
@@ -88,26 +117,18 @@
*/
@Override
public int getLevel() {
- int level;
+ return mLevel;
+ }
- // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
- // asu = 0 (-113dB or less) is very weak
- // signal, its better to show 0 bars to the user in such cases.
- // asu = 99 is a special case, where the signal strength is unknown.
- int asu = mSignalStrength;
- if (asu <= 2 || asu == 99) {
- level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- } else if (asu >= TDSCDMA_SIGNAL_STRENGTH_GREAT) {
- level = SIGNAL_STRENGTH_GREAT;
- } else if (asu >= TDSCDMA_SIGNAL_STRENGTH_GOOD) {
- level = SIGNAL_STRENGTH_GOOD;
- } else if (asu >= TDSCDMA_SIGNAL_STRENGTH_MODERATE) {
- level = SIGNAL_STRENGTH_MODERATE;
- } else {
- level = SIGNAL_STRENGTH_POOR;
- }
- if (DBG) log("getLevel=" + level);
- return level;
+ /** @hide */
+ @Override
+ public void updateLevel(PersistableBundle cc, ServiceState ss) {
+ if (mRssi > TDSCDMA_RSSI_MAX) mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ else if (mRssi >= TDSCDMA_RSSI_GREAT) mLevel = SIGNAL_STRENGTH_GREAT;
+ else if (mRssi >= TDSCDMA_RSSI_GOOD) mLevel = SIGNAL_STRENGTH_GOOD;
+ else if (mRssi >= TDSCDMA_RSSI_MODERATE) mLevel = SIGNAL_STRENGTH_MODERATE;
+ else if (mRssi >= TDSCDMA_RSSI_POOR) mLevel = SIGNAL_STRENGTH_POOR;
+ else mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
}
/**
@@ -115,56 +136,55 @@
*/
@Override
public int getDbm() {
- int dBm;
-
- int level = mSignalStrength;
- int asu = (level == 99 ? CellInfo.UNAVAILABLE : level);
- if (asu != CellInfo.UNAVAILABLE) {
- dBm = -113 + (2 * asu);
- } else {
- dBm = CellInfo.UNAVAILABLE;
- }
- if (DBG) log("getDbm=" + dBm);
- return dBm;
+ return mRscp;
}
/**
- * Get the signal level as an asu value between 0..31, 99 is unknown
+ * Get the RSCP as dBm
+ * @hide
+ */
+ public int getRscp() {
+ return mRscp;
+ }
+
+ /**
+ * Get the RSCP in ASU.
+ *
* Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
+ *
+ * @return RSCP in ASU 0..96, 255, or UNAVAILABLE
*/
@Override
public int getAsuLevel() {
- // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
- // asu = 0 (-113dB or less) is very weak
- // signal, its better to show 0 bars to the user in such cases.
- // asu = 99 is a special case, where the signal strength is unknown.
- int level = mSignalStrength;
- if (DBG) log("getAsuLevel=" + level);
- return level;
+ if (mRscp != CellInfo.UNAVAILABLE) return getAsuFromRscpDbm(mRscp);
+ // For historical reasons, if RSCP is unavailable, this API will very incorrectly return
+ // RSSI. This hackery will be removed when most devices are using Radio HAL 1.2+
+ if (mRssi != CellInfo.UNAVAILABLE) return getAsuFromRssiDbm(mRssi);
+ return getAsuFromRscpDbm(CellInfo.UNAVAILABLE);
}
@Override
public int hashCode() {
- return Objects.hash(mSignalStrength, mBitErrorRate);
+ return Objects.hash(mRssi, mBitErrorRate, mRscp, mLevel);
+ }
+
+ private static final CellSignalStrengthTdscdma sInvalid = new CellSignalStrengthTdscdma();
+
+ /** @hide */
+ @Override
+ public boolean isValid() {
+ return !this.equals(sInvalid);
}
@Override
public boolean equals(Object o) {
- CellSignalStrengthTdscdma s;
+ if (!(o instanceof CellSignalStrengthTdscdma)) return false;
+ CellSignalStrengthTdscdma s = (CellSignalStrengthTdscdma) o;
- try {
- s = (CellSignalStrengthTdscdma) o;
- } catch (ClassCastException ex) {
- return false;
- }
-
- if (o == null) {
- return false;
- }
-
- return mSignalStrength == s.mSignalStrength
+ return mRssi == s.mRssi
&& mBitErrorRate == s.mBitErrorRate
- && mRscp == s.mRscp;
+ && mRscp == s.mRscp
+ && mLevel == s.mLevel;
}
/**
@@ -173,18 +193,20 @@
@Override
public String toString() {
return "CellSignalStrengthTdscdma:"
- + " ss=" + mSignalStrength
+ + " rssi=" + mRssi
+ " ber=" + mBitErrorRate
- + " rscp=" + mRscp;
+ + " rscp=" + mRscp
+ + " level=" + mLevel;
}
/** Implement the Parcelable interface */
@Override
public void writeToParcel(Parcel dest, int flags) {
if (DBG) log("writeToParcel(Parcel, int): " + toString());
- dest.writeInt(mSignalStrength);
+ dest.writeInt(mRssi);
dest.writeInt(mBitErrorRate);
dest.writeInt(mRscp);
+ dest.writeInt(mLevel);
}
/**
@@ -192,9 +214,10 @@
* where the token is already been processed.
*/
private CellSignalStrengthTdscdma(Parcel in) {
- mSignalStrength = in.readInt();
+ mRssi = in.readInt();
mBitErrorRate = in.readInt();
mRscp = in.readInt();
+ mLevel = in.readInt();
if (DBG) log("CellSignalStrengthTdscdma(Parcel): " + toString());
}
diff --git a/telephony/java/android/telephony/CellSignalStrengthWcdma.java b/telephony/java/android/telephony/CellSignalStrengthWcdma.java
index 0048cbd..88f6fbc 100644
--- a/telephony/java/android/telephony/CellSignalStrengthWcdma.java
+++ b/telephony/java/android/telephony/CellSignalStrengthWcdma.java
@@ -16,11 +16,14 @@
package android.telephony;
-import android.annotation.UnsupportedAppUsage;
+import android.annotation.StringDef;
import android.os.Parcel;
import android.os.Parcelable;
+import android.os.PersistableBundle;
import android.telephony.Rlog;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
/**
@@ -31,20 +34,32 @@
private static final String LOG_TAG = "CellSignalStrengthWcdma";
private static final boolean DBG = false;
- private static final int WCDMA_SIGNAL_STRENGTH_GREAT = 12;
- private static final int WCDMA_SIGNAL_STRENGTH_GOOD = 8;
- private static final int WCDMA_SIGNAL_STRENGTH_MODERATE = 5;
+ private static final int WCDMA_RSSI_MAX = -51;
+ private static final int WCDMA_RSSI_GREAT = -77;
+ private static final int WCDMA_RSSI_GOOD = -87;
+ private static final int WCDMA_RSSI_MODERATE = -97;
+ private static final int WCDMA_RSSI_POOR = -107;
+ private static final int WCDMA_RSSI_MIN = -113;
- @UnsupportedAppUsage
- private int mSignalStrength; // in ASU; Valid values are (0-31, 99) as defined in TS 27.007 8.5
- // or CellInfo.UNAVAILABLE if unknown
- @UnsupportedAppUsage
+ private static final int WCDMA_RSCP_MIN = -120;
+ private static final int WCDMA_RSCP_MAX = -24;
+
+ // TODO: Because these are used as values in CarrierConfig, they should be exposed somehow.
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @StringDef({LEVEL_CALCULATION_METHOD_RSSI, LEVEL_CALCULATION_METHOD_RSCP})
+ public @interface LevelCalculationMethod {}
+ /** @hide */
+ public static final String LEVEL_CALCULATION_METHOD_RSSI = "rssi";
+ /** @hide */
+ public static final String LEVEL_CALCULATION_METHOD_RSCP = "rscp";
+
+ private int mRssi; // in dBm [-113, 51] or CellInfo.UNAVAILABLE if unknown
private int mBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 or
// CellInfo.UNAVAILABLE if unknown
- private int mRscp; // bit error rate (0-96, 255) as defined in TS 27.007 8.69 or
- // CellInfo.UNAVAILABLE if unknown
- private int mEcNo; // signal to noise radio (0-49, 255) as defined in TS 27.007 8.69 or
- // CellInfo.UNAVAILABLE if unknown
+ private int mRscp; // in dBm [-120, -24]
+ private int mEcNo; // range -24, 1, CellInfo.UNAVAILABLE if unknown
+ private int mLevel;
/** @hide */
public CellSignalStrengthWcdma() {
@@ -52,11 +67,28 @@
}
/** @hide */
- public CellSignalStrengthWcdma(int ss, int ber, int rscp, int ecno) {
- mSignalStrength = ss;
- mBitErrorRate = ber;
- mRscp = rscp;
- mEcNo = ecno;
+ public CellSignalStrengthWcdma(int rssi, int ber, int rscp, int ecno) {
+ mRssi = inRangeOrUnavailable(rssi, WCDMA_RSSI_MIN, WCDMA_RSSI_MAX);
+ mBitErrorRate = inRangeOrUnavailable(ber, 0, 7, 99);
+ mRscp = inRangeOrUnavailable(rscp, -120, -24);
+ mEcNo = inRangeOrUnavailable(ecno, -24, 1);
+ updateLevel(null, null);
+ }
+
+ /** @hide */
+ public CellSignalStrengthWcdma(android.hardware.radio.V1_0.WcdmaSignalStrength wcdma) {
+ // Convert from HAL values as part of construction.
+ this(getRssiDbmFromAsu(wcdma.signalStrength),
+ wcdma.bitErrorRate, CellInfo.UNAVAILABLE, CellInfo.UNAVAILABLE);
+ }
+
+ /** @hide */
+ public CellSignalStrengthWcdma(android.hardware.radio.V1_2.WcdmaSignalStrength wcdma) {
+ // Convert from HAL values as part of construction.
+ this(getRssiDbmFromAsu(wcdma.base.signalStrength),
+ wcdma.base.bitErrorRate,
+ getRscpDbmFromAsu(wcdma.rscp),
+ getEcNoDbFromAsu(wcdma.ecno));
}
/** @hide */
@@ -66,10 +98,11 @@
/** @hide */
protected void copyFrom(CellSignalStrengthWcdma s) {
- mSignalStrength = s.mSignalStrength;
+ mRssi = s.mRssi;
mBitErrorRate = s.mBitErrorRate;
mRscp = s.mRscp;
mEcNo = s.mEcNo;
+ mLevel = s.mLevel;
}
/** @hide */
@@ -81,12 +114,17 @@
/** @hide */
@Override
public void setDefaultValues() {
- mSignalStrength = CellInfo.UNAVAILABLE;
+ mRssi = CellInfo.UNAVAILABLE;
mBitErrorRate = CellInfo.UNAVAILABLE;
mRscp = CellInfo.UNAVAILABLE;
mEcNo = CellInfo.UNAVAILABLE;
+ mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
}
+ private static final String sLevelCalculationMethod = LEVEL_CALCULATION_METHOD_RSSI;
+ private static final int[] sThresholds = new int[]{
+ WCDMA_RSSI_POOR, WCDMA_RSSI_GOOD, WCDMA_RSSI_GOOD, WCDMA_RSSI_GREAT};
+
/**
* Retrieve an abstract level value for the overall signal strength.
*
@@ -95,20 +133,49 @@
*/
@Override
public int getLevel() {
- int level;
+ return mLevel;
+ }
- // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
- // asu = 0 (-113dB or less) is very weak
- // signal, its better to show 0 bars to the user in such cases.
- // asu = 99 is a special case, where the signal strength is unknown.
- int asu = mSignalStrength;
- if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- else if (asu >= WCDMA_SIGNAL_STRENGTH_GREAT) level = SIGNAL_STRENGTH_GREAT;
- else if (asu >= WCDMA_SIGNAL_STRENGTH_GOOD) level = SIGNAL_STRENGTH_GOOD;
- else if (asu >= WCDMA_SIGNAL_STRENGTH_MODERATE) level = SIGNAL_STRENGTH_MODERATE;
- else level = SIGNAL_STRENGTH_POOR;
- if (DBG) log("getLevel=" + level);
- return level;
+ /** @hide */
+ @Override
+ public void updateLevel(PersistableBundle cc, ServiceState ss) {
+ String calcMethod;
+ int[] thresholds;
+
+ if (cc == null) {
+ calcMethod = sLevelCalculationMethod;
+ thresholds = sThresholds;
+ } else {
+ // TODO: abstract this entire thing into a series of functions
+ calcMethod = cc.getString(
+ CarrierConfigManager.KEY_WCDMA_DEFAULT_SIGNAL_STRENGTH_MEASUREMENT_STRING,
+ sLevelCalculationMethod);
+ thresholds = cc.getIntArray(
+ CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY);
+ if (thresholds == null) thresholds = sThresholds;
+ }
+
+ int level = thresholds.length;
+ switch (calcMethod) {
+ case LEVEL_CALCULATION_METHOD_RSCP:
+ if (mRscp < WCDMA_RSCP_MIN || mRscp > WCDMA_RSCP_MAX) {
+ mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ return;
+ }
+ while (level > 0 && mRscp < thresholds[level - 1]) level--;
+ mLevel = level;
+ return;
+ case LEVEL_CALCULATION_METHOD_RSSI:
+ if (mRssi < WCDMA_RSSI_MIN || mRssi > WCDMA_RSSI_MAX) {
+ mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ return;
+ }
+ while (level > 0 && mRssi < thresholds[level - 1]) level--;
+ mLevel = level;
+ return;
+ default:
+ mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ }
}
/**
@@ -116,57 +183,66 @@
*/
@Override
public int getDbm() {
- int dBm;
-
- int level = mSignalStrength;
- int asu = (level == 99 ? CellInfo.UNAVAILABLE : level);
- if (asu != CellInfo.UNAVAILABLE) {
- dBm = -113 + (2 * asu);
- } else {
- dBm = CellInfo.UNAVAILABLE;
- }
- if (DBG) log("getDbm=" + dBm);
- return dBm;
+ if (mRscp != CellInfo.UNAVAILABLE) return mRscp;
+ return mRssi;
}
/**
- * Get the signal level as an asu value between 0..31, 99 is unknown
- * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
+ * Get the RSCP in ASU.
+ *
+ * Asu is calculated based on 3GPP RSCP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
+ *
+ * @return RSCP in ASU 0..96, 255, or UNAVAILABLE
*/
@Override
public int getAsuLevel() {
- // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
- // asu = 0 (-113dB or less) is very weak
- // signal, its better to show 0 bars to the user in such cases.
- // asu = 99 is a special case, where the signal strength is unknown.
- int level = mSignalStrength;
- if (DBG) log("getAsuLevel=" + level);
- return level;
+ if (mRscp != CellInfo.UNAVAILABLE) return getAsuFromRscpDbm(mRscp);
+ // For historical reasons, if RSCP is unavailable, this API will very incorrectly return
+ // RSSI. This hackery will be removed when most devices are using Radio HAL 1.2+
+ if (mRssi != CellInfo.UNAVAILABLE) return getAsuFromRssiDbm(mRssi);
+ return getAsuFromRscpDbm(CellInfo.UNAVAILABLE);
+ }
+
+ /**
+ * Get the signal strength as dBm
+ *
+ * @hide
+ */
+ public int getRssi() {
+ return mRssi;
+ }
+
+ /**
+ * Get the RSCP as dBm
+ * @hide
+ */
+ public int getRscp() {
+ return mRscp;
}
@Override
public int hashCode() {
- return Objects.hash(mSignalStrength, mBitErrorRate);
+ return Objects.hash(mRssi, mBitErrorRate, mRscp, mEcNo, mLevel);
+ }
+
+ private static final CellSignalStrengthWcdma sInvalid = new CellSignalStrengthWcdma();
+
+ /** @hide */
+ @Override
+ public boolean isValid() {
+ return !this.equals(sInvalid);
}
@Override
- public boolean equals (Object o) {
- CellSignalStrengthWcdma s;
+ public boolean equals(Object o) {
+ if (!(o instanceof CellSignalStrengthWcdma)) return false;
+ CellSignalStrengthWcdma s = (CellSignalStrengthWcdma) o;
- try {
- s = (CellSignalStrengthWcdma) o;
- } catch (ClassCastException ex) {
- return false;
- }
-
- if (o == null) {
- return false;
- }
-
- return mSignalStrength == s.mSignalStrength
+ return mRssi == s.mRssi
&& mBitErrorRate == s.mBitErrorRate
&& mRscp == s.mRscp
- && mEcNo == s.mEcNo;
+ && mEcNo == s.mEcNo
+ && mLevel == s.mLevel;
}
/**
@@ -175,20 +251,22 @@
@Override
public String toString() {
return "CellSignalStrengthWcdma:"
- + " ss=" + mSignalStrength
+ + " ss=" + mRssi
+ " ber=" + mBitErrorRate
+ " rscp=" + mRscp
- + " ecno=" + mEcNo;
+ + " ecno=" + mEcNo
+ + " level=" + mLevel;
}
/** Implement the Parcelable interface */
@Override
public void writeToParcel(Parcel dest, int flags) {
if (DBG) log("writeToParcel(Parcel, int): " + toString());
- dest.writeInt(mSignalStrength);
+ dest.writeInt(mRssi);
dest.writeInt(mBitErrorRate);
dest.writeInt(mRscp);
dest.writeInt(mEcNo);
+ dest.writeInt(mLevel);
}
/**
@@ -196,10 +274,11 @@
* where the token is already been processed.
*/
private CellSignalStrengthWcdma(Parcel in) {
- mSignalStrength = in.readInt();
+ mRssi = in.readInt();
mBitErrorRate = in.readInt();
mRscp = in.readInt();
mEcNo = in.readInt();
+ mLevel = in.readInt();
if (DBG) log("CellSignalStrengthWcdma(Parcel): " + toString());
}
diff --git a/telephony/java/android/telephony/DataFailCause.java b/telephony/java/android/telephony/DataFailCause.java
new file mode 100644
index 0000000..c53b37d
--- /dev/null
+++ b/telephony/java/android/telephony/DataFailCause.java
@@ -0,0 +1,503 @@
+/*
+ * Copyright (C) 2006 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.telephony;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.content.Context;
+import android.os.PersistableBundle;
+
+import com.android.internal.util.ArrayUtils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Returned as the reason for a data connection failure as defined by modem and some local errors.
+ * @hide
+ */
+public final class DataFailCause {
+ /** There is no failure */
+ public static final int NONE = 0;
+
+ // This series of errors as specified by the standards
+ // specified in ril.h
+ /** Operator determined barring. */
+ public static final int OPERATOR_BARRED = 0x08;
+ /** NAS signalling. */
+ public static final int NAS_SIGNALLING = 0x0E;
+ /** Logical Link Control (LLC) Sub Network Dependent Convergence Protocol (SNDCP). */
+ public static final int LLC_SNDCP = 0x19;
+ /** Insufficient resources. */
+ public static final int INSUFFICIENT_RESOURCES = 0x1A;
+ /** Missing or unknown APN. */
+ public static final int MISSING_UNKNOWN_APN = 0x1B; /* no retry */
+ /** Unknown Packet Data Protocol (PDP) address type. */
+ public static final int UNKNOWN_PDP_ADDRESS_TYPE = 0x1C; /* no retry */
+ /** User authentication. */
+ public static final int USER_AUTHENTICATION = 0x1D; /* no retry */
+ /** Activation rejected by Gateway GPRS Support Node (GGSN), Serving Gateway or PDN Gateway. */
+ public static final int ACTIVATION_REJECT_GGSN = 0x1E; /* no retry */
+ /** Activation rejected, unspecified. */
+ public static final int ACTIVATION_REJECT_UNSPECIFIED = 0x1F;
+ /** Service option not supported. */
+ public static final int SERVICE_OPTION_NOT_SUPPORTED = 0x20; /* no retry */
+ /** Requested service option not subscribed. */
+ public static final int SERVICE_OPTION_NOT_SUBSCRIBED = 0x21; /* no retry */
+ /** Service option temporarily out of order. */
+ public static final int SERVICE_OPTION_OUT_OF_ORDER = 0x22;
+ /** The Network Service Access Point Identifier (NSAPI) is in use. */
+ public static final int NSAPI_IN_USE = 0x23; /* no retry */
+ /* possibly restart radio, based on config */
+ /** Regular deactivation. */
+ public static final int REGULAR_DEACTIVATION = 0x24;
+ /** Quality of service (QoS) is not accepted. */
+ public static final int QOS_NOT_ACCEPTED = 0x25;
+ /** Network Failure. */
+ public static final int NETWORK_FAILURE = 0x26;
+ /** Universal Mobile Telecommunications System (UMTS) reactivation request. */
+ public static final int UMTS_REACTIVATION_REQ = 0x27;
+ /** Feature not supported. */
+ public static final int FEATURE_NOT_SUPP = 0x28;
+ /** Semantic error in the Traffic flow templates (TFT) operation. */
+ public static final int TFT_SEMANTIC_ERROR = 0x29;
+ /** Syntactical error in the Traffic flow templates (TFT) operation. */
+ public static final int TFT_SYTAX_ERROR = 0x2A;
+ /** Unknown Packet Data Protocol (PDP) context. */
+ public static final int UNKNOWN_PDP_CONTEXT = 0x2B;
+ /** Semantic errors in packet filter. */
+ public static final int FILTER_SEMANTIC_ERROR = 0x2C;
+ /** Syntactical errors in packet filter(s). */
+ 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;
+ /** 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. */
+ public static final int ONLY_IPV6_ALLOWED = 0x33; /* no retry */
+ /** Single address bearers only allowed. */
+ public static final int ONLY_SINGLE_BEARER_ALLOWED = 0x34;
+ /** EPS Session Management (ESM) information is not received. */
+ public static final int ESM_INFO_NOT_RECEIVED = 0x35;
+ /** PDN connection does not exist. */
+ 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;
+ /** Packet Data Protocol (PDP) */
+ public static final int MAX_ACTIVE_PDP_CONTEXT_REACHED = 0x41;
+ /** Unsupported APN in current public land mobile network (PLMN). */
+ public static final int UNSUPPORTED_APN_IN_CURRENT_PLMN = 0x42;
+ /** Invalid transaction id. */
+ public static final int INVALID_TRANSACTION_ID = 0x51;
+ /** Incorrect message semantic. */
+ public static final int MESSAGE_INCORRECT_SEMANTIC = 0x5F;
+ /** Invalid mandatory information. */
+ public static final int INVALID_MANDATORY_INFO = 0x60;
+ /** Unsupported message type. */
+ public static final int MESSAGE_TYPE_UNSUPPORTED = 0x61;
+ /** Message type uncompatible. */
+ public static final int MSG_TYPE_NONCOMPATIBLE_STATE = 0x62;
+ /** Unknown info element. */
+ public static final int UNKNOWN_INFO_ELEMENT = 0x63;
+ /** Conditional Information Element (IE) error. */
+ public static final int CONDITIONAL_IE_ERROR = 0x64;
+ /** Message and protocol state uncompatible. */
+ public static final int MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE = 0x65;
+ /** Protocol errors. */
+ public static final int PROTOCOL_ERRORS = 0x6F; /* no retry */
+ /** APN type conflict. */
+ public static final int APN_TYPE_CONFLICT = 0x70;
+ /** Invalid Proxy-Call Session Control Function (P-CSCF) address. */
+ public static final int INVALID_PCSCF_ADDR = 0x71;
+ /** Internal data call preempt by high priority APN. */
+ public static final int INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN = 0x72;
+ /** EPS (Evolved Packet System) Mobility Management (EMM) access barred. */
+ public static final int EMM_ACCESS_BARRED = 0x73;
+ /** Emergency interface only. */
+ public static final int EMERGENCY_IFACE_ONLY = 0x74;
+ /** Interface mismatch. */
+ public static final int IFACE_MISMATCH = 0x75;
+ /** Companion interface in use. */
+ public static final int COMPANION_IFACE_IN_USE = 0x76;
+ /** IP address mismatch. */
+ public static final int IP_ADDRESS_MISMATCH = 0x77;
+ public static final int IFACE_AND_POL_FAMILY_MISMATCH = 0x78;
+ /** EPS (Evolved Packet System) Mobility Management (EMM) access barred infinity retry. **/
+ 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;
+
+ // 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
+ public static final int OEM_DCFAILCAUSE_1 = 0x1001;
+ public static final int OEM_DCFAILCAUSE_2 = 0x1002;
+ public static final int OEM_DCFAILCAUSE_3 = 0x1003;
+ public static final int OEM_DCFAILCAUSE_4 = 0x1004;
+ public static final int OEM_DCFAILCAUSE_5 = 0x1005;
+ public static final int OEM_DCFAILCAUSE_6 = 0x1006;
+ public static final int OEM_DCFAILCAUSE_7 = 0x1007;
+ public static final int OEM_DCFAILCAUSE_8 = 0x1008;
+ public static final int OEM_DCFAILCAUSE_9 = 0x1009;
+ public static final int OEM_DCFAILCAUSE_10 = 0x100A;
+ public static final int OEM_DCFAILCAUSE_11 = 0x100B;
+ public static final int OEM_DCFAILCAUSE_12 = 0x100C;
+ public static final int OEM_DCFAILCAUSE_13 = 0x100D;
+ public static final int OEM_DCFAILCAUSE_14 = 0x100E;
+ public static final int OEM_DCFAILCAUSE_15 = 0x100F;
+
+ // Local errors generated by Vendor RIL
+ // specified in ril.h
+ public static final int REGISTRATION_FAIL = -1;
+ public static final int GPRS_REGISTRATION_FAIL = -2;
+ public static final int SIGNAL_LOST = -3; /* no retry */
+ public static final int PREF_RADIO_TECH_CHANGED = -4;
+ public static final int RADIO_POWER_OFF = -5; /* no retry */
+ public static final int TETHERED_CALL_ACTIVE = -6; /* no retry */
+ public static final int ERROR_UNSPECIFIED = 0xFFFF;
+
+ // Errors generated by the Framework
+ // specified here
+ public static final int UNKNOWN = 0x10000;
+ public static final int RADIO_NOT_AVAILABLE = 0x10001; /* no retry */
+ public static final int UNACCEPTABLE_NETWORK_PARAMETER = 0x10002; /* no retry */
+ public static final int CONNECTION_TO_DATACONNECTIONAC_BROKEN = 0x10003;
+ public static final int LOST_CONNECTION = 0x10004;
+ /** Data was reset by framework. */
+ public static final int RESET_BY_FRAMEWORK = 0x10005;
+
+ /** @hide */
+ @IntDef(value = {
+ NONE,
+ OPERATOR_BARRED,
+ NAS_SIGNALLING,
+ LLC_SNDCP,
+ INSUFFICIENT_RESOURCES,
+ MISSING_UNKNOWN_APN,
+ UNKNOWN_PDP_ADDRESS_TYPE,
+ USER_AUTHENTICATION,
+ ACTIVATION_REJECT_GGSN,
+ ACTIVATION_REJECT_UNSPECIFIED,
+ SERVICE_OPTION_NOT_SUPPORTED,
+ SERVICE_OPTION_NOT_SUBSCRIBED,
+ SERVICE_OPTION_OUT_OF_ORDER,
+ NSAPI_IN_USE,
+ REGULAR_DEACTIVATION,
+ QOS_NOT_ACCEPTED,
+ NETWORK_FAILURE,
+ UMTS_REACTIVATION_REQ,
+ FEATURE_NOT_SUPP,
+ TFT_SEMANTIC_ERROR,
+ TFT_SYTAX_ERROR,
+ UNKNOWN_PDP_CONTEXT,
+ FILTER_SEMANTIC_ERROR,
+ FILTER_SYTAX_ERROR,
+ PDP_WITHOUT_ACTIVE_TFT,
+ 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,
+ MAX_ACTIVE_PDP_CONTEXT_REACHED,
+ UNSUPPORTED_APN_IN_CURRENT_PLMN,
+ INVALID_TRANSACTION_ID,
+ MESSAGE_INCORRECT_SEMANTIC,
+ INVALID_MANDATORY_INFO,
+ MESSAGE_TYPE_UNSUPPORTED,
+ MSG_TYPE_NONCOMPATIBLE_STATE,
+ UNKNOWN_INFO_ELEMENT,
+ CONDITIONAL_IE_ERROR,
+ MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE,
+ PROTOCOL_ERRORS, /* no retry */
+ APN_TYPE_CONFLICT,
+ INVALID_PCSCF_ADDR,
+ INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN,
+ EMM_ACCESS_BARRED,
+ EMERGENCY_IFACE_ONLY,
+ IFACE_MISMATCH,
+ COMPANION_IFACE_IN_USE,
+ IP_ADDRESS_MISMATCH,
+ IFACE_AND_POL_FAMILY_MISMATCH,
+ EMM_ACCESS_BARRED_INFINITE_RETRY,
+ AUTH_FAILURE_ON_EMERGENCY_CALL,
+ OEM_DCFAILCAUSE_1,
+ OEM_DCFAILCAUSE_2,
+ OEM_DCFAILCAUSE_3,
+ OEM_DCFAILCAUSE_4,
+ OEM_DCFAILCAUSE_5,
+ OEM_DCFAILCAUSE_6,
+ OEM_DCFAILCAUSE_7,
+ OEM_DCFAILCAUSE_8,
+ OEM_DCFAILCAUSE_9,
+ OEM_DCFAILCAUSE_10,
+ OEM_DCFAILCAUSE_11,
+ OEM_DCFAILCAUSE_12,
+ OEM_DCFAILCAUSE_13,
+ OEM_DCFAILCAUSE_14,
+ OEM_DCFAILCAUSE_15,
+ REGISTRATION_FAIL,
+ GPRS_REGISTRATION_FAIL,
+ SIGNAL_LOST,
+ PREF_RADIO_TECH_CHANGED,
+ RADIO_POWER_OFF,
+ TETHERED_CALL_ACTIVE,
+ ERROR_UNSPECIFIED,
+ UNKNOWN,
+ RADIO_NOT_AVAILABLE,
+ UNACCEPTABLE_NETWORK_PARAMETER,
+ CONNECTION_TO_DATACONNECTIONAC_BROKEN,
+ LOST_CONNECTION,
+ RESET_BY_FRAMEWORK
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface FailCause{}
+
+ private static final Map<Integer, String> sFailCauseMap;
+ static {
+ sFailCauseMap = new HashMap<>();
+ sFailCauseMap.put(NONE, "NONE");
+ sFailCauseMap.put(OPERATOR_BARRED, "OPERATOR_BARRED");
+ sFailCauseMap.put(NAS_SIGNALLING, "NAS_SIGNALLING");
+ sFailCauseMap.put(LLC_SNDCP, "LLC_SNDCP");
+ sFailCauseMap.put(INSUFFICIENT_RESOURCES, "INSUFFICIENT_RESOURCES");
+ sFailCauseMap.put(MISSING_UNKNOWN_APN, "MISSING_UNKNOWN_APN");
+ sFailCauseMap.put(UNKNOWN_PDP_ADDRESS_TYPE, "UNKNOWN_PDP_ADDRESS_TYPE");
+ sFailCauseMap.put(USER_AUTHENTICATION, "USER_AUTHENTICATION");
+ sFailCauseMap.put(ACTIVATION_REJECT_GGSN, "ACTIVATION_REJECT_GGSN");
+ sFailCauseMap.put(ACTIVATION_REJECT_UNSPECIFIED,
+ "ACTIVATION_REJECT_UNSPECIFIED");
+ sFailCauseMap.put(SERVICE_OPTION_NOT_SUPPORTED,
+ "SERVICE_OPTION_NOT_SUPPORTED");
+ sFailCauseMap.put(SERVICE_OPTION_NOT_SUBSCRIBED,
+ "SERVICE_OPTION_NOT_SUBSCRIBED");
+ sFailCauseMap.put(SERVICE_OPTION_OUT_OF_ORDER, "SERVICE_OPTION_OUT_OF_ORDER");
+ sFailCauseMap.put(NSAPI_IN_USE, "NSAPI_IN_USE");
+ sFailCauseMap.put(REGULAR_DEACTIVATION, "REGULAR_DEACTIVATION");
+ sFailCauseMap.put(QOS_NOT_ACCEPTED, "QOS_NOT_ACCEPTED");
+ sFailCauseMap.put(NETWORK_FAILURE, "NETWORK_FAILURE");
+ sFailCauseMap.put(UMTS_REACTIVATION_REQ, "UMTS_REACTIVATION_REQ");
+ sFailCauseMap.put(FEATURE_NOT_SUPP, "FEATURE_NOT_SUPP");
+ sFailCauseMap.put(TFT_SEMANTIC_ERROR, "TFT_SEMANTIC_ERROR");
+ sFailCauseMap.put(TFT_SYTAX_ERROR, "TFT_SYTAX_ERROR");
+ sFailCauseMap.put(UNKNOWN_PDP_CONTEXT, "UNKNOWN_PDP_CONTEXT");
+ 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(ONLY_IPV4_ALLOWED, "ONLY_IPV4_ALLOWED");
+ sFailCauseMap.put(ONLY_IPV6_ALLOWED, "ONLY_IPV6_ALLOWED");
+ sFailCauseMap.put(ONLY_SINGLE_BEARER_ALLOWED, "ONLY_SINGLE_BEARER_ALLOWED");
+ sFailCauseMap.put(ESM_INFO_NOT_RECEIVED, "ESM_INFO_NOT_RECEIVED");
+ 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(MAX_ACTIVE_PDP_CONTEXT_REACHED,
+ "MAX_ACTIVE_PDP_CONTEXT_REACHED");
+ sFailCauseMap.put(UNSUPPORTED_APN_IN_CURRENT_PLMN,
+ "UNSUPPORTED_APN_IN_CURRENT_PLMN");
+ sFailCauseMap.put(INVALID_TRANSACTION_ID, "INVALID_TRANSACTION_ID");
+ sFailCauseMap.put(MESSAGE_INCORRECT_SEMANTIC, "MESSAGE_INCORRECT_SEMANTIC");
+ sFailCauseMap.put(INVALID_MANDATORY_INFO, "INVALID_MANDATORY_INFO");
+ sFailCauseMap.put(MESSAGE_TYPE_UNSUPPORTED, "MESSAGE_TYPE_UNSUPPORTED");
+ sFailCauseMap.put(MSG_TYPE_NONCOMPATIBLE_STATE, "MSG_TYPE_NONCOMPATIBLE_STATE");
+ sFailCauseMap.put(UNKNOWN_INFO_ELEMENT, "UNKNOWN_INFO_ELEMENT");
+ sFailCauseMap.put(CONDITIONAL_IE_ERROR, "CONDITIONAL_IE_ERROR");
+ sFailCauseMap.put(MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE,
+ "MSG_AND_PROTOCOL_STATE_UNCOMPATIBLE");
+ sFailCauseMap.put(PROTOCOL_ERRORS, "PROTOCOL_ERRORS");
+ sFailCauseMap.put(APN_TYPE_CONFLICT, "APN_TYPE_CONFLICT");
+ sFailCauseMap.put(INVALID_PCSCF_ADDR, "INVALID_PCSCF_ADDR");
+ sFailCauseMap.put(INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN,
+ "INTERNAL_CALL_PREEMPT_BY_HIGH_PRIO_APN");
+ sFailCauseMap.put(EMM_ACCESS_BARRED, "EMM_ACCESS_BARRED");
+ sFailCauseMap.put(EMERGENCY_IFACE_ONLY, "EMERGENCY_IFACE_ONLY");
+ sFailCauseMap.put(IFACE_MISMATCH, "IFACE_MISMATCH");
+ sFailCauseMap.put(COMPANION_IFACE_IN_USE, "COMPANION_IFACE_IN_USE");
+ sFailCauseMap.put(IP_ADDRESS_MISMATCH, "IP_ADDRESS_MISMATCH");
+ sFailCauseMap.put(IFACE_AND_POL_FAMILY_MISMATCH,
+ "IFACE_AND_POL_FAMILY_MISMATCH");
+ sFailCauseMap.put(EMM_ACCESS_BARRED_INFINITE_RETRY,
+ "EMM_ACCESS_BARRED_INFINITE_RETRY");
+ sFailCauseMap.put(AUTH_FAILURE_ON_EMERGENCY_CALL,
+ "AUTH_FAILURE_ON_EMERGENCY_CALL");
+ sFailCauseMap.put(OEM_DCFAILCAUSE_1, "OEM_DCFAILCAUSE_1");
+ sFailCauseMap.put(OEM_DCFAILCAUSE_2, "OEM_DCFAILCAUSE_2");
+ sFailCauseMap.put(OEM_DCFAILCAUSE_3, "OEM_DCFAILCAUSE_3");
+ sFailCauseMap.put(OEM_DCFAILCAUSE_4, "OEM_DCFAILCAUSE_4");
+ sFailCauseMap.put(OEM_DCFAILCAUSE_5, "OEM_DCFAILCAUSE_5");
+ sFailCauseMap.put(OEM_DCFAILCAUSE_6, "OEM_DCFAILCAUSE_6");
+ sFailCauseMap.put(OEM_DCFAILCAUSE_7, "OEM_DCFAILCAUSE_7");
+ sFailCauseMap.put(OEM_DCFAILCAUSE_8, "OEM_DCFAILCAUSE_8");
+ sFailCauseMap.put(OEM_DCFAILCAUSE_9, "OEM_DCFAILCAUSE_9");
+ sFailCauseMap.put(OEM_DCFAILCAUSE_10, "OEM_DCFAILCAUSE_10");
+ sFailCauseMap.put(OEM_DCFAILCAUSE_11, "OEM_DCFAILCAUSE_11");
+ sFailCauseMap.put(OEM_DCFAILCAUSE_12, "OEM_DCFAILCAUSE_12");
+ sFailCauseMap.put(OEM_DCFAILCAUSE_13, "OEM_DCFAILCAUSE_13");
+ sFailCauseMap.put(OEM_DCFAILCAUSE_14, "OEM_DCFAILCAUSE_14");
+ sFailCauseMap.put(OEM_DCFAILCAUSE_15, "OEM_DCFAILCAUSE_15");
+ sFailCauseMap.put(REGISTRATION_FAIL, "REGISTRATION_FAIL");
+ sFailCauseMap.put(GPRS_REGISTRATION_FAIL, "GPRS_REGISTRATION_FAIL");
+ sFailCauseMap.put(SIGNAL_LOST, "SIGNAL_LOST");
+ sFailCauseMap.put(PREF_RADIO_TECH_CHANGED, "PREF_RADIO_TECH_CHANGED");
+ sFailCauseMap.put(RADIO_POWER_OFF, "RADIO_POWER_OFF");
+ sFailCauseMap.put(TETHERED_CALL_ACTIVE, "TETHERED_CALL_ACTIVE");
+ sFailCauseMap.put(ERROR_UNSPECIFIED, "ERROR_UNSPECIFIED");
+ sFailCauseMap.put(UNKNOWN, "UNKNOWN");
+ sFailCauseMap.put(RADIO_NOT_AVAILABLE, "RADIO_NOT_AVAILABLE");
+ sFailCauseMap.put(UNACCEPTABLE_NETWORK_PARAMETER,
+ "UNACCEPTABLE_NETWORK_PARAMETER");
+ sFailCauseMap.put(CONNECTION_TO_DATACONNECTIONAC_BROKEN,
+ "CONNECTION_TO_DATACONNECTIONAC_BROKEN");
+ sFailCauseMap.put(LOST_CONNECTION, "LOST_CONNECTION");
+ sFailCauseMap.put(RESET_BY_FRAMEWORK, "RESET_BY_FRAMEWORK");
+ }
+
+ /**
+ * Map of subId -> set of data call setup permanent failure for the carrier.
+ */
+ private static final HashMap<Integer, Set<Integer>> sPermanentFailureCache =
+ new HashMap<>();
+
+ /**
+ * Returns whether or not the fail cause is a failure that requires a modem restart
+ *
+ * @param context device context
+ * @param cause data disconnect cause
+ * @param subId subscription index
+ * @return true if the fail cause code needs platform to trigger a modem restart.
+ */
+ public static boolean isRadioRestartFailure(@NonNull Context context, @FailCause int cause,
+ int subId) {
+ CarrierConfigManager configManager = (CarrierConfigManager)
+ context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ if (configManager != null) {
+ PersistableBundle b = configManager.getConfigForSubId(subId);
+
+ if (b != null) {
+ if (cause == REGULAR_DEACTIVATION
+ && b.getBoolean(CarrierConfigManager
+ .KEY_RESTART_RADIO_ON_PDP_FAIL_REGULAR_DEACTIVATION_BOOL)) {
+ // This is for backward compatibility support. We need to continue support this
+ // old configuration until it gets removed in the future.
+ return true;
+ }
+ // Check the current configurations.
+ int[] causeCodes = b.getIntArray(CarrierConfigManager
+ .KEY_RADIO_RESTART_FAILURE_CAUSES_INT_ARRAY);
+ if (causeCodes != null) {
+ return Arrays.stream(causeCodes).anyMatch(i -> i == cause);
+ }
+ }
+ }
+
+ return false;
+ }
+
+ public static boolean isPermanentFailure(@NonNull Context context, @FailCause int failCause,
+ int subId) {
+ synchronized (sPermanentFailureCache) {
+
+ Set<Integer> permanentFailureSet = sPermanentFailureCache.get(subId);
+
+ // In case of cache miss, we need to look up the settings from carrier config.
+ if (permanentFailureSet == null) {
+ // Retrieve the permanent failure from carrier config
+ CarrierConfigManager configManager = (CarrierConfigManager)
+ context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
+ if (configManager != null) {
+ PersistableBundle b = configManager.getConfigForSubId(subId);
+ if (b != null) {
+ String[] permanentFailureStrings = b.getStringArray(CarrierConfigManager.
+ KEY_CARRIER_DATA_CALL_PERMANENT_FAILURE_STRINGS);
+ if (permanentFailureStrings != null) {
+ permanentFailureSet = new HashSet<>();
+ for (Map.Entry<Integer, String> e : sFailCauseMap.entrySet()) {
+ if (ArrayUtils.contains(permanentFailureStrings, e.getValue())) {
+ permanentFailureSet.add(e.getKey());
+ }
+ }
+ }
+ }
+ }
+
+ // If we are not able to find the configuration from carrier config, use the default
+ // ones.
+ if (permanentFailureSet == null) {
+ permanentFailureSet = new HashSet<Integer>() {
+ {
+ add(OPERATOR_BARRED);
+ add(MISSING_UNKNOWN_APN);
+ add(UNKNOWN_PDP_ADDRESS_TYPE);
+ add(USER_AUTHENTICATION);
+ add(ACTIVATION_REJECT_GGSN);
+ add(SERVICE_OPTION_NOT_SUPPORTED);
+ add(SERVICE_OPTION_NOT_SUBSCRIBED);
+ add(NSAPI_IN_USE);
+ add(ONLY_IPV4_ALLOWED);
+ add(ONLY_IPV6_ALLOWED);
+ add(PROTOCOL_ERRORS);
+ add(RADIO_POWER_OFF);
+ add(TETHERED_CALL_ACTIVE);
+ add(RADIO_NOT_AVAILABLE);
+ add(UNACCEPTABLE_NETWORK_PARAMETER);
+ add(SIGNAL_LOST);
+ }
+ };
+ }
+
+ sPermanentFailureCache.put(subId, permanentFailureSet);
+ }
+
+ return permanentFailureSet.contains(failCause);
+ }
+ }
+
+ public static boolean isEventLoggable(@FailCause int dataFailCause) {
+ return (dataFailCause == OPERATOR_BARRED) || (dataFailCause == INSUFFICIENT_RESOURCES)
+ || (dataFailCause == UNKNOWN_PDP_ADDRESS_TYPE)
+ || (dataFailCause == USER_AUTHENTICATION)
+ || (dataFailCause == ACTIVATION_REJECT_GGSN)
+ || (dataFailCause == ACTIVATION_REJECT_UNSPECIFIED)
+ || (dataFailCause == SERVICE_OPTION_NOT_SUBSCRIBED)
+ || (dataFailCause == SERVICE_OPTION_NOT_SUPPORTED)
+ || (dataFailCause == SERVICE_OPTION_OUT_OF_ORDER)
+ || (dataFailCause == NSAPI_IN_USE)
+ || (dataFailCause == ONLY_IPV4_ALLOWED)
+ || (dataFailCause == ONLY_IPV6_ALLOWED)
+ || (dataFailCause == PROTOCOL_ERRORS)
+ || (dataFailCause == SIGNAL_LOST)
+ || (dataFailCause == RADIO_POWER_OFF)
+ || (dataFailCause == TETHERED_CALL_ACTIVE)
+ || (dataFailCause == UNACCEPTABLE_NETWORK_PARAMETER);
+ }
+
+ public static String toString(@FailCause int dataFailCause) {
+ int cause = getFailCause(dataFailCause);
+ return (cause == UNKNOWN) ? "UNKNOWN(" + dataFailCause + ")" : sFailCauseMap.get(cause);
+ }
+
+ public static int getFailCause(@FailCause int failCause) {
+ if (sFailCauseMap.containsKey(failCause)) {
+ return failCause;
+ } else {
+ return UNKNOWN;
+ }
+ }
+}
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index c6887ab..f53cb82 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -16,12 +16,16 @@
package android.telephony;
+import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
/**
- * Contains disconnect call causes generated by the framework and the RIL.
+ * Describes the cause of a disconnected call. Those disconnect causes can be converted into a more
+ * generic {@link android.telecom.DisconnectCause} object.
+ *
* @hide
*/
+@SystemApi
public class DisconnectCause {
/** The disconnect cause is not valid (Not received a disconnect cause) */
@@ -101,8 +105,8 @@
/** Unknown error or not specified */
public static final int ERROR_UNSPECIFIED = 36;
/**
- * Only emergency numbers are allowed, but we tried to dial
- * a non-emergency number.
+ * Only emergency numbers are allowed, but we tried to dial a non-emergency number.
+ * @hide
*/
// TODO: This should be the same as NOT_EMERGENCY
public static final int EMERGENCY_ONLY = 37;
@@ -115,8 +119,7 @@
*/
public static final int DIALED_MMI = 39;
/**
- * We tried to call a voicemail: URI but the device has no
- * voicemail number configured.
+ * We tried to call a voicemail: URI but the device has no voicemail number configured.
*/
public static final int VOICEMAIL_NUMBER_MISSING = 40;
/**
@@ -129,6 +132,8 @@
* needs to be triggered by a *disconnect* event, rather than when
* the InCallScreen first comes to the foreground. For now we use
* the needToShowCallLostDialog field for this (see below.)
+ *
+ * @hide
*/
public static final int CDMA_CALL_LOST = 41;
/**
@@ -169,62 +174,52 @@
/**
* Stk Call Control modified DIAL request to USSD request.
- * {@hide}
*/
public static final int DIAL_MODIFIED_TO_USSD = 46;
/**
* Stk Call Control modified DIAL request to SS request.
- * {@hide}
*/
public static final int DIAL_MODIFIED_TO_SS = 47;
/**
* Stk Call Control modified DIAL request to DIAL with modified data.
- * {@hide}
*/
public static final int DIAL_MODIFIED_TO_DIAL = 48;
/**
* The call was terminated because CDMA phone service and roaming have already been activated.
- * {@hide}
*/
public static final int CDMA_ALREADY_ACTIVATED = 49;
/**
* The call was terminated because it is not possible to place a video call while TTY is
* enabled.
- * {@hide}
*/
public static final int VIDEO_CALL_NOT_ALLOWED_WHILE_TTY_ENABLED = 50;
/**
* The call was terminated because it was pulled to another device.
- * {@hide}
*/
public static final int CALL_PULLED = 51;
/**
* The call was terminated because it was answered on another device.
- * {@hide}
*/
public static final int ANSWERED_ELSEWHERE = 52;
/**
* The call was terminated because the maximum allowable number of calls has been reached.
- * {@hide}
*/
public static final int MAXIMUM_NUMBER_OF_CALLS_REACHED = 53;
/**
* The call was terminated because cellular data has been disabled.
* Used when in a video call and the user disables cellular data via the settings.
- * {@hide}
*/
public static final int DATA_DISABLED = 54;
/**
* The call was terminated because the data policy has disabled cellular data.
* Used when in a video call and the user has exceeded the device data limit.
- * {@hide}
*/
public static final int DATA_LIMIT_REACHED = 55;
@@ -237,7 +232,6 @@
/**
* The network does not accept the emergency call request because IMEI was used as
* identification and this cability is not supported by the network.
- * {@hide}
*/
public static final int IMEI_NOT_ACCEPTED = 58;
@@ -249,7 +243,6 @@
/**
* The call has failed because of access class barring.
- * {@hide}
*/
public static final int IMS_ACCESS_BLOCKED = 60;
@@ -265,51 +258,43 @@
/**
* Emergency call failed with a temporary fail cause and can be redialed on this slot.
- * {@hide}
*/
public static final int EMERGENCY_TEMP_FAILURE = 63;
/**
* Emergency call failed with a permanent fail cause and should not be redialed on this
- * slot.
- * {@hide}
+ * slot.
*/
public static final int EMERGENCY_PERM_FAILURE = 64;
/**
* This cause is used to report a normal event only when no other cause in the normal class
* applies.
- * {@hide}
*/
public static final int NORMAL_UNSPECIFIED = 65;
/**
* Stk Call Control modified DIAL request to video DIAL request.
- * {@hide}
*/
public static final int DIAL_MODIFIED_TO_DIAL_VIDEO = 66;
/**
* Stk Call Control modified Video DIAL request to SS request.
- * {@hide}
*/
public static final int DIAL_VIDEO_MODIFIED_TO_SS = 67;
/**
* Stk Call Control modified Video DIAL request to USSD request.
- * {@hide}
*/
public static final int DIAL_VIDEO_MODIFIED_TO_USSD = 68;
/**
* Stk Call Control modified Video DIAL request to DIAL request.
- * {@hide}
*/
public static final int DIAL_VIDEO_MODIFIED_TO_DIAL = 69;
/**
* Stk Call Control modified Video DIAL request to Video DIAL request.
- * {@hide}
*/
public static final int DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO = 70;
@@ -359,7 +344,10 @@
// Do nothing.
}
- /** Returns descriptive string for the specified disconnect cause. */
+ /**
+ * Returns descriptive string for the specified disconnect cause.
+ * @hide
+ */
@UnsupportedAppUsage
public static String toString(int cause) {
switch (cause) {
diff --git a/telephony/java/android/telephony/NetworkService.java b/telephony/java/android/telephony/NetworkService.java
index 4354314..4bca404 100644
--- a/telephony/java/android/telephony/NetworkService.java
+++ b/telephony/java/android/telephony/NetworkService.java
@@ -16,7 +16,6 @@
package android.telephony;
-import android.annotation.CallSuper;
import android.annotation.SystemApi;
import android.app.Service;
import android.content.Intent;
@@ -53,7 +52,6 @@
private final String TAG = NetworkService.class.getSimpleName();
public static final String NETWORK_SERVICE_INTERFACE = "android.telephony.NetworkService";
- public static final String NETWORK_SERVICE_EXTRA_SLOT_ID = "android.telephony.extra.SLOT_ID";
private static final int NETWORK_SERVICE_CREATE_NETWORK_SERVICE_PROVIDER = 1;
private static final int NETWORK_SERVICE_REMOVE_NETWORK_SERVICE_PROVIDER = 2;
@@ -81,7 +79,7 @@
* must extend this class to support network connection. Note that each instance of network
* service is associated with one physical SIM slot.
*/
- public class NetworkServiceProvider {
+ public abstract class NetworkServiceProvider implements AutoCloseable {
private final int mSlotId;
private final List<INetworkServiceCallback>
@@ -137,12 +135,12 @@
}
/**
- * Called when the instance of network service is destroyed (e.g. got unbind or binder died).
+ * Called when the instance of network service is destroyed (e.g. got unbind or binder died)
+ * or when the network service provider is removed. The extended class should implement this
+ * method to perform cleanup works.
*/
- @CallSuper
- protected void onDestroy() {
- mNetworkRegistrationStateChangedCallbacks.clear();
- }
+ @Override
+ public abstract void close();
}
private class NetworkServiceHandler extends Handler {
@@ -168,7 +166,7 @@
case NETWORK_SERVICE_REMOVE_NETWORK_SERVICE_PROVIDER:
// If the service provider doesn't exist yet, we try to create it.
if (serviceProvider != null) {
- serviceProvider.onDestroy();
+ serviceProvider.close();
mServiceMap.remove(slotId);
}
break;
@@ -176,7 +174,7 @@
for (int i = 0; i < mServiceMap.size(); i++) {
serviceProvider = mServiceMap.get(i);
if (serviceProvider != null) {
- serviceProvider.onDestroy();
+ serviceProvider.close();
}
}
mServiceMap.clear();
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index e8a28ca..2b1628c 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -171,14 +171,14 @@
public static final int LISTEN_CELL_INFO = 0x00000400;
/**
- * Listen for precise changes and fails to the device calls (cellular).
+ * Listen for {@link PreciseCallState.State} of ringing, background and foreground calls.
* {@more}
* Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
* READ_PRECISE_PHONE_STATE}
*
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public static final int LISTEN_PRECISE_CALL_STATE = 0x00000800;
/**
@@ -316,6 +316,18 @@
*/
public static final int LISTEN_EMERGENCY_NUMBER_LIST = 0x01000000;
+ /**
+ * Listen for call disconnect causes which contains {@link DisconnectCause} and
+ * {@link PreciseDisconnectCause}.
+ * {@more}
+ * Requires Permission: {@link android.Manifest.permission#READ_PRECISE_PHONE_STATE
+ * READ_PRECISE_PHONE_STATE}
+ *
+ * @hide
+ */
+ @SystemApi
+ public static final int LISTEN_CALL_DISCONNECT_CAUSES = 0x02000000;
+
/*
* Subscription used to listen to the phone state changes
* @hide
@@ -526,11 +538,23 @@
/**
* Callback invoked when precise device call state changes.
+ * @param callState {@link PreciseCallState}
+ * @hide
+ */
+ @SystemApi
+ public void onPreciseCallStateChanged(PreciseCallState callState) {
+ // default implementation empty
+ }
+
+ /**
+ * Callback invoked when call disconnect cause changes.
+ * @param disconnectCause {@link DisconnectCause}.
+ * @param preciseDisconnectCause {@link PreciseDisconnectCause}.
*
* @hide
*/
- @UnsupportedAppUsage
- public void onPreciseCallStateChanged(PreciseCallState callState) {
+ @SystemApi
+ public void onCallDisconnectCauseChanged(int disconnectCause, int preciseDisconnectCause) {
// default implementation empty
}
@@ -780,6 +804,15 @@
() -> mExecutor.execute(() -> psl.onPreciseCallStateChanged(callState)));
}
+ public void onCallDisconnectCauseChanged(int disconnectCause, int preciseDisconnectCause) {
+ PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
+ if (psl == null) return;
+
+ Binder.withCleanCallingIdentity(
+ () -> mExecutor.execute(() -> psl.onCallDisconnectCauseChanged(
+ disconnectCause, preciseDisconnectCause)));
+ }
+
public void onPreciseDataConnectionStateChanged(
PreciseDataConnectionState dataConnectionState) {
PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
diff --git a/telephony/java/android/telephony/PreciseCallState.java b/telephony/java/android/telephony/PreciseCallState.java
index ed5c26a..59f3e1f 100644
--- a/telephony/java/android/telephony/PreciseCallState.java
+++ b/telephony/java/android/telephony/PreciseCallState.java
@@ -16,29 +16,51 @@
package android.telephony;
+import android.annotation.IntDef;
+import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.DisconnectCause;
import android.telephony.PreciseDisconnectCause;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
/**
- * Contains precise call state and call fail causes generated by the
- * framework and the RIL.
+ * Contains precise call states.
*
* The following call information is included in returned PreciseCallState:
*
* <ul>
- * <li>Ringing call state.
- * <li>Foreground call state.
- * <li>Background call state.
- * <li>Disconnect cause; generated by the framework.
- * <li>Precise disconnect cause; generated by the RIL.
+ * <li>Precise ringing call state.
+ * <li>Precise foreground call state.
+ * <li>Precise background call state.
* </ul>
*
+ * @see android.telephony.TelephonyManager.CallState which contains generic call states.
+ *
* @hide
*/
-public class PreciseCallState implements Parcelable {
+@SystemApi
+public final class PreciseCallState implements Parcelable {
+
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"PRECISE_CALL_STATE_"},
+ value = {
+ PRECISE_CALL_STATE_NOT_VALID,
+ PRECISE_CALL_STATE_IDLE,
+ PRECISE_CALL_STATE_ACTIVE,
+ PRECISE_CALL_STATE_HOLDING,
+ PRECISE_CALL_STATE_DIALING,
+ PRECISE_CALL_STATE_ALERTING,
+ PRECISE_CALL_STATE_INCOMING,
+ PRECISE_CALL_STATE_WAITING,
+ PRECISE_CALL_STATE_DISCONNECTED,
+ PRECISE_CALL_STATE_DISCONNECTING})
+ public @interface State {}
/** Call state is not valid (Not received a call state). */
public static final int PRECISE_CALL_STATE_NOT_VALID = -1;
@@ -61,9 +83,9 @@
/** Call state: Disconnecting. */
public static final int PRECISE_CALL_STATE_DISCONNECTING = 8;
- private int mRingingCallState = PRECISE_CALL_STATE_NOT_VALID;
- private int mForegroundCallState = PRECISE_CALL_STATE_NOT_VALID;
- private int mBackgroundCallState = PRECISE_CALL_STATE_NOT_VALID;
+ private @State int mRingingCallState = PRECISE_CALL_STATE_NOT_VALID;
+ private @State int mForegroundCallState = PRECISE_CALL_STATE_NOT_VALID;
+ private @State int mBackgroundCallState = PRECISE_CALL_STATE_NOT_VALID;
private int mDisconnectCause = DisconnectCause.NOT_VALID;
private int mPreciseDisconnectCause = PreciseDisconnectCause.NOT_VALID;
@@ -73,8 +95,9 @@
* @hide
*/
@UnsupportedAppUsage
- public PreciseCallState(int ringingCall, int foregroundCall, int backgroundCall,
- int disconnectCause, int preciseDisconnectCause) {
+ public PreciseCallState(@State int ringingCall, @State int foregroundCall,
+ @State int backgroundCall, int disconnectCause,
+ int preciseDisconnectCause) {
mRingingCallState = ringingCall;
mForegroundCallState = foregroundCall;
mBackgroundCallState = backgroundCall;
@@ -92,6 +115,8 @@
/**
* Construct a PreciseCallState object from the given parcel.
+ *
+ * @hide
*/
private PreciseCallState(Parcel in) {
mRingingCallState = in.readInt();
@@ -102,59 +127,23 @@
}
/**
- * Get precise ringing call state
- *
- * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
- * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
- * @see PreciseCallState#PRECISE_CALL_STATE_ACTIVE
- * @see PreciseCallState#PRECISE_CALL_STATE_HOLDING
- * @see PreciseCallState#PRECISE_CALL_STATE_DIALING
- * @see PreciseCallState#PRECISE_CALL_STATE_ALERTING
- * @see PreciseCallState#PRECISE_CALL_STATE_INCOMING
- * @see PreciseCallState#PRECISE_CALL_STATE_WAITING
- * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTED
- * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTING
+ * Returns the precise ringing call state.
*/
- @UnsupportedAppUsage
- public int getRingingCallState() {
+ public @State int getRingingCallState() {
return mRingingCallState;
}
/**
- * Get precise foreground call state
- *
- * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
- * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
- * @see PreciseCallState#PRECISE_CALL_STATE_ACTIVE
- * @see PreciseCallState#PRECISE_CALL_STATE_HOLDING
- * @see PreciseCallState#PRECISE_CALL_STATE_DIALING
- * @see PreciseCallState#PRECISE_CALL_STATE_ALERTING
- * @see PreciseCallState#PRECISE_CALL_STATE_INCOMING
- * @see PreciseCallState#PRECISE_CALL_STATE_WAITING
- * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTED
- * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTING
+ * Returns the precise foreground call state.
*/
- @UnsupportedAppUsage
- public int getForegroundCallState() {
+ public @State int getForegroundCallState() {
return mForegroundCallState;
}
/**
- * Get precise background call state
- *
- * @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
- * @see PreciseCallState#PRECISE_CALL_STATE_IDLE
- * @see PreciseCallState#PRECISE_CALL_STATE_ACTIVE
- * @see PreciseCallState#PRECISE_CALL_STATE_HOLDING
- * @see PreciseCallState#PRECISE_CALL_STATE_DIALING
- * @see PreciseCallState#PRECISE_CALL_STATE_ALERTING
- * @see PreciseCallState#PRECISE_CALL_STATE_INCOMING
- * @see PreciseCallState#PRECISE_CALL_STATE_WAITING
- * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTED
- * @see PreciseCallState#PRECISE_CALL_STATE_DISCONNECTING
+ * Returns the precise background call state.
*/
- @UnsupportedAppUsage
- public int getBackgroundCallState() {
+ public @State int getBackgroundCallState() {
return mBackgroundCallState;
}
@@ -199,6 +188,11 @@
* @see DisconnectCause#CDMA_NOT_EMERGENCY
* @see DisconnectCause#CDMA_ACCESS_BLOCKED
* @see DisconnectCause#ERROR_UNSPECIFIED
+ *
+ * TODO: remove disconnect cause from preciseCallState as there is no link between random
+ * connection disconnect cause with foreground, background or ringing call.
+ *
+ * @hide
*/
@UnsupportedAppUsage
public int getDisconnectCause() {
@@ -238,6 +232,11 @@
* @see PreciseDisconnectCause#CDMA_NOT_EMERGENCY
* @see PreciseDisconnectCause#CDMA_ACCESS_BLOCKED
* @see PreciseDisconnectCause#ERROR_UNSPECIFIED
+ *
+ * TODO: remove precise disconnect cause from preciseCallState as there is no link between
+ * random connection disconnect cause with foreground, background or ringing call.
+ *
+ * @hide
*/
@UnsupportedAppUsage
public int getPreciseDisconnectCause() {
@@ -272,14 +271,8 @@
@Override
public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + mRingingCallState;
- result = prime * result + mForegroundCallState;
- result = prime * result + mBackgroundCallState;
- result = prime * result + mDisconnectCause;
- result = prime * result + mPreciseDisconnectCause;
- return result;
+ return Objects.hash(mRingingCallState, mForegroundCallState, mForegroundCallState,
+ mDisconnectCause, mPreciseDisconnectCause);
}
@Override
diff --git a/telephony/java/android/telephony/PreciseDisconnectCause.java b/telephony/java/android/telephony/PreciseDisconnectCause.java
index 2acaf34..af88748 100644
--- a/telephony/java/android/telephony/PreciseDisconnectCause.java
+++ b/telephony/java/android/telephony/PreciseDisconnectCause.java
@@ -16,279 +16,329 @@
package android.telephony;
+import android.annotation.SystemApi;
+
/**
- * Contains precise disconnect call causes generated by the
- * framework and the RIL.
- *
+ * Contains precise disconnect call causes generated by the framework and the RIL.
* @hide
*/
+@SystemApi
public class PreciseDisconnectCause {
- /** The disconnect cause is not valid (Not received a disconnect cause)*/
+ /** The disconnect cause is not valid (Not received a disconnect cause).*/
public static final int NOT_VALID = -1;
- /** No disconnect cause provided. Generally a local disconnect or an incoming missed call */
+ /** No disconnect cause provided. Generally a local disconnect or an incoming missed call. */
public static final int NO_DISCONNECT_CAUSE_AVAILABLE = 0;
/**
* The destination cannot be reached because the number, although valid,
- * is not currently assigned
+ * is not currently assigned.
*/
public static final int UNOBTAINABLE_NUMBER = 1;
- /** The user cannot be reached because the network through which the call has been
- * routed does not serve the destination desired
+ /**
+ * The user cannot be reached because the network through which the call has been routed does
+ * not serve the destination desired.
*/
public static final int NO_ROUTE_TO_DESTINATION = 3;
- /** The channel most recently identified is not acceptable to the sending entity for
- * use in this call
+ /**
+ * The channel most recently identified is not acceptable to the sending entity for use in this
+ * call.
*/
public static final int CHANNEL_UNACCEPTABLE = 6;
- /** The MS has tried to access a service that the MS's network operator or service
- * provider is not prepared to allow
+ /**
+ * The mobile station (MS) has tried to access a service that the MS's network operator or
+ * service provider is not prepared to allow.
*/
public static final int OPERATOR_DETERMINED_BARRING = 8;
- /** One of the users involved in the call has requested that the call is cleared */
+ /** One of the users involved in the call has requested that the call is cleared. */
public static final int NORMAL = 16;
- /** The called user is unable to accept another call */
+ /** The called user is unable to accept another call. */
public static final int BUSY = 17;
- /** The user does not respond to a call establishment message with either an alerting
- * or connect indication within the prescribed period of time allocated
+ /**
+ * The user does not respond to a call establishment message with either an alerting or connect
+ * indication within the prescribed period of time allocated.
*/
public static final int NO_USER_RESPONDING = 18;
- /** The user has provided an alerting indication but has not provided a connect
- * indication within a prescribed period of time
+ /**
+ * The user has provided an alerting indication but has not provided a connect indication
+ * within a prescribed period of time.
*/
public static final int NO_ANSWER_FROM_USER = 19;
- /** The equipment sending this cause does not wish to accept this call */
+ /** The equipment sending this cause does not wish to accept this call. */
public static final int CALL_REJECTED = 21;
- /** The called number is no longer assigned */
+ /** The called number is no longer assigned. */
public static final int NUMBER_CHANGED = 22;
- /** This cause is returned to the network when a mobile station clears an active
- * call which is being pre-empted by another call with higher precedence
+ /**
+ * This cause is returned to the network when a mobile station clears an active call which is
+ * being pre-empted by another call with higher precedence.
*/
public static final int PREEMPTION = 25;
- /** The destination indicated by the mobile station cannot be reached because
- * the interface to the destination is not functioning correctly
+ /**
+ * The destination indicated by the mobile station cannot be reached because the interface to
+ * the destination is not functioning correctly.
*/
public static final int DESTINATION_OUT_OF_ORDER = 27;
- /** The called party number is not a valid format or is not complete */
+ /** The called party number is not a valid format or is not complete. */
public static final int INVALID_NUMBER_FORMAT = 28;
- /** The facility requested by user can not be provided by the network */
+ /** The facility requested by user can not be provided by the network. */
public static final int FACILITY_REJECTED = 29;
- /** Provided in response to a STATUS ENQUIRY message */
+ /** Provided in response to a STATUS ENQUIRY message. */
public static final int STATUS_ENQUIRY = 30;
- /** Reports a normal disconnect only when no other normal cause applies */
+ /** Reports a normal disconnect only when no other normal cause applies. */
public static final int NORMAL_UNSPECIFIED = 31;
- /** There is no channel presently available to handle the call */
+ /** There is no channel presently available to handle the call. */
public static final int NO_CIRCUIT_AVAIL = 34;
- /** The network is not functioning correctly and that the condition is likely
- * to last a relatively long period of time
+ /**
+ * The network is not functioning correctly and that the condition is likely to last a
+ * relatively long period of time.
*/
public static final int NETWORK_OUT_OF_ORDER = 38;
/**
- * The network is not functioning correctly and the condition is not likely to last
- * a long period of time
+ * The network is not functioning correctly and the condition is not likely to last a long
+ * period of time.
*/
public static final int TEMPORARY_FAILURE = 41;
- /** The switching equipment is experiencing a period of high traffic */
+ /** The switching equipment is experiencing a period of high traffic. */
public static final int SWITCHING_CONGESTION = 42;
- /** The network could not deliver access information to the remote user as requested */
+ /** The network could not deliver access information to the remote user as requested. */
public static final int ACCESS_INFORMATION_DISCARDED = 43;
- /** The channel cannot be provided */
+ /** The channel cannot be provided. */
public static final int CHANNEL_NOT_AVAIL = 44;
- /** This cause is used to report a resource unavailable event only when no other
- * cause in the resource unavailable class applies
+ /**
+ * This cause is used to report a resource unavailable event only when no other cause in the
+ * resource unavailable class applies.
*/
public static final int RESOURCES_UNAVAILABLE_OR_UNSPECIFIED = 47;
- /** The requested quality of service (ITU-T X.213) cannot be provided */
+ /** The requested quality of service (ITU-T X.213) cannot be provided. */
public static final int QOS_NOT_AVAIL = 49;
- /** The facility could not be provided by the network because the user has no
- * complete subscription
+ /**
+ * The facility could not be provided by the network because the user has no complete
+ * subscription.
*/
public static final int REQUESTED_FACILITY_NOT_SUBSCRIBED = 50;
- /** Incoming calls are not allowed within this CUG */
+ /** Incoming calls are not allowed within this calling user group (CUG). */
public static final int INCOMING_CALLS_BARRED_WITHIN_CUG = 55;
- /** The mobile station is not authorized to use bearer capability requested */
+ /** The mobile station is not authorized to use bearer capability requested. */
public static final int BEARER_CAPABILITY_NOT_AUTHORIZED = 57;
- /** The requested bearer capability is not available at this time */
+ /** The requested bearer capability is not available at this time. */
public static final int BEARER_NOT_AVAIL = 58;
- /** The service option is not availble at this time */
+ /** The service option is not availble at this time. */
public static final int SERVICE_OPTION_NOT_AVAILABLE = 63;
- /** The equipment sending this cause does not support the bearer capability requested */
+ /** The equipment sending this cause does not support the bearer capability requested. */
public static final int BEARER_SERVICE_NOT_IMPLEMENTED = 65;
- /** The call clearing is due to ACM being greater than or equal to ACMmax */
+ /** The call clearing is due to ACM being greater than or equal to ACMmax. */
public static final int ACM_LIMIT_EXCEEDED = 68;
- /** The equipment sending this cause does not support the requested facility */
+ /** The equipment sending this cause does not support the requested facility. */
public static final int REQUESTED_FACILITY_NOT_IMPLEMENTED = 69;
- /** The equipment sending this cause only supports the restricted version of
- * the requested bearer capability
+ /**
+ * The equipment sending this cause only supports the restricted version of the requested bearer
+ * capability.
*/
public static final int ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE = 70;
- /** The service requested is not implemented at network */
+ /** The service requested is not implemented at network. */
public static final int SERVICE_OR_OPTION_NOT_IMPLEMENTED = 79;
- /** The equipment sending this cause has received a message with a transaction identifier
- * which is not currently in use on the MS-network interface
+ /**
+ * The equipment sending this cause has received a message with a transaction identifier
+ * which is not currently in use on the mobile station network interface.
*/
public static final int INVALID_TRANSACTION_IDENTIFIER = 81;
- /** The called user for the incoming CUG call is not a member of the specified CUG */
+ /**
+ * The called user for the incoming CUG call is not a member of the specified calling user
+ * group (CUG).
+ */
public static final int USER_NOT_MEMBER_OF_CUG = 87;
- /** The equipment sending this cause has received a request which can't be accomodated */
+ /** The equipment sending this cause has received a request which can't be accomodated. */
public static final int INCOMPATIBLE_DESTINATION = 88;
- /** This cause is used to report receipt of a message with semantically incorrect contents */
+ /** This cause is used to report receipt of a message with semantically incorrect contents. */
public static final int SEMANTICALLY_INCORRECT_MESSAGE = 95;
- /** The equipment sending this cause has received a message with a non-semantical
- * mandatory IE error
+ /**
+ * The equipment sending this cause has received a message with a non-semantical mandatory
+ * information element (IE) error.
*/
public static final int INVALID_MANDATORY_INFORMATION = 96;
- /** This is sent in response to a message which is not defined, or defined but not
- * implemented by the equipment sending this cause
+ /**
+ * This is sent in response to a message which is not defined, or defined but not implemented
+ * by the equipment sending this cause.
*/
public static final int MESSAGE_TYPE_NON_IMPLEMENTED = 97;
- /** The equipment sending this cause has received a message not compatible with the
- * protocol state
+ /**
+ * The equipment sending this cause has received a message not compatible with the protocol
+ * state.
*/
public static final int MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98;
- /** The equipment sending this cause has received a message which includes information
- * elements not recognized because its identifier is not defined or it is defined but not
- * implemented by the equipment sending the cause
+ /**
+ * The equipment sending this cause has received a message which includes information
+ * elements not recognized because its identifier is not defined or it is defined but not
+ * implemented by the equipment sending the cause.
*/
public static final int INFORMATION_ELEMENT_NON_EXISTENT = 99;
- /** The equipment sending this cause has received a message with conditional IE errors */
+ /** The equipment sending this cause has received a message with conditional IE errors. */
public static final int CONDITIONAL_IE_ERROR = 100;
- /** The message has been received which is incompatible with the protocol state */
+ /** The message has been received which is incompatible with the protocol state. */
public static final int MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101;
- /** The procedure has been initiated by the expiry of a timer in association with
- * 3GPP TS 24.008 error handling procedures
+ /**
+ * The procedure has been initiated by the expiry of a timer in association with
+ * 3GPP TS 24.008 error handling procedures.
*/
public static final int RECOVERY_ON_TIMER_EXPIRED = 102;
- /** This protocol error event is reported only when no other cause in the protocol
- * error class applies
+ /**
+ * This protocol error event is reported only when no other cause in the protocol error class
+ * applies.
*/
public static final int PROTOCOL_ERROR_UNSPECIFIED = 111;
- /** interworking with a network which does not provide causes for actions it takes
- * thus, the precise cause for a message which is being sent cannot be ascertained
+ /**
+ * Interworking with a network which does not provide causes for actions it takes thus, the
+ * precise cause for a message which is being sent cannot be ascertained.
*/
public static final int INTERWORKING_UNSPECIFIED = 127;
- /** The call is restricted */
+ /** The call is restricted. */
public static final int CALL_BARRED = 240;
- /** The call is blocked by the Fixed Dialing Number list */
+ /** The call is blocked by the Fixed Dialing Number list. */
public static final int FDN_BLOCKED = 241;
- /** The given IMSI is not known at the VLR */
- /** TS 24.008 cause 4 */
+ /** The given IMSI is not known at the Visitor Location Register (VLR) TS 24.008 cause . */
public static final int IMSI_UNKNOWN_IN_VLR = 242;
/**
* The network does not accept emergency call establishment using an IMEI or not accept attach
- * procedure for emergency services using an IMEI
+ * procedure for emergency services using an IMEI.
*/
public static final int IMEI_NOT_ACCEPTED = 243;
- /** The call cannot be established because RADIO is OFF */
+ /** The call cannot be established because RADIO is OFF. */
public static final int RADIO_OFF = 247;
- /** The call cannot be established because of no cell coverage */
+ /** The call cannot be established because of no cell coverage. */
public static final int OUT_OF_SRV = 248;
- /** The call cannot be established because of no valid SIM */
+ /** The call cannot be established because of no valid SIM. */
public static final int NO_VALID_SIM = 249;
- /** The call is dropped or failed internally by modem */
+ /** The call is dropped or failed internally by modem. */
public static final int RADIO_INTERNAL_ERROR = 250;
- /** Call failed because of UE timer expired while waiting for a response from network */
+ /** Call failed because of UE timer expired while waiting for a response from network. */
public static final int NETWORK_RESP_TIMEOUT = 251;
- /** Call failed because of a network reject */
+ /** Call failed because of a network reject. */
public static final int NETWORK_REJECT = 252;
- /** Call failed because of radio access failure. ex. RACH failure */
+ /** Call failed because of radio access failure. ex. RACH failure. */
public static final int RADIO_ACCESS_FAILURE = 253;
- /** Call failed/dropped because of a RLF */
+ /** Call failed/dropped because of a Radio Link Failure (RLF). */
public static final int RADIO_LINK_FAILURE = 254;
- /** Call failed/dropped because of radio link lost */
+ /** Call failed/dropped because of radio link lost. */
public static final int RADIO_LINK_LOST = 255;
- /** Call failed because of a radio uplink issue */
+ /** Call failed because of a radio uplink issue. */
public static final int RADIO_UPLINK_FAILURE = 256;
- /** Call failed because of a RRC connection setup failure */
+ /** Call failed because of a RRC (Radio Resource Control) connection setup failure. */
public static final int RADIO_SETUP_FAILURE = 257;
- /** Call failed/dropped because of RRC connection release from NW */
+ /** Call failed/dropped because of RRC (Radio Resource Control) connection release from NW. */
public static final int RADIO_RELEASE_NORMAL = 258;
- /** Call failed/dropped because of RRC abnormally released by modem/network */
+ /**
+ * Call failed/dropped because of RRC (Radio Resource Control) abnormally released by
+ * modem/network.
+ */
public static final int RADIO_RELEASE_ABNORMAL = 259;
- /** Call setup failed because of access class barring */
+ /** Call setup failed because of access class barring. */
public static final int ACCESS_CLASS_BLOCKED = 260;
- /** Call failed/dropped because of a network detach */
+ /** Call failed/dropped because of a network detach. */
public static final int NETWORK_DETACH = 261;
- /** MS is locked until next power cycle */
+ /** Mobile station (MS) is locked until next power cycle. */
public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000;
- /** Drop call*/
+ /** Drop call. */
public static final int CDMA_DROP = 1001;
- /** INTERCEPT order received, MS state idle entered */
+ /** INTERCEPT order received, Mobile station (MS) state idle entered. */
public static final int CDMA_INTERCEPT = 1002;
- /** MS has been redirected, call is cancelled */
+ /** Mobile station (MS) has been redirected, call is cancelled. */
public static final int CDMA_REORDER = 1003;
- /** Service option rejection */
+ /** Service option rejection. */
public static final int CDMA_SO_REJECT = 1004;
- /** Requested service is rejected, retry delay is set */
+ /** Requested service is rejected, retry delay is set. */
public static final int CDMA_RETRY_ORDER = 1005;
- /** Unable to obtain access to the CDMA system */
+ /** Unable to obtain access to the CDMA system. */
public static final int CDMA_ACCESS_FAILURE = 1006;
- /** Not a preempted call */
+ /** Not a preempted call. */
public static final int CDMA_PREEMPTED = 1007;
- /** Not an emergency call */
+ /** Not an emergency call. */
public static final int CDMA_NOT_EMERGENCY = 1008;
- /** Access Blocked by CDMA network */
+ /** Access Blocked by CDMA network. */
public static final int CDMA_ACCESS_BLOCKED = 1009;
/** Mapped from ImsReasonInfo */
+ // TODO: remove ImsReasonInfo from preciseDisconnectCause
/* The passed argument is an invalid */
+ /** @hide */
public static final int LOCAL_ILLEGAL_ARGUMENT = 1200;
// The operation is invoked in invalid call state
+ /** @hide */
public static final int LOCAL_ILLEGAL_STATE = 1201;
// IMS service internal error
+ /** @hide */
public static final int LOCAL_INTERNAL_ERROR = 1202;
// IMS service goes down (service connection is lost)
+ /** @hide */
public static final int LOCAL_IMS_SERVICE_DOWN = 1203;
// No pending incoming call exists
+ /** @hide */
public static final int LOCAL_NO_PENDING_CALL = 1204;
// Service unavailable; by power off
+ /** @hide */
public static final int LOCAL_POWER_OFF = 1205;
// Service unavailable; by low battery
+ /** @hide */
public static final int LOCAL_LOW_BATTERY = 1206;
// Service unavailable; by out of service (data service state)
+ /** @hide */
public static final int LOCAL_NETWORK_NO_SERVICE = 1207;
/* Service unavailable; by no LTE coverage
* (VoLTE is not supported even though IMS is registered)
*/
+ /** @hide */
public static final int LOCAL_NETWORK_NO_LTE_COVERAGE = 1208;
/** Service unavailable; by located in roaming area */
+ /** @hide */
public static final int LOCAL_NETWORK_ROAMING = 1209;
/** Service unavailable; by IP changed */
+ /** @hide */
public static final int LOCAL_NETWORK_IP_CHANGED = 1210;
/** Service unavailable; other */
+ /** @hide */
public static final int LOCAL_SERVICE_UNAVAILABLE = 1211;
/* Service unavailable; IMS connection is lost (IMS is not registered) */
+ /** @hide */
public static final int LOCAL_NOT_REGISTERED = 1212;
/** Max call exceeded */
+ /** @hide */
public static final int LOCAL_MAX_CALL_EXCEEDED = 1213;
/** Call decline */
+ /** @hide */
public static final int LOCAL_CALL_DECLINE = 1214;
/** SRVCC is in progress */
+ /** @hide */
public static final int LOCAL_CALL_VCC_ON_PROGRESSING = 1215;
/** Resource reservation is failed (QoS precondition) */
+ /** @hide */
public static final int LOCAL_CALL_RESOURCE_RESERVATION_FAILED = 1216;
/** Retry CS call; VoLTE service can't be provided by the network or remote end
* Resolve the extra code(EXTRA_CODE_CALL_RETRY_*) if the below code is set
+ * @hide
*/
public static final int LOCAL_CALL_CS_RETRY_REQUIRED = 1217;
/** Retry VoLTE call; VoLTE service can't be provided by the network temporarily */
+ /** @hide */
public static final int LOCAL_CALL_VOLTE_RETRY_REQUIRED = 1218;
/** IMS call is already terminated (in TERMINATED state) */
+ /** @hide */
public static final int LOCAL_CALL_TERMINATED = 1219;
/** Handover not feasible */
+ /** @hide */
public static final int LOCAL_HO_NOT_FEASIBLE = 1220;
/** 1xx waiting timer is expired after sending INVITE request (MO only) */
+ /** @hide */
public static final int TIMEOUT_1XX_WAITING = 1221;
/** User no answer during call setup operation (MO/MT)
* MO : 200 OK to INVITE request is not received,
* MT : No action from user after alerting the call
+ * @hide
*/
public static final int TIMEOUT_NO_ANSWER = 1222;
/** User no answer during call update operation (MO/MT)
* MO : 200 OK to re-INVITE request is not received,
* MT : No action from user after alerting the call
+ * @hide
*/
public static final int TIMEOUT_NO_ANSWER_CALL_UPDATE = 1223;
@@ -296,102 +346,142 @@
* STATUSCODE (SIP response code) (IMS -> Telephony)
*/
/** SIP request is redirected */
+ /** @hide */
public static final int SIP_REDIRECTED = 1300;
/** 4xx responses */
/** 400 : Bad Request */
+ /** @hide */
public static final int SIP_BAD_REQUEST = 1310;
/** 403 : Forbidden */
+ /** @hide */
public static final int SIP_FORBIDDEN = 1311;
/** 404 : Not Found */
+ /** @hide */
public static final int SIP_NOT_FOUND = 1312;
/** 415 : Unsupported Media Type
* 416 : Unsupported URI Scheme
* 420 : Bad Extension
*/
+ /** @hide */
public static final int SIP_NOT_SUPPORTED = 1313;
/** 408 : Request Timeout */
+ /** @hide */
public static final int SIP_REQUEST_TIMEOUT = 1314;
/** 480 : Temporarily Unavailable */
+ /** @hide */
public static final int SIP_TEMPRARILY_UNAVAILABLE = 1315;
/** 484 : Address Incomplete */
+ /** @hide */
public static final int SIP_BAD_ADDRESS = 1316;
/** 486 : Busy Here
* 600 : Busy Everywhere
*/
+ /** @hide */
public static final int SIP_BUSY = 1317;
/** 487 : Request Terminated */
+ /** @hide */
public static final int SIP_REQUEST_CANCELLED = 1318;
/** 406 : Not Acceptable
* 488 : Not Acceptable Here
* 606 : Not Acceptable
*/
+ /** @hide */
public static final int SIP_NOT_ACCEPTABLE = 1319;
/** 410 : Gone
* 604 : Does Not Exist Anywhere
*/
+ /** @hide */
public static final int SIP_NOT_REACHABLE = 1320;
/** Others */
+ /** @hide */
public static final int SIP_CLIENT_ERROR = 1321;
/** 481 : Transaction Does Not Exist */
+ /** @hide */
public static final int SIP_TRANSACTION_DOES_NOT_EXIST = 1322;
/** 5xx responses
* 501 : Server Internal Error
*/
+ /** @hide */
public static final int SIP_SERVER_INTERNAL_ERROR = 1330;
/** 503 : Service Unavailable */
+ /** @hide */
public static final int SIP_SERVICE_UNAVAILABLE = 1331;
/** 504 : Server Time-out */
+ /** @hide */
public static final int SIP_SERVER_TIMEOUT = 1332;
/** Others */
+ /** @hide */
public static final int SIP_SERVER_ERROR = 1333;
/** 6xx responses
* 603 : Decline
*/
+ /** @hide */
public static final int SIP_USER_REJECTED = 1340;
/** Others */
+ /** @hide */
public static final int SIP_GLOBAL_ERROR = 1341;
/** Emergency failure */
+ /** @hide */
public static final int EMERGENCY_TEMP_FAILURE = 1342;
+ /** @hide */
public static final int EMERGENCY_PERM_FAILURE = 1343;
/** Media resource initialization failed */
+ /** @hide */
public static final int MEDIA_INIT_FAILED = 1400;
/** RTP timeout (no audio / video traffic in the session) */
+ /** @hide */
public static final int MEDIA_NO_DATA = 1401;
/** Media is not supported; so dropped the call */
+ /** @hide */
public static final int MEDIA_NOT_ACCEPTABLE = 1402;
/** Unknown media related errors */
+ /** @hide */
public static final int MEDIA_UNSPECIFIED = 1403;
/** User triggers the call end */
+ /** @hide */
public static final int USER_TERMINATED = 1500;
/** No action while an incoming call is ringing */
+ /** @hide */
public static final int USER_NOANSWER = 1501;
/** User ignores an incoming call */
+ /** @hide */
public static final int USER_IGNORE = 1502;
/** User declines an incoming call */
+ /** @hide */
public static final int USER_DECLINE = 1503;
/** Device declines/ends a call due to low battery */
+ /** @hide */
public static final int LOW_BATTERY = 1504;
/** Device declines call due to blacklisted call ID */
+ /** @hide */
public static final int BLACKLISTED_CALL_ID = 1505;
/** The call is terminated by the network or remote user */
+ /** @hide */
public static final int USER_TERMINATED_BY_REMOTE = 1510;
/**
* UT
*/
+ /** @hide */
public static final int UT_NOT_SUPPORTED = 1800;
+ /** @hide */
public static final int UT_SERVICE_UNAVAILABLE = 1801;
+ /** @hide */
public static final int UT_OPERATION_NOT_ALLOWED = 1802;
+ /** @hide */
public static final int UT_NETWORK_ERROR = 1803;
+ /** @hide */
public static final int UT_CB_PASSWORD_MISMATCH = 1804;
/**
* ECBM
+ * @hide
*/
public static final int ECBM_NOT_SUPPORTED = 1900;
/**
* Fail code used to indicate that Multi-endpoint is not supported by the Ims framework.
+ * @hide
*/
public static final int MULTIENDPOINT_NOT_SUPPORTED = 1901;
@@ -405,56 +495,68 @@
* active wifi call and at the edge of coverage and there is no qualified LTE network available
* to handover the call to. We get a handover NOT_TRIGERRED message from the modem. This error
* code is received as part of the handover message.
+ * @hide
*/
public static final int CALL_DROP_IWLAN_TO_LTE_UNAVAILABLE = 2000;
/**
* MT call has ended due to a release from the network
* because the call was answered elsewhere
+ * @hide
*/
public static final int ANSWERED_ELSEWHERE = 2100;
/**
* For MultiEndpoint - Call Pull request has failed
+ * @hide
*/
public static final int CALL_PULL_OUT_OF_SYNC = 2101;
/**
* For MultiEndpoint - Call has been pulled from primary to secondary
+ * @hide
*/
public static final int CALL_PULLED = 2102;
/**
* Supplementary services (HOLD/RESUME) failure error codes.
* Values for Supplemetary services failure - Failed, Cancelled and Re-Invite collision.
+ * @hide
*/
public static final int SUPP_SVC_FAILED = 2300;
+ /** @hide */
public static final int SUPP_SVC_CANCELLED = 2301;
+ /** @hide */
public static final int SUPP_SVC_REINVITE_COLLISION = 2302;
/**
* DPD Procedure received no response or send failed
+ * @hide
*/
public static final int IWLAN_DPD_FAILURE = 2400;
/**
* Establishment of the ePDG Tunnel Failed
+ * @hide
*/
public static final int EPDG_TUNNEL_ESTABLISH_FAILURE = 2500;
/**
* Re-keying of the ePDG Tunnel Failed; may not always result in teardown
+ * @hide
*/
public static final int EPDG_TUNNEL_REKEY_FAILURE = 2501;
/**
* Connection to the packet gateway is lost
+ * @hide
*/
public static final int EPDG_TUNNEL_LOST_CONNECTION = 2502;
/**
* The maximum number of calls allowed has been reached. Used in a multi-endpoint scenario
* where the number of calls across all connected devices has reached the maximum.
+ * @hide
*/
public static final int MAXIMUM_NUMBER_OF_CALLS_REACHED = 2503;
@@ -462,21 +564,25 @@
* Similar to {@link #CODE_LOCAL_CALL_DECLINE}, except indicates that a remote device has
* declined the call. Used in a multi-endpoint scenario where a remote device declined an
* incoming call.
+ * @hide
*/
public static final int REMOTE_CALL_DECLINE = 2504;
/**
* Indicates the call was disconnected due to the user reaching their data limit.
+ * @hide
*/
public static final int DATA_LIMIT_REACHED = 2505;
/**
* Indicates the call was disconnected due to the user disabling cellular data.
+ * @hide
*/
public static final int DATA_DISABLED = 2506;
/**
* Indicates a call was disconnected due to loss of wifi signal.
+ * @hide
*/
public static final int WIFI_LOST = 2507;
@@ -499,7 +605,7 @@
public static final int OEM_CAUSE_14 = 0xf00e;
public static final int OEM_CAUSE_15 = 0xf00f;
- /** Disconnected due to unspecified reasons */
+ /** Disconnected due to unspecified reasons. */
public static final int ERROR_UNSPECIFIED = 0xffff;
/** Private constructor to avoid class instantiation. */
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 13fbeaa..ca0c854 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -118,6 +118,13 @@
*/
public static final int FREQUENCY_RANGE_MMWAVE = 4;
+ private static final List<Integer> FREQUENCY_RANGE_ORDER = Arrays.asList(
+ FREQUENCY_RANGE_UNKNOWN,
+ FREQUENCY_RANGE_LOW,
+ FREQUENCY_RANGE_MID,
+ FREQUENCY_RANGE_HIGH,
+ FREQUENCY_RANGE_MMWAVE);
+
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = "DUPLEX_MODE_",
@@ -1835,4 +1842,13 @@
mNetworkRegistrationStates.add(regState);
}
}
+
+ /**
+ * @hide
+ */
+ public static final int getBetterNRFrequencyRange(int range1, int range2) {
+ return FREQUENCY_RANGE_ORDER.indexOf(range1) > FREQUENCY_RANGE_ORDER.indexOf(range2)
+ ? range1
+ : range2;
+ }
}
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index 240b8a9..ef185c5 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -16,16 +16,14 @@
package android.telephony;
+import android.annotation.NonNull;
import android.annotation.UnsupportedAppUsage;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
-import android.telephony.CarrierConfigManager;
-import android.util.Log;
+import android.os.PersistableBundle;
-import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Objects;
/**
@@ -59,6 +57,8 @@
/** @hide */
@UnsupportedAppUsage
public static final int NUM_SIGNAL_STRENGTH_BINS = 5;
+
+ /** SIGNAL_STRENGTH_NAMES is currently used by BatteryStats, but to-be-removed soon. */
/** @hide */
public static final String[] SIGNAL_STRENGTH_NAMES = {
"none", "poor", "moderate", "good", "great"
@@ -72,66 +72,22 @@
public static final int INVALID = Integer.MAX_VALUE;
private static final int LTE_RSRP_THRESHOLDS_NUM = 4;
- private static final int MAX_LTE_RSRP = -44;
- private static final int MIN_LTE_RSRP = -140;
private static final int WCDMA_RSCP_THRESHOLDS_NUM = 4;
- private static final int MAX_WCDMA_RSCP = -24;
- private static final int MIN_WCDMA_RSCP = -120;
/* The type of signal measurement */
- private static final String MEASUMENT_TYPE_RSCP = "rscp";
+ private static final String MEASUREMENT_TYPE_RSCP = "rscp";
- /** Parameters reported by the Radio */
- @UnsupportedAppUsage
- private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
- @UnsupportedAppUsage
- private int mGsmBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5
- @UnsupportedAppUsage
- private int mCdmaDbm; // This value is the RSSI value
- @UnsupportedAppUsage
- private int mCdmaEcio; // This value is the Ec/Io
- @UnsupportedAppUsage
- private int mEvdoDbm; // This value is the EVDO RSSI value
- @UnsupportedAppUsage
- private int mEvdoEcio; // This value is the EVDO Ec/Io
- @UnsupportedAppUsage
- private int mEvdoSnr; // Valid values are 0-8. 8 is the highest signal to noise ratio
- @UnsupportedAppUsage
- private int mLteSignalStrength;
- @UnsupportedAppUsage
- private int mLteRsrp;
- @UnsupportedAppUsage
- private int mLteRsrq;
- @UnsupportedAppUsage
- private int mLteRssnr;
- @UnsupportedAppUsage
- private int mLteCqi;
- @UnsupportedAppUsage
- private int mTdScdmaRscp; // Valid values are -24...-120dBm or INVALID if unknown
- private int mWcdmaSignalStrength;
- private int mWcdmaRscpAsu; // the WCDMA RSCP in ASU as reported from the HAL
- @UnsupportedAppUsage
- private int mWcdmaRscp; // the WCDMA RSCP in dBm
+ CellSignalStrengthCdma mCdma;
+ CellSignalStrengthGsm mGsm;
+ CellSignalStrengthWcdma mWcdma;
+ CellSignalStrengthTdscdma mTdscdma;
+ CellSignalStrengthLte mLte;
/** Parameters from the framework */
@UnsupportedAppUsage
private int mLteRsrpBoost; // offset to be reduced from the rsrp threshold while calculating
// signal strength level
- private boolean mIsGsm; // This value is set by the ServiceStateTracker
- // onSignalStrengthResult.
- private boolean mUseOnlyRsrpForLteLevel; // Use only RSRP for the number of LTE signal bar.
-
- // The threshold of LTE RSRP for determining the display level of LTE signal bar. Note that the
- // min and max are fixed at MIN_LTE_RSRP (-140) and MAX_LTE_RSRP (-44).
- private int mLteRsrpThresholds[] = new int[LTE_RSRP_THRESHOLDS_NUM];
-
- // The type of default measurement for determining the display level of WCDMA signal bar.
- private String mWcdmaDefaultSignalMeasurement;
-
- // The threshold of WCDMA RSCP for determining the display level of WCDMA signal bar. Note that
- // the min and max are fixed at MIN_WCDMA_RSCP (-120) and MAX_WCDMA_RSCP (-24).
- private int mWcdmaRscpThresholds[] = new int[WCDMA_RSCP_THRESHOLDS_NUM];
/**
* Create a new SignalStrength from a intent notifier Bundle
@@ -153,47 +109,17 @@
}
/**
- * Empty constructor
- *
- * @hide
- */
- @UnsupportedAppUsage
- public SignalStrength() {
- this(true);
- }
-
- /**
* This constructor is used to create SignalStrength with default
- * values and set the gsmFlag with the value passed in the input
+ * values.
*
- * @param gsmFlag true if Gsm Phone,false if Cdma phone
* @return newly created SignalStrength
* @hide
*/
@UnsupportedAppUsage
- public SignalStrength(boolean gsmFlag) {
- mGsmSignalStrength = 99;
- mGsmBitErrorRate = -1;
- mCdmaDbm = INVALID;
- mCdmaEcio = -1;
- mEvdoDbm = INVALID;
- mEvdoEcio = -1;
- mEvdoSnr = -1;
- mLteSignalStrength = 99;
- mLteRsrp = INVALID;
- mLteRsrq = INVALID;
- mLteRssnr = INVALID;
- mLteCqi = INVALID;
- mTdScdmaRscp = INVALID;
- mWcdmaSignalStrength = 99;
- mWcdmaRscp = INVALID;
- mWcdmaRscpAsu = 255;
- mLteRsrpBoost = 0;
- mIsGsm = gsmFlag;
- mUseOnlyRsrpForLteLevel = false;
- mWcdmaDefaultSignalMeasurement = "";
- setLteRsrpThresholds(getDefaultLteRsrpThresholds());
- setWcdmaRscpThresholds(getDefaultWcdmaRscpThresholds());
+ public SignalStrength() {
+ this(new CellSignalStrengthCdma(), new CellSignalStrengthGsm(),
+ new CellSignalStrengthWcdma(), new CellSignalStrengthTdscdma(),
+ new CellSignalStrengthLte());
}
/**
@@ -202,68 +128,64 @@
* @hide
*/
public SignalStrength(
- int gsmSignalStrength, int gsmBitErrorRate,
- int cdmaDbm, int cdmaEcio,
- int evdoDbm, int evdoEcio, int evdoSnr,
- int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
- int tdScdmaRscp, int wcdmaSignalStrength, int wcdmaRscpAsu,
- // values Added by config
- int lteRsrpBoost, boolean gsmFlag, boolean lteLevelBaseOnRsrp,
- String wcdmaDefaultMeasurement) {
- mGsmSignalStrength = gsmSignalStrength;
- mGsmBitErrorRate = gsmBitErrorRate;
- mCdmaDbm = cdmaDbm;
- mCdmaEcio = cdmaEcio;
- mEvdoDbm = evdoDbm;
- mEvdoEcio = evdoEcio;
- mEvdoSnr = evdoSnr;
- mLteSignalStrength = lteSignalStrength;
- mLteRsrp = lteRsrp;
- mLteRsrq = lteRsrq;
- mLteRssnr = lteRssnr;
- mLteCqi = lteCqi;
- mTdScdmaRscp = INVALID;
- mWcdmaSignalStrength = wcdmaSignalStrength;
- mWcdmaRscpAsu = wcdmaRscpAsu;
- mWcdmaRscp = wcdmaRscpAsu - 120;
- mLteRsrpBoost = lteRsrpBoost;
- mIsGsm = gsmFlag;
- mUseOnlyRsrpForLteLevel = lteLevelBaseOnRsrp;
- mWcdmaDefaultSignalMeasurement = wcdmaDefaultMeasurement;
- setLteRsrpThresholds(getDefaultLteRsrpThresholds());
- setWcdmaRscpThresholds(getDefaultWcdmaRscpThresholds());
- if (DBG) log("initialize: " + toString());
+ @NonNull CellSignalStrengthCdma cdma,
+ @NonNull CellSignalStrengthGsm gsm,
+ @NonNull CellSignalStrengthWcdma wcdma,
+ @NonNull CellSignalStrengthTdscdma tdscdma,
+ @NonNull CellSignalStrengthLte lte) {
+ mCdma = cdma;
+ mGsm = gsm;
+ mWcdma = wcdma;
+ mTdscdma = tdscdma;
+ mLte = lte;
+ mLteRsrpBoost = 0;
}
/**
- * Constructor for only values provided by Radio HAL V1.0
+ * Constructor for Radio HAL V1.0
*
* @hide
*/
- public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
- int cdmaDbm, int cdmaEcio,
- int evdoDbm, int evdoEcio, int evdoSnr,
- int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
- int tdScdmaRscp) {
- this(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
- evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
- lteRsrq, lteRssnr, lteCqi, tdScdmaRscp, 99, INVALID, 0, true, false, "");
+ public SignalStrength(android.hardware.radio.V1_0.SignalStrength signalStrength) {
+ this(new CellSignalStrengthCdma(signalStrength.cdma, signalStrength.evdo),
+ new CellSignalStrengthGsm(signalStrength.gw),
+ new CellSignalStrengthWcdma(),
+ new CellSignalStrengthTdscdma(signalStrength.tdScdma),
+ new CellSignalStrengthLte(signalStrength.lte));
}
/**
- * Constructor for only values provided by Radio HAL V1.2
+ * Constructor for Radio HAL V1.2
*
* @hide
*/
- public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
- int cdmaDbm, int cdmaEcio,
- int evdoDbm, int evdoEcio, int evdoSnr,
- int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
- int tdScdmaRscp, int wcdmaSignalStrength, int wcdmaRscp) {
- this(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
- evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
- lteRsrq, lteRssnr, lteCqi, tdScdmaRscp, wcdmaSignalStrength, wcdmaRscp, 0, true,
- false, "");
+ public SignalStrength(android.hardware.radio.V1_2.SignalStrength signalStrength) {
+ this(new CellSignalStrengthCdma(signalStrength.cdma, signalStrength.evdo),
+ new CellSignalStrengthGsm(signalStrength.gsm),
+ new CellSignalStrengthWcdma(signalStrength.wcdma),
+ new CellSignalStrengthTdscdma(signalStrength.tdScdma),
+ new CellSignalStrengthLte(signalStrength.lte));
+ }
+
+ private CellSignalStrength getPrimary() {
+ // This behavior is intended to replicate the legacy behavior of getLevel() by prioritizing
+ // newer faster RATs for default/for display purposes.
+ if (mLte.isValid()) return mLte;
+ if (mCdma.isValid()) return mCdma;
+ if (mTdscdma.isValid()) return mTdscdma;
+ if (mWcdma.isValid()) return mWcdma;
+ if (mGsm.isValid()) return mGsm;
+ return mLte;
+ }
+
+ /** @hide */
+ public void updateLevel(PersistableBundle cc, ServiceState ss) {
+ mLteRsrpBoost = ss.getLteEarfcnRsrpBoost();
+ mCdma.updateLevel(cc, ss);
+ mGsm.updateLevel(cc, ss);
+ mWcdma.updateLevel(cc, ss);
+ mTdscdma.updateLevel(cc, ss);
+ mLte.updateLevel(cc, ss);
}
/**
@@ -283,28 +205,12 @@
*/
@UnsupportedAppUsage
protected void copyFrom(SignalStrength s) {
- mGsmSignalStrength = s.mGsmSignalStrength;
- mGsmBitErrorRate = s.mGsmBitErrorRate;
- mCdmaDbm = s.mCdmaDbm;
- mCdmaEcio = s.mCdmaEcio;
- mEvdoDbm = s.mEvdoDbm;
- mEvdoEcio = s.mEvdoEcio;
- mEvdoSnr = s.mEvdoSnr;
- mLteSignalStrength = s.mLteSignalStrength;
- mLteRsrp = s.mLteRsrp;
- mLteRsrq = s.mLteRsrq;
- mLteRssnr = s.mLteRssnr;
- mLteCqi = s.mLteCqi;
- mTdScdmaRscp = s.mTdScdmaRscp;
- mWcdmaSignalStrength = s.mWcdmaSignalStrength;
- mWcdmaRscpAsu = s.mWcdmaRscpAsu;
- mWcdmaRscp = s.mWcdmaRscp;
+ mCdma = new CellSignalStrengthCdma(s.mCdma);
+ mGsm = new CellSignalStrengthGsm(s.mGsm);
+ mWcdma = new CellSignalStrengthWcdma(s.mWcdma);
+ mTdscdma = new CellSignalStrengthTdscdma(s.mTdscdma);
+ mLte = new CellSignalStrengthLte(s.mLte);
mLteRsrpBoost = s.mLteRsrpBoost;
- mIsGsm = s.mIsGsm;
- mUseOnlyRsrpForLteLevel = s.mUseOnlyRsrpForLteLevel;
- mWcdmaDefaultSignalMeasurement = s.mWcdmaDefaultSignalMeasurement;
- setLteRsrpThresholds(s.mLteRsrpThresholds);
- setWcdmaRscpThresholds(s.mWcdmaRscpThresholds);
}
/**
@@ -316,56 +222,25 @@
public SignalStrength(Parcel in) {
if (DBG) log("Size of signalstrength parcel:" + in.dataSize());
- mGsmSignalStrength = in.readInt();
- mGsmBitErrorRate = in.readInt();
- mCdmaDbm = in.readInt();
- mCdmaEcio = in.readInt();
- mEvdoDbm = in.readInt();
- mEvdoEcio = in.readInt();
- mEvdoSnr = in.readInt();
- mLteSignalStrength = in.readInt();
- mLteRsrp = in.readInt();
- mLteRsrq = in.readInt();
- mLteRssnr = in.readInt();
- mLteCqi = in.readInt();
- mTdScdmaRscp = in.readInt();
- mWcdmaSignalStrength = in.readInt();
- mWcdmaRscpAsu = in.readInt();
- mWcdmaRscp = in.readInt();
+ mCdma = in.readParcelable(CellSignalStrengthCdma.class.getClassLoader());
+ mGsm = in.readParcelable(CellSignalStrengthGsm.class.getClassLoader());
+ mWcdma = in.readParcelable(CellSignalStrengthWcdma.class.getClassLoader());
+ mTdscdma = in.readParcelable(CellSignalStrengthTdscdma.class.getClassLoader());
+ mLte = in.readParcelable(CellSignalStrengthLte.class.getClassLoader());
mLteRsrpBoost = in.readInt();
- mIsGsm = in.readBoolean();
- mUseOnlyRsrpForLteLevel = in.readBoolean();
- mWcdmaDefaultSignalMeasurement = in.readString();
- in.readIntArray(mLteRsrpThresholds);
- in.readIntArray(mWcdmaRscpThresholds);
}
/**
* {@link Parcelable#writeToParcel}
*/
public void writeToParcel(Parcel out, int flags) {
- out.writeInt(mGsmSignalStrength);
- out.writeInt(mGsmBitErrorRate);
- out.writeInt(mCdmaDbm);
- out.writeInt(mCdmaEcio);
- out.writeInt(mEvdoDbm);
- out.writeInt(mEvdoEcio);
- out.writeInt(mEvdoSnr);
- out.writeInt(mLteSignalStrength);
- out.writeInt(mLteRsrp);
- out.writeInt(mLteRsrq);
- out.writeInt(mLteRssnr);
- out.writeInt(mLteCqi);
- out.writeInt(mTdScdmaRscp);
- out.writeInt(mWcdmaSignalStrength);
- out.writeInt(mWcdmaRscpAsu);
- out.writeInt(mWcdmaRscp);
+ out.writeParcelable(mCdma, flags);
+ out.writeParcelable(mGsm, flags);
+ out.writeParcelable(mWcdma, flags);
+ out.writeParcelable(mTdscdma, flags);
+ out.writeParcelable(mLte, flags);
+
out.writeInt(mLteRsrpBoost);
- out.writeBoolean(mIsGsm);
- out.writeBoolean(mUseOnlyRsrpForLteLevel);
- out.writeString(mWcdmaDefaultSignalMeasurement);
- out.writeIntArray(mLteRsrpThresholds);
- out.writeIntArray(mWcdmaRscpThresholds);
}
/**
@@ -392,153 +267,21 @@
};
/**
- * Validate the individual signal strength fields as per the range
- * specified in ril.h
- * Set to invalid any field that is not in the valid range
- * Cdma, evdo, lte rsrp & rsrq values are sign converted
- * when received from ril interface
+ * Get the GSM RSSI in ASU.
*
- * @return
- * Valid values for all signalstrength fields
- * @hide
- */
- @UnsupportedAppUsage
- public void validateInput() {
- if (DBG) log("Signal before validate=" + this);
- // TS 27.007 8.5
- mGsmSignalStrength = mGsmSignalStrength >= 0 ? mGsmSignalStrength : 99;
- mWcdmaSignalStrength = (mWcdmaSignalStrength >= 0) ? mWcdmaSignalStrength : 99;
- mLteSignalStrength = (mLteSignalStrength >= 0) ? mLteSignalStrength : 99;
- // BER no change;
-
- // WCDMA RSCP valid values are -120 through -24 as defined in TS 27.007 8.69
- // but are reported in ASU which is 0 through 96, so we do the conversion here
- mWcdmaRscpAsu =
- ((mWcdmaRscpAsu - 120 >= MIN_WCDMA_RSCP) && (mWcdmaRscpAsu - 120 <= MAX_WCDMA_RSCP))
- ? mWcdmaRscpAsu : 255;
- mWcdmaRscp = ((mWcdmaRscp >= MIN_WCDMA_RSCP) && (mWcdmaRscp <= MAX_WCDMA_RSCP))
- ? mWcdmaRscp : INVALID;
-
- mCdmaDbm = mCdmaDbm > 0 ? -mCdmaDbm : -120;
- mCdmaEcio = (mCdmaEcio >= 0) ? -mCdmaEcio : -160;
-
- mEvdoDbm = (mEvdoDbm > 0) ? -mEvdoDbm : -120;
- mEvdoEcio = (mEvdoEcio >= 0) ? -mEvdoEcio : -160;
- mEvdoSnr = ((mEvdoSnr >= 0) && (mEvdoSnr <= 8)) ? mEvdoSnr : -1;
-
- // TS 36.214 Physical Layer Section 5.1.3, TS 36.331 RRC
- mLteRsrp = ((-mLteRsrp >= MIN_LTE_RSRP) && (-mLteRsrp <= MAX_LTE_RSRP)) ? -mLteRsrp
- : SignalStrength.INVALID;
- mLteRsrq = ((mLteRsrq >= 3) && (mLteRsrq <= 20)) ? -mLteRsrq : SignalStrength.INVALID;
- mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300)) ? mLteRssnr
- : SignalStrength.INVALID;
-
- mTdScdmaRscp = ((mTdScdmaRscp >= 0) && (mTdScdmaRscp <= 96))
- ? (mTdScdmaRscp - 120) : SignalStrength.INVALID;
- // Cqi no change
- if (DBG) log("Signal after validate=" + this);
- }
-
- /**
- * Fix {@link #mIsGsm} based on the signal strength data.
+ * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
*
- * @hide
- */
- public void fixType() {
- mIsGsm = getCdmaRelatedSignalStrength() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- }
-
- /**
- * @param true - Gsm, Lte phones
- * false - Cdma phones
- *
- * Used by voice phone to set the mIsGsm
- * flag
- * @hide
- */
- public void setGsm(boolean gsmFlag) {
- mIsGsm = gsmFlag;
- }
-
- /**
- * @param useOnlyRsrpForLteLevel true if it uses only RSRP for the number of LTE signal bar,
- * otherwise false.
- *
- * Used by phone to use only RSRP or not for the number of LTE signal bar.
- * @hide
- */
- public void setUseOnlyRsrpForLteLevel(boolean useOnlyRsrpForLteLevel) {
- mUseOnlyRsrpForLteLevel = useOnlyRsrpForLteLevel;
- }
-
- /**
- * @param defaultMeasurement sets the type of WCDMA default signal measurement
- *
- * Used by phone to determine default measurement type for calculation WCDMA signal level.
- * @hide
- */
- public void setWcdmaDefaultSignalMeasurement(String defaultMeasurement) {
- mWcdmaDefaultSignalMeasurement = defaultMeasurement;
- }
-
- /**
- * @param lteRsrpBoost - signal strength offset
- *
- * Used by phone to set the lte signal strength offset which will be
- * reduced from rsrp threshold while calculating signal strength level
- *
- * @hide
- */
- public void setLteRsrpBoost(int lteRsrpBoost) {
- mLteRsrpBoost = lteRsrpBoost;
- }
-
- /**
- * Sets the threshold array for determining the display level of LTE signal bar.
- *
- * @param lteRsrpThresholds int array for determining the display level.
- *
- * @hide
- */
- public void setLteRsrpThresholds(int[] lteRsrpThresholds) {
- if ((lteRsrpThresholds == null)
- || (lteRsrpThresholds.length != LTE_RSRP_THRESHOLDS_NUM)) {
- Log.wtf(LOG_TAG, "setLteRsrpThresholds - lteRsrpThresholds is invalid.");
- return;
- }
- System.arraycopy(lteRsrpThresholds, 0, mLteRsrpThresholds, 0, LTE_RSRP_THRESHOLDS_NUM);
- }
-
- /**
- * Get the GSM Signal Strength, valid values are (0-31, 99) as defined in TS
- * 27.007 8.5
+ * @return RSSI in ASU 0..31, 99, or UNAVAILABLE
*/
public int getGsmSignalStrength() {
- return this.mGsmSignalStrength;
+ return mGsm.getAsuLevel();
}
/**
* Get the GSM bit error rate (0-7, 99) as defined in TS 27.007 8.5
*/
public int getGsmBitErrorRate() {
- return this.mGsmBitErrorRate;
- }
-
- /**
- * Sets the threshold array for determining the display level of WCDMA signal bar.
- *
- * @param wcdmaRscpThresholds int array for determining the display level.
- *
- * @hide
- */
- public void setWcdmaRscpThresholds(int[] wcdmaRscpThresholds) {
- if ((wcdmaRscpThresholds == null)
- || (wcdmaRscpThresholds.length != WCDMA_RSCP_THRESHOLDS_NUM)) {
- Log.wtf(LOG_TAG, "setWcdmaRscpThresholds - wcdmaRscpThresholds is invalid.");
- return;
- }
- System.arraycopy(wcdmaRscpThresholds, 0, mWcdmaRscpThresholds, 0,
- WCDMA_RSCP_THRESHOLDS_NUM);
+ return mGsm.getBitErrorRate();
}
/**
@@ -547,14 +290,14 @@
* @return the CDMA RSSI value or {@link #INVALID} if invalid
*/
public int getCdmaDbm() {
- return this.mCdmaDbm;
+ return mCdma.getCdmaDbm();
}
/**
* Get the CDMA Ec/Io value in dB*10
*/
public int getCdmaEcio() {
- return this.mCdmaEcio;
+ return mCdma.getCdmaEcio();
}
/**
@@ -563,51 +306,51 @@
* @return the EVDO RSSI value or {@link #INVALID} if invalid
*/
public int getEvdoDbm() {
- return this.mEvdoDbm;
+ return mCdma.getEvdoDbm();
}
/**
* Get the EVDO Ec/Io value in dB*10
*/
public int getEvdoEcio() {
- return this.mEvdoEcio;
+ return mCdma.getEvdoEcio();
}
/**
* Get the signal to noise ratio. Valid values are 0-8. 8 is the highest.
*/
public int getEvdoSnr() {
- return this.mEvdoSnr;
+ return mCdma.getEvdoSnr();
}
/** @hide */
@UnsupportedAppUsage
public int getLteSignalStrength() {
- return mLteSignalStrength;
+ return mLte.getRssi();
}
/** @hide */
@UnsupportedAppUsage
public int getLteRsrp() {
- return mLteRsrp;
+ return mLte.getRsrp();
}
/** @hide */
@UnsupportedAppUsage
public int getLteRsrq() {
- return mLteRsrq;
+ return mLte.getRsrq();
}
/** @hide */
@UnsupportedAppUsage
public int getLteRssnr() {
- return mLteRssnr;
+ return mLte.getRssnr();
}
/** @hide */
@UnsupportedAppUsage
public int getLteCqi() {
- return mLteCqi;
+ return mLte.getCqi();
}
/** @hide */
@@ -624,9 +367,12 @@
* while 4 represents a very strong signal strength.
*/
public int getLevel() {
- int level = mIsGsm ? getGsmRelatedSignalStrength() : getCdmaRelatedSignalStrength();
- if (DBG) log("getLevel=" + level);
- return level;
+ int level = getPrimary().getLevel();
+ if (level < SIGNAL_STRENGTH_NONE_OR_UNKNOWN || level > SIGNAL_STRENGTH_GREAT) {
+ log("Invalid Level " + level + ", this=" + this);
+ return SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ }
+ return getPrimary().getLevel();
}
/**
@@ -636,33 +382,7 @@
*/
@UnsupportedAppUsage
public int getAsuLevel() {
- int asuLevel = 0;
- if (mIsGsm) {
- if (mLteRsrp != SignalStrength.INVALID) {
- asuLevel = getLteAsuLevel();
- } else if (mTdScdmaRscp != SignalStrength.INVALID) {
- asuLevel = getTdScdmaAsuLevel();
- } else if (mWcdmaRscp != SignalStrength.INVALID) {
- asuLevel = getWcdmaAsuLevel();
- } else {
- asuLevel = getGsmAsuLevel();
- }
- } else {
- int cdmaAsuLevel = getCdmaAsuLevel();
- int evdoAsuLevel = getEvdoAsuLevel();
- if (evdoAsuLevel == 0) {
- /* We don't know evdo use, cdma */
- asuLevel = cdmaAsuLevel;
- } else if (cdmaAsuLevel == 0) {
- /* We don't know cdma use, evdo */
- asuLevel = evdoAsuLevel;
- } else {
- /* We know both, use the lowest level */
- asuLevel = cdmaAsuLevel < evdoAsuLevel ? cdmaAsuLevel : evdoAsuLevel;
- }
- }
- if (DBG) log("getAsuLevel=" + asuLevel);
- return asuLevel;
+ return getPrimary().getAsuLevel();
}
/**
@@ -672,30 +392,7 @@
*/
@UnsupportedAppUsage
public int getDbm() {
- int dBm = INVALID;
-
- if(isGsm()) {
- dBm = getLteDbm();
- if (dBm == INVALID) {
- if (getTdScdmaLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
- if (getWcdmaDbm() == INVALID) {
- dBm = getGsmDbm();
- } else {
- dBm = getWcdmaDbm();
- }
- } else {
- dBm = getTdScdmaDbm();
- }
- }
- } else {
- int cdmaDbm = getCdmaDbm();
- int evdoDbm = getEvdoDbm();
-
- return (evdoDbm == -120) ? cdmaDbm : ((cdmaDbm == -120) ? evdoDbm
- : (cdmaDbm < evdoDbm ? cdmaDbm : evdoDbm));
- }
- if (DBG) log("getDbm=" + dBm);
- return dBm;
+ return getPrimary().getDbm();
}
/**
@@ -705,17 +402,7 @@
*/
@UnsupportedAppUsage
public int getGsmDbm() {
- int dBm;
-
- int gsmSignalStrength = getGsmSignalStrength();
- int asu = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
- if (asu != -1) {
- dBm = -113 + (2 * asu);
- } else {
- dBm = -1;
- }
- if (DBG) log("getGsmDbm=" + dBm);
- return dBm;
+ return mGsm.getDbm();
}
/**
@@ -725,20 +412,7 @@
*/
@UnsupportedAppUsage
public int getGsmLevel() {
- int level;
-
- // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
- // asu = 0 (-113dB or less) is very weak
- // signal, its better to show 0 bars to the user in such cases.
- // asu = 99 is a special case, where the signal strength is unknown.
- int asu = getGsmSignalStrength();
- if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- else if (asu >= 12) level = SIGNAL_STRENGTH_GREAT;
- else if (asu >= 8) level = SIGNAL_STRENGTH_GOOD;
- else if (asu >= 5) level = SIGNAL_STRENGTH_MODERATE;
- else level = SIGNAL_STRENGTH_POOR;
- if (DBG) log("getGsmLevel=" + level);
- return level;
+ return mGsm.getLevel();
}
/**
@@ -748,13 +422,7 @@
*/
@UnsupportedAppUsage
public int getGsmAsuLevel() {
- // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
- // asu = 0 (-113dB or less) is very weak
- // signal, its better to show 0 bars to the user in such cases.
- // asu = 99 is a special case, where the signal strength is unknown.
- int level = getGsmSignalStrength();
- if (DBG) log("getGsmAsuLevel=" + level);
- return level;
+ return mGsm.getAsuLevel();
}
/**
@@ -764,27 +432,7 @@
*/
@UnsupportedAppUsage
public int getCdmaLevel() {
- final int cdmaDbm = getCdmaDbm();
- final int cdmaEcio = getCdmaEcio();
- int levelDbm;
- int levelEcio;
-
- if (cdmaDbm >= -75) levelDbm = SIGNAL_STRENGTH_GREAT;
- else if (cdmaDbm >= -85) levelDbm = SIGNAL_STRENGTH_GOOD;
- else if (cdmaDbm >= -95) levelDbm = SIGNAL_STRENGTH_MODERATE;
- else if (cdmaDbm >= -100) levelDbm = SIGNAL_STRENGTH_POOR;
- else levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-
- // Ec/Io are in dB*10
- if (cdmaEcio >= -90) levelEcio = SIGNAL_STRENGTH_GREAT;
- else if (cdmaEcio >= -110) levelEcio = SIGNAL_STRENGTH_GOOD;
- else if (cdmaEcio >= -130) levelEcio = SIGNAL_STRENGTH_MODERATE;
- else if (cdmaEcio >= -150) levelEcio = SIGNAL_STRENGTH_POOR;
- else levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-
- int level = (levelDbm < levelEcio) ? levelDbm : levelEcio;
- if (DBG) log("getCdmaLevel=" + level);
- return level;
+ return mCdma.getLevel();
}
/**
@@ -794,29 +442,7 @@
*/
@UnsupportedAppUsage
public int getCdmaAsuLevel() {
- final int cdmaDbm = getCdmaDbm();
- final int cdmaEcio = getCdmaEcio();
- int cdmaAsuLevel;
- int ecioAsuLevel;
-
- if (cdmaDbm >= -75) cdmaAsuLevel = 16;
- else if (cdmaDbm >= -82) cdmaAsuLevel = 8;
- else if (cdmaDbm >= -90) cdmaAsuLevel = 4;
- else if (cdmaDbm >= -95) cdmaAsuLevel = 2;
- else if (cdmaDbm >= -100) cdmaAsuLevel = 1;
- else cdmaAsuLevel = 99;
-
- // Ec/Io are in dB*10
- if (cdmaEcio >= -90) ecioAsuLevel = 16;
- else if (cdmaEcio >= -100) ecioAsuLevel = 8;
- else if (cdmaEcio >= -115) ecioAsuLevel = 4;
- else if (cdmaEcio >= -130) ecioAsuLevel = 2;
- else if (cdmaEcio >= -150) ecioAsuLevel = 1;
- else ecioAsuLevel = 99;
-
- int level = (cdmaAsuLevel < ecioAsuLevel) ? cdmaAsuLevel : ecioAsuLevel;
- if (DBG) log("getCdmaAsuLevel=" + level);
- return level;
+ return mCdma.getAsuLevel();
}
/**
@@ -826,26 +452,7 @@
*/
@UnsupportedAppUsage
public int getEvdoLevel() {
- int evdoDbm = getEvdoDbm();
- int evdoSnr = getEvdoSnr();
- int levelEvdoDbm;
- int levelEvdoSnr;
-
- if (evdoDbm >= -65) levelEvdoDbm = SIGNAL_STRENGTH_GREAT;
- else if (evdoDbm >= -75) levelEvdoDbm = SIGNAL_STRENGTH_GOOD;
- else if (evdoDbm >= -90) levelEvdoDbm = SIGNAL_STRENGTH_MODERATE;
- else if (evdoDbm >= -105) levelEvdoDbm = SIGNAL_STRENGTH_POOR;
- else levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-
- if (evdoSnr >= 7) levelEvdoSnr = SIGNAL_STRENGTH_GREAT;
- else if (evdoSnr >= 5) levelEvdoSnr = SIGNAL_STRENGTH_GOOD;
- else if (evdoSnr >= 3) levelEvdoSnr = SIGNAL_STRENGTH_MODERATE;
- else if (evdoSnr >= 1) levelEvdoSnr = SIGNAL_STRENGTH_POOR;
- else levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-
- int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
- if (DBG) log("getEvdoLevel=" + level);
- return level;
+ return mCdma.getEvdoLevel();
}
/**
@@ -855,28 +462,7 @@
*/
@UnsupportedAppUsage
public int getEvdoAsuLevel() {
- int evdoDbm = getEvdoDbm();
- int evdoSnr = getEvdoSnr();
- int levelEvdoDbm;
- int levelEvdoSnr;
-
- if (evdoDbm >= -65) levelEvdoDbm = 16;
- else if (evdoDbm >= -75) levelEvdoDbm = 8;
- else if (evdoDbm >= -85) levelEvdoDbm = 4;
- else if (evdoDbm >= -95) levelEvdoDbm = 2;
- else if (evdoDbm >= -105) levelEvdoDbm = 1;
- else levelEvdoDbm = 99;
-
- if (evdoSnr >= 7) levelEvdoSnr = 16;
- else if (evdoSnr >= 6) levelEvdoSnr = 8;
- else if (evdoSnr >= 5) levelEvdoSnr = 4;
- else if (evdoSnr >= 3) levelEvdoSnr = 2;
- else if (evdoSnr >= 1) levelEvdoSnr = 1;
- else levelEvdoSnr = 99;
-
- int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
- if (DBG) log("getEvdoAsuLevel=" + level);
- return level;
+ return mCdma.getEvdoAsuLevel();
}
/**
@@ -886,7 +472,7 @@
*/
@UnsupportedAppUsage
public int getLteDbm() {
- return mLteRsrp;
+ return mLte.getRsrp();
}
/**
@@ -896,83 +482,7 @@
*/
@UnsupportedAppUsage
public int getLteLevel() {
- /*
- * TS 36.214 Physical Layer Section 5.1.3
- * TS 36.331 RRC
- *
- * RSSI = received signal + noise
- * RSRP = reference signal dBm
- * RSRQ = quality of signal dB = Number of Resource blocks*RSRP/RSSI
- * SNR = gain = signal/noise ratio = -10log P1/P2 dB
- */
- int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, rsrpIconLevel = -1, snrIconLevel = -1;
-
- if (mLteRsrp > MAX_LTE_RSRP || mLteRsrp < MIN_LTE_RSRP) {
- if (mLteRsrp != INVALID) {
- Log.wtf(LOG_TAG, "getLteLevel - invalid lte rsrp: mLteRsrp=" + mLteRsrp);
- }
- } else if (mLteRsrp >= (mLteRsrpThresholds[3] - mLteRsrpBoost)) {
- rsrpIconLevel = SIGNAL_STRENGTH_GREAT;
- } else if (mLteRsrp >= (mLteRsrpThresholds[2] - mLteRsrpBoost)) {
- rsrpIconLevel = SIGNAL_STRENGTH_GOOD;
- } else if (mLteRsrp >= (mLteRsrpThresholds[1] - mLteRsrpBoost)) {
- rsrpIconLevel = SIGNAL_STRENGTH_MODERATE;
- } else if (mLteRsrp >= (mLteRsrpThresholds[0] - mLteRsrpBoost)) {
- rsrpIconLevel = SIGNAL_STRENGTH_POOR;
- } else {
- rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- }
-
- if (useOnlyRsrpForLteLevel()) {
- log("getLTELevel - rsrp = " + rsrpIconLevel);
- if (rsrpIconLevel != -1) {
- return rsrpIconLevel;
- }
- }
-
- /*
- * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5
- * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars
- * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna
- * Icon Only
- */
- if (mLteRssnr > 300) snrIconLevel = -1;
- else if (mLteRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT;
- else if (mLteRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD;
- else if (mLteRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE;
- else if (mLteRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR;
- else if (mLteRssnr >= -200)
- snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-
- if (DBG) log("getLTELevel - rsrp:" + mLteRsrp + " snr:" + mLteRssnr + " rsrpIconLevel:"
- + rsrpIconLevel + " snrIconLevel:" + snrIconLevel
- + " lteRsrpBoost:" + mLteRsrpBoost);
-
- /* Choose a measurement type to use for notification */
- if (snrIconLevel != -1 && rsrpIconLevel != -1) {
- /*
- * The number of bars displayed shall be the smaller of the bars
- * associated with LTE RSRP and the bars associated with the LTE
- * RS_SNR
- */
- return (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel);
- }
-
- if (snrIconLevel != -1) return snrIconLevel;
-
- if (rsrpIconLevel != -1) return rsrpIconLevel;
-
- /* Valid values are (0-31, 99) as defined in TS 27.007 8.5 */
- if (mLteSignalStrength > 31) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- else if (mLteSignalStrength >= 12) rssiIconLevel = SIGNAL_STRENGTH_GREAT;
- else if (mLteSignalStrength >= 8) rssiIconLevel = SIGNAL_STRENGTH_GOOD;
- else if (mLteSignalStrength >= 5) rssiIconLevel = SIGNAL_STRENGTH_MODERATE;
- else if (mLteSignalStrength >= 0) rssiIconLevel = SIGNAL_STRENGTH_POOR;
-
- if (DBG) log("getLteLevel - rssi:" + mLteSignalStrength + " rssiIconLevel:"
- + rssiIconLevel);
- return rssiIconLevel;
-
+ return mLte.getLevel();
}
/**
@@ -983,41 +493,14 @@
*/
@UnsupportedAppUsage
public int getLteAsuLevel() {
- int lteAsuLevel = 99;
- int lteDbm = getLteDbm();
- /*
- * 3GPP 27.007 (Ver 10.3.0) Sec 8.69
- * 0 -140 dBm or less
- * 1 -139 dBm
- * 2...96 -138... -44 dBm
- * 97 -43 dBm or greater
- * 255 not known or not detectable
- */
- /*
- * validateInput will always give a valid range between -140 t0 -44 as
- * per ril.h. so RSRP >= -43 & <-140 will fall under asu level 255
- * and not 97 or 0
- */
- if (lteDbm == SignalStrength.INVALID) lteAsuLevel = 255;
- else lteAsuLevel = lteDbm + 140;
- if (DBG) log("Lte Asu level: "+lteAsuLevel);
- return lteAsuLevel;
+ return mLte.getAsuLevel();
}
/**
* @return true if this is for GSM
*/
public boolean isGsm() {
- return this.mIsGsm;
- }
-
- /**
- * @return true if it uses only RSRP for the number of LTE signal bar, otherwise false.
- *
- * @hide
- */
- public boolean useOnlyRsrpForLteLevel() {
- return this.mUseOnlyRsrpForLteLevel;
+ return !(getPrimary() instanceof CellSignalStrengthCdma);
}
/**
@@ -1027,7 +510,7 @@
*/
@UnsupportedAppUsage
public int getTdScdmaDbm() {
- return this.mTdScdmaRscp;
+ return mTdscdma.getRscp();
}
/**
@@ -1040,19 +523,7 @@
*/
@UnsupportedAppUsage
public int getTdScdmaLevel() {
- final int tdScdmaDbm = getTdScdmaDbm();
- int level;
-
- if ((tdScdmaDbm > -25) || (tdScdmaDbm == SignalStrength.INVALID))
- level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- else if (tdScdmaDbm >= -49) level = SIGNAL_STRENGTH_GREAT;
- else if (tdScdmaDbm >= -73) level = SIGNAL_STRENGTH_GOOD;
- else if (tdScdmaDbm >= -97) level = SIGNAL_STRENGTH_MODERATE;
- else if (tdScdmaDbm >= -110) level = SIGNAL_STRENGTH_POOR;
- else level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-
- if (DBG) log("getTdScdmaLevel = " + level);
- return level;
+ return mTdscdma.getLevel();
}
/**
@@ -1062,13 +533,7 @@
*/
@UnsupportedAppUsage
public int getTdScdmaAsuLevel() {
- final int tdScdmaDbm = getTdScdmaDbm();
- int tdScdmaAsuLevel;
-
- if (tdScdmaDbm == INVALID) tdScdmaAsuLevel = 255;
- else tdScdmaAsuLevel = tdScdmaDbm + 120;
- if (DBG) log("TD-SCDMA Asu level: " + tdScdmaAsuLevel);
- return tdScdmaAsuLevel;
+ return mTdscdma.getAsuLevel();
}
/**
@@ -1077,7 +542,7 @@
* @hide
*/
public int getWcdmaRscp() {
- return mWcdmaRscp;
+ return mWcdma.getRscp();
}
/**
@@ -1094,14 +559,7 @@
* 96 -24 dBm or greater
* 255 not known or not detectable
*/
- final int wcdmaDbm = getWcdmaDbm();
- int wcdmaAsuLevel = 255;
- // validateInput will always give a valid range between -120 to -24 as per ril.h. so RSCP
- // outside range is already set to INVALID
- if (wcdmaDbm == SignalStrength.INVALID) wcdmaAsuLevel = 255;
- else wcdmaAsuLevel = wcdmaDbm + 120;
- if (DBG) log("Wcdma Asu level: " + wcdmaAsuLevel);
- return wcdmaAsuLevel;
+ return mWcdma.getAsuLevel();
}
/**
@@ -1110,7 +568,7 @@
* @hide
*/
public int getWcdmaDbm() {
- return mWcdmaRscp;
+ return mWcdma.getDbm();
}
/**
@@ -1119,55 +577,7 @@
* @hide
*/
public int getWcdmaLevel() {
- int level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
-
- if (mWcdmaDefaultSignalMeasurement == null) {
- Log.wtf(LOG_TAG, "getWcdmaLevel - WCDMA default signal measurement is invalid.");
- return level;
- }
-
- switch (mWcdmaDefaultSignalMeasurement) {
- case MEASUMENT_TYPE_RSCP:
- // RSCP valid values are (-120 through -24) as defined in TS 27.007 8.69
- if (mWcdmaRscp < MIN_WCDMA_RSCP || mWcdmaRscp > MAX_WCDMA_RSCP) {
- if (mWcdmaRscp != INVALID) {
- Log.wtf(LOG_TAG, "getWcdmaLevel - invalid WCDMA RSCP: mWcdmaRscp="
- + mWcdmaRscp);
- }
- } else if (mWcdmaRscp >= mWcdmaRscpThresholds[3]) {
- level = SIGNAL_STRENGTH_GREAT;
- } else if (mWcdmaRscp >= mWcdmaRscpThresholds[2]) {
- level = SIGNAL_STRENGTH_GOOD;
- } else if (mWcdmaRscp >= mWcdmaRscpThresholds[1]) {
- level = SIGNAL_STRENGTH_MODERATE;
- } else if (mWcdmaRscp >= mWcdmaRscpThresholds[0]) {
- level = SIGNAL_STRENGTH_POOR;
- }
- if (DBG) log("getWcdmaLevel=" + level + " WcdmaRscp=" + mWcdmaRscp);
- break;
-
- default:
- // RSSI valid values are (0..31) as defined in TS 27.007 8.5
- if (mWcdmaSignalStrength < 0 || mWcdmaSignalStrength > 31) {
- if (mWcdmaSignalStrength != 99) {
- Log.wtf(LOG_TAG, "getWcdmaLevel - invalid WCDMA RSSI: mWcdmaSignalStrength="
- + mWcdmaSignalStrength);
- }
- } else if (mWcdmaSignalStrength >= 18) {
- level = SIGNAL_STRENGTH_GREAT;
- } else if (mWcdmaSignalStrength >= 13) {
- level = SIGNAL_STRENGTH_GOOD;
- } else if (mWcdmaSignalStrength >= 8) {
- level = SIGNAL_STRENGTH_MODERATE;
- } else if (mWcdmaSignalStrength >= 3) {
- level = SIGNAL_STRENGTH_POOR;
- }
- if (DBG) log("getWcdmaLevel=" + level + " WcdmaSignalStrength=" +
- mWcdmaSignalStrength);
- break;
-
- }
- return level;
+ return mWcdma.getLevel();
}
/**
@@ -1175,18 +585,7 @@
*/
@Override
public int hashCode() {
- int primeNum = 31;
- return ((mGsmSignalStrength * primeNum)
- + (mGsmBitErrorRate * primeNum)
- + (mCdmaDbm * primeNum) + (mCdmaEcio * primeNum)
- + (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum)
- + (mLteSignalStrength * primeNum) + (mLteRsrp * primeNum)
- + (mLteRsrq * primeNum) + (mLteRssnr * primeNum) + (mLteCqi * primeNum)
- + (mLteRsrpBoost * primeNum) + (mTdScdmaRscp * primeNum)
- + (mWcdmaSignalStrength * primeNum) + (mWcdmaRscpAsu * primeNum)
- + (mWcdmaRscp * primeNum) + (mIsGsm ? 1 : 0) + (mUseOnlyRsrpForLteLevel ? 1 : 0)
- + (Objects.hashCode(mWcdmaDefaultSignalMeasurement))
- + (Arrays.hashCode(mLteRsrpThresholds)) + (Arrays.hashCode(mWcdmaRscpThresholds)));
+ return Objects.hash(mCdma, mGsm, mWcdma, mTdscdma, mLte, mLteRsrpBoost);
}
/**
@@ -1194,40 +593,16 @@
*/
@Override
public boolean equals (Object o) {
- SignalStrength s;
+ if (!(o instanceof SignalStrength)) return false;
- try {
- s = (SignalStrength) o;
- } catch (ClassCastException ex) {
- return false;
- }
+ SignalStrength s = (SignalStrength) o;
- if (o == null) {
- return false;
- }
-
- return (mGsmSignalStrength == s.mGsmSignalStrength
- && mGsmBitErrorRate == s.mGsmBitErrorRate
- && mCdmaDbm == s.mCdmaDbm
- && mCdmaEcio == s.mCdmaEcio
- && mEvdoDbm == s.mEvdoDbm
- && mEvdoEcio == s.mEvdoEcio
- && mEvdoSnr == s.mEvdoSnr
- && mLteSignalStrength == s.mLteSignalStrength
- && mLteRsrp == s.mLteRsrp
- && mLteRsrq == s.mLteRsrq
- && mLteRssnr == s.mLteRssnr
- && mLteCqi == s.mLteCqi
- && mLteRsrpBoost == s.mLteRsrpBoost
- && mTdScdmaRscp == s.mTdScdmaRscp
- && mWcdmaSignalStrength == s.mWcdmaSignalStrength
- && mWcdmaRscpAsu == s.mWcdmaRscpAsu
- && mWcdmaRscp == s.mWcdmaRscp
- && mIsGsm == s.mIsGsm
- && mUseOnlyRsrpForLteLevel == s.mUseOnlyRsrpForLteLevel
- && Objects.equals(mWcdmaDefaultSignalMeasurement, s.mWcdmaDefaultSignalMeasurement)
- && Arrays.equals(mLteRsrpThresholds, s.mLteRsrpThresholds)
- && Arrays.equals(mWcdmaRscpThresholds, s.mWcdmaRscpThresholds));
+ return mCdma.equals(s.mCdma)
+ && mGsm.equals(s.mGsm)
+ && mWcdma.equals(s.mWcdma)
+ && mTdscdma.equals(s.mTdscdma)
+ && mLte.equals(s.mLte)
+ && mLteRsrpBoost == s.mLteRsrpBoost;
}
/**
@@ -1235,63 +610,16 @@
*/
@Override
public String toString() {
- return ("SignalStrength:"
- + " " + mGsmSignalStrength
- + " " + mGsmBitErrorRate
- + " " + mCdmaDbm
- + " " + mCdmaEcio
- + " " + mEvdoDbm
- + " " + mEvdoEcio
- + " " + mEvdoSnr
- + " " + mLteSignalStrength
- + " " + mLteRsrp
- + " " + mLteRsrq
- + " " + mLteRssnr
- + " " + mLteCqi
- + " " + mLteRsrpBoost
- + " " + mTdScdmaRscp
- + " " + mWcdmaSignalStrength
- + " " + mWcdmaRscpAsu
- + " " + mWcdmaRscp
- + " " + (mIsGsm ? "gsm|lte" : "cdma")
- + " " + (mUseOnlyRsrpForLteLevel ? "use_only_rsrp_for_lte_level" :
- "use_rsrp_and_rssnr_for_lte_level")
- + " " + mWcdmaDefaultSignalMeasurement
- + " " + (Arrays.toString(mLteRsrpThresholds))
- + " " + (Arrays.toString(mWcdmaRscpThresholds)));
- }
-
- /** Returns the signal strength related to GSM. */
- private int getGsmRelatedSignalStrength() {
- int level = getLteLevel();
- if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
- level = getTdScdmaLevel();
- if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
- level = getWcdmaLevel();
- if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
- level = getGsmLevel();
- }
- }
- }
- return level;
- }
-
- /** Returns the signal strength related to CDMA. */
- private int getCdmaRelatedSignalStrength() {
- int level;
- int cdmaLevel = getCdmaLevel();
- int evdoLevel = getEvdoLevel();
- if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
- /* We don't know evdo, use cdma */
- level = cdmaLevel;
- } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
- /* We don't know cdma, use evdo */
- level = evdoLevel;
- } else {
- /* We know both, use the lowest level */
- level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
- }
- return level;
+ return new StringBuilder().append("SignalStrength:{")
+ .append("mCdma=").append(mCdma)
+ .append(",mGsm=").append(mGsm)
+ .append(",mWcdma=").append(mWcdma)
+ .append(",mTdscdma=").append(mTdscdma)
+ .append(",mLte=").append(mLte)
+ .append(",mLteRsrpBoost=").append(mLteRsrpBoost)
+ .append(",primary=").append(getPrimary().getClass().getSimpleName())
+ .append("}")
+ .toString();
}
/**
@@ -1302,34 +630,13 @@
*/
@UnsupportedAppUsage
private void setFromNotifierBundle(Bundle m) {
- mGsmSignalStrength = m.getInt("GsmSignalStrength");
- mGsmBitErrorRate = m.getInt("GsmBitErrorRate");
- mCdmaDbm = m.getInt("CdmaDbm");
- mCdmaEcio = m.getInt("CdmaEcio");
- mEvdoDbm = m.getInt("EvdoDbm");
- mEvdoEcio = m.getInt("EvdoEcio");
- mEvdoSnr = m.getInt("EvdoSnr");
- mLteSignalStrength = m.getInt("LteSignalStrength");
- mLteRsrp = m.getInt("LteRsrp");
- mLteRsrq = m.getInt("LteRsrq");
- mLteRssnr = m.getInt("LteRssnr");
- mLteCqi = m.getInt("LteCqi");
+ mCdma = m.getParcelable("Cdma");
+ mGsm = m.getParcelable("Gsm");
+ mWcdma = m.getParcelable("Wcdma");
+ mTdscdma = m.getParcelable("Tdscdma");
+ mLte = m.getParcelable("Lte");
+
mLteRsrpBoost = m.getInt("LteRsrpBoost");
- mTdScdmaRscp = m.getInt("TdScdma");
- mWcdmaSignalStrength = m.getInt("WcdmaSignalStrength");
- mWcdmaRscpAsu = m.getInt("WcdmaRscpAsu");
- mWcdmaRscp = m.getInt("WcdmaRscp");
- mIsGsm = m.getBoolean("IsGsm");
- mUseOnlyRsrpForLteLevel = m.getBoolean("UseOnlyRsrpForLteLevel");
- mWcdmaDefaultSignalMeasurement = m.getString("WcdmaDefaultSignalMeasurement");
- ArrayList<Integer> lteRsrpThresholds = m.getIntegerArrayList("lteRsrpThresholds");
- for (int i = 0; i < lteRsrpThresholds.size(); i++) {
- mLteRsrpThresholds[i] = lteRsrpThresholds.get(i);
- }
- ArrayList<Integer> wcdmaRscpThresholds = m.getIntegerArrayList("wcdmaRscpThresholds");
- for (int i = 0; i < wcdmaRscpThresholds.size(); i++) {
- mWcdmaRscpThresholds[i] = wcdmaRscpThresholds.get(i);
- }
}
/**
@@ -1340,56 +647,13 @@
*/
@UnsupportedAppUsage
public void fillInNotifierBundle(Bundle m) {
- m.putInt("GsmSignalStrength", mGsmSignalStrength);
- m.putInt("GsmBitErrorRate", mGsmBitErrorRate);
- m.putInt("CdmaDbm", mCdmaDbm);
- m.putInt("CdmaEcio", mCdmaEcio);
- m.putInt("EvdoDbm", mEvdoDbm);
- m.putInt("EvdoEcio", mEvdoEcio);
- m.putInt("EvdoSnr", mEvdoSnr);
- m.putInt("LteSignalStrength", mLteSignalStrength);
- m.putInt("LteRsrp", mLteRsrp);
- m.putInt("LteRsrq", mLteRsrq);
- m.putInt("LteRssnr", mLteRssnr);
- m.putInt("LteCqi", mLteCqi);
+ m.putParcelable("Cdma", mCdma);
+ m.putParcelable("Gsm", mGsm);
+ m.putParcelable("Wcdma", mWcdma);
+ m.putParcelable("Tdscdma", mTdscdma);
+ m.putParcelable("Lte", mLte);
+
m.putInt("LteRsrpBoost", mLteRsrpBoost);
- m.putInt("TdScdma", mTdScdmaRscp);
- m.putInt("WcdmaSignalStrength", mWcdmaSignalStrength);
- m.putInt("WcdmaRscpAsu", mWcdmaRscpAsu);
- m.putInt("WcdmaRscp", mWcdmaRscp);
- m.putBoolean("IsGsm", mIsGsm);
- m.putBoolean("UseOnlyRsrpForLteLevel", mUseOnlyRsrpForLteLevel);
- m.putString("WcdmaDefaultSignalMeasurement", mWcdmaDefaultSignalMeasurement);
- ArrayList<Integer> lteRsrpThresholds = new ArrayList<Integer>();
- for (int value : mLteRsrpThresholds) {
- lteRsrpThresholds.add(value);
- }
- m.putIntegerArrayList("lteRsrpThresholds", lteRsrpThresholds);
- ArrayList<Integer> wcdmaRscpThresholds = new ArrayList<Integer>();
- for (int value : mWcdmaRscpThresholds) {
- wcdmaRscpThresholds.add(value);
- }
- m.putIntegerArrayList("wcdmaRscpThresholds", wcdmaRscpThresholds);
- }
-
- /**
- * Gets the default threshold array for determining the display level of LTE signal bar.
- *
- * @return int array for determining the display level.
- */
- private int[] getDefaultLteRsrpThresholds() {
- return CarrierConfigManager.getDefaultConfig().getIntArray(
- CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY);
- }
-
- /**
- * Gets the default threshold array for determining the display level of WCDMA signal bar.
- *
- * @return int array for determining the display level.
- */
- private int[] getDefaultWcdmaRscpThresholds() {
- return CarrierConfigManager.getDefaultConfig().getIntArray(
- CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY);
}
/**
diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java
index dacc5d8..0a58fa0 100644
--- a/telephony/java/android/telephony/SubscriptionInfo.java
+++ b/telephony/java/android/telephony/SubscriptionInfo.java
@@ -80,6 +80,12 @@
private CharSequence mCarrierName;
/**
+ * The subscription carrier id.
+ * @see TelephonyManager#getSimCarrierId()
+ */
+ private int mCarrierId;
+
+ /**
* The source of the name, NAME_SOURCE_UNDEFINED, NAME_SOURCE_DEFAULT_SOURCE,
* NAME_SOURCE_SIM_SOURCE or NAME_SOURCE_USER_INPUT.
*/
@@ -132,10 +138,15 @@
private UiccAccessRule[] mAccessRules;
/**
- * The ID of the SIM card. It is the ICCID of the active profile for a UICC card and the EID
- * for an eUICC card.
+ * The string ID of the SIM card. It is the ICCID of the active profile for a UICC card and the
+ * EID for an eUICC card.
*/
- private String mCardId;
+ private String mCardString;
+
+ /**
+ * The card ID of the SIM card. This maps uniquely to the card string.
+ */
+ private int mCardId;
/**
* Whether the subscription is opportunistic.
@@ -168,10 +179,10 @@
public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded,
- @Nullable UiccAccessRule[] accessRules, String cardId) {
+ @Nullable UiccAccessRule[] accessRules, String cardString) {
this(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number,
- roaming, icon, mcc, mnc, countryIso, isEmbedded, accessRules, cardId,
- false, null, true);
+ roaming, icon, mcc, mnc, countryIso, isEmbedded, accessRules, cardString,
+ false, null, true, TelephonyManager.UNKNOWN_CARRIER_ID);
}
/**
@@ -180,20 +191,22 @@
public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded,
- @Nullable UiccAccessRule[] accessRules, String cardId, boolean isOpportunistic,
- @Nullable String groupUUID, boolean isMetered) {
+ @Nullable UiccAccessRule[] accessRules, String cardString, boolean isOpportunistic,
+ @Nullable String groupUUID, boolean isMetered, int carrierId) {
this(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number,
- roaming, icon, mcc, mnc, countryIso, isEmbedded, accessRules, cardId,
- isOpportunistic, groupUUID, isMetered, false);
+ roaming, icon, mcc, mnc, countryIso, isEmbedded, accessRules, cardString, -1,
+ isOpportunistic, groupUUID, isMetered, false, carrierId);
}
+
/**
* @hide
*/
public SubscriptionInfo(int id, String iccId, int simSlotIndex, CharSequence displayName,
CharSequence carrierName, int nameSource, int iconTint, String number, int roaming,
Bitmap icon, String mcc, String mnc, String countryIso, boolean isEmbedded,
- @Nullable UiccAccessRule[] accessRules, String cardId, boolean isOpportunistic,
- @Nullable String groupUUID, boolean isMetered, boolean isGroupDisabled) {
+ @Nullable UiccAccessRule[] accessRules, String cardString, int cardId,
+ boolean isOpportunistic, @Nullable String groupUUID, boolean isMetered,
+ boolean isGroupDisabled, int carrierid) {
this.mId = id;
this.mIccId = iccId;
this.mSimSlotIndex = simSlotIndex;
@@ -209,11 +222,13 @@
this.mCountryIso = countryIso;
this.mIsEmbedded = isEmbedded;
this.mAccessRules = accessRules;
+ this.mCardString = cardString;
this.mCardId = cardId;
this.mIsOpportunistic = isOpportunistic;
this.mGroupUUID = groupUUID;
this.mIsMetered = isMetered;
this.mIsGroupDisabled = isGroupDisabled;
+ this.mCarrierId = carrierid;
}
@@ -239,6 +254,14 @@
}
/**
+ * @return the carrier id of this Subscription carrier.
+ * @see TelephonyManager#getSimCarrierId()
+ */
+ public int getCarrierId() {
+ return this.mCarrierId;
+ }
+
+ /**
* @return the name displayed to the user that identifies this subscription
*/
public CharSequence getDisplayName() {
@@ -508,10 +531,20 @@
}
/**
- * @return the ID of the SIM card which contains the subscription.
+ * @return the card string of the SIM card which contains the subscription. The card string is
+ * the ICCID for UICCs or the EID for eUICCs.
* @hide
*/
- public String getCardId() {
+ public String getCardString() {
+ return this.mCardString;
+ }
+
+ /**
+ * @return the cardId of the SIM card which contains the subscription.
+ * @hide
+ */
+ @SystemApi
+ public int getCardId() {
return this.mCardId;
}
@@ -549,16 +582,18 @@
Bitmap iconBitmap = Bitmap.CREATOR.createFromParcel(source);
boolean isEmbedded = source.readBoolean();
UiccAccessRule[] accessRules = source.createTypedArray(UiccAccessRule.CREATOR);
- String cardId = source.readString();
+ String cardString = source.readString();
+ int cardId = source.readInt();
boolean isOpportunistic = source.readBoolean();
String groupUUID = source.readString();
boolean isMetered = source.readBoolean();
boolean isGroupDisabled = source.readBoolean();
+ int carrierid = source.readInt();
return new SubscriptionInfo(id, iccId, simSlotIndex, displayName, carrierName,
nameSource, iconTint, number, dataRoaming, iconBitmap, mcc, mnc, countryIso,
- isEmbedded, accessRules, cardId, isOpportunistic, groupUUID, isMetered,
- isGroupDisabled);
+ isEmbedded, accessRules, cardString, cardId, isOpportunistic, groupUUID,
+ isMetered, isGroupDisabled, carrierid);
}
@Override
@@ -584,11 +619,13 @@
mIconBitmap.writeToParcel(dest, flags);
dest.writeBoolean(mIsEmbedded);
dest.writeTypedArray(mAccessRules, flags);
- dest.writeString(mCardId);
+ dest.writeString(mCardString);
+ dest.writeInt(mCardId);
dest.writeBoolean(mIsOpportunistic);
dest.writeString(mGroupUUID);
dest.writeBoolean(mIsMetered);
dest.writeBoolean(mIsGroupDisabled);
+ dest.writeInt(mCarrierId);
}
@Override
@@ -614,23 +651,25 @@
@Override
public String toString() {
String iccIdToPrint = givePrintableIccid(mIccId);
- String cardIdToPrint = givePrintableIccid(mCardId);
+ String cardStringToPrint = givePrintableIccid(mCardString);
return "{id=" + mId + ", iccId=" + iccIdToPrint + " simSlotIndex=" + mSimSlotIndex
- + " displayName=" + mDisplayName + " carrierName=" + mCarrierName
- + " nameSource=" + mNameSource + " iconTint=" + mIconTint + " mNumber=" + mNumber
+ + " carrierId=" + mCarrierId + " displayName=" + mDisplayName
+ + " carrierName=" + mCarrierName + " nameSource=" + mNameSource
+ + " iconTint=" + mIconTint + " mNumber=" + mNumber
+ " dataRoaming=" + mDataRoaming + " iconBitmap=" + mIconBitmap + " mcc " + mMcc
+ " mnc " + mMnc + "mCountryIso=" + mCountryIso + " isEmbedded " + mIsEmbedded
+ " accessRules " + Arrays.toString(mAccessRules)
- + " cardId=" + cardIdToPrint + " isOpportunistic " + mIsOpportunistic
- + " mGroupUUID=" + mGroupUUID + " isMetered=" + mIsMetered
- + " mIsGroupDisabled=" + mIsGroupDisabled + "}";
+ + " cardString=" + cardStringToPrint + " cardId=" + mCardId
+ + " isOpportunistic " + mIsOpportunistic + " mGroupUUID=" + mGroupUUID
+ + " isMetered=" + mIsMetered + " mIsGroupDisabled=" + mIsGroupDisabled + "}";
}
@Override
public int hashCode() {
return Objects.hash(mId, mSimSlotIndex, mNameSource, mIconTint, mDataRoaming, mIsEmbedded,
mIsOpportunistic, mGroupUUID, mIsMetered, mIccId, mNumber, mMcc, mMnc,
- mCountryIso, mCardId, mDisplayName, mCarrierName, mAccessRules, mIsGroupDisabled);
+ mCountryIso, mCardString, mCardId, mDisplayName, mCarrierName, mAccessRules,
+ mIsGroupDisabled, mCarrierId);
}
@Override
@@ -653,13 +692,15 @@
&& mIsEmbedded == toCompare.mIsEmbedded
&& mIsOpportunistic == toCompare.mIsOpportunistic
&& mIsGroupDisabled == toCompare.mIsGroupDisabled
- && Objects.equals(mGroupUUID, toCompare.mGroupUUID)
+ && mCarrierId == toCompare.mCarrierId
&& mIsMetered == toCompare.mIsMetered
+ && Objects.equals(mGroupUUID, toCompare.mGroupUUID)
&& Objects.equals(mIccId, toCompare.mIccId)
&& Objects.equals(mNumber, toCompare.mNumber)
&& Objects.equals(mMcc, toCompare.mMcc)
&& Objects.equals(mMnc, toCompare.mMnc)
&& Objects.equals(mCountryIso, toCompare.mCountryIso)
+ && Objects.equals(mCardString, toCompare.mCardString)
&& Objects.equals(mCardId, toCompare.mCardId)
&& TextUtils.equals(mDisplayName, toCompare.mDisplayName)
&& TextUtils.equals(mCarrierName, toCompare.mCarrierName)
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 6a22f7e..3235507 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -19,6 +19,7 @@
import static android.net.NetworkPolicyManager.OVERRIDE_CONGESTED;
import static android.net.NetworkPolicyManager.OVERRIDE_UNMETERED;
+import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.DurationMillisLong;
import android.annotation.NonNull;
@@ -52,6 +53,7 @@
import android.os.ServiceManager;
import android.telephony.euicc.EuiccManager;
import android.telephony.ims.ImsMmTelManager;
+import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
@@ -67,6 +69,7 @@
import java.util.Locale;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
/**
* SubscriptionManager is the application interface to SubscriptionController
@@ -379,6 +382,14 @@
public static final int SIM_PROVISIONED = 0;
/**
+ * TelephonyProvider column name for subscription carrier id.
+ * @see TelephonyManager#getSimCarrierId()
+ * <p>Type: INTEGER (int) </p>
+ * @hide
+ */
+ public static final String CARRIER_ID = "carrier_id";
+
+ /**
* TelephonyProvider column name for the MCC associated with a SIM, stored as a string.
* <P>Type: TEXT (String)</P>
* @hide
@@ -2401,16 +2412,21 @@
* together, some of them may be invisible to the users, etc.
*
* Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
- * permission or can manage all subscriptions in the list, according to their
- * acess rules.
+ * permission or had carrier privilege permission on the subscriptions:
+ * {@link TelephonyManager#hasCarrierPrivileges()} or
+ * {@link #canManageSubscription(SubscriptionInfo)}
+ *
+ * @throws SecurityException if the caller doesn't meet the requirements
+ * outlined above.
*
* @param subIdList list of subId that will be in the same group
* @return groupUUID a UUID assigned to the subscription group. It returns
* null if fails.
*
*/
+ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
- public String setSubscriptionGroup(int[] subIdList) {
+ public @Nullable String setSubscriptionGroup(@NonNull int[] subIdList) {
String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
if (VDBG) {
logd("[setSubscriptionGroup]+ subIdList:" + Arrays.toString(subIdList));
@@ -2430,6 +2446,80 @@
}
/**
+ * Remove a list of subscriptions from their subscription group.
+ * See {@link #setSubscriptionGroup(int[])} for more details.
+ *
+ * Caller will either have {@link android.Manifest.permission#MODIFY_PHONE_STATE}
+ * permission or had carrier privilege permission on the subscriptions:
+ * {@link TelephonyManager#hasCarrierPrivileges()} or
+ * {@link #canManageSubscription(SubscriptionInfo)}
+ *
+ * @throws SecurityException if the caller doesn't meet the requirements
+ * outlined above.
+ *
+ * @param subIdList list of subId that need removing from their groups.
+ * @return whether the operation succeeds.
+ *
+ */
+ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
+ @RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
+ public boolean removeSubscriptionsFromGroup(@NonNull int[] subIdList) {
+ String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+ if (VDBG) {
+ logd("[removeSubscriptionsFromGroup]+ subIdList:" + Arrays.toString(subIdList));
+ }
+
+ try {
+ ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+ if (iSub != null) {
+ return iSub.removeSubscriptionsFromGroup(subIdList, pkgForDebug);
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }
+
+ return false;
+ }
+
+ /**
+ * Get subscriptionInfo list of subscriptions that are in the same group of given subId.
+ * See {@link #setSubscriptionGroup(int[])} for more details.
+ *
+ * Caller will either have {@link android.Manifest.permission#READ_PHONE_STATE}
+ * permission or had carrier privilege permission on the subscription.
+ * {@link TelephonyManager#hasCarrierPrivileges()}
+ *
+ * @throws SecurityException if the caller doesn't meet the requirements
+ * outlined above.
+ *
+ * @param subId of which list of subInfo from the same group will be returned.
+ * @return list of subscriptionInfo that belong to the same group, including the given
+ * subscription itself. It will return null if the subscription doesn't exist or it
+ * doesn't belong to any group.
+ *
+ */
+ @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
+ @RequiresPermission(Manifest.permission.READ_PHONE_STATE)
+ public @Nullable List<SubscriptionInfo> getSubscriptionsInGroup(int subId) {
+ String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
+ if (VDBG) {
+ logd("[getSubscriptionsInGroup]+ subId:" + subId);
+ }
+
+ List<SubscriptionInfo> result = null;
+ try {
+ ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
+ if (iSub != null) {
+ result = iSub.getSubscriptionsInGroup(subId, pkgForDebug);
+ }
+ } catch (RemoteException ex) {
+ // ignore it
+ }
+
+ return result;
+ }
+
+ /**
* Set metered by simInfo index
*
* @param isMetered whether it’s a metered subscription.
@@ -2444,6 +2534,42 @@
(iSub)-> iSub.setMetered(isMetered, subId));
}
+ /**
+ * Whether system UI should hide a subscription. If it's a bundled opportunistic
+ * subscription, it shouldn't show up in anywhere in Settings app, dialer app,
+ * or status bar.
+ *
+ * @param info the subscriptionInfo to check against.
+ * @return true if this subscription should be hidden.
+ *
+ * @hide
+ */
+ public static boolean shouldHideSubscription(SubscriptionInfo info) {
+ return (info != null && !TextUtils.isEmpty(info.getGroupUuid()) && info.isOpportunistic());
+ }
+
+ /**
+ * Return a list of subscriptions that are available and visible to the user.
+ * Used by Settings app to show a list of subscriptions for user to pick.
+ *
+ * <p>
+ * Permissions android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE is required
+ * for getSelectableSubscriptionInfoList to be invoked.
+ * @return list of user selectable subscriptions.
+ *
+ * @hide
+ */
+ public @Nullable List<SubscriptionInfo> getSelectableSubscriptionInfoList() {
+ List<SubscriptionInfo> availableList = getAvailableSubscriptionInfoList();
+ if (availableList == null) {
+ return null;
+ } else {
+ return getAvailableSubscriptionInfoList().stream()
+ .filter(subInfo -> !shouldHideSubscription(subInfo))
+ .collect(Collectors.toList());
+ }
+ }
+
private interface CallISubMethodHelper {
int callMethod(ISub iSub) throws RemoteException;
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 3649ecad..26d2459 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -625,8 +625,6 @@
* The {@link #EXTRA_RINGING_CALL_STATE} extra indicates the ringing call state.
* The {@link #EXTRA_FOREGROUND_CALL_STATE} extra indicates the foreground call state.
* The {@link #EXTRA_BACKGROUND_CALL_STATE} extra indicates the background call state.
- * The {@link #EXTRA_DISCONNECT_CAUSE} extra indicates the disconnect cause.
- * The {@link #EXTRA_PRECISE_DISCONNECT_CAUSE} extra indicates the precise disconnect cause.
*
* <p class="note">
* Requires the READ_PRECISE_PHONE_STATE permission.
@@ -634,12 +632,10 @@
* @see #EXTRA_RINGING_CALL_STATE
* @see #EXTRA_FOREGROUND_CALL_STATE
* @see #EXTRA_BACKGROUND_CALL_STATE
- * @see #EXTRA_DISCONNECT_CAUSE
- * @see #EXTRA_PRECISE_DISCONNECT_CAUSE
*
* <p class="note">
* Requires the READ_PRECISE_PHONE_STATE permission.
- *
+ * @deprecated use {@link PhoneStateListener#LISTEN_PRECISE_CALL_STATE} instead
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@@ -647,8 +643,28 @@
"android.intent.action.PRECISE_CALL_STATE";
/**
- * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
- * for an integer containing the state of the current ringing call.
+ * Broadcast intent action indicating that call disconnect cause has changed.
+ *
+ * <p>
+ * The {@link #EXTRA_DISCONNECT_CAUSE} extra indicates the disconnect cause.
+ * The {@link #EXTRA_PRECISE_DISCONNECT_CAUSE} extra indicates the precise disconnect cause.
+ *
+ * <p class="note">
+ * Requires the READ_PRECISE_PHONE_STATE permission.
+ *
+ * @see #EXTRA_DISCONNECT_CAUSE
+ * @see #EXTRA_PRECISE_DISCONNECT_CAUSE
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_CALL_DISCONNECT_CAUSE_CHANGED =
+ "android.intent.action.CALL_DISCONNECT_CAUSE";
+
+ /**
+ * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast and
+ * {@link PhoneStateListener#onPreciseCallStateChanged(PreciseCallState)} for an integer
+ * containing the state of the current ringing call.
*
* @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
* @see PreciseCallState#PRECISE_CALL_STATE_IDLE
@@ -670,8 +686,9 @@
public static final String EXTRA_RINGING_CALL_STATE = "ringing_state";
/**
- * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
- * for an integer containing the state of the current foreground call.
+ * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast and
+ * {@link PhoneStateListener#onPreciseCallStateChanged(PreciseCallState)} for an integer
+ * containing the state of the current foreground call.
*
* @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
* @see PreciseCallState#PRECISE_CALL_STATE_IDLE
@@ -693,8 +710,9 @@
public static final String EXTRA_FOREGROUND_CALL_STATE = "foreground_state";
/**
- * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
- * for an integer containing the state of the current background call.
+ * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast and
+ * {@link PhoneStateListener#onPreciseCallStateChanged(PreciseCallState)} for an integer
+ * containing the state of the current background call.
*
* @see PreciseCallState#PRECISE_CALL_STATE_NOT_VALID
* @see PreciseCallState#PRECISE_CALL_STATE_IDLE
@@ -716,8 +734,9 @@
public static final String EXTRA_BACKGROUND_CALL_STATE = "background_state";
/**
- * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
- * for an integer containing the disconnect cause.
+ * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast and
+ * {@link PhoneStateListener#onPreciseCallStateChanged(PreciseCallState)} for an integer
+ * containing the disconnect cause.
*
* @see DisconnectCause
*
@@ -730,8 +749,9 @@
public static final String EXTRA_DISCONNECT_CAUSE = "disconnect_cause";
/**
- * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast
- * for an integer containing the disconnect cause provided by the RIL.
+ * The lookup key used with the {@link #ACTION_PRECISE_CALL_STATE_CHANGED} broadcast and
+ * {@link PhoneStateListener#onPreciseCallStateChanged(PreciseCallState)} for an integer
+ * containing the disconnect cause provided by the RIL.
*
* @see PreciseDisconnectCause
*
@@ -1223,81 +1243,79 @@
"android.telephony.action.SUBSCRIPTION_CARRIER_IDENTITY_CHANGED";
/**
- * Broadcast Action: The subscription precise carrier identity has changed.
- * Similar like {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED}, this intent will be sent
- * on the event of {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED}. However, its possible
- * that precise carrier identity changes while
- * {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} remains the same e.g, the same
- * subscription switches to different IMSI could potentially change its precise carrier id.
- *
- * The intent will have the following extra values:
- * <ul>
- * <li>{@link #EXTRA_PRECISE_CARRIER_ID} The up-to-date precise carrier id of the
- * current subscription.
- * </li>
- * <li>{@link #EXTRA_PRECISE_CARRIER_NAME} The up-to-date carrier name of the current
- * subscription.
- * </li>
- * <li>{@link #EXTRA_SUBSCRIPTION_ID} The subscription id associated with the changed carrier
- * identity.
- * </li>
- * </ul>
- * <p class="note">This is a protected intent that can only be sent by the system.
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED =
- "android.telephony.action.SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED";
-
- /**
* An int extra used with {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} which indicates
- * the updated carrier id {@link TelephonyManager#getSimCarrierId()} of
- * the current subscription.
+ * the updated carrier id returned by {@link TelephonyManager#getSimCarrierId()}.
* <p>Will be {@link TelephonyManager#UNKNOWN_CARRIER_ID} if the subscription is unavailable or
* the carrier cannot be identified.
*/
public static final String EXTRA_CARRIER_ID = "android.telephony.extra.CARRIER_ID";
/**
- * An int extra used with {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} which indicates
- * the updated mno carrier id of the current subscription.
- * <p>Will be {@link TelephonyManager#UNKNOWN_CARRIER_ID} if the subscription is unavailable or
- * the carrier cannot be identified.
- *
- *@hide
- */
- public static final String EXTRA_MNO_CARRIER_ID = "android.telephony.extra.MNO_CARRIER_ID";
-
- /**
* An string extra used with {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} which
* indicates the updated carrier name of the current subscription.
- * {@see TelephonyManager#getSimCarrierIdName()}
+ * @see TelephonyManager#getSimCarrierIdName()
* <p>Carrier name is a user-facing name of the carrier id {@link #EXTRA_CARRIER_ID},
* usually the brand name of the subsidiary (e.g. T-Mobile).
*/
public static final String EXTRA_CARRIER_NAME = "android.telephony.extra.CARRIER_NAME";
/**
+ * Broadcast Action: The subscription precise carrier identity has changed.
+ * The precise carrier id can be used to further differentiate a carrier by different
+ * networks, by prepaid v.s.postpaid or even by 4G v.s.3G plan. Each carrier has a unique
+ * carrier id returned by {@link #getSimCarrierId()} but could have multiple precise carrier id.
+ * e.g, {@link #getSimCarrierId()} will always return Tracfone (id 2022) for a Tracfone SIM,
+ * while {@link #getSimPreciseCarrierId()} can return Tracfone AT&T or Tracfone T-Mobile based
+ * on the current subscription IMSI. For carriers without any fine-grained ids, precise carrier
+ * id is same as carrier id.
+ *
+ * <p>Similar like {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED}, this intent will be
+ * sent on the event of {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} while its also
+ * possible to be sent without {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} when
+ * precise carrier id changes with the same carrier id.
+ * e.g, the same subscription switches to different IMSI could potentially change its
+ * precise carrier id while carrier id remains the same.
+ * @see #getSimPreciseCarrierId()
+ * @see #getSimCarrierId()
+ *
+ * The intent will have the following extra values:
+ * <ul>
+ * <li>{@link #EXTRA_PRECISE_CARRIER_ID} The up-to-date precise carrier id of the
+ * current subscription.
+ * </li>
+ * <li>{@link #EXTRA_PRECISE_CARRIER_NAME} The up-to-date name of the precise carrier id.
+ * </li>
+ * <li>{@link #EXTRA_SUBSCRIPTION_ID} The subscription id associated with the changed carrier
+ * identity.
+ * </li>
+ * </ul>
+ * <p class="note">This is a protected intent that can only be sent by the system.
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ public static final String ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED =
+ "android.telephony.action.SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED";
+
+ /**
* An int extra used with {@link #ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED} which
- * indicates the updated precise carrier id {@link TelephonyManager#getSimPreciseCarrierId()} of
- * the current subscription. Note, its possible precise carrier id changes while
- * {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} remains the same e.g, when
- * subscription switch to different IMSI.
+ * indicates the updated precise carrier id returned by
+ * {@link TelephonyManager#getSimPreciseCarrierId()}. Note, its possible precise carrier id
+ * changes while {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} remains the same
+ * e.g, when subscription switch to different IMSIs.
* <p>Will be {@link TelephonyManager#UNKNOWN_CARRIER_ID} if the subscription is unavailable or
* the carrier cannot be identified.
- * @hide
*/
public static final String EXTRA_PRECISE_CARRIER_ID =
"android.telephony.extra.PRECISE_CARRIER_ID";
/**
* An string extra used with {@link #ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED} which
- * indicates the updated precise carrier name of the current subscription.
- * {@see TelephonyManager#getSimPreciseCarrierIdName()}
- * <p>it's a user-facing name of the precise carrier id {@link #EXTRA_PRECISE_CARRIER_ID},
- * @hide
+ * indicates the updated precise carrier name returned by
+ * {@link TelephonyManager#getSimPreciseCarrierIdName()}.
+ * <p>it's a user-facing name of the precise carrier id {@link #EXTRA_PRECISE_CARRIER_ID}, e.g,
+ * Tracfone-AT&T.
*/
- public static final String EXTRA_PRECISE_CARRIER_NAME = "android.telephony.extra.CARRIER_NAME";
+ public static final String EXTRA_PRECISE_CARRIER_NAME =
+ "android.telephony.extra.PRECISE_CARRIER_NAME";
/**
* An int extra used with {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} to indicate the
@@ -3129,6 +3147,29 @@
}
/**
+ * Gets information about currently inserted UICCs and eUICCs. See {@link UiccCardInfo} for more
+ * details on the kind of information available.
+ *
+ * @return UiccCardInfo an array of UiccCardInfo objects, representing information on the
+ * currently inserted UICCs and eUICCs.
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public UiccCardInfo[] getUiccCardsInfo() {
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony == null) {
+ return null;
+ }
+ return telephony.getUiccCardsInfo();
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
* Gets all the UICC slots. The objects in the array can be null if the slot info is not
* available, which is possible between phone process starting and getting slot info from modem.
*
@@ -4863,7 +4904,7 @@
*/
@RequiresPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION)
public void requestCellInfoUpdate(
- @NonNull Executor executor, @NonNull CellInfoCallback callback) {
+ @NonNull @CallbackExecutor Executor executor, @NonNull CellInfoCallback callback) {
try {
ITelephony telephony = getITelephony();
if (telephony == null) return;
@@ -6647,7 +6688,7 @@
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
- return telephony.getCarrierPrivilegeStatus(mSubId) ==
+ return telephony.getCarrierPrivilegeStatus(subId) ==
CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
}
} catch (RemoteException ex) {
@@ -8533,7 +8574,7 @@
/**
* Returns carrier id name of the current subscription.
- * <p>Carrier id name is a user-facing name of carrier id
+ * <p>Carrier id name is a user-facing name of carrier id returned by
* {@link #getSimCarrierId()}, usually the brand name of the subsidiary
* (e.g. T-Mobile). Each carrier could configure multiple {@link #getSimOperatorName() SPN} but
* should have a single carrier name. Carrier name is not a canonical identity,
@@ -8543,7 +8584,7 @@
* @return Carrier name of the current subscription. Return {@code null} if the subscription is
* unavailable or the carrier cannot be identified.
*/
- public CharSequence getSimCarrierIdName() {
+ public @Nullable CharSequence getSimCarrierIdName() {
try {
ITelephony service = getITelephony();
if (service != null) {
@@ -8560,10 +8601,10 @@
*
* <p>The precise carrier id can be used to further differentiate a carrier by different
* networks, by prepaid v.s.postpaid or even by 4G v.s.3G plan. Each carrier has a unique
- * carrier id {@link #getSimCarrierId()} but can have multiple precise carrier id. e.g,
- * {@link #getSimCarrierId()} will always return Tracfone (id 2022) for a Tracfone SIM, while
- * {@link #getSimPreciseCarrierId()} can return Tracfone AT&T or Tracfone T-Mobile based on the
- * current subscription IMSI.
+ * carrier id returned by {@link #getSimCarrierId()} but could have multiple precise carrier id.
+ * e.g, {@link #getSimCarrierId()} will always return Tracfone (id 2022) for a Tracfone SIM,
+ * while {@link #getSimPreciseCarrierId()} can return Tracfone AT&T or Tracfone T-Mobile based
+ * on the current subscription IMSI.
*
* <p>For carriers without any fine-grained carrier ids, return {@link #getSimCarrierId()}
* <p>Precise carrier ids are defined in the same way as carrier id
@@ -8573,8 +8614,6 @@
* @return Returns fine-grained carrier id of the current subscription.
* Return {@link #UNKNOWN_CARRIER_ID} if the subscription is unavailable or the carrier cannot
* be identified.
- *
- * @hide
*/
public int getSimPreciseCarrierId() {
try {
@@ -8590,16 +8629,14 @@
/**
* Similar like {@link #getSimCarrierIdName()}, returns user-facing name of the
- * precise carrier id {@link #getSimPreciseCarrierId()}
+ * precise carrier id returned by {@link #getSimPreciseCarrierId()}.
*
* <p>The returned name is unlocalized.
*
* @return user-facing name of the subscription precise carrier id. Return {@code null} if the
* subscription is unavailable or the carrier cannot be identified.
- *
- * @hide
*/
- public CharSequence getSimPreciseCarrierIdName() {
+ public @Nullable CharSequence getSimPreciseCarrierIdName() {
try {
ITelephony service = getITelephony();
if (service != null) {
@@ -8612,6 +8649,62 @@
}
/**
+ * Returns carrier id based on sim MCCMNC (returned by {@link #getSimOperator()}) only.
+ * This is used for fallback when configurations/logic for exact carrier id
+ * {@link #getSimCarrierId()} are not found.
+ *
+ * Android carrier id table <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/carrier_list.textpb">here</a>
+ * can be updated out-of-band, its possible a MVNO (Mobile Virtual Network Operator) carrier
+ * was not fully recognized and assigned to its MNO (Mobile Network Operator) carrier id
+ * by default. After carrier id table update, a new carrier id was assigned. If apps don't
+ * take the update with the new id, it might be helpful to always fallback by using carrier
+ * id based on MCCMNC if there is no match.
+ *
+ * @return matching carrier id from sim MCCMNC. Return {@link #UNKNOWN_CARRIER_ID} if the
+ * subscription is unavailable or the carrier cannot be identified.
+ */
+ public int getCarrierIdFromSimMccMnc() {
+ try {
+ ITelephony service = getITelephony();
+ if (service != null) {
+ return service.getCarrierIdFromMccMnc(getSlotIndex(), getSimOperator(), true);
+ }
+ } catch (RemoteException ex) {
+ // This could happen if binder process crashes.
+ }
+ return UNKNOWN_CARRIER_ID;
+ }
+
+ /**
+ * Returns carrier id based on MCCMNC (returned by {@link #getSimOperator()}) only. This is
+ * used for fallback when configurations/logic for exact carrier id {@link #getSimCarrierId()}
+ * are not found.
+ *
+ * Android carrier id table <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/carrier_list.textpb">here</a>
+ * can be updated out-of-band, its possible a MVNO (Mobile Virtual Network Operator) carrier
+ * was not fully recognized and assigned to its MNO (Mobile Network Operator) carrier id
+ * by default. After carrier id table update, a new carrier id was assigned. If apps don't
+ * take the update with the new id, it might be helpful to always fallback by using carrier
+ * id based on MCCMNC if there is no match.
+ *
+ * @return matching carrier id from passing MCCMNC. Return {@link #UNKNOWN_CARRIER_ID} if the
+ * subscription is unavailable or the carrier cannot be identified.
+ * @hide
+ */
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public int getCarrierIdFromMccMnc(String mccmnc) {
+ try {
+ ITelephony service = getITelephony();
+ if (service != null) {
+ return service.getCarrierIdFromMccMnc(getSlotIndex(), mccmnc, false);
+ }
+ } catch (RemoteException ex) {
+ // This could happen if binder process crashes.
+ }
+ return UNKNOWN_CARRIER_ID;
+ }
+
+ /**
* Return a list of certs in hex string from loaded carrier privileges access rules.
*
* @return a list of certificate in hex string. return {@code null} if there is no certs
@@ -8635,48 +8728,6 @@
}
/**
- * Returns MNO carrier id of the current subscription’s MCCMNC.
- * <p>MNO carrier id can be solely identified by subscription mccmnc. This is mainly used
- * for MNO fallback when exact carrier id {@link #getSimCarrierId()}
- * configurations are not found.
- *
- * @return MNO carrier id of the current subscription. Return the value same as carrier id
- * {@link #getSimCarrierId()}, if MNO carrier id cannot be identified.
- * @hide
- */
- public int getSimMNOCarrierId() {
- try {
- ITelephony service = getITelephony();
- if (service != null) {
- return service.getSubscriptionMNOCarrierId(getSubId());
- }
- } catch (RemoteException ex) {
- // This could happen if binder process crashes.
- }
- return UNKNOWN_CARRIER_ID;
- }
-
- /**
- * Returns carrier id based on MCCMNC only. This is for fallback when exact carrier id
- * {@link #getSimCarrierId()} configurations are not found
- *
- * @return matching carrier id from passing mccmnc.
- * @hide
- */
- @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- public int getCarrierIdFromMccMnc(String mccmnc) {
- try {
- ITelephony service = getITelephony();
- if (service != null) {
- return service.getCarrierIdFromMccMnc(getSlotIndex(), mccmnc);
- }
- } catch (RemoteException ex) {
- // This could happen if binder process crashes.
- }
- return UNKNOWN_CARRIER_ID;
- }
-
- /**
* Return the application ID for the uicc application type like {@link #APPTYPE_CSIM}.
* All uicc applications are uniquely identified by application ID, represented by the hex
* string. e.g, A00000015141434C00. See ETSI 102.221 and 101.220
diff --git a/telephony/java/android/telephony/UiccCardInfo.aidl b/telephony/java/android/telephony/UiccCardInfo.aidl
new file mode 100644
index 0000000..882c233
--- /dev/null
+++ b/telephony/java/android/telephony/UiccCardInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.
+ */
+
+package android.telephony;
+
+parcelable UiccCardInfo;
diff --git a/telephony/java/android/telephony/UiccCardInfo.java b/telephony/java/android/telephony/UiccCardInfo.java
new file mode 100644
index 0000000..45e4704
--- /dev/null
+++ b/telephony/java/android/telephony/UiccCardInfo.java
@@ -0,0 +1,156 @@
+/*
+ * 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.
+ */
+package android.telephony;
+
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * The UiccCardInfo represents information about a currently inserted UICC or embedded eUICC.
+ * @hide
+ */
+@SystemApi
+public class UiccCardInfo implements Parcelable {
+
+ private final boolean mIsEuicc;
+ private final int mCardId;
+ private final String mEid;
+ private final String mIccId;
+ private final int mSlotIndex;
+
+ public static final Creator<UiccCardInfo> CREATOR = new Creator<UiccCardInfo>() {
+ @Override
+ public UiccCardInfo createFromParcel(Parcel in) {
+ return new UiccCardInfo(in);
+ }
+
+ @Override
+ public UiccCardInfo[] newArray(int size) {
+ return new UiccCardInfo[size];
+ }
+ };
+
+ private UiccCardInfo(Parcel in) {
+ mIsEuicc = in.readByte() != 0;
+ mCardId = in.readInt();
+ mEid = in.readString();
+ mIccId = in.readString();
+ mSlotIndex = in.readInt();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeByte((byte) (mIsEuicc ? 1 : 0));
+ dest.writeInt(mCardId);
+ dest.writeString(mEid);
+ dest.writeString(mIccId);
+ dest.writeInt(mSlotIndex);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public UiccCardInfo(boolean isEuicc, int cardId, String eid, String iccId, int slotIndex) {
+ this.mIsEuicc = isEuicc;
+ this.mCardId = cardId;
+ this.mEid = eid;
+ this.mIccId = iccId;
+ this.mSlotIndex = slotIndex;
+ }
+
+ /**
+ * Return whether the UiccCardInfo is an eUICC.
+ * @return true if the UICC is an eUICC.
+ */
+ public boolean isEuicc() {
+ return mIsEuicc;
+ }
+
+ /**
+ * Get the card ID of the UICC. See {@link TelephonyManager#getCardIdForDefaultEuicc()} for more
+ * details on card ID.
+ */
+ public int getCardId() {
+ return mCardId;
+ }
+
+ /**
+ * Get the embedded ID (EID) of the eUICC. If the UiccCardInfo is not an eUICC
+ * (see {@link #isEuicc()}), returns null.
+ */
+ public String getEid() {
+ if (!mIsEuicc) {
+ return null;
+ }
+ return mEid;
+ }
+
+ /**
+ * Get the ICCID of the UICC.
+ */
+ public String getIccId() {
+ return mIccId;
+ }
+
+ /**
+ * Gets the slot index for the slot that the UICC is currently inserted in.
+ */
+ public int getSlotIndex() {
+ return mSlotIndex;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+
+ UiccCardInfo that = (UiccCardInfo) obj;
+ return ((mIsEuicc == that.mIsEuicc)
+ && (mCardId == that.mCardId)
+ && (Objects.equals(mEid, that.mEid))
+ && (Objects.equals(mIccId, that.mIccId))
+ && (mSlotIndex == that.mSlotIndex));
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mIsEuicc, mCardId, mEid, mIccId, mSlotIndex);
+ }
+
+ @Override
+ public String toString() {
+ return "UiccCardInfo (mIsEuicc="
+ + mIsEuicc
+ + ", mCardId="
+ + mCardId
+ + ", mEid="
+ + mEid
+ + ", mIccId="
+ + mIccId
+ + ", mSlotIndex="
+ + mSlotIndex
+ + ")";
+ }
+}
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index b5a8758..200b540 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -969,7 +969,7 @@
*/
public String toString() {
StringBuilder sb = new StringBuilder();
- sb.append("[ApnSettingV5] ")
+ sb.append("[ApnSettingV6] ")
.append(mEntryName)
.append(", ").append(mId)
.append(", ").append(mOperatorNumeric)
@@ -996,6 +996,7 @@
sb.append(", ").append(mPermanentFailed);
sb.append(", ").append(mNetworkTypeBitmask);
sb.append(", ").append(mApnSetId);
+ sb.append(", ").append(mCarrierId);
return sb.toString();
}
diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java
index 1db5850..74d1e83 100644
--- a/telephony/java/android/telephony/data/DataService.java
+++ b/telephony/java/android/telephony/data/DataService.java
@@ -16,7 +16,6 @@
package android.telephony.data;
-import android.annotation.CallSuper;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -60,7 +59,6 @@
private static final String TAG = DataService.class.getSimpleName();
public static final String DATA_SERVICE_INTERFACE = "android.telephony.data.DataService";
- public static final String DATA_SERVICE_EXTRA_SLOT_ID = "android.telephony.data.extra.SLOT_ID";
/** {@hide} */
@IntDef(prefix = "REQUEST_REASON_", value = {
@@ -116,7 +114,7 @@
* must extend this class to support data connection. Note that each instance of data service
* provider is associated with one physical SIM slot.
*/
- public class DataServiceProvider {
+ public abstract class DataServiceProvider implements AutoCloseable {
private final int mSlotId;
@@ -250,12 +248,12 @@
}
/**
- * Called when the instance of data service is destroyed (e.g. got unbind or binder died).
+ * Called when the instance of data service is destroyed (e.g. got unbind or binder died)
+ * or when the data service provider is removed. The extended class should implement this
+ * method to perform cleanup works.
*/
- @CallSuper
- protected void onDestroy() {
- mDataCallListChangedCallbacks.clear();
- }
+ @Override
+ public abstract void close();
}
private static final class SetupDataCallRequest {
@@ -345,7 +343,7 @@
break;
case DATA_SERVICE_REMOVE_DATA_SERVICE_PROVIDER:
if (serviceProvider != null) {
- serviceProvider.onDestroy();
+ serviceProvider.close();
mServiceMap.remove(slotId);
}
break;
@@ -353,7 +351,7 @@
for (int i = 0; i < mServiceMap.size(); i++) {
serviceProvider = mServiceMap.get(i);
if (serviceProvider != null) {
- serviceProvider.onDestroy();
+ serviceProvider.close();
}
}
mServiceMap.clear();
diff --git a/telephony/java/android/telephony/data/QualifiedNetworksService.java b/telephony/java/android/telephony/data/QualifiedNetworksService.java
index 57d9cce..45b4849 100644
--- a/telephony/java/android/telephony/data/QualifiedNetworksService.java
+++ b/telephony/java/android/telephony/data/QualifiedNetworksService.java
@@ -151,7 +151,7 @@
/**
* Called when the qualified networks updater is removed. The extended class should
- * implement this method to perform clean up works.
+ * implement this method to perform cleanup works.
*/
@Override
public abstract void close();
diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java
index f124595..4d95e55 100644
--- a/telephony/java/android/telephony/ims/ImsReasonInfo.java
+++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java
@@ -331,7 +331,80 @@
*/
public static final int CODE_SIP_USER_MARKED_UNWANTED = 365;
- /*
+ /**
+ * SIP Response : 405
+ * Method not allowed for the address in the Request URI
+ */
+ public static final int CODE_SIP_METHOD_NOT_ALLOWED = 366;
+
+ /**
+ * SIP Response : 407
+ * The request requires user authentication
+ */
+ public static final int CODE_SIP_PROXY_AUTHENTICATION_REQUIRED = 367;
+
+ /**
+ * SIP Response : 413
+ * Request body too large
+ */
+ public static final int CODE_SIP_REQUEST_ENTITY_TOO_LARGE = 368;
+
+ /**
+ * SIP Response : 414
+ * Request-URI too large
+ */
+ public static final int CODE_SIP_REQUEST_URI_TOO_LARGE = 369;
+
+ /**
+ * SIP Response : 421
+ * Specific extension is required, which is not present in the HEADER
+ */
+ public static final int CODE_SIP_EXTENSION_REQUIRED = 370;
+
+ /**
+ * SIP Response : 422
+ * The session expiration field too small
+ */
+ public static final int CODE_SIP_INTERVAL_TOO_BRIEF = 371;
+
+ /**
+ * SIP Response : 481
+ * Request received by the server does not match any dialog or transaction
+ */
+ public static final int CODE_SIP_CALL_OR_TRANS_DOES_NOT_EXIST = 372;
+
+ /**
+ * SIP Response : 482
+ * Server has detected a loop
+ */
+ public static final int CODE_SIP_LOOP_DETECTED = 373;
+
+ /**
+ * SIP Response : 483
+ * Max-Forwards value reached
+ */
+ public static final int CODE_SIP_TOO_MANY_HOPS = 374;
+
+ /**
+ * SIP Response : 485
+ * Request-URI is ambiguous
+ *
+ */
+ public static final int CODE_SIP_AMBIGUOUS = 376;
+
+ /**
+ * SIP Response : 491
+ * Server has pending request for same dialog
+ */
+ public static final int CODE_SIP_REQUEST_PENDING = 377;
+
+ /**
+ * SIP Response : 493
+ * The request cannot be decrypted by recipient
+ */
+ public static final int CODE_SIP_UNDECIPHERABLE = 378;
+
+ /**
* MEDIA (IMS -> Telephony)
*/
/**
@@ -384,6 +457,24 @@
* The call has been terminated by the network or remote user.
*/
public static final int CODE_USER_TERMINATED_BY_REMOTE = 510;
+ /**
+ * Upgrade Downgrade request rejected by
+ * Remote user if the request is MO initiated
+ * Local user if the request is MT initiated
+ */
+ public static final int CODE_USER_REJECTED_SESSION_MODIFICATION = 511;
+
+ /**
+ * Upgrade Downgrade request cacncelled by the user who initiated it
+ */
+ public static final int CODE_USER_CANCELLED_SESSION_MODIFICATION = 512;
+
+ /**
+ * UPGRADE DOWNGRADE operation failed
+ * This can happen due to failure from SIP/RTP/SDP generation or a Call end is
+ * triggered/received while Reinvite is in progress.
+ */
+ public static final int CODE_SESSION_MODIFICATION_FAILED = 1517;
/*
* UT
@@ -484,6 +575,16 @@
public static final int CODE_CALL_DROP_IWLAN_TO_LTE_UNAVAILABLE = 1100;
/**
+ * For MultiEndPoint - Call was rejected elsewhere
+ */
+ public static final int CODE_REJECTED_ELSEWHERE = 1017;
+
+ /**
+ * Supplementary services (HOLD/RESUME) failure error codes.
+ * Values for Supplemetary services failure - Failed, Cancelled and Re-Invite collision.
+ */
+
+ /**
* Supplementary Services (HOLD/RESUME) - the command failed.
*/
public static final int CODE_SUPP_SVC_FAILED = 1201;
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index b0c875e..0fdca5d 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -79,10 +79,7 @@
public static final int EVENT_PS_RESTRICT_DISABLED = BASE + 23;
public static final int EVENT_CLEAN_UP_CONNECTION = BASE + 24;
public static final int EVENT_RESTART_RADIO = BASE + 26;
- public static final int EVENT_SET_INTERNAL_DATA_ENABLE = BASE + 27;
public static final int EVENT_CLEAN_UP_ALL_CONNECTIONS = BASE + 29;
- public static final int CMD_SET_USER_DATA_ENABLE = BASE + 30;
- public static final int CMD_SET_POLICY_DATA_ENABLE = BASE + 32;
public static final int EVENT_ICC_CHANGED = BASE + 33;
public static final int EVENT_DISCONNECT_DC_RETRYING = BASE + 34;
public static final int EVENT_DATA_SETUP_COMPLETE_ERROR = BASE + 35;
@@ -93,14 +90,12 @@
public static final int CMD_NET_STAT_POLL = BASE + 40;
public static final int EVENT_DATA_RAT_CHANGED = BASE + 41;
public static final int CMD_CLEAR_PROVISIONING_SPINNER = BASE + 42;
- public static final int EVENT_DEVICE_PROVISIONED_CHANGE = BASE + 43;
public static final int EVENT_REDIRECTION_DETECTED = BASE + 44;
public static final int EVENT_PCO_DATA_RECEIVED = BASE + 45;
- public static final int EVENT_SET_CARRIER_DATA_ENABLED = BASE + 46;
+ public static final int EVENT_DATA_ENABLED_CHANGED = BASE + 46;
public static final int EVENT_DATA_RECONNECT = BASE + 47;
public static final int EVENT_ROAMING_SETTING_CHANGE = BASE + 48;
public static final int EVENT_DATA_SERVICE_BINDING_CHANGED = BASE + 49;
- public static final int EVENT_DEVICE_PROVISIONING_DATA_SETTING_CHANGE = BASE + 50;
/***** Constants *****/
diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
index 442fc34..40c7a9a 100644
--- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -53,5 +53,6 @@
void onPhoneCapabilityChanged(in PhoneCapability capability);
void onRadioPowerStateChanged(in int state);
void onPreferredDataSubIdChanged(in int subId);
+ void onCallDisconnectCauseChanged(in int disconnectCause, in int preciseDisconnectCause);
}
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index f9db4b0..65d1a920 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -210,6 +210,10 @@
*/
List<SubscriptionInfo> getOpportunisticSubscriptions(String callingPackage);
+ boolean removeSubscriptionsFromGroup(in int[] subIdList, String callingPackage);
+
+ List<SubscriptionInfo> getSubscriptionsInGroup(int subId, String callingPackage);
+
int getSlotIndex(int subId);
int[] getSubId(int slotIndex);
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 5a06f6a..99d362a 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -56,6 +56,7 @@
import java.util.List;
import java.util.Map;
+import android.telephony.UiccCardInfo;
import android.telephony.UiccSlotInfo;
/**
@@ -1337,18 +1338,6 @@
String getSubscriptionCarrierName(int subId);
/**
- * Returns MNO carrier id of the current subscription’s MCCMNC.
- * <p>MNO carrier id can be solely identified by subscription mccmnc. This is mainly used
- * for MNO fallback when exact carrier id {@link #getSimCarrierId()}
- * configurations are not found.
- *
- * @return MNO carrier id of the current subscription. Return the value same as carrier id
- * {@link #getSimCarrierId()}, if MNO carrier id cannot be identified.
- * @hide
- */
- int getSubscriptionMNOCarrierId(int subId);
-
- /**
* Returns fine-grained carrier id of the current subscription.
*
* <p>The precise carrier id can be used to further differentiate a carrier by different
@@ -1383,10 +1372,13 @@
* Returns carrier id based on MCCMNC only. This will return a MNO carrier id used for fallback
* check when exact carrier id {@link #getSimCarrierId()} configurations are not found
*
+ * @param isSubscriptionMccMnc. If {@true} it means this is a query for subscription mccmnc
+ * {@false} otherwise.
+ *
* @return carrier id from passing mccmnc.
* @hide
*/
- int getCarrierIdFromMccMnc(int slotIndex, String mccmnc);
+ int getCarrierIdFromMccMnc(int slotIndex, String mccmnc, boolean isSubscriptionMccMnc);
/**
* Action set from carrier signalling broadcast receivers to enable/disable metered apns
@@ -1495,6 +1487,17 @@
int getCardIdForDefaultEuicc(int subId, String callingPackage);
/**
+ * Gets information about currently inserted UICCs and eUICCs. See {@link UiccCardInfo} for more
+ * details on the kind of information available.
+ *
+ * @return UiccCardInfo an array of UiccCardInfo objects, representing information on the
+ * currently inserted UICCs and eUICCs.
+ *
+ * @hide
+ */
+ UiccCardInfo[] getUiccCardsInfo();
+
+ /**
* Get slot info for all the UICC slots.
* @return UiccSlotInfo array.
* @hide
diff --git a/tests/net/java/android/net/apf/ApfTest.java b/tests/net/java/android/net/apf/ApfTest.java
index 436dd85..151b559 100644
--- a/tests/net/java/android/net/apf/ApfTest.java
+++ b/tests/net/java/android/net/apf/ApfTest.java
@@ -1048,12 +1048,17 @@
4, // Protocol size: 4
0, 2 // Opcode: reply (2)
};
- private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ETH_HEADER_LEN + 24;
+ private static final int ARP_SOURCE_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 14;
+ private static final int ARP_TARGET_IP_ADDRESS_OFFSET = ARP_HEADER_OFFSET + 24;
private static final byte[] MOCK_IPV4_ADDR = {10, 0, 0, 1};
private static final byte[] MOCK_BROADCAST_IPV4_ADDR = {10, 0, 31, (byte) 255}; // prefix = 19
private static final byte[] MOCK_MULTICAST_IPV4_ADDR = {(byte) 224, 0, 0, 1};
private static final byte[] ANOTHER_IPV4_ADDR = {10, 0, 0, 2};
+ private static final byte[] IPV4_SOURCE_ADDR = {10, 0, 0, 3};
+ private static final byte[] ANOTHER_IPV4_SOURCE_ADDR = {(byte) 192, 0, 2, 1};
+ private static final byte[] BUG_PROBE_SOURCE_ADDR1 = {0, 0, 1, 2};
+ private static final byte[] BUG_PROBE_SOURCE_ADDR2 = {3, 4, 0, 0};
private static final byte[] IPV4_ANY_HOST_ADDR = {0, 0, 0, 0};
// Helper to initialize a default apfFilter.
@@ -1399,10 +1404,16 @@
assertVerdict(filterResult, program, arpRequestBroadcast(ANOTHER_IPV4_ADDR));
assertDrop(program, arpRequestBroadcast(IPV4_ANY_HOST_ADDR));
+ // Verify ARP reply packets from different source ip
+ assertDrop(program, arpReply(IPV4_ANY_HOST_ADDR, IPV4_ANY_HOST_ADDR));
+ assertPass(program, arpReply(ANOTHER_IPV4_SOURCE_ADDR, IPV4_ANY_HOST_ADDR));
+ assertPass(program, arpReply(BUG_PROBE_SOURCE_ADDR1, IPV4_ANY_HOST_ADDR));
+ assertPass(program, arpReply(BUG_PROBE_SOURCE_ADDR2, IPV4_ANY_HOST_ADDR));
+
// Verify unicast ARP reply packet is always accepted.
- assertPass(program, arpReplyUnicast(MOCK_IPV4_ADDR));
- assertPass(program, arpReplyUnicast(ANOTHER_IPV4_ADDR));
- assertPass(program, arpReplyUnicast(IPV4_ANY_HOST_ADDR));
+ assertPass(program, arpReply(IPV4_SOURCE_ADDR, MOCK_IPV4_ADDR));
+ assertPass(program, arpReply(IPV4_SOURCE_ADDR, ANOTHER_IPV4_ADDR));
+ assertPass(program, arpReply(IPV4_SOURCE_ADDR, IPV4_ANY_HOST_ADDR));
// Verify GARP reply packets are always filtered
assertDrop(program, garpReply());
@@ -1431,19 +1442,20 @@
apfFilter.shutdown();
}
- private static byte[] arpRequestBroadcast(byte[] tip) {
+ private static byte[] arpReply(byte[] sip, byte[] tip) {
ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
- put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS);
put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER);
+ put(packet, ARP_SOURCE_IP_ADDRESS_OFFSET, sip);
put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, tip);
return packet.array();
}
- private static byte[] arpReplyUnicast(byte[] tip) {
+ private static byte[] arpRequestBroadcast(byte[] tip) {
ByteBuffer packet = ByteBuffer.wrap(new byte[100]);
packet.putShort(ETH_ETHERTYPE_OFFSET, (short)ETH_P_ARP);
- put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REPLY_HEADER);
+ put(packet, ETH_DEST_ADDR_OFFSET, ETH_BROADCAST_MAC_ADDRESS);
+ put(packet, ARP_HEADER_OFFSET, ARP_IPV4_REQUEST_HEADER);
put(packet, ARP_TARGET_IP_ADDRESS_OFFSET, tip);
return packet.array();
}
diff --git a/tests/net/java/android/net/dhcp/DhcpServerTest.java b/tests/net/java/android/net/dhcp/DhcpServerTest.java
index df34c73..ab9bd84 100644
--- a/tests/net/java/android/net/dhcp/DhcpServerTest.java
+++ b/tests/net/java/android/net/dhcp/DhcpServerTest.java
@@ -25,7 +25,6 @@
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
-import static junit.framework.Assert.assertNull;
import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -48,7 +47,6 @@
import android.net.dhcp.DhcpLeaseRepository.OutOfAddressesException;
import android.net.dhcp.DhcpServer.Clock;
import android.net.dhcp.DhcpServer.Dependencies;
-import android.net.util.InterfaceParams;
import android.net.util.SharedLog;
import android.os.test.TestLooper;
import android.support.test.filters.SmallTest;
@@ -74,9 +72,6 @@
public class DhcpServerTest {
private static final String PROP_DEXMAKER_SHARE_CLASSLOADER = "dexmaker.share_classloader";
private static final String TEST_IFACE = "testiface";
- private static final MacAddress TEST_IFACE_MAC = MacAddress.fromString("11:22:33:44:55:66");
- private static final InterfaceParams TEST_IFACEPARAMS =
- new InterfaceParams(TEST_IFACE, 1, TEST_IFACE_MAC);
private static final Inet4Address TEST_SERVER_ADDR = parseAddr("192.168.0.2");
private static final LinkAddress TEST_SERVER_LINKADDR = new LinkAddress(TEST_SERVER_ADDR, 20);
@@ -149,7 +144,7 @@
.build();
mLooper = new TestLooper();
- mServer = new DhcpServer(mLooper.getLooper(), TEST_IFACEPARAMS, servingParams,
+ mServer = new DhcpServer(mLooper.getLooper(), TEST_IFACE, servingParams,
new SharedLog(DhcpServerTest.class.getSimpleName()), mDeps);
mServer.start();
diff --git a/tests/net/java/android/net/ip/IpServerTest.java b/tests/net/java/android/net/ip/IpServerTest.java
index cff0b54..2c675c6 100644
--- a/tests/net/java/android/net/ip/IpServerTest.java
+++ b/tests/net/java/android/net/ip/IpServerTest.java
@@ -404,7 +404,7 @@
private void assertDhcpStarted(IpPrefix expectedPrefix) {
verify(mDependencies, times(1)).makeDhcpServer(
- eq(mLooper.getLooper()), eq(TEST_IFACE_PARAMS), any(), eq(mSharedLog));
+ eq(mLooper.getLooper()), eq(IFACE_NAME), any(), eq(mSharedLog));
verify(mDhcpServer, times(1)).start();
final DhcpServingParams params = mDhcpParamsCaptor.getValue();
// Last address byte is random
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index bca9be7..e6b43d2 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -240,7 +240,7 @@
}
@Override
- public DhcpServer makeDhcpServer(Looper looper, InterfaceParams iface,
+ public DhcpServer makeDhcpServer(Looper looper, String ifName,
DhcpServingParams params, SharedLog log) {
return mDhcpServer;
}
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 39ca80b..968376b 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -78,7 +78,7 @@
static uint32_t ParseFormatAttribute(const StringPiece& str) {
uint32_t mask = 0;
- for (StringPiece part : util::Tokenize(str, '|')) {
+ for (const StringPiece& part : util::Tokenize(str, '|')) {
StringPiece trimmed_part = util::TrimWhitespace(part);
uint32_t type = ParseFormatType(trimmed_part);
if (type == 0) {
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index 82d9e04..99420de 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -360,7 +360,7 @@
return util::make_unique<BinaryPrimitive>(flags);
}
- for (StringPiece part : util::Tokenize(str, '|')) {
+ for (const StringPiece& part : util::Tokenize(str, '|')) {
StringPiece trimmed_part = util::TrimWhitespace(part);
bool flag_set = false;
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index 411ad74..0b43c5d 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -486,7 +486,7 @@
}
Printer r_txt_printer(&fout_text);
- for (const auto res : xmlres->file.exported_symbols) {
+ for (const auto& res : xmlres->file.exported_symbols) {
r_txt_printer.Print("default int id ");
r_txt_printer.Println(res.name.entry);
}
diff --git a/tools/aapt2/java/AnnotationProcessor.cpp b/tools/aapt2/java/AnnotationProcessor.cpp
index 8d91b00..a4610b2 100644
--- a/tools/aapt2/java/AnnotationProcessor.cpp
+++ b/tools/aapt2/java/AnnotationProcessor.cpp
@@ -113,7 +113,7 @@
void AnnotationProcessor::Print(Printer* printer) const {
if (has_comments_) {
std::string result = comment_.str();
- for (StringPiece line : util::Tokenize(result, '\n')) {
+ for (const StringPiece& line : util::Tokenize(result, '\n')) {
printer->Println(line);
}
printer->Println(" */");
diff --git a/tools/aapt2/util/Files.cpp b/tools/aapt2/util/Files.cpp
index 5a8ff09..a407c22 100644
--- a/tools/aapt2/util/Files.cpp
+++ b/tools/aapt2/util/Files.cpp
@@ -165,7 +165,7 @@
std::string PackageToPath(const StringPiece& package) {
std::string out_path;
- for (StringPiece part : util::Tokenize(package, '.')) {
+ for (const StringPiece& part : util::Tokenize(package, '.')) {
AppendPath(&out_path, part);
}
return out_path;
diff --git a/tools/incident_report/printer.h b/tools/incident_report/printer.h
index ed93fa1..63e276b 100644
--- a/tools/incident_report/printer.h
+++ b/tools/incident_report/printer.h
@@ -22,7 +22,7 @@
class Out
{
public:
- Out(int fd);
+ explicit Out(int fd);
~Out();
void printf(const char* format, ...);
diff --git a/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessor.java b/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessor.java
index 1d4c435..d368136 100644
--- a/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessor.java
+++ b/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessor.java
@@ -28,6 +28,7 @@
import java.io.IOException;
import java.io.PrintStream;
+import java.net.URLEncoder;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
@@ -38,7 +39,9 @@
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
/**
@@ -108,10 +111,25 @@
"startline",
"startcol",
"endline",
- "endcol"
+ "endcol",
+ "properties"
);
}
+ private String encodeAnnotationProperties(AnnotationMirror annotation) {
+ StringBuilder sb = new StringBuilder();
+ for (Map.Entry<? extends ExecutableElement, ? extends AnnotationValue> e
+ : annotation.getElementValues().entrySet()) {
+ if (sb.length() > 0) {
+ sb.append("&");
+ }
+ sb.append(e.getKey().getSimpleName())
+ .append("=")
+ .append(URLEncoder.encode(e.getValue().toString()));
+ }
+ return sb.toString();
+ }
+
/**
* Maps an annotated element to the source position of the @UnsupportedAppUsage annotation
* attached to it. It returns CSV in the format:
@@ -137,7 +155,8 @@
lines.getLineNumber(pair.fst.pos().getStartPosition()),
lines.getColumnNumber(pair.fst.pos().getStartPosition()),
lines.getLineNumber(pair.fst.pos().getEndPosition(pair.snd.endPositions)),
- lines.getColumnNumber(pair.fst.pos().getEndPosition(pair.snd.endPositions)));
+ lines.getColumnNumber(pair.fst.pos().getEndPosition(pair.snd.endPositions)),
+ encodeAnnotationProperties(unsupportedAppUsage));
}
/**
diff --git a/tools/stats_log_api_gen/Android.bp b/tools/stats_log_api_gen/Android.bp
index 703a67b..5725f0c 100644
--- a/tools/stats_log_api_gen/Android.bp
+++ b/tools/stats_log_api_gen/Android.bp
@@ -96,6 +96,7 @@
cc_library_shared {
name: "libstatslog",
+ host_supported: true,
generated_sources: ["statslog.cpp"],
generated_headers: ["statslog.h"],
cflags: [
@@ -105,8 +106,19 @@
export_generated_headers: ["statslog.h"],
shared_libs: [
"liblog",
- "libutils",
"libcutils",
],
static_libs: ["libstatssocket"],
+ target: {
+ android: {
+ shared_libs: [
+ "libutils",
+ ],
+ },
+ host: {
+ static_libs: [
+ "libutils",
+ ],
+ },
+ },
}
diff --git a/tools/stats_log_api_gen/Collation.cpp b/tools/stats_log_api_gen/Collation.cpp
index ebdcdfd..61174d9 100644
--- a/tools/stats_log_api_gen/Collation.cpp
+++ b/tools/stats_log_api_gen/Collation.cpp
@@ -47,7 +47,8 @@
fields(that.fields),
primaryFields(that.primaryFields),
exclusiveField(that.exclusiveField),
- uidField(that.uidField) {}
+ uidField(that.uidField),
+ binaryFields(that.binaryFields) {}
AtomDecl::AtomDecl(int c, const string& n, const string& m)
:code(c),
@@ -116,6 +117,9 @@
if (field->message_type()->full_name() ==
"android.os.statsd.AttributionNode") {
return JAVA_TYPE_ATTRIBUTION_CHAIN;
+ } else if (field->options().GetExtension(os::statsd::log_mode) ==
+ os::statsd::LogMode::MODE_BYTES) {
+ return JAVA_TYPE_BYTE_ARRAY;
} else {
return JAVA_TYPE_OBJECT;
}
@@ -185,6 +189,8 @@
for (map<int, const FieldDescriptor *>::const_iterator it = fields.begin();
it != fields.end(); it++) {
const FieldDescriptor *field = it->second;
+ bool isBinaryField = field->options().GetExtension(os::statsd::log_mode) ==
+ os::statsd::LogMode::MODE_BYTES;
java_type_t javaType = java_type(field);
@@ -198,12 +204,19 @@
field->name().c_str());
errorCount++;
continue;
- } else if (javaType == JAVA_TYPE_BYTE_ARRAY) {
+ } else if (javaType == JAVA_TYPE_BYTE_ARRAY && !isBinaryField) {
print_error(field, "Raw bytes type not allowed for field: %s\n",
field->name().c_str());
errorCount++;
continue;
}
+
+ if (isBinaryField && javaType != JAVA_TYPE_BYTE_ARRAY) {
+ print_error(field, "Cannot mark field %s as bytes.\n",
+ field->name().c_str());
+ errorCount++;
+ continue;
+ }
}
// Check that if there's an attribution chain, it's at position 1.
@@ -228,12 +241,16 @@
it != fields.end(); it++) {
const FieldDescriptor *field = it->second;
java_type_t javaType = java_type(field);
+ bool isBinaryField = field->options().GetExtension(os::statsd::log_mode) ==
+ os::statsd::LogMode::MODE_BYTES;
AtomField atField(field->name(), javaType);
if (javaType == JAVA_TYPE_ENUM) {
// All enums are treated as ints when it comes to function signatures.
signature->push_back(JAVA_TYPE_INT);
collate_enums(*field->enum_type(), &atField);
+ } else if (javaType == JAVA_TYPE_OBJECT && isBinaryField) {
+ signature->push_back(JAVA_TYPE_BYTE_ARRAY);
} else {
signature->push_back(javaType);
}
@@ -275,6 +292,10 @@
errorCount++;
}
}
+ // Binary field validity is already checked above.
+ if (isBinaryField) {
+ atomDecl->binaryFields.push_back(it->first);
+ }
}
return errorCount;
diff --git a/tools/stats_log_api_gen/Collation.h b/tools/stats_log_api_gen/Collation.h
index 5d2c302..a8b270c 100644
--- a/tools/stats_log_api_gen/Collation.h
+++ b/tools/stats_log_api_gen/Collation.h
@@ -86,6 +86,8 @@
int uidField = 0;
+ vector<int> binaryFields;
+
AtomDecl();
AtomDecl(const AtomDecl& that);
AtomDecl(int code, const string& name, const string& message);
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index e519909..2478b91 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -68,6 +68,8 @@
return "double";
case JAVA_TYPE_STRING:
return "char const*";
+ case JAVA_TYPE_BYTE_ARRAY:
+ return "char const*";
default:
return "UNKNOWN";
}
@@ -90,6 +92,8 @@
return "double";
case JAVA_TYPE_STRING:
return "java.lang.String";
+ case JAVA_TYPE_BYTE_ARRAY:
+ return "byte[]";
default:
return "UNKNOWN";
}
@@ -104,7 +108,9 @@
fprintf(out, "#include <mutex>\n");
fprintf(out, "#include <chrono>\n");
fprintf(out, "#include <thread>\n");
+ fprintf(out, "#ifdef __ANDROID__\n");
fprintf(out, "#include <cutils/properties.h>\n");
+ fprintf(out, "#endif\n");
fprintf(out, "#include <stats_event_list.h>\n");
fprintf(out, "#include <log/log.h>\n");
fprintf(out, "#include <statslog.h>\n");
@@ -115,7 +121,11 @@
fprintf(out, "namespace util {\n");
fprintf(out, "// the single event tag id for all stats logs\n");
fprintf(out, "const static int kStatsEventTag = 1937006964;\n");
+ fprintf(out, "#ifdef __ANDROID__\n");
fprintf(out, "const static bool kStatsdEnabled = property_get_bool(\"ro.statsd.enable\", true);\n");
+ fprintf(out, "#else\n");
+ fprintf(out, "const static bool kStatsdEnabled = false;\n");
+ fprintf(out, "#endif\n");
std::set<string> kTruncatingAtomNames = {"mobile_radio_power_state_changed",
"audio_state_changed",
@@ -200,13 +210,40 @@
}
fprintf(out, " return options;\n");
- fprintf(out, " }\n");
+ fprintf(out, "}\n");
fprintf(out,
"const std::map<int, StateAtomFieldOptions> "
"AtomsInfo::kStateAtomsFieldOptions = "
"getStateAtomFieldOptions();\n");
+ fprintf(out,
+ "static std::map<int, std::vector<int>> "
+ "getBinaryFieldAtoms() {\n");
+ fprintf(out, " std::map<int, std::vector<int>> options;\n");
+ for (set<AtomDecl>::const_iterator atom = atoms.decls.begin();
+ atom != atoms.decls.end(); atom++) {
+ if (atom->binaryFields.size() == 0) {
+ continue;
+ }
+ fprintf(out,
+ "\n // Adding binary fields for atom "
+ "(%d)%s\n",
+ atom->code, atom->name.c_str());
+
+ for (const auto& field : atom->binaryFields) {
+ fprintf(out, " options[static_cast<int>(%s)].push_back(%d);\n",
+ make_constant_name(atom->name).c_str(), field);
+ }
+ }
+
+ fprintf(out, " return options;\n");
+ fprintf(out, "}\n");
+
+ fprintf(out,
+ "const std::map<int, std::vector<int>> "
+ "AtomsInfo::kBytesFieldAtoms = "
+ "getBinaryFieldAtoms();\n");
fprintf(out, "int64_t lastRetryTimestampNs = -1;\n");
fprintf(out, "const int64_t kMinRetryIntervalNs = NS_PER_SEC * 60 * 20; // 20 minutes\n");
@@ -235,6 +272,9 @@
chainField.name.c_str(), chainField.name.c_str());
}
}
+ } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
+ fprintf(out, ", %s arg%d, size_t arg%d_length",
+ cpp_type_name(*arg), argIndex, argIndex);
} else {
fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
}
@@ -277,6 +317,10 @@
fprintf(out, " event.end();\n");
fprintf(out, " }\n");
fprintf(out, " event.end();\n\n");
+ } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
+ fprintf(out,
+ " event.AppendCharArray(arg%d, arg%d_length);\n",
+ argIndex, argIndex);
} else {
if (*arg == JAVA_TYPE_STRING) {
fprintf(out, " if (arg%d == NULL) {\n", argIndex);
@@ -317,6 +361,9 @@
chainField.name.c_str(), chainField.name.c_str());
}
}
+ } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
+ fprintf(out, ", %s arg%d, size_t arg%d_length",
+ cpp_type_name(*arg), argIndex, argIndex);
} else {
fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
}
@@ -343,6 +390,8 @@
chainField.name.c_str(), chainField.name.c_str());
}
}
+ } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
+ fprintf(out, ", arg%d, arg%d_length", argIndex, argIndex);
} else {
fprintf(out, ", arg%d", argIndex);
}
@@ -491,6 +540,10 @@
chainField.name.c_str(), chainField.name.c_str());
}
}
+ } else if (field->javaType == JAVA_TYPE_BYTE_ARRAY) {
+ fprintf(out, ", %s %s, size_t %s_length",
+ cpp_type_name(field->javaType), field->name.c_str(),
+ field->name.c_str());
} else {
fprintf(out, ", %s %s", cpp_type_name(field->javaType), field->name.c_str());
}
@@ -518,6 +571,9 @@
chainField.name.c_str(), chainField.name.c_str());
}
}
+ } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
+ fprintf(out, ", %s arg%d, size_t arg%d_length",
+ cpp_type_name(*arg), argIndex, argIndex);
} else {
fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
}
@@ -600,6 +656,9 @@
fprintf(out,
" const static std::map<int, StateAtomFieldOptions> "
"kStateAtomsFieldOptions;\n");
+ fprintf(out,
+ " const static std::map<int, std::vector<int>> "
+ "kBytesFieldAtoms;");
fprintf(out, "};\n");
fprintf(out, "const static int kMaxPushedAtomId = %d;\n\n",
@@ -632,6 +691,8 @@
field != atom.fields.end(); field++) {
if (field->javaType == JAVA_TYPE_ATTRIBUTION_CHAIN) {
fprintf(out, ", android.os.WorkSource workSource");
+ } else if (field->javaType == JAVA_TYPE_BYTE_ARRAY) {
+ fprintf(out, ", byte[] %s", field->name.c_str());
} else {
fprintf(out, ", %s %s", java_type_name(field->javaType), field->name.c_str());
}
@@ -821,6 +882,8 @@
return "jdouble";
case JAVA_TYPE_STRING:
return "jstring";
+ case JAVA_TYPE_BYTE_ARRAY:
+ return "jbyteArray";
default:
return "UNKNOWN";
}
@@ -868,6 +931,9 @@
case JAVA_TYPE_ATTRIBUTION_CHAIN:
result += "_AttributionChain";
break;
+ case JAVA_TYPE_BYTE_ARRAY:
+ result += "_bytes";
+ break;
default:
result += "_UNKNOWN";
break;
@@ -893,6 +959,8 @@
return "D";
case JAVA_TYPE_STRING:
return "Ljava/lang/String;";
+ case JAVA_TYPE_BYTE_ARRAY:
+ return "[B";
default:
return "UNKNOWN";
}
@@ -960,6 +1028,32 @@
fprintf(out, " } else {\n");
fprintf(out, " str%d = NULL;\n", argIndex);
fprintf(out, " }\n");
+ } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
+ hadStringOrChain = true;
+ fprintf(out, " jbyte* jbyte_array%d;\n", argIndex);
+ fprintf(out, " const char* str%d;\n", argIndex);
+ fprintf(out, " int str%d_length = 0;\n", argIndex);
+ fprintf(out,
+ " if (arg%d != NULL && env->GetArrayLength(arg%d) > "
+ "0) {\n",
+ argIndex, argIndex);
+ fprintf(out,
+ " jbyte_array%d = "
+ "env->GetByteArrayElements(arg%d, NULL);\n",
+ argIndex, argIndex);
+ fprintf(out,
+ " str%d_length = env->GetArrayLength(arg%d);\n",
+ argIndex, argIndex);
+ fprintf(out,
+ " str%d = "
+ "reinterpret_cast<char*>(env->GetByteArrayElements(arg%"
+ "d, NULL));\n",
+ argIndex, argIndex);
+ fprintf(out, " } else {\n");
+ fprintf(out, " jbyte_array%d = NULL;\n", argIndex);
+ fprintf(out, " str%d = NULL;\n", argIndex);
+ fprintf(out, " }\n");
+
} else if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
hadStringOrChain = true;
for (auto chainField : attributionDecl.fields) {
@@ -1026,8 +1120,15 @@
}
}
} else {
- const char *argName = (*arg == JAVA_TYPE_STRING) ? "str" : "arg";
+ const char* argName = (*arg == JAVA_TYPE_STRING ||
+ *arg == JAVA_TYPE_BYTE_ARRAY)
+ ? "str"
+ : "arg";
fprintf(out, ", (%s)%s%d", cpp_type_name(*arg), argName, argIndex);
+
+ if (*arg == JAVA_TYPE_BYTE_ARRAY) {
+ fprintf(out, ", %s%d_length", argName, argIndex);
+ }
}
argIndex++;
}
@@ -1043,6 +1144,13 @@
fprintf(out, " env->ReleaseStringUTFChars(arg%d, str%d);\n",
argIndex, argIndex);
fprintf(out, " }\n");
+ } else if (*arg == JAVA_TYPE_BYTE_ARRAY) {
+ fprintf(out, " if (str%d != NULL) { \n", argIndex);
+ fprintf(out,
+ " env->ReleaseByteArrayElements(arg%d, "
+ "jbyte_array%d, 0);\n",
+ argIndex, argIndex);
+ fprintf(out, " }\n");
} else if (*arg == JAVA_TYPE_ATTRIBUTION_CHAIN) {
for (auto chainField : attributionDecl.fields) {
if (chainField.javaType == JAVA_TYPE_INT) {
diff --git a/tools/stats_log_api_gen/test.proto b/tools/stats_log_api_gen/test.proto
index 264a865..188b765 100644
--- a/tools/stats_log_api_gen/test.proto
+++ b/tools/stats_log_api_gen/test.proto
@@ -109,6 +109,28 @@
oneof event { BadAttributionNodePositionAtom bad = 1; }
}
+message GoodEventWithBinaryFieldAtom {
+ oneof event { GoodBinaryFieldAtom field1 = 1; }
+}
+
+message ComplexField {
+ optional string str = 1;
+}
+
+message GoodBinaryFieldAtom {
+ optional int32 field1 = 1;
+ optional ComplexField bf = 2 [(android.os.statsd.log_mode) = MODE_BYTES];
+}
+
+message BadEventWithBinaryFieldAtom {
+ oneof event { BadBinaryFieldAtom field1 = 1; }
+}
+
+message BadBinaryFieldAtom {
+ optional int32 field1 = 1;
+ optional ComplexField bf = 2;
+}
+
message BadStateAtoms {
oneof event {
BadStateAtom1 bad1 = 1;
diff --git a/tools/stats_log_api_gen/test_collation.cpp b/tools/stats_log_api_gen/test_collation.cpp
index 1936d96..ad3bffac 100644
--- a/tools/stats_log_api_gen/test_collation.cpp
+++ b/tools/stats_log_api_gen/test_collation.cpp
@@ -212,5 +212,19 @@
EXPECT_EQ(0, errorCount);
}
+TEST(CollationTest, PassOnGoodBinaryFieldAtom) {
+ Atoms atoms;
+ int errorCount =
+ collate_atoms(GoodEventWithBinaryFieldAtom::descriptor(), &atoms);
+ EXPECT_EQ(0, errorCount);
+}
+
+TEST(CollationTest, FailOnBadBinaryFieldAtom) {
+ Atoms atoms;
+ int errorCount =
+ collate_atoms(BadEventWithBinaryFieldAtom::descriptor(), &atoms);
+ EXPECT_TRUE(errorCount > 0);
+}
+
} // namespace stats_log_api_gen
} // namespace android
\ No newline at end of file