diff options
401 files changed, 9959 insertions, 4593 deletions
diff --git a/Android.bp b/Android.bp index 9a815c69751c..124f4732f2c5 100644 --- a/Android.bp +++ b/Android.bp @@ -484,6 +484,8 @@ java_defaults { "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", @@ -502,6 +504,7 @@ java_defaults { "telephony/java/android/telephony/ims/aidl/IImsServiceController.aidl", "telephony/java/android/telephony/ims/aidl/IImsServiceControllerListener.aidl", "telephony/java/android/telephony/ims/aidl/IImsSmsListener.aidl", + "telephony/java/android/telephony/ims/aidl/IRcs.aidl", "telephony/java/android/telephony/mbms/IMbmsDownloadSessionCallback.aidl", "telephony/java/android/telephony/mbms/IMbmsStreamingSessionCallback.aidl", "telephony/java/android/telephony/mbms/IMbmsGroupCallSessionCallback.aidl", @@ -578,7 +581,6 @@ java_defaults { "telephony/java/com/android/internal/telephony/euicc/ISetDefaultSmdpAddressCallback.aidl", "telephony/java/com/android/internal/telephony/euicc/ISetNicknameCallback.aidl", "telephony/java/com/android/internal/telephony/euicc/ISwitchToProfileCallback.aidl", - "telephony/java/com/android/internal/telephony/rcs/IRcs.aidl", "wifi/java/android/net/wifi/ISoftApCallback.aidl", "wifi/java/android/net/wifi/IWifiManager.aidl", "wifi/java/android/net/wifi/aware/IWifiAwareDiscoverySessionCallback.aidl", @@ -621,6 +623,8 @@ java_defaults { "core/java/com/android/server/DropboxLogTags.logtags", "core/java/org/chromium/arc/EventLogTags.logtags", + ":platform-properties", + ":framework-statslog-gen", ], @@ -653,7 +657,6 @@ java_defaults { "frameworks/av/media/libaudioclient/aidl", "frameworks/native/aidl/gui", "system/core/storaged/binder", - "system/netd/server/binder", "system/vold/binder", "system/bt/binder", "system/security/keystore/binder", @@ -676,6 +679,7 @@ java_defaults { static_libs: [ "apex_aidl_interface-java", + "networkstack-aidl-interfaces-java", "framework-protos", "android.hidl.base-V1.0-java", "android.hardware.cas-V1.0-java", @@ -815,6 +819,16 @@ gensrcs { 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 { @@ -1146,6 +1160,7 @@ framework_docs_only_libs = [ 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 " + @@ -1562,6 +1577,7 @@ droidstubs { 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/Android.mk b/Android.mk index 92e33e988249..e3cc2754fed3 100644 --- a/Android.mk +++ b/Android.mk @@ -72,6 +72,11 @@ $(OUT_DOCS)/offline-sdk-timestamp: $(OUT_DOCS)/offline-sdk-docs-docs.zip $(hide) mkdir -p $(OUT_DOCS)/offline-sdk ( unzip -qo $< -d $(OUT_DOCS)/offline-sdk && touch -f $@ ) || exit 1 +# Run this for checkbuild +checkbuild: doc-comment-check-docs +# Check comment when you are updating the API +update-api: doc-comment-check-docs + # ==== hiddenapi lists ======================================= .KATI_RESTAT: $(INTERNAL_PLATFORM_HIDDENAPI_FLAGS) $(INTERNAL_PLATFORM_HIDDENAPI_FLAGS): \ diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg index e061b1548e58..543f0edbf835 100644 --- a/PREUPLOAD.cfg +++ b/PREUPLOAD.cfg @@ -1,13 +1,5 @@ [Hook Scripts] checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT} - -fw core/java/android/ - graphics/java/android - core/tests/coretests/src/android/ - packages/PrintRecommendationService/ - packages/PrintSpooler/ - services/print/ - services/usb/ - telephony/ api_lint_hook = ${REPO_ROOT}/frameworks/base/tools/apilint/apilint_sha.sh ${PREUPLOAD_COMMIT} diff --git a/api/current.txt b/api/current.txt index 4e4d823d2f4e..89b14b894f64 100755 --- a/api/current.txt +++ b/api/current.txt @@ -27225,7 +27225,7 @@ package android.net { 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 @@ package android.net { 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 @@ package android.net { 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 @@ package android.net { 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 @@ package android.net { 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 @@ package android.net { 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 @@ package android.net { 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 @@ package android.net { 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 @@ package android.provider { } 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 @@ package android.provider { 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 @@ package android.service.carrier { 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 @@ package android.system { 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 @@ package android.system { 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; @@ -41116,8 +41131,9 @@ package android.telecom { method public void swapConference(); method public void unhold(); method public void unregisterCallback(android.telecom.Call.Callback); - field public static final java.lang.String AVAILABLE_PHONE_ACCOUNTS = "selectPhoneAccountAccounts"; + field public static final deprecated java.lang.String AVAILABLE_PHONE_ACCOUNTS = "selectPhoneAccountAccounts"; field public static final java.lang.String EXTRA_LAST_EMERGENCY_CALLBACK_TIME_MILLIS = "android.telecom.extra.LAST_EMERGENCY_CALLBACK_TIME_MILLIS"; + field public static final java.lang.String EXTRA_SUGGESTED_PHONE_ACCOUNTS = "android.telecom.extra.SUGGESTED_PHONE_ACCOUNTS"; field public static final int STATE_ACTIVE = 4; // 0x4 field public static final int STATE_CONNECTING = 9; // 0x9 field public static final int STATE_DIALING = 1; // 0x1 @@ -41688,6 +41704,20 @@ package android.telecom { field public static final android.os.Parcelable.Creator<android.telecom.PhoneAccountHandle> CREATOR; } + public final class PhoneAccountSuggestion implements android.os.Parcelable { + method public int describeContents(); + method public android.telecom.PhoneAccountHandle getPhoneAccountHandle(); + method public int getReason(); + method public boolean shouldAutoSelect(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telecom.PhoneAccountSuggestion> CREATOR; + field public static final int REASON_FREQUENT = 2; // 0x2 + field public static final int REASON_INTRA_CARRIER = 1; // 0x1 + field public static final int REASON_NONE = 0; // 0x0 + field public static final int REASON_OTHER = 4; // 0x4 + field public static final int REASON_USER_SET = 3; // 0x3 + } + public final class RemoteConference { method public void disconnect(); method public java.util.List<android.telecom.RemoteConnection> getConferenceableConnections(); @@ -41919,9 +41949,12 @@ package android.telecom { 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; } @@ -42072,6 +42105,7 @@ package android.telephony { field public static final java.lang.String KEY_CALL_FORWARDING_BLOCKS_WHILE_ROAMING_STRING_ARRAY = "call_forwarding_blocks_while_roaming_string_array"; field public static final java.lang.String KEY_CARRIER_ALLOW_TURNOFF_IMS_BOOL = "carrier_allow_turnoff_ims_bool"; field public static final java.lang.String KEY_CARRIER_CALL_SCREENING_APP_STRING = "call_screening_app"; + field public static final java.lang.String KEY_CARRIER_CONFIG_VERSION_STRING = "carrier_config_version_string"; field public static final java.lang.String KEY_CARRIER_DATA_CALL_PERMANENT_FAILURE_STRINGS = "carrier_data_call_permanent_failure_strings"; field public static final java.lang.String KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT = "carrier_default_wfc_ims_mode_int"; field public static final java.lang.String KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_MODE_INT = "carrier_default_wfc_ims_roaming_mode_int"; @@ -42830,6 +42864,7 @@ package android.telephony { 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(); @@ -42869,12 +42904,14 @@ package android.telephony { 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); @@ -42939,6 +42976,7 @@ package android.telephony { 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); @@ -42976,6 +43014,8 @@ package android.telephony { 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); @@ -43031,6 +43071,7 @@ package android.telephony { 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 @@ -43063,6 +43104,8 @@ package android.telephony { 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 eea053c7d4a3..5b27b1235116 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -4,7 +4,6 @@ package android { field public static final java.lang.String ACCESS_AMBIENT_LIGHT_STATS = "android.permission.ACCESS_AMBIENT_LIGHT_STATS"; field public static final java.lang.String ACCESS_BROADCAST_RADIO = "android.permission.ACCESS_BROADCAST_RADIO"; field public static final java.lang.String ACCESS_CACHE_FILESYSTEM = "android.permission.ACCESS_CACHE_FILESYSTEM"; - field public static final java.lang.String ACCESS_CHECKIN_PROPERTIES = "android.permission.ACCESS_CHECKIN_PROPERTIES"; field public static final java.lang.String ACCESS_DRM_CERTIFICATES = "android.permission.ACCESS_DRM_CERTIFICATES"; field public static final deprecated java.lang.String ACCESS_FM_RADIO = "android.permission.ACCESS_FM_RADIO"; field public static final java.lang.String ACCESS_MOCK_LOCATION = "android.permission.ACCESS_MOCK_LOCATION"; @@ -13,13 +12,10 @@ package android { field public static final java.lang.String ACCESS_NOTIFICATIONS = "android.permission.ACCESS_NOTIFICATIONS"; field public static final java.lang.String ACCESS_SHORTCUTS = "android.permission.ACCESS_SHORTCUTS"; field public static final java.lang.String ACCESS_SURFACE_FLINGER = "android.permission.ACCESS_SURFACE_FLINGER"; - field public static final java.lang.String ACCOUNT_MANAGER = "android.permission.ACCOUNT_MANAGER"; field public static final java.lang.String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING"; field public static final java.lang.String ALLOCATE_AGGRESSIVE = "android.permission.ALLOCATE_AGGRESSIVE"; field public static final java.lang.String ALLOW_ANY_CODEC_FOR_PLAYBACK = "android.permission.ALLOW_ANY_CODEC_FOR_PLAYBACK"; field public static final java.lang.String BACKUP = "android.permission.BACKUP"; - field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS"; - field public static final java.lang.String BIND_APPWIDGET = "android.permission.BIND_APPWIDGET"; field public static final deprecated java.lang.String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE"; field public static final java.lang.String BIND_DIRECTORY_SEARCH = "android.permission.BIND_DIRECTORY_SEARCH"; field public static final java.lang.String BIND_EUICC_SERVICE = "android.permission.BIND_EUICC_SERVICE"; @@ -27,8 +23,8 @@ package android { 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_REMOTEVIEWS = "android.permission.BIND_REMOTEVIEWS"; 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"; field public static final java.lang.String BIND_SETTINGS_SUGGESTIONS_SERVICE = "android.permission.BIND_SETTINGS_SUGGESTIONS_SERVICE"; @@ -38,20 +34,13 @@ package android { field public static final java.lang.String BIND_TEXTCLASSIFIER_SERVICE = "android.permission.BIND_TEXTCLASSIFIER_SERVICE"; field public static final java.lang.String BIND_TRUST_AGENT = "android.permission.BIND_TRUST_AGENT"; field public static final java.lang.String BIND_TV_REMOTE_SERVICE = "android.permission.BIND_TV_REMOTE_SERVICE"; - field public static final java.lang.String BLUETOOTH_PRIVILEGED = "android.permission.BLUETOOTH_PRIVILEGED"; field public static final java.lang.String BRICK = "android.permission.BRICK"; field public static final java.lang.String BRIGHTNESS_SLIDER_USAGE = "android.permission.BRIGHTNESS_SLIDER_USAGE"; field public static final deprecated java.lang.String BROADCAST_NETWORK_PRIVILEGED = "android.permission.BROADCAST_NETWORK_PRIVILEGED"; - field public static final java.lang.String CALL_PRIVILEGED = "android.permission.CALL_PRIVILEGED"; field public static final java.lang.String CAMERA_DISABLE_TRANSMIT_LED = "android.permission.CAMERA_DISABLE_TRANSMIT_LED"; field public static final java.lang.String CAPTURE_AUDIO_HOTWORD = "android.permission.CAPTURE_AUDIO_HOTWORD"; - field public static final java.lang.String CAPTURE_AUDIO_OUTPUT = "android.permission.CAPTURE_AUDIO_OUTPUT"; - field public static final java.lang.String CAPTURE_SECURE_VIDEO_OUTPUT = "android.permission.CAPTURE_SECURE_VIDEO_OUTPUT"; field public static final java.lang.String CAPTURE_TV_INPUT = "android.permission.CAPTURE_TV_INPUT"; - field public static final java.lang.String CAPTURE_VIDEO_OUTPUT = "android.permission.CAPTURE_VIDEO_OUTPUT"; field public static final java.lang.String CHANGE_APP_IDLE_STATE = "android.permission.CHANGE_APP_IDLE_STATE"; - field public static final java.lang.String CHANGE_COMPONENT_ENABLED_STATE = "android.permission.CHANGE_COMPONENT_ENABLED_STATE"; - field public static final java.lang.String CHANGE_CONFIGURATION = "android.permission.CHANGE_CONFIGURATION"; field public static final java.lang.String CHANGE_DEVICE_IDLE_TEMP_WHITELIST = "android.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST"; field public static final java.lang.String CLEAR_APP_USER_DATA = "android.permission.CLEAR_APP_USER_DATA"; field public static final java.lang.String CONFIGURE_DISPLAY_BRIGHTNESS = "android.permission.CONFIGURE_DISPLAY_BRIGHTNESS"; @@ -59,30 +48,21 @@ package android { field public static final java.lang.String CONNECTIVITY_USE_RESTRICTED_NETWORKS = "android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"; field public static final java.lang.String CONTROL_DISPLAY_SATURATION = "android.permission.CONTROL_DISPLAY_SATURATION"; field public static final java.lang.String CONTROL_INCALL_EXPERIENCE = "android.permission.CONTROL_INCALL_EXPERIENCE"; - field public static final java.lang.String CONTROL_LOCATION_UPDATES = "android.permission.CONTROL_LOCATION_UPDATES"; field public static final java.lang.String CONTROL_VPN = "android.permission.CONTROL_VPN"; field public static final java.lang.String CRYPT_KEEPER = "android.permission.CRYPT_KEEPER"; - field public static final java.lang.String DELETE_CACHE_FILES = "android.permission.DELETE_CACHE_FILES"; - field public static final java.lang.String DELETE_PACKAGES = "android.permission.DELETE_PACKAGES"; field public static final java.lang.String DEVICE_POWER = "android.permission.DEVICE_POWER"; - field public static final java.lang.String DIAGNOSTIC = "android.permission.DIAGNOSTIC"; field public static final java.lang.String DISPATCH_PROVISIONING_MESSAGE = "android.permission.DISPATCH_PROVISIONING_MESSAGE"; - field public static final java.lang.String DUMP = "android.permission.DUMP"; field public static final java.lang.String FORCE_BACK = "android.permission.FORCE_BACK"; field public static final java.lang.String FORCE_STOP_PACKAGES = "android.permission.FORCE_STOP_PACKAGES"; - field public static final java.lang.String GET_ACCOUNTS_PRIVILEGED = "android.permission.GET_ACCOUNTS_PRIVILEGED"; field public static final java.lang.String GET_APP_OPS_STATS = "android.permission.GET_APP_OPS_STATS"; field public static final java.lang.String GET_PROCESS_STATE_AND_OOM_SCORE = "android.permission.GET_PROCESS_STATE_AND_OOM_SCORE"; field public static final java.lang.String GET_TOP_ACTIVITY_INFO = "android.permission.GET_TOP_ACTIVITY_INFO"; - field public static final java.lang.String GLOBAL_SEARCH = "android.permission.GLOBAL_SEARCH"; field public static final java.lang.String GRANT_RUNTIME_PERMISSIONS = "android.permission.GRANT_RUNTIME_PERMISSIONS"; field public static final java.lang.String HARDWARE_TEST = "android.permission.HARDWARE_TEST"; field public static final java.lang.String HDMI_CEC = "android.permission.HDMI_CEC"; field public static final java.lang.String HIDE_NON_SYSTEM_OVERLAY_WINDOWS = "android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS"; field public static final java.lang.String INJECT_EVENTS = "android.permission.INJECT_EVENTS"; field public static final java.lang.String INSTALL_GRANT_RUNTIME_PERMISSIONS = "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS"; - field public static final java.lang.String INSTALL_LOCATION_PROVIDER = "android.permission.INSTALL_LOCATION_PROVIDER"; - field public static final java.lang.String INSTALL_PACKAGES = "android.permission.INSTALL_PACKAGES"; field public static final java.lang.String INSTALL_PACKAGE_UPDATES = "android.permission.INSTALL_PACKAGE_UPDATES"; field public static final java.lang.String INSTALL_SELF_UPDATES = "android.permission.INSTALL_SELF_UPDATES"; field public static final java.lang.String INTENT_FILTER_VERIFICATION_AGENT = "android.permission.INTENT_FILTER_VERIFICATION_AGENT"; @@ -92,7 +72,6 @@ package android { field public static final java.lang.String INVOKE_CARRIER_SETUP = "android.permission.INVOKE_CARRIER_SETUP"; field public static final java.lang.String KILL_UID = "android.permission.KILL_UID"; field public static final java.lang.String LOCAL_MAC_ADDRESS = "android.permission.LOCAL_MAC_ADDRESS"; - field public static final java.lang.String LOCATION_HARDWARE = "android.permission.LOCATION_HARDWARE"; field public static final java.lang.String LOOP_RADIO = "android.permission.LOOP_RADIO"; field public static final java.lang.String MANAGE_ACTIVITY_STACKS = "android.permission.MANAGE_ACTIVITY_STACKS"; field public static final java.lang.String MANAGE_APP_OPS_RESTRICTIONS = "android.permission.MANAGE_APP_OPS_RESTRICTIONS"; @@ -107,25 +86,19 @@ package android { field public static final java.lang.String MANAGE_USB = "android.permission.MANAGE_USB"; field public static final java.lang.String MANAGE_USERS = "android.permission.MANAGE_USERS"; field public static final java.lang.String MANAGE_USER_OEM_UNLOCK_STATE = "android.permission.MANAGE_USER_OEM_UNLOCK_STATE"; - field public static final java.lang.String MASTER_CLEAR = "android.permission.MASTER_CLEAR"; - field public static final java.lang.String MEDIA_CONTENT_CONTROL = "android.permission.MEDIA_CONTENT_CONTROL"; field public static final java.lang.String MODIFY_APPWIDGET_BIND_PERMISSIONS = "android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS"; field public static final java.lang.String MODIFY_AUDIO_ROUTING = "android.permission.MODIFY_AUDIO_ROUTING"; field public static final java.lang.String MODIFY_CELL_BROADCASTS = "android.permission.MODIFY_CELL_BROADCASTS"; field public static final java.lang.String MODIFY_DAY_NIGHT_MODE = "android.permission.MODIFY_DAY_NIGHT_MODE"; field public static final deprecated java.lang.String MODIFY_NETWORK_ACCOUNTING = "android.permission.MODIFY_NETWORK_ACCOUNTING"; field public static final java.lang.String MODIFY_PARENTAL_CONTROLS = "android.permission.MODIFY_PARENTAL_CONTROLS"; - field public static final java.lang.String MODIFY_PHONE_STATE = "android.permission.MODIFY_PHONE_STATE"; field public static final java.lang.String MODIFY_QUIET_MODE = "android.permission.MODIFY_QUIET_MODE"; - field public static final java.lang.String MOUNT_FORMAT_FILESYSTEMS = "android.permission.MOUNT_FORMAT_FILESYSTEMS"; - field public static final java.lang.String MOUNT_UNMOUNT_FILESYSTEMS = "android.permission.MOUNT_UNMOUNT_FILESYSTEMS"; field public static final java.lang.String MOVE_PACKAGE = "android.permission.MOVE_PACKAGE"; field public static final java.lang.String NETWORK_SETUP_WIZARD = "android.permission.NETWORK_SETUP_WIZARD"; field public static final java.lang.String NOTIFICATION_DURING_SETUP = "android.permission.NOTIFICATION_DURING_SETUP"; field public static final java.lang.String NOTIFY_TV_INPUTS = "android.permission.NOTIFY_TV_INPUTS"; field public static final java.lang.String OBSERVE_APP_USAGE = "android.permission.OBSERVE_APP_USAGE"; field public static final java.lang.String OVERRIDE_WIFI_CONFIG = "android.permission.OVERRIDE_WIFI_CONFIG"; - field public static final java.lang.String PACKAGE_USAGE_STATS = "android.permission.PACKAGE_USAGE_STATS"; field public static final java.lang.String PACKAGE_VERIFICATION_AGENT = "android.permission.PACKAGE_VERIFICATION_AGENT"; field public static final java.lang.String PEERS_MAC_ADDRESS = "android.permission.PEERS_MAC_ADDRESS"; field public static final java.lang.String PERFORM_CDMA_PROVISIONING = "android.permission.PERFORM_CDMA_PROVISIONING"; @@ -135,9 +108,7 @@ package android { field public static final java.lang.String QUERY_TIME_ZONE_RULES = "android.permission.QUERY_TIME_ZONE_RULES"; field public static final java.lang.String READ_CONTENT_RATING_SYSTEMS = "android.permission.READ_CONTENT_RATING_SYSTEMS"; field public static final java.lang.String READ_DREAM_STATE = "android.permission.READ_DREAM_STATE"; - field public static final java.lang.String READ_FRAME_BUFFER = "android.permission.READ_FRAME_BUFFER"; field public static final java.lang.String READ_INSTALL_SESSIONS = "android.permission.READ_INSTALL_SESSIONS"; - field public static final java.lang.String READ_LOGS = "android.permission.READ_LOGS"; field public static final java.lang.String READ_NETWORK_USAGE_HISTORY = "android.permission.READ_NETWORK_USAGE_HISTORY"; field public static final java.lang.String READ_OEM_UNLOCK_STATE = "android.permission.READ_OEM_UNLOCK_STATE"; field public static final java.lang.String READ_PRINT_SERVICES = "android.permission.READ_PRINT_SERVICES"; @@ -149,7 +120,6 @@ package android { field public static final java.lang.String READ_WALLPAPER_INTERNAL = "android.permission.READ_WALLPAPER_INTERNAL"; field public static final java.lang.String READ_WIFI_CREDENTIAL = "android.permission.READ_WIFI_CREDENTIAL"; field public static final java.lang.String REAL_GET_TASKS = "android.permission.REAL_GET_TASKS"; - field public static final java.lang.String REBOOT = "android.permission.REBOOT"; field public static final java.lang.String RECEIVE_DATA_ACTIVITY_CHANGE = "android.permission.RECEIVE_DATA_ACTIVITY_CHANGE"; field public static final java.lang.String RECEIVE_EMERGENCY_BROADCAST = "android.permission.RECEIVE_EMERGENCY_BROADCAST"; field public static final java.lang.String RECEIVE_WIFI_CREDENTIAL_CHANGE = "android.permission.RECEIVE_WIFI_CREDENTIAL_CHANGE"; @@ -163,27 +133,19 @@ package android { field public static final java.lang.String RETRIEVE_WINDOW_CONTENT = "android.permission.RETRIEVE_WINDOW_CONTENT"; field public static final java.lang.String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS"; field public static final java.lang.String SCORE_NETWORKS = "android.permission.SCORE_NETWORKS"; - field public static final java.lang.String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE"; field public static final java.lang.String SEND_SHOW_SUSPENDED_APP_DETAILS = "android.permission.SEND_SHOW_SUSPENDED_APP_DETAILS"; field public static final java.lang.String SEND_SMS_NO_CONFIRMATION = "android.permission.SEND_SMS_NO_CONFIRMATION"; field public static final java.lang.String SERIAL_PORT = "android.permission.SERIAL_PORT"; field public static final java.lang.String SET_ACTIVITY_WATCHER = "android.permission.SET_ACTIVITY_WATCHER"; - field public static final java.lang.String SET_ALWAYS_FINISH = "android.permission.SET_ALWAYS_FINISH"; - field public static final java.lang.String SET_ANIMATION_SCALE = "android.permission.SET_ANIMATION_SCALE"; - field public static final java.lang.String SET_DEBUG_APP = "android.permission.SET_DEBUG_APP"; field public static final java.lang.String SET_HARMFUL_APP_WARNINGS = "android.permission.SET_HARMFUL_APP_WARNINGS"; field public static final java.lang.String SET_MEDIA_KEY_LISTENER = "android.permission.SET_MEDIA_KEY_LISTENER"; field public static final java.lang.String SET_ORIENTATION = "android.permission.SET_ORIENTATION"; field public static final java.lang.String SET_POINTER_SPEED = "android.permission.SET_POINTER_SPEED"; - field public static final java.lang.String SET_PROCESS_LIMIT = "android.permission.SET_PROCESS_LIMIT"; field public static final java.lang.String SET_SCREEN_COMPATIBILITY = "android.permission.SET_SCREEN_COMPATIBILITY"; - field public static final java.lang.String SET_TIME = "android.permission.SET_TIME"; field public static final java.lang.String SET_VOLUME_KEY_LONG_PRESS_LISTENER = "android.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER"; field public static final java.lang.String SET_WALLPAPER_COMPONENT = "android.permission.SET_WALLPAPER_COMPONENT"; field public static final java.lang.String SHOW_KEYGUARD_MESSAGE = "android.permission.SHOW_KEYGUARD_MESSAGE"; field public static final java.lang.String SHUTDOWN = "android.permission.SHUTDOWN"; - field public static final java.lang.String SIGNAL_PERSISTENT_PROCESSES = "android.permission.SIGNAL_PERSISTENT_PROCESSES"; - field public static final java.lang.String STATUS_BAR = "android.permission.STATUS_BAR"; field public static final java.lang.String STOP_APP_SWITCHES = "android.permission.STOP_APP_SWITCHES"; field public static final java.lang.String SUBSTITUTE_NOTIFICATION_APP_NAME = "android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME"; field public static final java.lang.String SUSPEND_APPS = "android.permission.SUSPEND_APPS"; @@ -192,17 +154,13 @@ package android { field public static final java.lang.String TV_VIRTUAL_REMOTE_CONTROLLER = "android.permission.TV_VIRTUAL_REMOTE_CONTROLLER"; field public static final java.lang.String UNLIMITED_SHORTCUTS_API_CALLS = "android.permission.UNLIMITED_SHORTCUTS_API_CALLS"; field public static final java.lang.String UPDATE_APP_OPS_STATS = "android.permission.UPDATE_APP_OPS_STATS"; - field public static final java.lang.String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS"; field public static final java.lang.String UPDATE_LOCK = "android.permission.UPDATE_LOCK"; field public static final java.lang.String UPDATE_TIME_ZONE_RULES = "android.permission.UPDATE_TIME_ZONE_RULES"; field public static final java.lang.String USER_ACTIVITY = "android.permission.USER_ACTIVITY"; field public static final java.lang.String USE_RESERVED_DISK = "android.permission.USE_RESERVED_DISK"; - field public static final java.lang.String WRITE_APN_SETTINGS = "android.permission.WRITE_APN_SETTINGS"; field public static final java.lang.String WRITE_DREAM_STATE = "android.permission.WRITE_DREAM_STATE"; field public static final java.lang.String WRITE_EMBEDDED_SUBSCRIPTIONS = "android.permission.WRITE_EMBEDDED_SUBSCRIPTIONS"; - field public static final java.lang.String WRITE_GSERVICES = "android.permission.WRITE_GSERVICES"; field public static final java.lang.String WRITE_MEDIA_STORAGE = "android.permission.WRITE_MEDIA_STORAGE"; - field public static final java.lang.String WRITE_SECURE_SETTINGS = "android.permission.WRITE_SECURE_SETTINGS"; } public static final class R.array { @@ -425,10 +383,6 @@ package android.app { package android.app.admin { - public class DeviceAdminReceiver extends android.content.BroadcastReceiver { - method public deprecated void onReadyForUserInitialization(android.content.Context, android.content.Intent); - } - public class DevicePolicyManager { method public java.lang.String getDeviceOwner(); method public android.content.ComponentName getDeviceOwnerComponentOnAnyUser(); @@ -466,10 +420,7 @@ package android.app.admin { } public final class SystemUpdatePolicy implements android.os.Parcelable { - method public int describeContents(); method public android.app.admin.SystemUpdatePolicy.InstallationOption getInstallationOptionAt(long); - method public void writeToParcel(android.os.Parcel, int); - field public static final android.os.Parcelable.Creator<android.app.admin.SystemUpdatePolicy> CREATOR; field public static final int TYPE_PAUSE = 4; // 0x4 } @@ -2948,7 +2899,6 @@ package android.media.tv { method public void addBlockedRating(android.media.tv.TvContentRating); method public boolean captureFrame(java.lang.String, android.view.Surface, android.media.tv.TvStreamConfig); method public java.util.List<android.media.tv.TvStreamConfig> getAvailableTvStreamConfigList(java.lang.String); - method public java.util.List<android.media.tv.TvContentRating> getBlockedRatings(); method public java.util.List<android.media.tv.TvInputHardwareInfo> getHardwareList(); method public java.util.List<android.media.tv.TvContentRatingSystemInfo> getTvContentRatingSystemList(); method public boolean isSingleSessionActive(); @@ -3095,7 +3045,20 @@ package android.net { 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 } @@ -3115,6 +3078,10 @@ package android.net { 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; @@ -3163,11 +3130,9 @@ package android.net { } public class TrafficStats { - method public static void clearThreadStatsUid(); method public static void setThreadStatsTagApp(); method public static void setThreadStatsTagBackup(); method public static void setThreadStatsTagRestore(); - method public static void setThreadStatsUid(int); } public class VpnService extends android.app.Service { @@ -3189,14 +3154,6 @@ package android.net { } -package android.net.http { - - public class X509TrustManagerExtensions { - method public boolean isSameTrustConfiguration(java.lang.String, java.lang.String); - } - -} - package android.net.wifi { public deprecated class RttManager { @@ -3415,7 +3372,6 @@ package android.net.wifi { method public java.util.List<android.net.wifi.WifiConfiguration> getPrivilegedConfiguredNetworks(); method public android.net.wifi.WifiConfiguration getWifiApConfiguration(); method public int getWifiApState(); - method public boolean isDeviceToApRttSupported(); method public boolean isDeviceToDeviceRttSupported(); method public boolean isPortableHotspotSupported(); method public boolean isWifiApEnabled(); @@ -4614,28 +4570,6 @@ package android.service.notification { field public static final java.lang.String KEY_USER_SENTIMENT = "key_user_sentiment"; } - public final class Condition implements android.os.Parcelable { - ctor public Condition(android.net.Uri, java.lang.String, java.lang.String, java.lang.String, int, int, int); - method public android.service.notification.Condition copy(); - method public static boolean isValidId(android.net.Uri, java.lang.String); - method public static android.net.Uri.Builder newId(android.content.Context); - method public static java.lang.String relevanceToString(int); - method public static java.lang.String stateToString(int); - field public static final int FLAG_RELEVANT_ALWAYS = 2; // 0x2 - field public static final int FLAG_RELEVANT_NOW = 1; // 0x1 - field public static final java.lang.String SCHEME = "condition"; - field public static final int STATE_ERROR = 3; // 0x3 - field public static final int STATE_UNKNOWN = 2; // 0x2 - field public final int flags; - field public final int icon; - field public final java.lang.String line1; - field public final java.lang.String line2; - } - - public abstract class ConditionProviderService extends android.app.Service { - method public void onRequestConditions(int); - } - public abstract class NotificationAssistantService extends android.service.notification.NotificationListenerService { ctor public NotificationAssistantService(); method public final void adjustNotification(android.service.notification.Adjustment); @@ -5022,6 +4956,18 @@ package android.telecom { field public static final int CAPABILITY_MULTI_USER = 32; // 0x20 } + public final class PhoneAccountSuggestion implements android.os.Parcelable { + 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); } @@ -5078,7 +5024,6 @@ package android.telecom { method public void clearPhoneAccounts(); method public android.telecom.TelecomAnalytics dumpAnalytics(); method public void enablePhoneAccount(android.telecom.PhoneAccountHandle, boolean); - method public boolean endCall(); method public java.util.List<android.telecom.PhoneAccountHandle> getAllPhoneAccountHandles(); method public java.util.List<android.telecom.PhoneAccount> getAllPhoneAccounts(); method public int getAllPhoneAccountsCount(); @@ -5090,7 +5035,6 @@ package android.telecom { method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsSupportingScheme(java.lang.String); method public boolean isInEmergencyCall(); method public boolean isRinging(); - method public boolean isTtySupported(); method public boolean setDefaultDialer(java.lang.String); field public static final java.lang.String EXTRA_CALL_BACK_INTENT = "android.telecom.extra.CALL_BACK_INTENT"; field public static final java.lang.String EXTRA_CLEAR_MISSED_CALLS_INTENT = "android.telecom.extra.CLEAR_MISSED_CALLS_INTENT"; @@ -5115,7 +5059,83 @@ package android.telephony { method public void overrideConfig(int, android.os.PersistableBundle); method public void updateConfigForPhoneId(int, java.lang.String); field public static final java.lang.String KEY_CARRIER_SETUP_APP_STRING = "carrier_setup_app_string"; - field public static final java.lang.String KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING = "config_plans_package_override_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 { @@ -5164,16 +5184,15 @@ package android.telephony { 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 { @@ -5207,14 +5226,134 @@ package android.telephony { } 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(); @@ -5230,7 +5369,6 @@ package android.telephony { public final class SmsManager { method public void sendMultipartTextMessageWithoutPersisting(java.lang.String, java.lang.String, java.util.List<java.lang.String>, java.util.List<android.app.PendingIntent>, java.util.List<android.app.PendingIntent>); - method public void sendTextMessageWithoutPersisting(java.lang.String, java.lang.String, java.lang.String, android.app.PendingIntent, android.app.PendingIntent); field public static final int RESULT_CANCELLED = 23; // 0x17 field public static final int RESULT_ENCODING_ERROR = 18; // 0x12 field public static final int RESULT_ERROR_FDN_CHECK_FAILURE = 6; // 0x6 @@ -5253,17 +5391,14 @@ package android.telephony { public class SubscriptionInfo implements android.os.Parcelable { method public java.util.List<android.telephony.UiccAccessRule> getAccessRules(); + method public int getCardId(); } public class SubscriptionManager { method public java.util.List<android.telephony.SubscriptionInfo> getAvailableSubscriptionInfoList(); - method public java.util.List<android.telephony.SubscriptionPlan> getSubscriptionPlans(int); method public void requestEmbeddedSubscriptionInfoListRefresh(); - method public void setSubscriptionOverrideCongested(int, boolean, long); - method public void setSubscriptionOverrideUnmetered(int, boolean, long); - method public void setSubscriptionPlans(int, java.util.List<android.telephony.SubscriptionPlan>); - field public static final java.lang.String ACTION_MANAGE_SUBSCRIPTION_PLANS = "android.telephony.action.MANAGE_SUBSCRIPTION_PLANS"; - field public static final java.lang.String ACTION_REFRESH_SUBSCRIPTION_PLANS = "android.telephony.action.REFRESH_SUBSCRIPTION_PLANS"; + method public void setDefaultDataSubId(int); + method public void setDefaultSmsSubId(int); field public static final android.net.Uri ADVANCED_CALLING_ENABLED_CONTENT_URI; field public static final android.net.Uri VT_ENABLED_CONTENT_URI; field public static final android.net.Uri WFC_ENABLED_CONTENT_URI; @@ -5272,37 +5407,10 @@ package android.telephony { field public static final android.net.Uri WFC_ROAMING_MODE_CONTENT_URI; } - public final class SubscriptionPlan implements android.os.Parcelable { - method public java.util.Iterator<android.util.Range<java.time.ZonedDateTime>> cycleIterator(); - method public int describeContents(); - method public int getDataLimitBehavior(); - method public long getDataLimitBytes(); - method public long getDataUsageBytes(); - method public long getDataUsageTime(); - method public java.lang.CharSequence getSummary(); - method public java.lang.CharSequence getTitle(); - method public void writeToParcel(android.os.Parcel, int); - field public static final long BYTES_UNKNOWN = -1L; // 0xffffffffffffffffL - field public static final long BYTES_UNLIMITED = 9223372036854775807L; // 0x7fffffffffffffffL - field public static final android.os.Parcelable.Creator<android.telephony.SubscriptionPlan> CREATOR; - field public static final int LIMIT_BEHAVIOR_BILLED = 1; // 0x1 - field public static final int LIMIT_BEHAVIOR_DISABLED = 0; // 0x0 - field public static final int LIMIT_BEHAVIOR_THROTTLED = 2; // 0x2 - field public static final int LIMIT_BEHAVIOR_UNKNOWN = -1; // 0xffffffff - field public static final long TIME_UNKNOWN = -1L; // 0xffffffffffffffffL - } - public static class SubscriptionPlan.Builder { - method public android.telephony.SubscriptionPlan build(); - method public static android.telephony.SubscriptionPlan.Builder createNonrecurring(java.time.ZonedDateTime, java.time.ZonedDateTime); - method public static android.telephony.SubscriptionPlan.Builder createRecurring(java.time.ZonedDateTime, java.time.Period); method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringDaily(java.time.ZonedDateTime); method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringMonthly(java.time.ZonedDateTime); method public static deprecated android.telephony.SubscriptionPlan.Builder createRecurringWeekly(java.time.ZonedDateTime); - method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int); - method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long); - method public android.telephony.SubscriptionPlan.Builder setSummary(java.lang.CharSequence); - method public android.telephony.SubscriptionPlan.Builder setTitle(java.lang.CharSequence); } public final class TelephonyHistogram implements android.os.Parcelable { @@ -5335,6 +5443,7 @@ package android.telephony { method public void enableVideoCalling(boolean); method public java.lang.String getAidForAppType(int); method public java.util.List<android.service.carrier.CarrierIdentifier> getAllowedCarriers(int); + method public int getCardIdForDefaultEuicc(); method public java.util.List<java.lang.String> getCarrierPackageNamesForIntent(android.content.Intent); method public java.util.List<java.lang.String> getCarrierPackageNamesForIntentAndPhone(android.content.Intent, int); method public java.lang.String getCdmaMdn(); @@ -5355,6 +5464,7 @@ package android.telephony { 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(); @@ -5400,6 +5510,7 @@ package android.telephony { field public static final java.lang.String EXTRA_SIM_STATE = "android.telephony.extra.SIM_STATE"; field public static final java.lang.String EXTRA_VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL = "android.telephony.extra.VISUAL_VOICEMAIL_ENABLED_BY_USER_BOOL"; field public static final java.lang.String EXTRA_VOICEMAIL_SCRAMBLED_PIN_STRING = "android.telephony.extra.VOICEMAIL_SCRAMBLED_PIN_STRING"; + field public static final int INVALID_CARD_ID = -1; // 0xffffffff field public static final long MAX_NUMBER_VERIFICATION_TIMEOUT_MILLIS = 60000L; // 0xea60L field public static final int NETWORK_MODE_CDMA_EVDO = 4; // 0x4 field public static final int NETWORK_MODE_CDMA_NO_EVDO = 5; // 0x5 @@ -5471,6 +5582,18 @@ package android.telephony { 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(); @@ -5542,20 +5665,19 @@ package android.telephony.data { 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); @@ -6022,6 +6144,7 @@ package android.telephony.ims { 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 @@ -6045,26 +6168,39 @@ package android.telephony.ims { 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 @@ -6074,9 +6210,11 @@ package android.telephony.ims { 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 @@ -6220,12 +6358,6 @@ package android.telephony.ims { method public android.telephony.ims.ImsSsInfo.Builder setProvisionStatus(int); } - public static abstract class ImsSsInfo.ClirInterrogationStatus implements java.lang.annotation.Annotation { - } - - public static abstract class ImsSsInfo.ClirOutgoingState implements java.lang.annotation.Annotation { - } - public final class ImsStreamMediaProfile implements android.os.Parcelable { ctor public ImsStreamMediaProfile(int, int, int, int, int); method public void copyFrom(android.telephony.ims.ImsStreamMediaProfile); diff --git a/api/test-current.txt b/api/test-current.txt index 8466ef037142..dfa1c1652bff 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -963,6 +963,18 @@ package android.telecom { ctor public CallAudioState(boolean, int, int, android.bluetooth.BluetoothDevice, java.util.Collection<android.bluetooth.BluetoothDevice>); } + public final class PhoneAccountSuggestion implements android.os.Parcelable { + 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/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index 8ffe5bf59315..ed6c25dc49c3 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -302,6 +302,7 @@ status_t BootAnimation::readyToRun() { mHeight = h; mFlingerSurfaceControl = control; mFlingerSurface = s; + mTargetInset = -1; // If the device has encryption turned on or is in process // of being encrypted we show the encrypted boot animation. @@ -942,6 +943,7 @@ bool BootAnimation::playAnimation(const Animation& animation) if (mClockEnabled && mTimeIsAccurate && validClock(part)) { drawClock(animation.clockFont, part.clockPosX, part.clockPosY); } + handleViewport(frameDuration); eglSwapBuffers(mDisplay, mSurface); @@ -966,7 +968,7 @@ bool BootAnimation::playAnimation(const Animation& animation) usleep(part.pause * ns2us(frameDuration)); // For infinite parts, we've now played them at least once, so perhaps exit - if(exitPending() && !part.count) + if(exitPending() && !part.count && mCurrentInset >= mTargetInset) break; } @@ -986,6 +988,51 @@ bool BootAnimation::playAnimation(const Animation& animation) return true; } +void BootAnimation::handleViewport(nsecs_t timestep) { + if (mShuttingDown || !mFlingerSurfaceControl || mTargetInset == 0) { + return; + } + if (mTargetInset < 0) { + // Poll the amount for the top display inset. This will return -1 until persistent properties + // have been loaded. + mTargetInset = android::base::GetIntProperty("persist.sys.displayinset.top", + -1 /* default */, -1 /* min */, mHeight / 2 /* max */); + } + if (mTargetInset <= 0) { + return; + } + + if (mCurrentInset < mTargetInset) { + // After the device boots, the inset will effectively be cropped away. We animate this here. + float fraction = static_cast<float>(mCurrentInset) / mTargetInset; + int interpolatedInset = (cosf((fraction + 1) * M_PI) / 2.0f + 0.5f) * mTargetInset; + + SurfaceComposerClient::Transaction() + .setCrop(mFlingerSurfaceControl, Rect(0, interpolatedInset, mWidth, mHeight)) + .apply(); + } else { + // At the end of the animation, we switch to the viewport that DisplayManager will apply + // later. This changes the coordinate system, and means we must move the surface up by + // the inset amount. + sp<IBinder> dtoken(SurfaceComposerClient::getBuiltInDisplay( + ISurfaceComposer::eDisplayIdMain)); + + Rect layerStackRect(0, 0, mWidth, mHeight - mTargetInset); + Rect displayRect(0, mTargetInset, mWidth, mHeight); + + SurfaceComposerClient::Transaction t; + t.setPosition(mFlingerSurfaceControl, 0, -mTargetInset) + .setCrop(mFlingerSurfaceControl, Rect(0, mTargetInset, mWidth, mHeight)); + t.setDisplayProjection(dtoken, 0 /* orientation */, layerStackRect, displayRect); + t.apply(); + + mTargetInset = mCurrentInset = 0; + } + + int delta = timestep * mTargetInset / ms2ns(200); + mCurrentInset += delta; +} + void BootAnimation::releaseAnimation(Animation* animation) const { for (Vector<Animation::Part>::iterator it = animation->parts.begin(), diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h index 56e131523bcb..b4699d884681 100644 --- a/cmds/bootanimation/BootAnimation.h +++ b/cmds/bootanimation/BootAnimation.h @@ -157,11 +157,15 @@ private: void checkExit(); + void handleViewport(nsecs_t timestep); + sp<SurfaceComposerClient> mSession; AssetManager mAssets; Texture mAndroid[2]; int mWidth; int mHeight; + int mCurrentInset; + int mTargetInset; bool mUseNpotTextures = false; EGLDisplay mDisplay; EGLDisplay mContext; diff --git a/cmds/incident_helper/src/TextParserBase.h b/cmds/incident_helper/src/TextParserBase.h index 784c181d9741..a6074e71c035 100644 --- a/cmds/incident_helper/src/TextParserBase.h +++ b/cmds/incident_helper/src/TextParserBase.h @@ -30,7 +30,7 @@ class TextParserBase { 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 c02a3493724a..09dc8e6fdbfc 100644 --- a/cmds/incident_helper/src/ih_util.h +++ b/cmds/incident_helper/src/ih_util.h @@ -109,7 +109,7 @@ double toDouble(const std::string& s); class Reader { public: - Reader(const int fd); + explicit Reader(const int fd); ~Reader(); bool readLine(std::string* line); @@ -162,7 +162,7 @@ private: 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/incident_helper/tests/KernelWakesParser_test.cpp b/cmds/incident_helper/tests/KernelWakesParser_test.cpp index f92d81361eab..573ca4f632e0 100644 --- a/cmds/incident_helper/tests/KernelWakesParser_test.cpp +++ b/cmds/incident_helper/tests/KernelWakesParser_test.cpp @@ -84,9 +84,9 @@ TEST_F(KernelWakesParserTest, Normal) { record1->set_event_count(8); record1->set_wakeup_count(0); record1->set_expire_count(0); - record1->set_active_since(0l); - record1->set_total_time(0l); - record1->set_max_time(0l); + record1->set_active_since(0L); + record1->set_total_time(0L); + record1->set_max_time(0L); record1->set_last_change(131348LL); record1->set_prevent_suspend_time(0LL); @@ -96,9 +96,9 @@ TEST_F(KernelWakesParserTest, Normal) { record2->set_event_count(143); record2->set_wakeup_count(0); record2->set_expire_count(0); - record2->set_active_since(0l); - record2->set_total_time(123l); - record2->set_max_time(3l); + record2->set_active_since(0L); + record2->set_total_time(123L); + record2->set_max_time(3L); record2->set_last_change(2067286206LL); record2->set_prevent_suspend_time(0LL); diff --git a/cmds/incidentd/src/IncidentService.h b/cmds/incidentd/src/IncidentService.h index e176bfd95c5f..140484ba5275 100644 --- a/cmds/incidentd/src/IncidentService.h +++ b/cmds/incidentd/src/IncidentService.h @@ -97,7 +97,7 @@ private: // ================================================================================ 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 a3df4903de45..a0159d9a8649 100644 --- a/cmds/incidentd/src/Privacy.h +++ b/cmds/incidentd/src/Privacy.h @@ -83,7 +83,7 @@ public: 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 45fd9443e9d0..2a3abd7b4d97 100644 --- a/cmds/incidentd/src/Reporter.h +++ b/cmds/incidentd/src/Reporter.h @@ -89,7 +89,7 @@ public: 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 72a41036e595..bb5221c7404c 100644 --- a/cmds/incidentd/src/Section.cpp +++ b/cmds/incidentd/src/Section.cpp @@ -410,7 +410,7 @@ struct WorkerThreadData : public virtual RefBase { 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 3badb1faece6..bca858e67f13 100644 --- a/cmds/statsd/src/anomaly/AlarmMonitor.h +++ b/cmds/statsd/src/anomaly/AlarmMonitor.h @@ -42,7 +42,7 @@ namespace statsd { * 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 a2a03b14c073..7dfe7d6ecb7e 100644 --- a/cmds/statsd/src/atom_field_options.proto +++ b/cmds/statsd/src/atom_field_options.proto @@ -64,10 +64,22 @@ message StateAtomFieldOption { 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 281f900d9cb9..d9fa0f13f5bf 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -26,6 +26,7 @@ import "frameworks/base/core/proto/android/app/job/enums.proto"; 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 @@ message Atom { 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 @@ message PhoneStateChanged { 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 a6f88af4b4d6..2c8814772839 100644 --- a/cmds/statsd/src/condition/ConditionWizard.h +++ b/cmds/statsd/src/condition/ConditionWizard.h @@ -29,7 +29,7 @@ namespace statsd { 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 dc79519d1f34..4cc9393fbd02 100644 --- a/cmds/statsd/src/config/ConfigKey.h +++ b/cmds/statsd/src/config/ConfigKey.h @@ -33,7 +33,7 @@ using std::string; 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 16b7e79c0ed7..5fea90b61c80 100644 --- a/cmds/statsd/src/config/ConfigManager.cpp +++ b/cmds/statsd/src/config/ConfigManager.cpp @@ -106,14 +106,14 @@ void ConfigManager::UpdateConfig(const ConfigKey& key, const StatsdConfig& confi // 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 @@ void ConfigManager::RemoveConfig(const ConfigKey& key) { 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 @@ void ConfigManager::RemoveConfig(const ConfigKey& key) { remove_saved_configs(key); } - for (sp<ConfigListener> listener:broadcastList) { + for (const sp<ConfigListener>& listener:broadcastList) { listener->OnConfigRemoved(key); } } @@ -183,7 +183,7 @@ void ConfigManager::RemoveConfigs(int uid) { mConfigs.erase(uidIt); - for (sp<ConfigListener> listener : mListeners) { + for (const sp<ConfigListener>& listener : mListeners) { broadcastList.push_back(listener); } } @@ -191,7 +191,7 @@ void ConfigManager::RemoveConfigs(int uid) { // 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 @@ void ConfigManager::RemoveAllConfigs() { } mConfigReceivers.clear(); - for (sp<ConfigListener> listener : mListeners) { + for (const sp<ConfigListener>& listener : mListeners) { broadcastList.push_back(listener); } } @@ -221,7 +221,7 @@ void ConfigManager::RemoveAllConfigs() { // 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 9b238eaf5f83..ba6e6c33b1a5 100644 --- a/cmds/statsd/src/external/ResourceHealthManagerPuller.h +++ b/cmds/statsd/src/external/ResourceHealthManagerPuller.h @@ -28,7 +28,7 @@ namespace statsd { */ 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 0a49732fe120..a16baf025a34 100644 --- a/cmds/statsd/src/external/StatsCompanionServicePuller.h +++ b/cmds/statsd/src/external/StatsCompanionServicePuller.h @@ -25,7 +25,7 @@ namespace statsd { 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 caac677ee215..35be12b4768e 100644 --- a/cmds/statsd/src/external/StatsPuller.h +++ b/cmds/statsd/src/external/StatsPuller.h @@ -33,7 +33,7 @@ namespace statsd { 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 4501b64ad47e..2713d327995d 100644 --- a/cmds/statsd/src/external/SubsystemSleepStatePuller.cpp +++ b/cmds/statsd/src/external/SubsystemSleepStatePuller.cpp @@ -111,7 +111,7 @@ bool SubsystemSleepStatePuller::PullInternal(vector<shared_ptr<LogEvent>>* data) (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 4e4f146d27ac..5d6d02b4948b 100644 --- a/cmds/statsd/src/logd/LogEvent.cpp +++ b/cmds/statsd/src/logd/LogEvent.cpp @@ -379,7 +379,7 @@ float LogEvent::GetFloat(size_t key, status_t* err) const { 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 24d624d9d9be..8a03ac458cce 100644 --- a/cmds/statsd/src/logd/LogEvent.h +++ b/cmds/statsd/src/logd/LogEvent.h @@ -158,7 +158,7 @@ private: * 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 4fac0e1a141b..a6c7f3a0dc87 100644 --- a/cmds/statsd/src/metrics/MetricsManager.cpp +++ b/cmds/statsd/src/metrics/MetricsManager.cpp @@ -395,7 +395,7 @@ void MetricsManager::onPeriodicAlarmFired( // 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 811a00e47ae5..a1c80b84f9b1 100644 --- a/cmds/statsd/src/metrics/metrics_manager_util.cpp +++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp @@ -537,7 +537,7 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, } 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 73ac9686889e..88957df87d08 100644 --- a/cmds/statsd/src/packages/UidMap.cpp +++ b/cmds/statsd/src/packages/UidMap.cpp @@ -141,7 +141,7 @@ void UidMap::updateMap(const int64_t& timestamp, const vector<int32_t>& uid, // 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 @@ void UidMap::updateApp(const int64_t& timestamp, const String16& app_16, const i 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 @@ void UidMap::removeApp(const int64_t& timestamp, const String16& app_16, const i 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 73e4d33d3e18..b8185d2a32d2 100644 --- a/cmds/statsd/src/socket/StatsSocketListener.h +++ b/cmds/statsd/src/socket/StatsSocketListener.h @@ -35,7 +35,7 @@ namespace statsd { 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 @@ private: }; } // 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 a0ab3e46e719..11ce71705fc1 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 writeDimensionPathToProto(const std::vector<Matcher>& fieldMatchers, // } // // -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 @@ void writeFieldValueTreeToStreamHelper(const std::vector<FieldValue>& dims, size 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 @@ void writeFieldValueTreeToStreamHelper(const std::vector<FieldValue>& dims, size } // 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 @@ void writeFieldValueTreeToStream(int tagId, const std::vector<FieldValue>& value 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 2fcde29fbbdb..b29de5385cf4 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 android { namespace os { namespace statsd { +using std::string; +using util::ProtoOutputStream; + TEST(LogEventTest, TestLogParsing) { LogEvent event1(1, 2000); @@ -159,6 +164,94 @@ TEST(LogEventTest, TestLogParsing2) { } +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 218d52a5c046..e1258875551e 100644 --- a/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp +++ b/cmds/statsd/tests/anomaly/AnomalyTracker_test.cpp @@ -71,12 +71,12 @@ bool detectAnomaliesPass(AnomalyTracker& tracker, 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 f3bf6e7b7231..4174ad7cd586 100644 --- a/cmds/telecom/src/com/android/commands/telecom/Telecom.java +++ b/cmds/telecom/src/com/android/commands/telecom/Telecom.java @@ -46,10 +46,13 @@ public final class Telecom extends BaseCommand { private static final String COMMAND_SET_PHONE_ACCOUNT_DISABLED = "set-phone-account-disabled"; private static final String COMMAND_REGISTER_PHONE_ACCOUNT = "register-phone-account"; private static final String COMMAND_REGISTER_SIM_PHONE_ACCOUNT = "register-sim-phone-account"; + private static final String COMMAND_SET_TEST_CALL_REDIRECTION_APP = "set-test-call-redirection-app"; private static final String COMMAND_SET_TEST_CALL_SCREENING_APP = "set-test-call-screening-app"; 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"; @@ -63,35 +66,37 @@ public final class Telecom extends BaseCommand { @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-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 @@ -120,6 +125,9 @@ public final class Telecom extends BaseCommand { case COMMAND_REGISTER_PHONE_ACCOUNT: runRegisterPhoneAccount(); break; + case COMMAND_SET_TEST_CALL_REDIRECTION_APP: + runSetTestCallRedirectionApp(); + break; case COMMAND_SET_TEST_CALL_SCREENING_APP: runSetTestCallScreeningApp(); break; @@ -129,6 +137,9 @@ public final class Telecom extends BaseCommand { 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; @@ -189,6 +200,11 @@ public final class Telecom extends BaseCommand { System.out.println("Success - " + handle + " registered."); } + private void runSetTestCallRedirectionApp() throws RemoteException { + final String packageName = nextArg(); + mTelecomService.setTestDefaultCallRedirectionApp(packageName); + } + private void runSetTestCallScreeningApp() throws RemoteException { final String packageName = nextArg(); mTelecomService.setTestDefaultCallScreeningApp(packageName); @@ -206,6 +222,11 @@ public final class Telecom extends BaseCommand { 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 9b4d199dc723..9e2230b288c8 100644 --- a/config/dirty-image-objects +++ b/config/dirty-image-objects @@ -44,7 +44,6 @@ java.util.function.ToIntFunction 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 @@ java.lang.CharSequence 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 1488b0964fe8..648ff274f37c 100644 --- a/config/hiddenapi-greylist.txt +++ b/config/hiddenapi-greylist.txt @@ -1716,10 +1716,6 @@ Landroid/widget/QuickContactBadge$QueryHandler;-><init>(Landroid/widget/QuickCon Landroid/widget/RelativeLayout$DependencyGraph$Node;-><init>()V Landroid/widget/RemoteViews$OnClickHandler;-><init>()V Landroid/widget/ScrollBarDrawable;-><init>()V -Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber$CountryCodeSource;->values()[Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber$CountryCodeSource; -Lcom/android/i18n/phonenumbers/PhoneNumberUtil$MatchType;->values()[Lcom/android/i18n/phonenumbers/PhoneNumberUtil$MatchType; -Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberFormat;->values()[Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberFormat; -Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;->values()[Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType; Lcom/android/ims/ImsCall;->deflect(Ljava/lang/String;)V Lcom/android/ims/ImsCall;->isMultiparty()Z Lcom/android/ims/ImsCall;->reject(I)V @@ -2942,7 +2938,6 @@ Lcom/android/internal/telephony/dataconnection/DataConnection;->mActivatingState 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; @@ -2953,10 +2948,8 @@ Lcom/android/internal/telephony/dataconnection/DataConnection;->mLinkProperties: 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 @@ -2965,22 +2958,6 @@ Lcom/android/internal/telephony/dataconnection/DcController;->lr(Ljava/lang/Stri 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 @@ -3015,7 +2992,6 @@ Lcom/android/internal/telephony/dataconnection/DcTracker;->notifyOffApnsOfAvaila 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 495615b90b15..fafcc6bea793 100644 --- a/config/preloaded-classes +++ b/config/preloaded-classes @@ -6124,12 +6124,6 @@ libcore.io.BufferIterator 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/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java index be2e2faf3739..f0a0e88310f9 100644 --- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java +++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java @@ -30,7 +30,6 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.hardware.fingerprint.FingerprintManager; -import android.os.Build; import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; @@ -190,12 +189,10 @@ public class AccessibilityServiceInfo implements Parcelable { * content and also the accessibility service will receive accessibility events from * them. * <p> - * <strong>Note:</strong> For accessibility services targeting API version - * {@link Build.VERSION_CODES#JELLY_BEAN} or higher this flag has to be explicitly - * set for the system to regard views that are not important for accessibility. For - * accessibility services targeting API version lower than - * {@link Build.VERSION_CODES#JELLY_BEAN} this flag is ignored and all views are - * regarded for accessibility purposes. + * <strong>Note:</strong> For accessibility services targeting Android 4.1 (API level 16) or + * higher, this flag has to be explicitly set for the system to regard views that are not + * important for accessibility. For accessibility services targeting Android 4.0.4 (API level + * 15) or lower, this flag is ignored and all views are regarded for accessibility purposes. * </p> * <p> * Usually views not important for accessibility are layout managers that do not @@ -220,19 +217,19 @@ public class AccessibilityServiceInfo implements Parcelable { * flag does not guarantee that the device will not be in touch exploration * mode since there may be another enabled service that requested it. * <p> - * For accessibility services targeting API version higher than - * {@link Build.VERSION_CODES#JELLY_BEAN_MR1} that want to set - * this flag have to declare this capability in their meta-data by setting - * the attribute {@link android.R.attr#canRequestTouchExplorationMode - * canRequestTouchExplorationMode} to true, otherwise this flag will + * For accessibility services targeting Android 4.3 (API level 18) or higher + * that want to set this flag have to declare this capability in their + * meta-data by setting the attribute + * {@link android.R.attr#canRequestTouchExplorationMode + * canRequestTouchExplorationMode} to true. Otherwise, this flag will * be ignored. For how to declare the meta-data of a service refer to * {@value AccessibilityService#SERVICE_META_DATA}. * </p> * <p> - * Services targeting API version equal to or lower than - * {@link Build.VERSION_CODES#JELLY_BEAN_MR1} will work normally, i.e. - * the first time they are run, if this flag is specified, a dialog is - * shown to the user to confirm enabling explore by touch. + * Services targeting Android 4.2.2 (API level 17) or lower will work + * normally. In other words, the first time they are run, if this flag is + * specified, a dialog is shown to the user to confirm enabling explore by + * touch. * </p> * @see android.R.styleable#AccessibilityService_canRequestTouchExplorationMode */ @@ -388,10 +385,10 @@ public class AccessibilityServiceInfo implements Parcelable { public int feedbackType; /** - * The timeout after the most recent event of a given type before an + * The timeout, in milliseconds, after the most recent event of a given type before an * {@link AccessibilityService} is notified. * <p> - * <strong>Can be dynamically set at runtime.</strong>. + * <strong>Can be dynamically set at runtime.</strong> * </p> * <p> * <strong>Note:</strong> The event notification timeout is useful to avoid propagating diff --git a/core/java/android/annotation/UnsupportedAppUsage.java b/core/java/android/annotation/UnsupportedAppUsage.java index 65e3f25f8fb6..ac3daaf638ad 100644 --- a/core/java/android/annotation/UnsupportedAppUsage.java +++ b/core/java/android/annotation/UnsupportedAppUsage.java @@ -26,16 +26,32 @@ import java.lang.annotation.Retention; import java.lang.annotation.Target; /** - * Indicates that a class member, that is not part of the SDK, is used by apps. - * Since the member is not part of the SDK, such use is not supported. + * Indicates that this non-SDK interface is used by apps. A non-SDK interface is a + * class member (field or method) that is not part of the public SDK. Since the + * member is not part of the SDK, usage by apps is not supported. * - * <p>This annotation acts as a heads up that changing a given method or field + * <h2>If you are an Android App developer</h2> + * + * This annotation indicates that you may be able to access the member, but that + * this access is discouraged and not supported by Android. If there is a value + * for {@link #maxTargetSdk()} on the annotation, access will be restricted based + * on the {@code targetSdkVersion} value set in your manifest. + * + * <p>Fields and methods annotated with this are likely to be restricted, changed + * or removed in future Android releases. If you rely on these members for + * functionality that is not otherwise supported by Android, consider filing a + * <a href="http://g.co/dev/appcompat">feature request</a>. + * + * <h2>If you are an Android OS developer</h2> + * + * This annotation acts as a heads up that changing a given method or field * may affect apps, potentially breaking them when the next Android version is * released. In some cases, for members that are heavily used, this annotation * may imply restrictions on changes to the member. * * <p>This annotation also results in access to the member being permitted by the - * runtime, with a warning being generated in debug builds. + * runtime, with a warning being generated in debug builds. Which apps can access + * the member is determined by the value of {@link #maxTargetSdk()}. * * <p>For more details, see go/UnsupportedAppUsage. * diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 31b5e0a8e2bf..a6f9bcab716d 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -6375,6 +6375,10 @@ public class Activity extends ContextThemeWrapper } void dumpInner(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + if (args != null && args.length > 0 && args[0].equals("--autofill")) { + dumpAutofillManager(prefix, writer); + return; + } writer.print(prefix); writer.print("Local Activity "); writer.print(Integer.toHexString(System.identityHashCode(this))); writer.println(" State:"); @@ -6402,16 +6406,20 @@ public class Activity extends ContextThemeWrapper mHandler.getLooper().dump(new PrintWriterPrinter(writer), prefix); + dumpAutofillManager(prefix, writer); + + ResourcesManager.getInstance().dump(prefix, writer); + } + + void dumpAutofillManager(String prefix, PrintWriter writer) { final AutofillManager afm = getAutofillManager(); if (afm != null) { + afm.dump(prefix, writer); writer.print(prefix); writer.print("Autofill Compat Mode: "); writer.println(isAutofillCompatibilityEnabled()); - afm.dump(prefix, writer); } else { writer.print(prefix); writer.println("No AutofillManager"); } - - ResourcesManager.getInstance().dump(prefix, writer); } /** diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 9b6764d96fb2..14cae95508e7 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -413,4 +413,9 @@ public abstract class ActivityManagerInternal { * @return The intent used to launch the home activity. */ public abstract Intent getHomeIntent(); + + /** + * WindowManager notifies AM when display size of the default display changes. + */ + public abstract void notifyDefaultDisplaySizeChanged(); } diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 0a238588787d..15af8a90dd49 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -81,7 +81,6 @@ import android.os.Binder; 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; @@ -147,6 +146,7 @@ import com.android.internal.os.RuntimeInit; import com.android.internal.os.SomeArgs; import com.android.internal.util.ArrayUtils; import com.android.internal.util.FastPrintWriter; +import com.android.internal.util.Preconditions; import com.android.internal.util.function.pooled.PooledLambda; import com.android.org.conscrypt.OpenSSLSocketImpl; import com.android.org.conscrypt.TrustedCertificateStore; @@ -156,8 +156,6 @@ import dalvik.system.CloseGuard; 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; @@ -384,6 +382,9 @@ public final class ActivityThread extends ClientTransactionHandler { = new ArrayMap<Activity, ArrayList<OnActivityPausedListener>>(); final GcIdler mGcIdler = new GcIdler(); + final PurgeIdler mPurgeIdler = new PurgeIdler(); + + boolean mPurgeIdlerScheduled = false; boolean mGcIdlerScheduled = false; @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) @@ -1666,6 +1667,7 @@ public final class ActivityThread extends ClientTransactionHandler { public static final int RUN_ISOLATED_ENTRY_POINT = 158; public static final int EXECUTE_TRANSACTION = 159; public static final int RELAUNCH_ACTIVITY = 160; + public static final int PURGE_RESOURCES = 161; String codeToString(int code) { if (DEBUG_MESSAGES) { @@ -1709,6 +1711,7 @@ public final class ActivityThread extends ClientTransactionHandler { case RUN_ISOLATED_ENTRY_POINT: return "RUN_ISOLATED_ENTRY_POINT"; case EXECUTE_TRANSACTION: return "EXECUTE_TRANSACTION"; case RELAUNCH_ACTIVITY: return "RELAUNCH_ACTIVITY"; + case PURGE_RESOURCES: return "PURGE_RESOURCES"; } } return Integer.toString(code); @@ -1746,6 +1749,7 @@ public final class ActivityThread extends ClientTransactionHandler { case UNBIND_SERVICE: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceUnbind"); handleUnbindService((BindServiceData)msg.obj); + schedulePurgeIdler(); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; case SERVICE_ARGS: @@ -1756,6 +1760,7 @@ public final class ActivityThread extends ClientTransactionHandler { case STOP_SERVICE: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "serviceStop"); handleStopService((IBinder)msg.obj); + schedulePurgeIdler(); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; case CONFIGURATION_CHANGED: @@ -1889,6 +1894,9 @@ public final class ActivityThread extends ClientTransactionHandler { case RELAUNCH_ACTIVITY: handleRelaunchActivityLocally((IBinder) msg.obj); break; + case PURGE_RESOURCES: + schedulePurgeIdler(); + break; } Object obj = msg.obj; if (obj instanceof SomeArgs) { @@ -1941,6 +1949,17 @@ public final class ActivityThread extends ClientTransactionHandler { @Override public final boolean queueIdle() { doGcIfNeeded(); + nPurgePendingResources(); + return false; + } + } + + final class PurgeIdler implements MessageQueue.IdleHandler { + @Override + public boolean queueIdle() { + Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "purgePendingResources"); + nPurgePendingResources(); + Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); return false; } } @@ -2270,6 +2289,22 @@ public final class ActivityThread extends ClientTransactionHandler { mH.removeMessages(H.GC_WHEN_IDLE); } + void schedulePurgeIdler() { + if (!mPurgeIdlerScheduled) { + mPurgeIdlerScheduled = true; + Looper.myQueue().addIdleHandler(mPurgeIdler); + } + mH.removeMessages(H.PURGE_RESOURCES); + } + + void unschedulePurgeIdler() { + if (mPurgeIdlerScheduled) { + mPurgeIdlerScheduled = false; + Looper.myQueue().removeIdleHandler(mPurgeIdler); + } + mH.removeMessages(H.PURGE_RESOURCES); + } + void doGcIfNeeded() { mGcIdlerScheduled = false; final long now = SystemClock.uptimeMillis(); @@ -4559,6 +4594,7 @@ public final class ActivityThread extends ClientTransactionHandler { } r.setState(ON_DESTROY); } + schedulePurgeIdler(); mActivities.remove(token); StrictMode.decrementExpectedActivityCount(activityClass); return r; @@ -5243,6 +5279,16 @@ public final class ActivityThread extends ClientTransactionHandler { } } + /** + * Updates the application info. + * + * This only works in the system process. Must be called on the main thread. + */ + public void handleSystemApplicationInfoChanged(@NonNull ApplicationInfo ai) { + Preconditions.checkState(mSystemThread, "Must only be called in the system process"); + handleApplicationInfoChanged(ai); + } + void handleApplicationInfoChanged(@NonNull final ApplicationInfo ai) { // Updates triggered by package installation go through a package update // receiver. Here we try to capture ApplicationInfo changes that are @@ -6631,9 +6677,6 @@ public final class ActivityThread extends ClientTransactionHandler { } } - // add dropbox logging to libcore - DropBox.setReporter(new DropBoxReporter()); - ViewRootImpl.ConfigChangedCallback configChangedCallback = (Configuration globalConfig) -> { synchronized (mResourcesManager) { @@ -6687,38 +6730,6 @@ public final class ActivityThread extends ClientTransactionHandler { } } - 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"); @@ -6729,9 +6740,6 @@ public final class ActivityThread extends ClientTransactionHandler { 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); @@ -6771,6 +6779,6 @@ public final class ActivityThread extends ClientTransactionHandler { } // ------------------ Regular JNI ------------------------ - + private native void nPurgePendingResources(); private native void nDumpGraphicsInfo(FileDescriptor fd); } diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java index 68869c65d7c9..2d9fbf974397 100644 --- a/core/java/android/app/ResourcesManager.java +++ b/core/java/android/app/ResourcesManager.java @@ -125,10 +125,13 @@ public class ResourcesManager { } } + private static final boolean ENABLE_APK_ASSETS_CACHE = false; + /** * The ApkAssets we are caching and intend to hold strong references to. */ - private final LruCache<ApkKey, ApkAssets> mLoadedApkAssets = new LruCache<>(3); + private final LruCache<ApkKey, ApkAssets> mLoadedApkAssets = + (ENABLE_APK_ASSETS_CACHE) ? new LruCache<>(3) : null; /** * The ApkAssets that are being referenced in the wild that we can reuse, even if they aren't @@ -316,9 +319,12 @@ public class ResourcesManager { private @NonNull ApkAssets loadApkAssets(String path, boolean sharedLib, boolean overlay) throws IOException { final ApkKey newKey = new ApkKey(path, sharedLib, overlay); - ApkAssets apkAssets = mLoadedApkAssets.get(newKey); - if (apkAssets != null) { - return apkAssets; + ApkAssets apkAssets = null; + if (mLoadedApkAssets != null) { + apkAssets = mLoadedApkAssets.get(newKey); + if (apkAssets != null) { + return apkAssets; + } } // Optimistically check if this ApkAssets exists somewhere else. @@ -326,7 +332,10 @@ public class ResourcesManager { if (apkAssetsRef != null) { apkAssets = apkAssetsRef.get(); if (apkAssets != null) { - mLoadedApkAssets.put(newKey, apkAssets); + if (mLoadedApkAssets != null) { + mLoadedApkAssets.put(newKey, apkAssets); + } + return apkAssets; } else { // Clean up the reference. @@ -341,7 +350,11 @@ public class ResourcesManager { } else { apkAssets = ApkAssets.loadFromPath(path, false /*system*/, sharedLib); } - mLoadedApkAssets.put(newKey, apkAssets); + + if (mLoadedApkAssets != null) { + mLoadedApkAssets.put(newKey, apkAssets); + } + mCachedApkAssets.put(newKey, new WeakReference<>(apkAssets)); return apkAssets; } @@ -441,18 +454,22 @@ public class ResourcesManager { pw.println("ResourcesManager:"); pw.increaseIndent(); - pw.print("cached apks: total="); - pw.print(mLoadedApkAssets.size()); - pw.print(" created="); - pw.print(mLoadedApkAssets.createCount()); - pw.print(" evicted="); - pw.print(mLoadedApkAssets.evictionCount()); - pw.print(" hit="); - pw.print(mLoadedApkAssets.hitCount()); - pw.print(" miss="); - pw.print(mLoadedApkAssets.missCount()); - pw.print(" max="); - pw.print(mLoadedApkAssets.maxSize()); + if (mLoadedApkAssets != null) { + pw.print("cached apks: total="); + pw.print(mLoadedApkAssets.size()); + pw.print(" created="); + pw.print(mLoadedApkAssets.createCount()); + pw.print(" evicted="); + pw.print(mLoadedApkAssets.evictionCount()); + pw.print(" hit="); + pw.print(mLoadedApkAssets.hitCount()); + pw.print(" miss="); + pw.print(mLoadedApkAssets.missCount()); + pw.print(" max="); + pw.print(mLoadedApkAssets.maxSize()); + } else { + pw.print("cached apks: 0 [cache disabled]"); + } pw.println(); pw.print("total apks: "); diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 83c43e7b83e1..15005d094af4 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -87,6 +87,7 @@ import android.net.INetworkPolicyManager; 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; @@ -143,7 +144,7 @@ import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.telephony.euicc.EuiccCardManager; import android.telephony.euicc.EuiccManager; -import android.telephony.rcs.RcsManager; +import android.telephony.ims.RcsManager; import android.util.Log; import android.view.ContextThemeWrapper; import android.view.LayoutInflater; @@ -283,6 +284,13 @@ final class SystemServiceRegistry { 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/app/VrManager.java b/core/java/android/app/VrManager.java index 66d7a2507bb7..b1465ae9a798 100644 --- a/core/java/android/app/VrManager.java +++ b/core/java/android/app/VrManager.java @@ -4,7 +4,6 @@ import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.SystemService; -import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.content.ComponentName; import android.content.Context; @@ -230,7 +229,6 @@ public class VrManager { * input by InputMethodManagerService. * @hide */ - @TestApi @RequiresPermission(android.Manifest.permission.RESTRICTED_VR_ACCESS) public void setVrInputMethod(ComponentName componentName) { try { diff --git a/core/java/android/app/admin/DeviceAdminReceiver.java b/core/java/android/app/admin/DeviceAdminReceiver.java index 1c9477d08cb3..6fb0d7ec33ae 100644 --- a/core/java/android/app/admin/DeviceAdminReceiver.java +++ b/core/java/android/app/admin/DeviceAdminReceiver.java @@ -23,7 +23,6 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; -import android.annotation.SystemApi; import android.app.Service; import android.content.BroadcastReceiver; import android.content.ComponentName; @@ -755,7 +754,6 @@ public class DeviceAdminReceiver extends BroadcastReceiver { * @deprecated Do not use */ @Deprecated - @SystemApi public void onReadyForUserInitialization(Context context, Intent intent) { } diff --git a/core/java/android/app/admin/SystemUpdatePolicy.java b/core/java/android/app/admin/SystemUpdatePolicy.java index 2a451ff07672..96dbc760278f 100644 --- a/core/java/android/app/admin/SystemUpdatePolicy.java +++ b/core/java/android/app/admin/SystemUpdatePolicy.java @@ -691,13 +691,11 @@ public final class SystemUpdatePolicy implements Parcelable { mFreezePeriods.stream().map(n -> n.toString()).collect(Collectors.joining(","))); } - @SystemApi @Override public int describeContents() { return 0; } - @SystemApi @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mPolicyType); @@ -714,7 +712,6 @@ public final class SystemUpdatePolicy implements Parcelable { } } - @SystemApi public static final Parcelable.Creator<SystemUpdatePolicy> CREATOR = new Parcelable.Creator<SystemUpdatePolicy>() { diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java index d568662409d7..dd61f286c88e 100644 --- a/core/java/android/app/assist/AssistStructure.java +++ b/core/java/android/app/assist/AssistStructure.java @@ -41,18 +41,23 @@ import java.util.Arrays; import java.util.List; /** - * Assist data automatically created by the platform's implementation of assist and autofill. + * <p>This API automatically creates assist data from the platform's + * implementation of assist and autofill. * * <p>The structure is used for assist purposes when created by * {@link android.app.Activity#onProvideAssistData}, {@link View#onProvideStructure(ViewStructure)}, * or {@link View#onProvideVirtualStructure(ViewStructure)}. * - * <p>The structure is used for autofill purposes when created by + * <p>The structure is also used for autofill purposes when created by * {@link View#onProvideAutofillStructure(ViewStructure, int)}, * or {@link View#onProvideAutofillVirtualStructure(ViewStructure, int)}. * - * <p>For performance reasons, some properties of the assist data might be available just for assist - * or autofill purposes; in those case, the property availability will be document in its javadoc. + * <p>For performance reasons, some properties of the assist data might only be available for + * assist or autofill purposes. In those cases, a property's availability will be documented + * in its javadoc. + * + * <p>To learn about using Autofill in your app, read the + * <a href="/guide/topics/text/autofill">Autofill Framework</a> guides. */ public class AssistStructure implements Parcelable { static final String TAG = "AssistStructure"; diff --git a/core/java/android/appwidget/AppWidgetManagerInternal.java b/core/java/android/appwidget/AppWidgetManagerInternal.java index 7ab3d8bdd857..5694ca860453 100644 --- a/core/java/android/appwidget/AppWidgetManagerInternal.java +++ b/core/java/android/appwidget/AppWidgetManagerInternal.java @@ -16,12 +16,9 @@ package android.appwidget; -import android.annotation.NonNull; import android.annotation.Nullable; import android.util.ArraySet; -import java.util.Set; - /** * App widget manager local system service interface. * @@ -36,4 +33,13 @@ public abstract class AppWidgetManagerInternal { * @return Whether the UID hosts widgets from the package. */ public abstract @Nullable ArraySet<String> getHostedWidgetPackages(int uid); + + /** + * Execute the widget-related work of unlocking a user. This is intentionally + * invoked just <em>before</em> the boot-completed broadcast is issued, after + * the data-related work of unlock has completed. + * + * @param userId The user that is being unlocked. + */ + public abstract void unlockUser(int userId); } diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index 654bfaf293b8..10c8b15a7a79 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -643,6 +643,7 @@ public final class BluetoothAdapter { private final IBluetoothManager mManagerService; @UnsupportedAppUsage private IBluetooth mService; + private Context mContext; private final ReentrantReadWriteLock mServiceLock = new ReentrantReadWriteLock(); private final Object mLock = new Object(); @@ -1541,6 +1542,23 @@ public final class BluetoothAdapter { } /** + * Set the context for this BluetoothAdapter (only called from BluetoothManager) + * @hide + */ + public void setContext(Context context) { + mContext = context; + } + + private String getOpPackageName() { + // Workaround for legacy API for getting a BluetoothAdapter not + // passing a context + if (mContext != null) { + return mContext.getOpPackageName(); + } + return ActivityThread.currentOpPackageName(); + } + + /** * Start the remote device discovery process. * <p>The discovery process usually involves an inquiry scan of about 12 * seconds, followed by a page scan of each new device to retrieve its @@ -1577,7 +1595,7 @@ public final class BluetoothAdapter { try { mServiceLock.readLock().lock(); if (mService != null) { - return mService.startDiscovery(); + return mService.startDiscovery(getOpPackageName()); } } catch (RemoteException e) { Log.e(TAG, "", e); diff --git a/core/java/android/bluetooth/BluetoothManager.java b/core/java/android/bluetooth/BluetoothManager.java index e3672a7e064f..e08d405324ea 100644 --- a/core/java/android/bluetooth/BluetoothManager.java +++ b/core/java/android/bluetooth/BluetoothManager.java @@ -67,6 +67,7 @@ public final class BluetoothManager { } // Legacy api - getDefaultAdapter does not take in the context mAdapter = BluetoothAdapter.getDefaultAdapter(); + mAdapter.setContext(context); } /** diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java index 4c98e23fe9b4..d3393b9193ce 100644 --- a/core/java/android/content/ContentProvider.java +++ b/core/java/android/content/ContentProvider.java @@ -56,6 +56,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; +import java.util.Objects; /** * Content providers are one of the primary building blocks of Android applications, providing @@ -218,7 +219,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public Cursor query(String callingPkg, Uri uri, @Nullable String[] projection, @Nullable Bundle queryArgs, @Nullable ICancellationSignal cancellationSignal) { - validateIncomingUri(uri); + uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { // The caller has no access to the data, so return an empty cursor with @@ -257,14 +258,14 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public String getType(Uri uri) { - validateIncomingUri(uri); + uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); return ContentProvider.this.getType(uri); } @Override public Uri insert(String callingPkg, Uri uri, ContentValues initialValues) { - validateIncomingUri(uri); + uri = validateIncomingUri(uri); int userId = getUserIdFromUri(uri); uri = maybeGetUriWithoutUserId(uri); if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { @@ -280,7 +281,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public int bulkInsert(String callingPkg, Uri uri, ContentValues[] initialValues) { - validateIncomingUri(uri); + uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return 0; @@ -302,11 +303,12 @@ public abstract class ContentProvider implements ComponentCallbacks2 { for (int i = 0; i < numOperations; i++) { ContentProviderOperation operation = operations.get(i); Uri uri = operation.getUri(); - validateIncomingUri(uri); userIds[i] = getUserIdFromUri(uri); - if (userIds[i] != UserHandle.USER_CURRENT) { - // Removing the user id from the uri. - operation = new ContentProviderOperation(operation, true); + uri = validateIncomingUri(uri); + uri = maybeGetUriWithoutUserId(uri); + // Rebuild operation if we changed the Uri above + if (!Objects.equals(operation.getUri(), uri)) { + operation = new ContentProviderOperation(operation, uri); operations.set(i, operation); } if (operation.isReadOperation()) { @@ -341,7 +343,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public int delete(String callingPkg, Uri uri, String selection, String[] selectionArgs) { - validateIncomingUri(uri); + uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return 0; @@ -357,7 +359,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public int update(String callingPkg, Uri uri, ContentValues values, String selection, String[] selectionArgs) { - validateIncomingUri(uri); + uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); if (enforceWritePermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return 0; @@ -374,7 +376,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { public ParcelFileDescriptor openFile( String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal, IBinder callerToken) throws FileNotFoundException { - validateIncomingUri(uri); + uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); enforceFilePermission(callingPkg, uri, mode, callerToken); final String original = setCallingPackage(callingPkg); @@ -390,7 +392,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { public AssetFileDescriptor openAssetFile( String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal) throws FileNotFoundException { - validateIncomingUri(uri); + uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); enforceFilePermission(callingPkg, uri, mode, null); final String original = setCallingPackage(callingPkg); @@ -416,7 +418,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public String[] getStreamTypes(Uri uri, String mimeTypeFilter) { - validateIncomingUri(uri); + uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); return ContentProvider.this.getStreamTypes(uri, mimeTypeFilter); } @@ -425,7 +427,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri uri, String mimeType, Bundle opts, ICancellationSignal cancellationSignal) throws FileNotFoundException { Bundle.setDefusable(opts, true); - validateIncomingUri(uri); + uri = validateIncomingUri(uri); uri = maybeGetUriWithoutUserId(uri); enforceFilePermission(callingPkg, uri, "r", null); final String original = setCallingPackage(callingPkg); @@ -444,7 +446,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public Uri canonicalize(String callingPkg, Uri uri) { - validateIncomingUri(uri); + uri = validateIncomingUri(uri); int userId = getUserIdFromUri(uri); uri = getUriWithoutUserId(uri); if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { @@ -460,7 +462,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public Uri uncanonicalize(String callingPkg, Uri uri) { - validateIncomingUri(uri); + uri = validateIncomingUri(uri); int userId = getUserIdFromUri(uri); uri = getUriWithoutUserId(uri); if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { @@ -477,7 +479,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { @Override public boolean refresh(String callingPkg, Uri uri, Bundle args, ICancellationSignal cancellationSignal) throws RemoteException { - validateIncomingUri(uri); + uri = validateIncomingUri(uri); uri = getUriWithoutUserId(uri); if (enforceReadPermission(callingPkg, uri, null) != AppOpsManager.MODE_ALLOWED) { return false; @@ -1914,7 +1916,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { */ if (mContext == null) { mContext = context; - if (context != null) { + if (context != null && mTransport != null) { mTransport.mAppOpsManager = (AppOpsManager) context.getSystemService( Context.APP_OPS_SERVICE); } @@ -2023,7 +2025,7 @@ public abstract class ContentProvider implements ComponentCallbacks2 { } /** @hide */ - private void validateIncomingUri(Uri uri) throws SecurityException { + public Uri validateIncomingUri(Uri uri) throws SecurityException { String auth = uri.getAuthority(); if (!mSingleUser) { int userId = getUserIdFromAuthority(auth, UserHandle.USER_CURRENT); @@ -2042,6 +2044,19 @@ public abstract class ContentProvider implements ComponentCallbacks2 { } throw new SecurityException(message); } + + // Normalize the path by removing any empty path segments, which can be + // a source of security issues. + final String encodedPath = uri.getEncodedPath(); + if (encodedPath != null && encodedPath.indexOf("//") != -1) { + final Uri normalized = uri.buildUpon() + .encodedPath(encodedPath.replaceAll("//+", "/")).build(); + Log.w(TAG, "Normalized " + uri + " to " + normalized + + " to avoid possible security issues"); + return normalized; + } else { + return uri; + } } /** @hide */ diff --git a/core/java/android/content/ContentProviderOperation.java b/core/java/android/content/ContentProviderOperation.java index e3d9b1931faa..7dc45776715c 100644 --- a/core/java/android/content/ContentProviderOperation.java +++ b/core/java/android/content/ContentProviderOperation.java @@ -101,13 +101,9 @@ public class ContentProviderOperation implements Parcelable { } /** @hide */ - public ContentProviderOperation(ContentProviderOperation cpo, boolean removeUserIdFromUri) { + public ContentProviderOperation(ContentProviderOperation cpo, Uri withUri) { mType = cpo.mType; - if (removeUserIdFromUri) { - mUri = ContentProvider.getUriWithoutUserId(cpo.mUri); - } else { - mUri = cpo.mUri; - } + mUri = withUri; mValues = cpo.mValues; mSelection = cpo.mSelection; mSelectionArgs = cpo.mSelectionArgs; @@ -117,14 +113,6 @@ public class ContentProviderOperation implements Parcelable { mYieldAllowed = cpo.mYieldAllowed; } - /** @hide */ - public ContentProviderOperation getWithoutUserIdInUri() { - if (ContentProvider.uriHasUserId(mUri)) { - return new ContentProviderOperation(this, true); - } - return this; - } - public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mType); Uri.writeToParcel(dest, mUri); diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 5cbb1f8895c5..81e72ccafe4d 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -49,6 +49,7 @@ import android.database.sqlite.SQLiteDatabase; 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; @@ -327,6 +328,15 @@ public abstract class Context { public static final int BIND_ADJUST_WITH_ACTIVITY = 0x0080; /** + * Flag for {@link #bindService}: If binding from something better than perceptible, + * still set the adjust below perceptible. This would be used for bound services that can + * afford to be evicted when under extreme memory pressure, but should be restarted as soon + * as possible. + * @hide + */ + public static final int BIND_ADJUST_BELOW_PERCEPTIBLE = 0x0100; + + /** * @hide Flag for {@link #bindService}: allows binding to a service provided * by an instant app. Note that the caller may not have access to the instant * app providing the service which is a violation of the instant app sandbox. @@ -3495,6 +3505,15 @@ public abstract class Context { /** * 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. * @@ -4251,7 +4270,7 @@ public abstract class Context { /** * Use with {@link #getSystemService(String)} to retrieve an - * {@link android.telephony.rcs.RcsManager}. + * {@link android.telephony.ims.RcsManager}. * @hide */ public static final String TELEPHONY_RCS_SERVICE = "ircs"; diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java index 3de7a8bdfaf3..2d590033259f 100644 --- a/core/java/android/content/pm/ShortcutManager.java +++ b/core/java/android/content/pm/ShortcutManager.java @@ -21,7 +21,6 @@ import android.annotation.SystemService; import android.annotation.TestApi; import android.annotation.UnsupportedAppUsage; import android.annotation.UserIdInt; -import android.app.Activity; import android.app.usage.UsageStatsManager; import android.content.Context; import android.content.Intent; @@ -31,256 +30,23 @@ import android.os.Build; import android.os.Build.VERSION_CODES; import android.os.RemoteException; import android.os.ServiceManager; -import android.os.UserHandle; import com.android.internal.annotations.VisibleForTesting; import java.util.List; /** - * The ShortcutManager performs operations on an app's set of <em>shortcuts</em>. The - * {@link ShortcutInfo} class contains information about each of the shortcuts themselves. + * <p><code>ShortcutManager</code> executes operations on an app's set of <i>shortcuts</i>, which + * represent specific tasks and actions that users can perform within your app. This page lists + * components of the <code>ShortcutManager</code> class that you can use to create and manage + * sets of shortcuts. * - * <p>An app's shortcuts represent specific tasks and actions that users can perform within your - * app. When a user selects a shortcut in the currently-active launcher, your app opens an activity - * other than the app's starting activity, provided that the currently-active launcher supports app - * shortcuts.</p> + * <p>To learn about methods that retrieve information about a single shortcut—including + * identifiers, type, and status—read the <code> + * <a href="/reference/android/content/pm/ShortcutInfo.html">ShortcutInfo</a></code> reference. * - * <p>The types of shortcuts that you create for your app depend on the app's key use cases. For - * example, an email app may publish the "compose new email" shortcut, which allows the app to - * directly open the compose activity.</p> - * - * <p class="note"><b>Note:</b> Only main activities—activities that handle the - * {@link Intent#ACTION_MAIN} action and the {@link Intent#CATEGORY_LAUNCHER} category—can - * have shortcuts. If an app has multiple main activities, you need to define the set of shortcuts - * for <em>each</em> activity. - * - * <p>This page discusses the implementation details of the <code>ShortcutManager</code> class. For - * definitions of key terms and guidance on performing operations on shortcuts within your app, see - * the <a href="/guide/topics/ui/shortcuts.html">App Shortcuts</a> feature guide. - * - * <h3>Shortcut characteristics</h3> - * - * This section describes in-depth details about each shortcut type's usage and availability. - * - * <p class="note"><b>Important security note:</b> All shortcut information is stored in - * <a href="/training/articles/direct-boot.html">credential encrypted storage</a>, so your app - * cannot access a user's shortcuts until after they've unlocked the device. - * - * <h4>Static and dynamic shortcuts</h4> - * - * <p>Static shortcuts and dynamic shortcuts are shown in a supported launcher when the user - * performs a specific gesture. On currently-supported launchers, the gesture is a long-press on the - * app's launcher icon, but the actual gesture may be different on other launcher apps. - * - * <p>The {@link LauncherApps} class provides APIs for launcher apps to access shortcuts. - * - * <h4>Pinned shortcuts</h4> - * - * <p>Because pinned shortcuts appear in the launcher itself, they're always visible. A pinned - * shortcut is removed from the launcher only in the following situations: - * <ul> - * <li>The user removes it. - * <li>The publisher app associated with the shortcut is uninstalled. - * <li>The user selects <b>Clear data</b> from the publisher app's <i>Storage</i> screen, within - * the system's <b>Settings</b> app. - * </ul> - * - * <p>Because the system performs - * <a href="/guide/topics/ui/shortcuts.html#backup-and-restore">backup and restore</a> on pinned - * shortcuts automatically, these shortcuts' IDs should contain either stable, constant strings or - * server-side identifiers, rather than identifiers generated locally that might not make sense on - * other devices. - * - * <h3>Shortcut display order</h3> - * - * <p>When the launcher displays an app's shortcuts, they should appear in the following order: - * - * <ol> - * <li><b>Static shortcuts:</b> Shortcuts whose {@link ShortcutInfo#isDeclaredInManifest()} method - * returns {@code true}.</li> - * <li><b>Dynamic shortcuts:</b> Shortcuts whose {@link ShortcutInfo#isDynamic()} method returns - * {@code true}.</li> - * </ol> - * - * <p>Within each shortcut type (static and dynamic), shortcuts are sorted in order of increasing - * rank according to {@link ShortcutInfo#getRank()}.</p> - * - * <h4>Shortcut ranks</h4> - * - * <p>Shortcut ranks are non-negative, sequential integers that determine the order in which - * shortcuts appear, assuming that the shortcuts are all in the same category. You can update ranks - * of existing shortcuts when you call {@link #updateShortcuts(List)}, - * {@link #addDynamicShortcuts(List)}, or {@link #setDynamicShortcuts(List)}. - * - * <p class="note"><b>Note:</b> Ranks are auto-adjusted so that they're unique for each type of - * shortcut (static or dynamic). For example, if there are 3 dynamic shortcuts with ranks 0, 1 and - * 2, adding another dynamic shortcut with a rank of 1 represents a request to place this shortcut - * at the second position. In response, the third and fourth shortcuts move closer to the bottom of - * the shortcut list, with their ranks changing to 2 and 3, respectively. - * - * <h3>Options for static shortcuts</h3> - * - * The following list includes descriptions for the different attributes within a static shortcut. - * You must provide a value for {@code android:shortcutId} and {@code android:shortcutShortLabel}; - * all other values are optional. - * - * <dl> - * <dt>{@code android:shortcutId}</dt> - * <dd><p>A string literal, which represents the shortcut when a {@code ShortcutManager} object - * performs operations on it.</p> - * <p class="note"><b>Note: </b>You cannot set this attribute's value to a resource string, such - * as <code>@string/foo</code>.</p> - * </dd> - * - * <dt>{@code android:enabled}</dt> - * <dd><p>Whether the user can interact with the shortcut from a supported launcher.</p> - * <p>The default value is {@code true}. If you set it to {@code false}, you should also set - * {@code android:shortcutDisabledMessage} to a message that explains why you've disabled the - * shortcut. If you don't think you need to provide such a message, it's easiest to just remove - * the shortcut from the XML file entirely, rather than changing the values of the shortcut's - * {@code android:enabled} and {@code android:shortcutDisabledMessage} attributes. - * </dd> - * - * <dt>{@code android:icon}</dt> - * <dd><p>The <a href="/topic/performance/graphics/index.html">bitmap</a> or - * <a href="/guide/practices/ui_guidelines/icon_design_adaptive.html">adaptive icon</a> that the - * launcher uses when displaying the shortcut to the user. This value can be either the path to an - * image or the resource file that contains the image. Use adaptive icons whenever possible to - * improve performance and consistency.</p> - * <p class="note"><b>Note: </b>Shortcut icons cannot include - * <a href="/training/material/drawables.html#DrawableTint">tints</a>. - * </dd> - * - * <dt>{@code android:shortcutShortLabel}</dt> - * <dd><p>A concise phrase that describes the shortcut's purpose. For more information, see - * {@link ShortcutInfo.Builder#setShortLabel(CharSequence)}.</p> - * <p class="note"><b>Note: </b>This attribute's value must be a resource string, such as - * <code>@string/shortcut_short_label</code>.</p> - * </dd> - * - * <dt>{@code android:shortcutLongLabel}</dt> - * <dd><p>An extended phrase that describes the shortcut's purpose. If there's enough space, the - * launcher displays this value instead of {@code android:shortcutShortLabel}. For more - * information, see {@link ShortcutInfo.Builder#setLongLabel(CharSequence)}.</p> - * <p class="note"><b>Note: </b>This attribute's value must be a resource string, such as - * <code>@string/shortcut_long_label</code>.</p> - * </dd> - * - * <dt>{@code android:shortcutDisabledMessage}</dt> - * <dd><p>The message that appears in a supported launcher when the user attempts to launch a - * disabled shortcut. The message should explain to the user why the shortcut is now disabled. - * This attribute's value has no effect if {@code android:enabled} is {@code true}.</p> - * <p class="note"><b>Note: </b>This attribute's value must be a resource string, such as - * <code>@string/shortcut_disabled_message</code>.</p> - * </dd> - * </dl> - * - * <h3>Inner elements that define static shortcuts</h3> - * - * <p>The XML file that lists an app's static shortcuts supports the following elements inside each - * {@code <shortcut>} element. You must include an {@code intent} inner element for each - * static shortcut that you define.</p> - * - * <dl> - * <dt>{@code intent}</dt> - * <dd><p>The action that the system launches when the user selects the shortcut. This intent must - * provide a value for the {@code android:action} attribute.</p> - * <p>You can provide multiple intents for a single shortcut. If you do so, the last defined - * activity is launched, and the other activities are placed in the - * <a href="/guide/components/tasks-and-back-stack.html">back stack</a>. See - * <a href="/guide/topics/ui/shortcuts.html#static">Using Static Shortcuts</a> and the - * {@link android.app.TaskStackBuilder} class reference for details.</p> - * <p class="note"><b>Note:</b> This {@code intent} element cannot include string resources.</p> - * <p>To learn more about how to configure intents, see - * <a href="{@docRoot}guide/topics/ui/settings.html#Intents">Using intents</a>.</p> - * </dd> - * - * <dt>{@code categories}</dt> - * <dd><p>Provides a grouping for the types of actions that your app's shortcuts perform, such as - * creating new chat messages.</p> - * <p>For a list of supported shortcut categories, see the {@link ShortcutInfo} class reference - * for a list of supported shortcut categories. - * </dd> - * </dl> - * - * <h3>Updating shortcuts</h3> - * - * <p>Each app's launcher icon can contain at most {@link #getMaxShortcutCountPerActivity()} number - * of static and dynamic shortcuts combined. There is no limit to the number of pinned shortcuts - * that an app can create, though. - * - * <p>When a dynamic shortcut is pinned, even when the publisher removes it as a dynamic shortcut, - * the pinned shortcut is still visible and launchable. This allows an app to have more than - * {@link #getMaxShortcutCountPerActivity()} number of shortcuts. - * - * <p>As an example, suppose {@link #getMaxShortcutCountPerActivity()} is 5: - * <ol> - * <li>A chat app publishes 5 dynamic shortcuts for the 5 most recent - * conversations (c1, c2, ..., c5). - * - * <li>The user pins all 5 of the shortcuts. - * - * <li>Later, the user has started 3 additional conversations (c6, c7, and c8), so the publisher - * app re-publishes its dynamic shortcuts. The new dynamic shortcut list is: c4, c5, ..., c8. - * <p>The publisher app has to remove c1, c2, and c3 because it can't have more than 5 dynamic - * shortcuts. However, c1, c2, and c3 are still pinned shortcuts that the user can access and - * launch. - * <p>At this point, the user can access a total of 8 shortcuts that link to activities in the - * publisher app, including the 3 pinned shortcuts, even though an app can have at most 5 - * dynamic shortcuts. - * - * <li>The app can use {@link #updateShortcuts(List)} to update <em>any</em> of the existing - * 8 shortcuts, when, for example, the chat peers' icons have changed. - * <p>The {@link #addDynamicShortcuts(List)} and {@link #setDynamicShortcuts(List)} methods - * can also be used to update existing shortcuts with the same IDs, but they <b>cannot</b> be - * used for updating non-dynamic, pinned shortcuts because these 2 methods try to convert the - * given lists of shortcuts to dynamic shortcuts. - * </ol> - * - * <h3>Shortcut intents</h3> - * - * <p> - * Dynamic shortcuts can be published with any set of {@link Intent#addFlags Intent} flags. - * Typically, {@link Intent#FLAG_ACTIVITY_CLEAR_TASK} is specified, possibly along with other - * flags; otherwise, if the app is already running, the app is simply brought to - * the foreground, and the target activity might not appear. - * - * <p>Static shortcuts <b>cannot</b> have custom intent flags. - * The first intent of a static shortcut will always have {@link Intent#FLAG_ACTIVITY_NEW_TASK} - * and {@link Intent#FLAG_ACTIVITY_CLEAR_TASK} set. This means, when the app is already running, all - * the existing activities in your app are destroyed when a static shortcut is launched. - * If this behavior is not desirable, you can use a <em>trampoline activity</em>, or an invisible - * activity that starts another activity in {@link Activity#onCreate}, then calls - * {@link Activity#finish()}: - * <ol> - * <li>In the <code>AndroidManifest.xml</code> file, the trampoline activity should include the - * attribute assignment {@code android:taskAffinity=""}. - * <li>In the shortcuts resource file, the intent within the static shortcut should reference - * the trampoline activity. - * </ol> - * - * <h3>Rate limiting</h3> - * - * <p>When <a href="/guide/topics/ui/shortcuts.html#rate-limit">rate limiting</a> is active, - * {@link #isRateLimitingActive()} returns {@code true}. - * - * <p>Rate limiting is reset upon certain events, so even background apps can call these APIs until - * the rate limit is reached again. These events include the following: - * <ul> - * <li>An app comes to the foreground. - * <li>The system locale changes. - * <li>The user performs the <a href="/guide/topics/ui/notifiers/notifications.html#direct">inline - * reply</a> action on a notification. - * </ul> - * - * <h3>Handling system locale changes</h3> - * - * <p>Apps should update dynamic and pinned shortcuts when they receive the - * {@link Intent#ACTION_LOCALE_CHANGED} broadcast, indicating that the system locale has changed. - * <p>When the system locale changes, <a href="/guide/topics/ui/shortcuts.html#rate-limit">rate - * limiting</a> is reset, so even background apps can add and update dynamic shortcuts until the - * rate limit is reached again. + * <p>For guidance about using shortcuts, see + * <a href="/guide/topics/ui/shortcuts/index.html">App shortcuts</a>. * * <h3>Retrieving class instances</h3> * <!-- Provides a heading for the content filled in by the @SystemService annotation below --> @@ -461,8 +227,9 @@ public class ShortcutManager { } /** - * Disable pinned shortcuts. For more details, see the Javadoc for the {@link ShortcutManager} - * class. + * Disable pinned shortcuts. For more details, read + * <a href="/guide/topics/ui/shortcuts/managing-shortcuts.html#disable-shortcuts"> + * Disable shortcuts</a>. * * @throws IllegalArgumentException If trying to disable immutable shortcuts. * @@ -501,7 +268,9 @@ public class ShortcutManager { /** * Disable pinned shortcuts, showing the user a custom error message when they try to select * the disabled shortcuts. - * For more details, see the Javadoc for the {@link ShortcutManager} class. + * For more details, read + * <a href="/guide/topics/ui/shortcuts/managing-shortcuts.html#disable-shortcuts"> + * Disable shortcuts</a>. * * @throws IllegalArgumentException If trying to disable immutable shortcuts. * @@ -589,7 +358,8 @@ public class ShortcutManager { /** * Return {@code true} when rate-limiting is active for the caller app. * - * <p>See the class level javadoc for details. + * <p>For details, see <a href="/guide/topics/ui/shortcuts/managing-shortcuts#rate-limiting"> + * Rate limiting</a>. * * @throws IllegalStateException when the user is locked. */ @@ -635,7 +405,9 @@ public class ShortcutManager { * Apps that publish shortcuts should call this method whenever the user * selects the shortcut containing the given ID or when the user completes * an action in the app that is equivalent to selecting the shortcut. - * For more details, see the Javadoc for the {@link ShortcutManager} class + * For more details, read about + * <a href="/guide/topics/ui/shortcuts/managing-shortcuts.html#track-usage"> + * tracking shortcut usage</a>. * * <p>The information is accessible via {@link UsageStatsManager#queryEvents} * Typically, launcher apps use this information to build a prediction model @@ -703,7 +475,9 @@ public class ShortcutManager { * @param resultIntent If not null, this intent will be sent when the shortcut is pinned. * Use {@link android.app.PendingIntent#getIntentSender()} to create an {@link IntentSender}. * To avoid background execution limits, use an unexported, manifest-declared receiver. - * For more details, see the overview documentation for the {@link ShortcutManager} class. + * For more details, see + * <a href="/guide/topics/ui/shortcuts/creating-shortcuts.html#pinned"> + * Creating pinned shortcuts</a>. * * @return {@code TRUE} if the launcher supports this feature. Note the API will return without * waiting for the user to respond, so getting {@code TRUE} from this API does *not* mean diff --git a/core/java/android/database/sqlite/SQLiteDebug.java b/core/java/android/database/sqlite/SQLiteDebug.java index d39252130d4b..48f8ac97254a 100644 --- a/core/java/android/database/sqlite/SQLiteDebug.java +++ b/core/java/android/database/sqlite/SQLiteDebug.java @@ -119,7 +119,6 @@ public final class SQLiteDebug { /** * contains statistics about a database */ - @TestApi public static class DbStats { /** name of the database */ public String dbName; @@ -151,7 +150,6 @@ public final class SQLiteDebug { * return all pager and database stats for the current process. * @return {@link PagerStats} */ - @TestApi public static PagerStats getDatabaseInfo() { PagerStats stats = new PagerStats(); nativeGetPagerStats(stats); diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index 47145874490f..49c3dc63e151 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -187,13 +187,19 @@ public class ConnectivityManager { * 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 @@ public class ConnectivityManager { * 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 @@ public class ConnectivityManager { * * @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 @@ public class ConnectivityManager { * @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 4b1a08ded9d6..0877a1a47e2b 100644 --- a/core/java/android/net/INetdEventCallback.aidl +++ b/core/java/android/net/INetdEventCallback.aidl @@ -45,6 +45,20 @@ oneway interface INetdEventCallback { 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 000000000000..29f882858c05 --- /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 000000000000..8e6c69a97edb --- /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 1b9a66cd6ea7..80517ce28cda 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -18,6 +18,7 @@ package android.net; 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 @@ public final class LinkProperties implements Parcelable { /** * @hide */ - @UnsupportedAppUsage + @SystemApi public LinkProperties() { } @@ -195,7 +196,7 @@ public final class LinkProperties implements Parcelable { * @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 @@ public final class LinkProperties implements Parcelable { * object. * @hide */ - @UnsupportedAppUsage + @SystemApi public void setLinkAddresses(Collection<LinkAddress> addresses) { mLinkAddresses.clear(); for (LinkAddress address: addresses) { @@ -392,7 +393,7 @@ public final class LinkProperties implements Parcelable { * @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 @@ public final class LinkProperties implements Parcelable { * domains to search when resolving host names on this link. * @hide */ - @UnsupportedAppUsage + @SystemApi public void setDomains(String domains) { mDomains = domains; } @@ -552,7 +553,7 @@ public final class LinkProperties implements Parcelable { * @param mtu The MTU to use for this link. * @hide */ - @UnsupportedAppUsage + @SystemApi public void setMtu(int mtu) { mMtu = mtu; } @@ -562,9 +563,7 @@ public final class LinkProperties implements Parcelable { * this will return 0. * * @return The mtu value set for this link. - * @hide */ - @UnsupportedAppUsage public int getMtu() { return mMtu; } @@ -613,7 +612,7 @@ public final class LinkProperties implements Parcelable { * * @hide */ - @UnsupportedAppUsage + @SystemApi public boolean addRoute(RouteInfo route) { if (route != null) { String routeIface = route.getInterface(); @@ -688,7 +687,7 @@ public final class LinkProperties implements Parcelable { * @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 @@ public final class LinkProperties implements Parcelable { * 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 0c44a566b48a..1b44c920a205 100644 --- a/core/java/android/net/NetworkCapabilities.java +++ b/core/java/android/net/NetworkCapabilities.java @@ -931,7 +931,7 @@ public final class NetworkCapabilities implements Parcelable { * Returns a transport-specific information container. The application may cast this * container to a concrete sub-class based on its knowledge of the network request. The * application should be able to deal with a {@code null} return value or an invalid case, - * e.g. use {@code instanceof} operation to verify expected type. + * e.g. use {@code instanceof} operator to verify expected type. * * @return A concrete implementation of the {@link TransportInfo} class or null if not * available for the network. @@ -1017,7 +1017,7 @@ public final class NetworkCapabilities implements Parcelable { * @return The bearer-specific signal strength. * @hide */ - @UnsupportedAppUsage + @SystemApi public int getSignalStrength() { return mSignalStrength; } @@ -1467,7 +1467,7 @@ public final class NetworkCapabilities implements Parcelable { 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 1a1d2d33424c..89d99617dfbf 100644 --- a/core/java/android/net/NetworkInfo.java +++ b/core/java/android/net/NetworkInfo.java @@ -28,7 +28,20 @@ import java.util.EnumMap; * 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 @@ public class NetworkInfo implements Parcelable { * <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 @@ public class NetworkInfo implements Parcelable { * 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 @@ public class NetworkInfo implements Parcelable { * 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 @@ public class NetworkInfo implements Parcelable { * 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 04b6b44013b9..3b01b03edd4e 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 @@ public class NetworkRequest implements Parcelable { * @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 000000000000..82a4e31a81dd --- /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 34e9476b3e08..c0aa4a6faf12 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 @@ public class NetworkUtils { * @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/net/TrafficStats.java b/core/java/android/net/TrafficStats.java index 1b22911f0cdc..bbf8f97c8865 100644 --- a/core/java/android/net/TrafficStats.java +++ b/core/java/android/net/TrafficStats.java @@ -274,7 +274,6 @@ public class TrafficStats { * Changes only take effect during subsequent calls to * {@link #tagSocket(Socket)}. */ - @SystemApi @SuppressLint("Doclava125") public static void setThreadStatsUid(int uid) { NetworkManagementSocketTagger.setThreadSocketStatsUid(uid); @@ -313,7 +312,6 @@ public class TrafficStats { * * @see #setThreadStatsUid(int) */ - @SystemApi @SuppressLint("Doclava125") public static void clearThreadStatsUid() { NetworkManagementSocketTagger.setThreadSocketStatsUid(-1); @@ -333,6 +331,14 @@ public class TrafficStats { /** * Remove any statistics parameters from the given {@link Socket}. + * <p> + * In Android 8.1 (API level 27) and lower, a socket is automatically + * untagged when it's sent to another process using binder IPC with a + * {@code ParcelFileDescriptor} container. In Android 9.0 (API level 28) + * and higher, the socket tag is kept when the socket is sent to another + * process using binder IPC. You can mimic the previous behavior by + * calling {@code untagSocket()} before sending the socket to another + * process. */ public static void untagSocket(Socket socket) throws SocketException { SocketTagger.get().untag(socket); diff --git a/core/java/android/net/http/X509TrustManagerExtensions.java b/core/java/android/net/http/X509TrustManagerExtensions.java index f9b6dfce32ff..280dad0284b6 100644 --- a/core/java/android/net/http/X509TrustManagerExtensions.java +++ b/core/java/android/net/http/X509TrustManagerExtensions.java @@ -16,7 +16,6 @@ package android.net.http; -import android.annotation.SystemApi; import android.security.net.config.UserCertificateSource; import com.android.org.conscrypt.TrustManagerImpl; @@ -133,7 +132,6 @@ public class X509TrustManagerExtensions { * Returns {@code true} if the TrustManager uses the same trust configuration for the provided * hostnames. */ - @SystemApi public boolean isSameTrustConfiguration(String hostname1, String hostname2) { if (mIsSameTrustConfiguration == null) { return true; diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index 91888949829f..6de575960f48 100644..100755 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -628,7 +628,8 @@ public class Build { * October 2013: Android 4.4, KitKat, another tasty treat. * * <p>Applications targeting this or a later release will get these - * new changes in behavior:</p> + * new changes in behavior. For more information about this release, see the + * <a href="/about/versions/kitkat/">Android KitKat overview</a>.</p> * <ul> * <li> The default result of * {@link android.preference.PreferenceActivity#isValidFragment(String) @@ -678,7 +679,8 @@ public class Build { * November 2014: Lollipop. A flat one with beautiful shadows. But still tasty. * * <p>Applications targeting this or a later release will get these - * new changes in behavior:</p> + * new changes in behavior. For more information about this release, see the + * <a href="/about/versions/lollipop/">Android Lollipop overview</a>.</p> * <ul> * <li> {@link android.content.Context#bindService Context.bindService} now * requires an explicit Intent, and will throw an exception if given an implicit @@ -707,6 +709,8 @@ public class Build { /** * March 2015: Lollipop with an extra sugar coating on the outside! + * For more information about this release, see the + * <a href="/about/versions/android-5.1">Android 5.1 APIs</a>. */ public static final int LOLLIPOP_MR1 = 22; @@ -714,7 +718,8 @@ public class Build { * M is for Marshmallow! * * <p>Applications targeting this or a later release will get these - * new changes in behavior:</p> + * new changes in behavior. For more information about this release, see the + * <a href="/about/versions/marshmallow/">Android 6.0 Marshmallow overview</a>.</p> * <ul> * <li> Runtime permissions. Dangerous permissions are no longer granted at * install time, but must be requested by the application at runtime through @@ -745,7 +750,8 @@ public class Build { * N is for Nougat. * * <p>Applications targeting this or a later release will get these - * new changes in behavior:</p> + * new changes in behavior. For more information about this release, see + * the <a href="/about/versions/nougat/">Android Nougat overview</a>.</p> * <ul> * <li> {@link android.app.DownloadManager.Request#setAllowedNetworkTypes * DownloadManager.Request.setAllowedNetworkTypes} @@ -795,7 +801,9 @@ public class Build { public static final int N = 24; /** - * N MR1: Nougat++. + * N MR1: Nougat++. For more information about this release, see + * <a href="/about/versions/nougat/android-7.1">Android 7.1 for + * Developers</a>. */ public static final int N_MR1 = 25; @@ -803,7 +811,8 @@ public class Build { * O. * * <p>Applications targeting this or a later release will get these - * new changes in behavior:</p> + * new changes in behavior. For more information about this release, see + * the <a href="/about/versions/oreo/">Android Oreo overview</a>.</p> * <ul> * <li><a href="{@docRoot}about/versions/oreo/background.html">Background execution limits</a> * are applied to the application.</li> @@ -892,13 +901,16 @@ public class Build { * O MR1. * * <p>Applications targeting this or a later release will get these - * new changes in behavior:</p> + * new changes in behavior. For more information about this release, see + * <a href="/about/versions/oreo/android-8.1">Android 8.1 features and + * APIs</a>.</p> * <ul> * <li>Apps exporting and linking to apk shared libraries must explicitly * enumerate all signing certificates in a consistent order.</li> * <li>{@link android.R.attr#screenOrientation} can not be used to request a fixed * orientation if the associated activity is not fullscreen and opaque.</li> * </ul> + * */ public static final int O_MR1 = 27; @@ -906,7 +918,8 @@ public class Build { * P. * * <p>Applications targeting this or a later release will get these - * new changes in behavior:</p> + * new changes in behavior. For more information about this release, see the + * <a href="/about/versions/pie/">Android 9 Pie overview</a>.</p> * <ul> * <li>{@link android.app.Service#startForeground Service.startForeground} requires * that apps hold the permission @@ -914,6 +927,7 @@ public class Build { * <li>{@link android.widget.LinearLayout} will always remeasure weighted children, * even if there is no excess space.</li> * </ul> + * */ public static final int P = 28; @@ -1113,7 +1127,8 @@ public class Build { * null (if, for instance, the radio is not currently on). */ public static String getRadioVersion() { - return SystemProperties.get(TelephonyProperties.PROPERTY_BASEBAND_VERSION, null); + String propVal = SystemProperties.get(TelephonyProperties.PROPERTY_BASEBAND_VERSION); + return TextUtils.isEmpty(propVal) ? null : propVal; } private static String getString(String property) { diff --git a/core/java/android/os/HwBinder.java b/core/java/android/os/HwBinder.java index 228fe7a3dae5..3de3494e7ea7 100644 --- a/core/java/android/os/HwBinder.java +++ b/core/java/android/os/HwBinder.java @@ -32,10 +32,7 @@ public abstract class HwBinder implements IHwBinder { /** * Create and initialize a HwBinder object and the native objects * used to allow this to participate in hwbinder transactions. - * - * @hide */ - @SystemApi public HwBinder() { native_setup(); @@ -44,7 +41,6 @@ public abstract class HwBinder implements IHwBinder { mNativeContext); } - /** @hide */ @Override public final native void transact( int code, HwParcel request, HwParcel reply, int flags) @@ -57,10 +53,7 @@ public abstract class HwBinder implements IHwBinder { * @param request parceled transaction * @param reply object to parcel reply into * @param flags transaction flags to be chosen by wire protocol - * - * @hide */ - @SystemApi public abstract void onTransact( int code, HwParcel request, HwParcel reply, int flags) throws RemoteException; @@ -69,9 +62,7 @@ public abstract class HwBinder implements IHwBinder { * Registers this service with the hwservicemanager. * * @param serviceName instance name of the service - * @hide */ - @SystemApi public native final void registerService(String serviceName) throws RemoteException; @@ -81,9 +72,7 @@ public abstract class HwBinder implements IHwBinder { * @param iface fully-qualified interface name for example foo.bar@1.3::IBaz * @param serviceName the instance name of the service for example default. * @throws NoSuchElementException when the service is unavailable - * @hide */ - @SystemApi public static final IHwBinder getService( String iface, String serviceName) @@ -96,9 +85,7 @@ public abstract class HwBinder implements IHwBinder { * @param serviceName the instance name of the service for example default. * @param retry whether to wait for the service to start if it's not already started * @throws NoSuchElementException when the service is unavailable - * @hide */ - @SystemApi public static native final IHwBinder getService( String iface, String serviceName, @@ -112,9 +99,7 @@ public abstract class HwBinder implements IHwBinder { * @param maxThreads total number of threads to create (includes this thread if * callerWillJoin is true) * @param callerWillJoin whether joinRpcThreadpool will be called in advance - * @hide */ - @SystemApi public static native final void configureRpcThreadpool( long maxThreads, boolean callerWillJoin); @@ -124,10 +109,7 @@ public abstract class HwBinder implements IHwBinder { * a threadpool with callerWillJoin true and then registering * the provided service if this thread doesn't need to do * anything else. - * - * @hide */ - @SystemApi public static native final void joinRpcThreadpool(); // Returns address of the "freeFunction". @@ -155,10 +137,7 @@ public abstract class HwBinder implements IHwBinder { * - tries to enable atracing (if enabled) * - tries to enable coverage dumps (if running in VTS) * - tries to enable record and replay (if running in VTS) - * - * @hide */ - @SystemApi public static void enableInstrumentation() { native_report_sysprop_change(); } diff --git a/core/java/android/os/IHwBinder.java b/core/java/android/os/IHwBinder.java index fbdf27e38d67..249eb3aa3456 100644 --- a/core/java/android/os/IHwBinder.java +++ b/core/java/android/os/IHwBinder.java @@ -28,10 +28,7 @@ public interface IHwBinder { * @param request parceled transaction * @param reply object to parcel reply into * @param flags transaction flags to be chosen by wire protocol - * - * @hide */ - @SystemApi public void transact( int code, HwParcel request, HwParcel reply, int flags) throws RemoteException; @@ -40,23 +37,19 @@ public interface IHwBinder { * Return as IHwInterface instance only if this implements descriptor. * * @param descriptor for example foo.bar@1.0::IBaz - * @hide */ - @SystemApi public IHwInterface queryLocalInterface(String descriptor); /** * Interface for receiving a callback when the process hosting a service * has gone away. */ - @SystemApi public interface DeathRecipient { /** * Callback for a registered process dying. * * @param cookie cookie this death recipient was registered with. */ - @SystemApi public void serviceDied(long cookie); } @@ -67,13 +60,11 @@ public interface IHwBinder { * @param recipient callback object to be called on object death. * @param cookie value to be given to callback on object death. */ - @SystemApi public boolean linkToDeath(DeathRecipient recipient, long cookie); /** * Unregisters the death recipient from this binder. * * @param recipient callback to no longer recieve death notifications on this binder. */ - @SystemApi public boolean unlinkToDeath(DeathRecipient recipient); } diff --git a/core/java/android/os/IHwInterface.java b/core/java/android/os/IHwInterface.java index 1d9e2b0197c7..f9edd5bf8883 100644 --- a/core/java/android/os/IHwInterface.java +++ b/core/java/android/os/IHwInterface.java @@ -23,6 +23,5 @@ public interface IHwInterface { /** * @return the binder object that corresponds to this interface. */ - @SystemApi public IHwBinder asBinder(); } diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl index c9c42058bad0..fdd74882eb39 100644 --- a/core/java/android/os/INetworkManagementService.aidl +++ b/core/java/android/os/INetworkManagementService.aidl @@ -18,7 +18,6 @@ package android.os; import android.net.InterfaceConfiguration; -import android.net.INetd; import android.net.INetworkManagementEventObserver; import android.net.ITetheringStatsProvider; import android.net.Network; @@ -47,11 +46,6 @@ interface INetworkManagementService void unregisterObserver(INetworkManagementEventObserver obs); /** - * Retrieve an INetd to talk to netd. - */ - INetd getNetdService(); - - /** * Returns a list of currently known network interfaces */ String[] listInterfaces(); @@ -396,7 +390,7 @@ interface INetworkManagementService /** * 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/Message.java b/core/java/android/os/Message.java index c3f60a332a2b..47659a295c50 100644 --- a/core/java/android/os/Message.java +++ b/core/java/android/os/Message.java @@ -349,7 +349,7 @@ public final class Message implements Parcelable { } /** - * Retrieve the a {@link android.os.Handler Handler} implementation that + * Retrieve the {@link android.os.Handler Handler} implementation that * will receive this message. The object must implement * {@link android.os.Handler#handleMessage(android.os.Message) * Handler.handleMessage()}. Each Handler has its own name-space for diff --git a/core/java/android/os/NativeHandle.java b/core/java/android/os/NativeHandle.java index fbecc8ec1cd9..f7ffc37f085f 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 @@ public final class NativeHandle implements Closeable { 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/Parcel.java b/core/java/android/os/Parcel.java index c7ebc8905692..210404ce4d71 100644 --- a/core/java/android/os/Parcel.java +++ b/core/java/android/os/Parcel.java @@ -834,11 +834,19 @@ public final class Parcel { return; } Set<Map.Entry<String,Object>> entries = val.entrySet(); - writeInt(entries.size()); + int size = entries.size(); + writeInt(size); + for (Map.Entry<String,Object> e : entries) { writeValue(e.getKey()); writeValue(e.getValue()); + size--; } + + if (size != 0) { + throw new BadParcelableException("Map size does not match number of entries!"); + } + } /** diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index d0cdf6e75224..f2837ecba215 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -174,6 +174,12 @@ public class Process { */ 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/os/StatsLogEventWrapper.java b/core/java/android/os/StatsLogEventWrapper.java index d4d3dc838d91..7b3ea57ba0e9 100644 --- a/core/java/android/os/StatsLogEventWrapper.java +++ b/core/java/android/os/StatsLogEventWrapper.java @@ -65,11 +65,17 @@ public final class StatsLogEventWrapper implements Parcelable { public static final Parcelable.Creator<StatsLogEventWrapper> CREATOR = new Parcelable.Creator<StatsLogEventWrapper>() { public StatsLogEventWrapper createFromParcel(Parcel in) { - return new StatsLogEventWrapper(in); + android.util.EventLog.writeEvent(0x534e4554, "112550251", + android.os.Binder.getCallingUid(), ""); + // Purposefully leaving this method not implemented. + throw new RuntimeException("Not implemented"); } public StatsLogEventWrapper[] newArray(int size) { - return new StatsLogEventWrapper[size]; + android.util.EventLog.writeEvent(0x534e4554, "112550251", + android.os.Binder.getCallingUid(), ""); + // Purposefully leaving this method not implemented. + throw new RuntimeException("Not implemented"); } }; @@ -120,10 +126,6 @@ public final class StatsLogEventWrapper implements Parcelable { mStorage.write(bytes, 0, bytes.length); } - private StatsLogEventWrapper(Parcel in) { - readFromParcel(in); - } - /** * Writes the stored fields to a byte array. Will first write a new-line character to denote * END_LIST before writing contents to byte array. @@ -134,13 +136,6 @@ public final class StatsLogEventWrapper implements Parcelable { } /** - * Not implemented. - */ - public void readFromParcel(Parcel in) { - // Not needed since this java class is for sending to statsd only. - } - - /** * Boilerplate for Parcel. */ public int describeContents() { diff --git a/core/java/android/os/SystemUpdateManager.java b/core/java/android/os/SystemUpdateManager.java index ce3e225975f0..9146731f8f9f 100644 --- a/core/java/android/os/SystemUpdateManager.java +++ b/core/java/android/os/SystemUpdateManager.java @@ -34,62 +34,51 @@ public class SystemUpdateManager { private static final String TAG = "SystemUpdateManager"; /** The status key of the system update info, expecting an int value. */ - @SystemApi public static final String KEY_STATUS = "status"; /** The title of the current update, expecting a String value. */ - @SystemApi public static final String KEY_TITLE = "title"; /** Whether it is a security update, expecting a boolean value. */ - @SystemApi public static final String KEY_IS_SECURITY_UPDATE = "is_security_update"; /** The build fingerprint after installing the current update, expecting a String value. */ - @SystemApi public static final String KEY_TARGET_BUILD_FINGERPRINT = "target_build_fingerprint"; /** The security patch level after installing the current update, expecting a String value. */ - @SystemApi public static final String KEY_TARGET_SECURITY_PATCH_LEVEL = "target_security_patch_level"; /** * The KEY_STATUS value that indicates there's no update status info available. */ - @SystemApi public static final int STATUS_UNKNOWN = 0; /** * The KEY_STATUS value that indicates there's no pending update. */ - @SystemApi public static final int STATUS_IDLE = 1; /** * The KEY_STATUS value that indicates an update is available for download, but pending user * approval to start. */ - @SystemApi public static final int STATUS_WAITING_DOWNLOAD = 2; /** * The KEY_STATUS value that indicates an update is in progress (i.e. downloading or installing * has started). */ - @SystemApi public static final int STATUS_IN_PROGRESS = 3; /** * The KEY_STATUS value that indicates an update is available for install. */ - @SystemApi public static final int STATUS_WAITING_INSTALL = 4; /** * The KEY_STATUS value that indicates an update will be installed after a reboot. This applies * to both of A/B and non-A/B OTAs. */ - @SystemApi public static final int STATUS_WAITING_REBOOT = 5; private final ISystemUpdateManager mService; @@ -110,7 +99,6 @@ public class SystemUpdateManager { * * @throws SecurityException if the caller is not allowed to read the info. */ - @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.READ_SYSTEM_UPDATE_INFO, android.Manifest.permission.RECOVERY, @@ -137,7 +125,6 @@ public class SystemUpdateManager { * @throws IllegalArgumentException if @link #KEY_STATUS} does not exist. * @throws SecurityException if the caller is not allowed to update the info. */ - @SystemApi @RequiresPermission(android.Manifest.permission.RECOVERY) public void updateSystemUpdateInfo(PersistableBundle infoBundle) { if (infoBundle == null || !infoBundle.containsKey(KEY_STATUS)) { diff --git a/core/java/android/os/UpdateEngine.java b/core/java/android/os/UpdateEngine.java index 24c9c9177360..8f2826c16b63 100644 --- a/core/java/android/os/UpdateEngine.java +++ b/core/java/android/os/UpdateEngine.java @@ -54,7 +54,6 @@ public class UpdateEngine { * Error code from the update engine. Values must agree with the ones in * system/update_engine/common/error_code.h. */ - @SystemApi public static final class ErrorCodeConstants { public static final int SUCCESS = 0; public static final int ERROR = 1; @@ -74,7 +73,6 @@ public class UpdateEngine { * Update status code from the update engine. Values must agree with the * ones in system/update_engine/client_library/include/update_engine/update_status.h. */ - @SystemApi public static final class UpdateStatusConstants { public static final int IDLE = 0; public static final int CHECKING_FOR_UPDATE = 1; @@ -95,7 +93,6 @@ public class UpdateEngine { /** * Creates a new instance. */ - @SystemApi public UpdateEngine() { mUpdateEngine = IUpdateEngine.Stub.asInterface( ServiceManager.getService(UPDATE_ENGINE_SERVICE)); @@ -106,7 +103,6 @@ public class UpdateEngine { * status change, and when the update completes. A handler can be supplied * to control which thread runs the callback, or null. */ - @SystemApi public boolean bind(final UpdateEngineCallback callback, final Handler handler) { synchronized (mUpdateEngineCallbackLock) { mUpdateEngineCallback = new IUpdateEngineCallback.Stub() { @@ -150,7 +146,6 @@ public class UpdateEngine { /** * Equivalent to {@code bind(callback, null)}. */ - @SystemApi public boolean bind(final UpdateEngineCallback callback) { return bind(callback, null); } @@ -183,7 +178,6 @@ public class UpdateEngine { * }; * </pre> */ - @SystemApi public void applyPayload(String url, long offset, long size, String[] headerKeyValuePairs) { try { mUpdateEngine.applyPayload(url, offset, size, headerKeyValuePairs); @@ -201,7 +195,6 @@ public class UpdateEngine { * <p>See {@link #suspend} for a way to temporarily stop an in-progress * update with the ability to resume it later. */ - @SystemApi public void cancel() { try { mUpdateEngine.cancel(); @@ -214,7 +207,6 @@ public class UpdateEngine { * Suspends an in-progress update. This can be undone by calling * {@link #resume}. */ - @SystemApi public void suspend() { try { mUpdateEngine.suspend(); @@ -226,7 +218,6 @@ public class UpdateEngine { /** * Resumes a suspended update. */ - @SystemApi public void resume() { try { mUpdateEngine.resume(); @@ -244,7 +235,6 @@ public class UpdateEngine { * {@code UPDATED_NEED_REBOOT}, so your callback can remove any outstanding * notification that rebooting into the new system is possible. */ - @SystemApi public void resetStatus() { try { mUpdateEngine.resetStatus(); @@ -256,7 +246,6 @@ public class UpdateEngine { /** * Unbinds the last bound callback function. */ - @SystemApi public boolean unbind() { synchronized (mUpdateEngineCallbackLock) { if (mUpdateEngineCallback == null) { @@ -281,7 +270,6 @@ public class UpdateEngine { * @param payloadMetadataFilename the location of the metadata without the * {@code file://} prefix. */ - @SystemApi public boolean verifyPayloadMetadata(String payloadMetadataFilename) { try { return mUpdateEngine.verifyPayloadApplicable(payloadMetadataFilename); diff --git a/core/java/android/os/UpdateEngineCallback.java b/core/java/android/os/UpdateEngineCallback.java index afff60abb22b..f07294e222e2 100644 --- a/core/java/android/os/UpdateEngineCallback.java +++ b/core/java/android/os/UpdateEngineCallback.java @@ -37,7 +37,6 @@ public abstract class UpdateEngineCallback { * be one of the values from {@link UpdateEngine.UpdateStatusConstants}, * and {@code percent} will be valid [TODO: in which cases?]. */ - @SystemApi public abstract void onStatusUpdate(int status, float percent); /** @@ -45,6 +44,5 @@ public abstract class UpdateEngineCallback { * unsuccessfully. The value of {@code errorCode} will be one of the * values from {@link UpdateEngine.ErrorCodeConstants}. */ - @SystemApi public abstract void onPayloadApplicationComplete(int errorCode); } diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index d072d02741ed..6b5927992677 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -52,6 +52,7 @@ import android.os.ServiceManager; import android.os.ServiceManager.ServiceNotFoundException; import android.os.SystemProperties; import android.provider.Settings; +import android.sysprop.VoldProperties; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; @@ -1465,7 +1466,7 @@ public class StorageManager { * framework, so no service needs to check for changes during their lifespan */ public static boolean isBlockEncrypting() { - final String state = SystemProperties.get("vold.encrypt_progress", ""); + final String state = VoldProperties.encrypt_progress().orElse(""); return !"".equalsIgnoreCase(state); } @@ -1481,7 +1482,7 @@ public class StorageManager { * framework, so no service needs to check for changes during their lifespan */ public static boolean inCryptKeeperBounce() { - final String status = SystemProperties.get("vold.decrypt"); + final String status = VoldProperties.decrypt().orElse(""); return "trigger_restart_min_framework".equals(status); } diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java index d16390976d1f..8ed2605e9e8c 100644 --- a/core/java/android/preference/PreferenceActivity.java +++ b/core/java/android/preference/PreferenceActivity.java @@ -80,7 +80,7 @@ import java.util.List; * <li>On a small screen it may display only the headers as a single list when first launched. * Selecting one of the header items will only show the PreferenceFragment of that header (on * Android N and lower a new Activity is launched). - * <li>On a large screen in may display both the headers and current PreferenceFragment together as + * <li>On a large screen it may display both the headers and current PreferenceFragment together as * panes. Selecting a header item switches to showing the correct PreferenceFragment for that item. * </ul> * diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 258c9a92fbfc..e6f8a56c17f0 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -10682,6 +10682,15 @@ public final class Settings { public static final String ACTIVITY_MANAGER_CONSTANTS = "activity_manager_constants"; /** + * Feature flag to enable or disable the activity starts logging feature. + * Type: int (0 for false, 1 for true) + * Default: 0 + * @hide + */ + public static final String ACTIVITY_STARTS_LOGGING_ENABLED + = "activity_starts_logging_enabled"; + + /** * App ops specific settings. * This is encoded as a key=value list, separated by commas. Ex: * diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java index 521176797657..f8408bedd7bc 100644 --- a/core/java/android/service/autofill/Dataset.java +++ b/core/java/android/service/autofill/Dataset.java @@ -33,8 +33,13 @@ import java.util.ArrayList; import java.util.regex.Pattern; /** - * A dataset object represents a group of fields (key / value pairs) used to autofill parts of a - * screen. + * <p>A <code>Dataset</code> object represents a group of fields (key / value pairs) used + * to autofill parts of a screen. + * + * <p>For more information about the role of datasets in the autofill workflow, read + * <a href="/guide/topics/text/autofill-services">Build autofill services</a> and the + * <code><a href="/reference/android/service/autofill/AutofillService">AutofillService</a></code> + * documentation. * * <a name="BasicUsage"></a> * <h3>Basic usage</h3> @@ -88,10 +93,6 @@ import java.util.regex.Pattern; * <li>All other datasets are hidden. * </ol> * - * <a name="MoreInfo"></a> - * <h3>More information</h3> - * <p>See {@link android.service.autofill.AutofillService} for more information and examples about - * the role of datasets in the autofill workflow. */ public final class Dataset implements Parcelable { diff --git a/core/java/android/service/autofill/FillCallback.java b/core/java/android/service/autofill/FillCallback.java index 0257891e5f38..1695c1306824 100644 --- a/core/java/android/service/autofill/FillCallback.java +++ b/core/java/android/service/autofill/FillCallback.java @@ -21,8 +21,11 @@ import android.app.Activity; import android.os.RemoteException; /** - * Handles autofill requests from the {@link AutofillService} into the {@link Activity} being - * autofilled. + * <p><code>FillCallback</code> handles autofill requests from the {@link AutofillService} into + * the {@link Activity} being autofilled. + * + * <p>To learn about using Autofill services in your app, read + * <a href="/guide/topics/text/autofill-services">Build autofill services</a>. */ public final class FillCallback { private final IFillCallback mCallback; diff --git a/core/java/android/service/carrier/CarrierIdentifier.java b/core/java/android/service/carrier/CarrierIdentifier.java index e930f401ecd5..568ca0f6b56e 100644 --- a/core/java/android/service/carrier/CarrierIdentifier.java +++ b/core/java/android/service/carrier/CarrierIdentifier.java @@ -71,10 +71,8 @@ public class CarrierIdentifier implements Parcelable { * @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 @@ public class CarrierIdentifier implements Parcelable { } /** - * 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/service/notification/Condition.java b/core/java/android/service/notification/Condition.java index b6c6bdc00bbe..af7e93e0ed74 100644 --- a/core/java/android/service/notification/Condition.java +++ b/core/java/android/service/notification/Condition.java @@ -17,7 +17,6 @@ package android.service.notification; import android.annotation.IntDef; -import android.annotation.SystemApi; import android.content.Context; import android.net.Uri; import android.os.Parcel; @@ -35,7 +34,6 @@ import java.util.Objects; */ public final class Condition implements Parcelable { - @SystemApi public static final String SCHEME = "condition"; /** @hide */ @@ -59,14 +57,10 @@ public final class Condition implements Parcelable { */ public static final int STATE_TRUE = 1; - @SystemApi public static final int STATE_UNKNOWN = 2; - @SystemApi public static final int STATE_ERROR = 3; - @SystemApi public static final int FLAG_RELEVANT_NOW = 1 << 0; - @SystemApi public static final int FLAG_RELEVANT_ALWAYS = 1 << 1; /** @@ -81,9 +75,7 @@ public final class Condition implements Parcelable { */ public final String summary; - @SystemApi public final String line1; - @SystemApi public final String line2; /** @@ -94,9 +86,7 @@ public final class Condition implements Parcelable { @State public final int state; - @SystemApi public final int flags; - @SystemApi public final int icon; /** @@ -108,7 +98,6 @@ public final class Condition implements Parcelable { this(id, summary, "", "", -1, state, FLAG_RELEVANT_ALWAYS); } - @SystemApi public Condition(Uri id, String summary, String line1, String line2, int icon, int state, int flags) { if (id == null) throw new IllegalArgumentException("id is required"); @@ -151,14 +140,14 @@ public final class Condition implements Parcelable { @Override public String toString() { return new StringBuilder(Condition.class.getSimpleName()).append('[') - .append("id=").append(id) - .append(",summary=").append(summary) - .append(",line1=").append(line1) - .append(",line2=").append(line2) - .append(",icon=").append(icon) - .append(",state=").append(stateToString(state)) - .append(",flags=").append(flags) - .append(']').toString(); + .append("state=").append(stateToString(state)) + .append(",id=").append(id) + .append(",summary=").append(summary) + .append(",line1=").append(line1) + .append(",line2=").append(line2) + .append(",icon=").append(icon) + .append(",flags=").append(flags) + .append(']').toString(); } /** @hide */ @@ -177,7 +166,6 @@ public final class Condition implements Parcelable { proto.end(token); } - @SystemApi public static String stateToString(int state) { if (state == STATE_FALSE) return "STATE_FALSE"; if (state == STATE_TRUE) return "STATE_TRUE"; @@ -186,7 +174,6 @@ public final class Condition implements Parcelable { throw new IllegalArgumentException("state is invalid: " + state); } - @SystemApi public static String relevanceToString(int flags) { final boolean now = (flags & FLAG_RELEVANT_NOW) != 0; final boolean always = (flags & FLAG_RELEVANT_ALWAYS) != 0; @@ -219,7 +206,6 @@ public final class Condition implements Parcelable { return 0; } - @SystemApi public Condition copy() { final Parcel parcel = Parcel.obtain(); try { @@ -231,14 +217,12 @@ public final class Condition implements Parcelable { } } - @SystemApi public static Uri.Builder newId(Context context) { return new Uri.Builder() .scheme(Condition.SCHEME) .authority(context.getPackageName()); } - @SystemApi public static boolean isValidId(Uri id, String pkg) { return id != null && SCHEME.equals(id.getScheme()) && pkg.equals(id.getAuthority()); } diff --git a/core/java/android/service/notification/ConditionProviderService.java b/core/java/android/service/notification/ConditionProviderService.java index 6fc689ab07cf..5203c8f4bb27 100644 --- a/core/java/android/service/notification/ConditionProviderService.java +++ b/core/java/android/service/notification/ConditionProviderService.java @@ -17,7 +17,6 @@ package android.service.notification; import android.annotation.SdkConstant; -import android.annotation.SystemApi; import android.annotation.TestApi; import android.app.ActivityManager; import android.app.INotificationManager; @@ -107,7 +106,6 @@ public abstract class ConditionProviderService extends Service { */ abstract public void onConnected(); - @SystemApi public void onRequestConditions(int relevance) {} /** diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java index f6749ee66bb4..1af2e73c95ce 100644 --- a/core/java/android/service/notification/ZenModeConfig.java +++ b/core/java/android/service/notification/ZenModeConfig.java @@ -244,11 +244,29 @@ public class ZenModeConfig implements Parcelable { .append(",allowMessagesFrom=").append(sourceToString(allowMessagesFrom)) .append(",suppressedVisualEffects=").append(suppressedVisualEffects) .append(",areChannelsBypassingDnd=").append(areChannelsBypassingDnd) - .append(",automaticRules=").append(automaticRules) - .append(",manualRule=").append(manualRule) + .append(",\nautomaticRules=").append(rulesToString()) + .append(",\nmanualRule=").append(manualRule) .append(']').toString(); } + private String rulesToString() { + if (automaticRules.isEmpty()) { + return "{}"; + } + + StringBuilder buffer = new StringBuilder(automaticRules.size() * 28); + buffer.append('{'); + for (int i = 0; i < automaticRules.size(); i++) { + if (i > 0) { + buffer.append(",\n"); + } + Object value = automaticRules.valueAt(i); + buffer.append(value); + } + buffer.append('}'); + return buffer.toString(); + } + private Diff diff(ZenModeConfig to) { final Diff d = new Diff(); if (to == null) { @@ -1014,10 +1032,10 @@ public class ZenModeConfig implements Parcelable { @UnsupportedAppUsage public static ScheduleInfo tryParseScheduleConditionId(Uri conditionId) { final boolean isSchedule = conditionId != null - && conditionId.getScheme().equals(Condition.SCHEME) - && conditionId.getAuthority().equals(ZenModeConfig.SYSTEM_AUTHORITY) + && Condition.SCHEME.equals(conditionId.getScheme()) + && ZenModeConfig.SYSTEM_AUTHORITY.equals(conditionId.getAuthority()) && conditionId.getPathSegments().size() == 1 - && conditionId.getPathSegments().get(0).equals(ZenModeConfig.SCHEDULE_PATH); + && ZenModeConfig.SCHEDULE_PATH.equals(conditionId.getPathSegments().get(0)); if (!isSchedule) return null; final int[] start = tryParseHourAndMinute(conditionId.getQueryParameter("start")); final int[] end = tryParseHourAndMinute(conditionId.getQueryParameter("end")); @@ -1120,10 +1138,10 @@ public class ZenModeConfig implements Parcelable { public static EventInfo tryParseEventConditionId(Uri conditionId) { final boolean isEvent = conditionId != null - && conditionId.getScheme().equals(Condition.SCHEME) - && conditionId.getAuthority().equals(ZenModeConfig.SYSTEM_AUTHORITY) + && Condition.SCHEME.equals(conditionId.getScheme()) + && ZenModeConfig.SYSTEM_AUTHORITY.equals(conditionId.getAuthority()) && conditionId.getPathSegments().size() == 1 - && conditionId.getPathSegments().get(0).equals(EVENT_PATH); + && EVENT_PATH.equals(conditionId.getPathSegments().get(0)); if (!isEvent) return null; final EventInfo rt = new EventInfo(); rt.userId = tryParseInt(conditionId.getQueryParameter("userId"), UserHandle.USER_NULL); @@ -1338,14 +1356,14 @@ public class ZenModeConfig implements Parcelable { @Override public String toString() { return new StringBuilder(ZenRule.class.getSimpleName()).append('[') - .append("enabled=").append(enabled) + .append("id=").append(id) + .append(",enabled=").append(String.valueOf(enabled).toUpperCase()) .append(",snoozing=").append(snoozing) .append(",name=").append(name) .append(",zenMode=").append(Global.zenModeToString(zenMode)) .append(",conditionId=").append(conditionId) .append(",condition=").append(condition) .append(",component=").append(component) - .append(",id=").append(id) .append(",creationTime=").append(creationTime) .append(",enabler=").append(enabler) .append(']').toString(); @@ -1477,7 +1495,7 @@ public class ZenModeConfig implements Parcelable { final int N = lines.size(); for (int i = 0; i < N; i++) { if (i > 0) { - sb.append(','); + sb.append(",\n"); } sb.append(lines.get(i)); } diff --git a/core/java/android/service/textclassifier/TextClassifierService.java b/core/java/android/service/textclassifier/TextClassifierService.java index b461c0daaca5..2417e591cb2b 100644 --- a/core/java/android/service/textclassifier/TextClassifierService.java +++ b/core/java/android/service/textclassifier/TextClassifierService.java @@ -80,7 +80,6 @@ public abstract class TextClassifierService extends Service { * {@link android.Manifest.permission#BIND_TEXTCLASSIFIER_SERVICE} permission so * that other applications can not abuse it. */ - @SystemApi public static final String SERVICE_INTERFACE = "android.service.textclassifier.TextClassifierService"; @@ -371,9 +370,7 @@ public abstract class TextClassifierService extends Service { * Callbacks for TextClassifierService results. * * @param <T> the type of the result - * @hide */ - @SystemApi public interface Callback<T> { /** * Returns the result. diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java index dc07494b15db..aa5ca3530621 100644 --- a/core/java/android/util/SparseArray.java +++ b/core/java/android/util/SparseArray.java @@ -23,32 +23,34 @@ import android.annotation.UnsupportedAppUsage; import libcore.util.EmptyArray; /** - * SparseArrays map integers to Objects. Unlike a normal array of Objects, - * there can be gaps in the indices. It is intended to be more memory efficient - * than using a HashMap to map Integers to Objects, both because it avoids + * <code>SparseArray</code> maps integers to Objects and, unlike a normal array of Objects, + * its indices can contain gaps. <code>SparseArray</code> is intended to be more memory-efficient + * than a + * <a href="/reference/java/util/HashMap"><code>HashMap</code></a>, because it avoids * auto-boxing keys and its data structure doesn't rely on an extra entry object * for each mapping. * * <p>Note that this container keeps its mappings in an array data structure, - * using a binary search to find keys. The implementation is not intended to be appropriate for + * using a binary search to find keys. The implementation is not intended to be appropriate for * data structures - * that may contain large numbers of items. It is generally slower than a traditional - * HashMap, since lookups require a binary search and adds and removes require inserting - * and deleting entries in the array. For containers holding up to hundreds of items, - * the performance difference is not significant, less than 50%.</p> + * that may contain large numbers of items. It is generally slower than a + * <code>HashMap</code> because lookups require a binary search, + * and adds and removes require inserting + * and deleting entries in the array. For containers holding up to hundreds of items, + * the performance difference is less than 50%. * * <p>To help with performance, the container includes an optimization when removing * keys: instead of compacting its array immediately, it leaves the removed entry marked - * as deleted. The entry can then be re-used for the same key, or compacted later in - * a single garbage collection step of all removed entries. This garbage collection will - * need to be performed at any time the array needs to be grown or the the map size or - * entry values are retrieved.</p> + * as deleted. The entry can then be re-used for the same key or compacted later in + * a single garbage collection of all removed entries. This garbage collection + * must be performed whenever the array needs to be grown, or when the map size or + * entry values are retrieved. * * <p>It is possible to iterate over the items in this container using * {@link #keyAt(int)} and {@link #valueAt(int)}. Iterating over the keys using - * <code>keyAt(int)</code> with ascending values of the index will return the - * keys in ascending order, or the values corresponding to the keys in ascending - * order in the case of <code>valueAt(int)</code>.</p> + * <code>keyAt(int)</code> with ascending values of the index returns the + * keys in ascending order. In the case of <code>valueAt(int)</code>, the + * values corresponding to the keys are returned in ascending order. */ public class SparseArray<E> implements Cloneable { private static final Object DELETED = new Object(); @@ -337,7 +339,7 @@ public class SparseArray<E> implements Cloneable { /** * Returns an index for which {@link #valueAt} would return the - * specified key, or a negative number if no keys map to the + * specified value, or a negative number if no keys map to the * specified value. * <p>Beware that this is a linear search, unlike lookups by key, * and that multiple keys can map to the same value and this will @@ -361,7 +363,7 @@ public class SparseArray<E> implements Cloneable { /** * Returns an index for which {@link #valueAt} would return the - * specified key, or a negative number if no keys map to the + * specified value, or a negative number if no keys map to the * specified value. * <p>Beware that this is a linear search, unlike lookups by key, * and that multiple keys can map to the same value and this will diff --git a/core/java/android/view/DisplayCutout.java b/core/java/android/view/DisplayCutout.java index 496bc9ff5383..5f80d31651a8 100644 --- a/core/java/android/view/DisplayCutout.java +++ b/core/java/android/view/DisplayCutout.java @@ -325,6 +325,7 @@ public final class DisplayCutout { * * @hide */ + @VisibleForTesting public static DisplayCutout fromBoundingRect(int left, int top, int right, int bottom) { Region r = Region.obtain(); r.set(left, top, right, bottom); @@ -422,8 +423,11 @@ public final class DisplayCutout { m.postTranslate(offsetX, 0); p.transform(m); - addToRegion(p, r); + final Rect tmpRect = new Rect(); + toRectAndAddToRegion(p, r, tmpRect); + final int topInset = tmpRect.bottom; + final int bottomInset; if (bottomSpec != null) { final Path bottomPath; try { @@ -436,10 +440,17 @@ public final class DisplayCutout { m.postTranslate(0, displayHeight); bottomPath.transform(m); p.addPath(bottomPath); - addToRegion(bottomPath, r); + toRectAndAddToRegion(bottomPath, r, tmpRect); + bottomInset = displayHeight - tmpRect.top; + } else { + bottomInset = 0; } - final Pair<Path, DisplayCutout> result = new Pair<>(p, fromBounds(r)); + // Reuse tmpRect as the inset rect we store into the DisplayCutout instance. + tmpRect.set(0, topInset, 0, bottomInset); + final DisplayCutout cutout = new DisplayCutout(tmpRect, r, false /* copyArguments */); + + final Pair<Path, DisplayCutout> result = new Pair<>(p, cutout); synchronized (CACHE_LOCK) { sCachedSpec = spec; sCachedDisplayWidth = displayWidth; @@ -450,12 +461,11 @@ public final class DisplayCutout { return result; } - private static void addToRegion(Path p, Region r) { + private static void toRectAndAddToRegion(Path p, Region inoutRegion, Rect inoutRect) { final RectF rectF = new RectF(); - final Rect rect = new Rect(); p.computeBounds(rectF, false /* unused */); - rectF.round(rect); - r.op(rect, Op.UNION); + rectF.round(inoutRect); + inoutRegion.op(inoutRect, Op.UNION); } private static Region boundingRectsToRegion(List<Rect> rects) { diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 2e98d033fa7f..1dbe166899dc 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -268,6 +268,13 @@ public class SurfaceControl implements Parcelable { 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 class SurfaceControl implements Parcelable { */ public Builder setColorLayer(boolean isColorLayer) { if (isColorLayer) { - mFlags |= FX_SURFACE_DIM; + setFlags(FX_SURFACE_DIM, FX_SURFACE_MASK); + } else { + 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 { - mFlags &= ~FX_SURFACE_DIM; + 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 @@ public class SurfaceControl implements Parcelable { mFlags = flags; return this; } + + private Builder setFlags(int flags, int mask) { + mFlags = (mFlags & ~mask) | flags; + return this; + } } /** diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java index 3f7ab2aed4af..38dcdd30d843 100644 --- a/core/java/android/view/ViewStructure.java +++ b/core/java/android/view/ViewStructure.java @@ -33,9 +33,14 @@ import com.android.internal.util.Preconditions; import java.util.List; /** - * Container for storing additional per-view data generated by {@link View#onProvideStructure + * <p><code>ViewStructure</code> is a container for storing additional + * per-view data generated by {@link View#onProvideStructure * View.onProvideStructure} and {@link View#onProvideAutofillStructure * View.onProvideAutofillStructure}. + * + * <p>To learn more about using Autofill in your app, read the + * <a href="/guide/topics/text/autofill">Autofill Framework</a> guides. + * */ public abstract class ViewStructure { diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 8b9b85651e7e..84a460119726 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -1699,6 +1699,15 @@ public interface WindowManager extends ViewManager { public static final int PRIVATE_FLAG_IS_SCREEN_DECOR = 0x00400000; /** + * Flag to indicate that the status bar window is now in an explicit expanded state, meaning + * that status bar will not be hidden by any window with flag {@link #FLAG_FULLSCREEN} or + * {@link View#SYSTEM_UI_FLAG_FULLSCREEN} set. + * This can only be set by {@link LayoutParams#TYPE_STATUS_BAR}. + * @hide + */ + public static final int PRIVATE_FLAG_STATUS_BAR_EXPANDED = 0x00800000; + + /** * Control flags that are private to the platform. * @hide */ @@ -1786,7 +1795,11 @@ public interface WindowManager extends ViewManager { @ViewDebug.FlagToString( mask = PRIVATE_FLAG_IS_SCREEN_DECOR, equals = PRIVATE_FLAG_IS_SCREEN_DECOR, - name = "IS_SCREEN_DECOR") + name = "IS_SCREEN_DECOR"), + @ViewDebug.FlagToString( + mask = PRIVATE_FLAG_STATUS_BAR_EXPANDED, + equals = PRIVATE_FLAG_STATUS_BAR_EXPANDED, + name = "STATUS_BAR_EXPANDED") }) @TestApi public int privateFlags; diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java index 769ea3e1d2c4..b382a1863af3 100644 --- a/core/java/android/view/accessibility/AccessibilityRecord.java +++ b/core/java/android/view/accessibility/AccessibilityRecord.java @@ -628,7 +628,7 @@ public class AccessibilityRecord { } /** - * Sets the text before a change. + * Gets the text before a change. * * @return The text before the change. */ diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java index 7555ffff3e38..d21cb3e64b8c 100644 --- a/core/java/android/view/autofill/AutofillManager.java +++ b/core/java/android/view/autofill/AutofillManager.java @@ -77,11 +77,16 @@ import java.util.Objects; import sun.misc.Cleaner; /** - * The {@link AutofillManager} provides ways for apps and custom views to integrate with the - * Autofill Framework lifecycle. + * <p>The {@link AutofillManager} class provides ways for apps and custom views to + * integrate with the Autofill Framework lifecycle. + * + * <p>To learn about using Autofill in your app, read + * the <a href="/guide/topics/text/autofill">Autofill Framework</a> guides. + * + * <h3 id="autofill-lifecycle">Autofill lifecycle</h3> * * <p>The autofill lifecycle starts with the creation of an autofill context associated with an - * activity context; the autofill context is created when one of the following methods is called for + * activity context. The autofill context is created when one of the following methods is called for * the first time in an activity context, and the current user has an enabled autofill service: * * <ul> @@ -90,7 +95,7 @@ import sun.misc.Cleaner; * <li>{@link #requestAutofill(View)} * </ul> * - * <p>Tipically, the context is automatically created when the first view of the activity is + * <p>Typically, the context is automatically created when the first view of the activity is * focused because {@code View.onFocusChanged()} indirectly calls * {@link #notifyViewEntered(View)}. App developers can call {@link #requestAutofill(View)} to * explicitly create it (for example, a custom view developer could offer a contextual menu action @@ -134,7 +139,9 @@ import sun.misc.Cleaner; * shows an autofill save UI if the value of savable views have changed. If the user selects the * option to Save, the current value of the views is then sent to the autofill service. * - * <p>It is safe to call into its methods from any thread. + * <h3 id="additional-notes">Additional notes</h3> + * + * <p>It is safe to call <code>AutofillManager</code> methods from any thread. */ @SystemService(Context.AUTOFILL_MANAGER_SERVICE) @RequiresFeature(PackageManager.FEATURE_AUTOFILL) @@ -2138,7 +2145,11 @@ public final class AutofillManager { pw.print(pfx); pw.print("sessionId: "); pw.println(mSessionId); pw.print(pfx); pw.print("state: "); pw.println(getStateAsStringLocked()); pw.print(pfx); pw.print("context: "); pw.println(mContext); - pw.print(pfx); pw.print("client: "); pw.println(getClient()); + final AutofillClient client = getClient(); + if (client != null) { + pw.print(pfx); pw.print("client: "); pw.print(client); + pw.print(" ("); pw.print(client.autofillClientGetActivityToken()); pw.println(')'); + } pw.print(pfx); pw.print("enabled: "); pw.println(mEnabled); pw.print(pfx); pw.print("hasService: "); pw.println(mService != null); pw.print(pfx); pw.print("hasCallback: "); pw.println(mCallback != null); @@ -2157,8 +2168,24 @@ public final class AutofillManager { pw.print(pfx); pw.print("entered ids: "); pw.println(mEnteredIds); pw.print(pfx); pw.print("save trigger id: "); pw.println(mSaveTriggerId); pw.print(pfx); pw.print("save on finish(): "); pw.println(mSaveOnFinish); - pw.print(pfx); pw.print("compat mode enabled: "); pw.println( - isCompatibilityModeEnabledLocked()); + pw.print(pfx); pw.print("compat mode enabled: "); + synchronized (mLock) { + if (mCompatibilityBridge != null) { + final String pfx2 = pfx + " "; + pw.println("true"); + pw.print(pfx2); pw.print("windowId: "); + pw.println(mCompatibilityBridge.mFocusedWindowId); + pw.print(pfx2); pw.print("nodeId: "); + pw.println(mCompatibilityBridge.mFocusedNodeId); + pw.print(pfx2); pw.print("virtualId: "); + pw.println(AccessibilityNodeInfo + .getVirtualDescendantId(mCompatibilityBridge.mFocusedNodeId)); + pw.print(pfx2); pw.print("focusedBounds: "); + pw.println(mCompatibilityBridge.mFocusedBounds); + } else { + pw.println("false"); + } + } pw.print(pfx); pw.print("debug: "); pw.print(sDebug); pw.print(" verbose: "); pw.println(sVerbose); } @@ -2292,7 +2319,15 @@ public final class AutofillManager { @Override public AccessibilityEvent onAccessibilityEvent(AccessibilityEvent event, boolean accessibilityEnabled, int relevantEventTypes) { - switch (event.getEventType()) { + final int type = event.getEventType(); + if (sVerbose) { + // NOTE: this is waaay spammy, but that's life. + Log.v(TAG, "onAccessibilityEvent(" + AccessibilityEvent.eventTypeToString(type) + + "): virtualId=" + + AccessibilityNodeInfo.getVirtualDescendantId(event.getSourceNodeId()) + + ", client=" + getClient()); + } + switch (type) { case AccessibilityEvent.TYPE_VIEW_FOCUSED: { synchronized (mLock) { if (mFocusedWindowId == event.getWindowId() diff --git a/core/java/android/webkit/WebBackForwardList.java b/core/java/android/webkit/WebBackForwardList.java index 0c34e3c16ac6..4d3bbe475920 100644 --- a/core/java/android/webkit/WebBackForwardList.java +++ b/core/java/android/webkit/WebBackForwardList.java @@ -57,7 +57,8 @@ public abstract class WebBackForwardList implements Cloneable, Serializable { /** * Clone the entire object to be used in the UI thread by clients of * WebView. This creates a copy that should never be modified by any of the - * webkit package classes. + * webkit package classes. On Android 4.4 and later there is no need to use + * this, as the object is already a read-only copy of the internal state. */ protected abstract WebBackForwardList clone(); } diff --git a/core/java/android/webkit/WebHistoryItem.java b/core/java/android/webkit/WebHistoryItem.java index 74db039e015d..b9e704285f84 100644 --- a/core/java/android/webkit/WebHistoryItem.java +++ b/core/java/android/webkit/WebHistoryItem.java @@ -23,7 +23,7 @@ import android.graphics.Bitmap; /** * A convenience class for accessing fields in an entry in the back/forward list * of a WebView. Each WebHistoryItem is a snapshot of the requested history - * item. Each history item may be updated during the load of a page. + * item. * @see WebBackForwardList */ public abstract class WebHistoryItem implements Cloneable { @@ -44,8 +44,6 @@ public abstract class WebHistoryItem implements Cloneable { * history item. See getTargetUrl() for the url that is the actual target of * this history item. * @return The base url of this history item. - * Note: The VM ensures 32-bit atomic read/write operations so we don't have - * to synchronize this method. */ public abstract String getUrl(); @@ -60,22 +58,20 @@ public abstract class WebHistoryItem implements Cloneable { /** * Return the document title of this history item. * @return The document title of this history item. - * Note: The VM ensures 32-bit atomic read/write operations so we don't have - * to synchronize this method. */ public abstract String getTitle(); /** * Return the favicon of this history item or {@code null} if no favicon was found. * @return A Bitmap containing the favicon for this history item or {@code null}. - * Note: The VM ensures 32-bit atomic read/write operations so we don't have - * to synchronize this method. */ @Nullable public abstract Bitmap getFavicon(); /** - * Clone the history item for use by clients of WebView. + * Clone the history item for use by clients of WebView. On Android 4.4 and later + * there is no need to use this, as the object is already a read-only copy of the + * internal state. */ protected abstract WebHistoryItem clone(); } diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java index 66e079e26f1f..c30edd30361f 100644 --- a/core/java/android/webkit/WebSettings.java +++ b/core/java/android/webkit/WebSettings.java @@ -991,7 +991,9 @@ public abstract class WebSettings { * {@link PluginState#OFF}. * * @param state a PluginState value - * @deprecated Plugins will not be supported in future, and should not be used. + * @deprecated Plugins are not supported in API level + * {@link android.os.Build.VERSION_CODES#KITKAT} or later; + * enabling plugins is a no-op. */ @Deprecated public abstract void setPluginState(PluginState state); @@ -1187,7 +1189,9 @@ public abstract class WebSettings { * * @return the plugin state as a {@link PluginState} value * @see #setPluginState - * @deprecated Plugins will not be supported in future, and should not be used. + * @deprecated Plugins are not supported in API level + * {@link android.os.Build.VERSION_CODES#KITKAT} or later; + * enabling plugins is a no-op. */ @Deprecated public abstract PluginState getPluginState(); diff --git a/core/java/android/webkit/WebSyncManager.java b/core/java/android/webkit/WebSyncManager.java index 3fa1b01cf701..e44d6ebf37d1 100644 --- a/core/java/android/webkit/WebSyncManager.java +++ b/core/java/android/webkit/WebSyncManager.java @@ -26,6 +26,7 @@ import android.content.Context; 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/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 5c5e9de77916..8f03b693e587 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -42,7 +42,6 @@ import android.os.Message; import android.os.RemoteException; import android.os.StrictMode; import android.print.PrintDocumentAdapter; -import android.security.KeyChain; import android.util.AttributeSet; import android.util.Log; import android.util.SparseArray; @@ -1432,9 +1431,8 @@ public class WebView extends AbsoluteLayout /** * Clears the client certificate preferences stored in response * to proceeding/cancelling client cert requests. Note that WebView - * automatically clears these preferences when it receives a - * {@link KeyChain#ACTION_STORAGE_CHANGED} intent. The preferences are - * shared by all the WebViews that are created by the embedder application. + * automatically clears these preferences when the system keychain is updated. + * The preferences are shared by all the WebViews that are created by the embedder application. * * @param onCleared A runnable to be invoked when client certs are cleared. * The runnable will be called in UI thread. diff --git a/core/java/android/webkit/WebViewClient.java b/core/java/android/webkit/WebViewClient.java index f686b6645655..bdd7a0900213 100644 --- a/core/java/android/webkit/WebViewClient.java +++ b/core/java/android/webkit/WebViewClient.java @@ -31,18 +31,25 @@ import java.lang.annotation.RetentionPolicy; public class WebViewClient { /** - * Give the host application a chance to take over the control when a new - * url is about to be loaded in the current WebView. If WebViewClient is not - * provided, by default WebView will ask Activity Manager to choose the - * proper handler for the url. If WebViewClient is provided, return {@code true} - * means the host application handles the url, while return {@code false} means the - * current WebView handles the url. - * This method is not called for requests using the POST "method". + * Give the host application a chance to take control when a URL is about to be loaded in the + * current WebView. If a WebViewClient is not provided, by default WebView will ask Activity + * Manager to choose the proper handler for the URL. If a WebViewClient is provided, returning + * {@code true} causes the current WebView to abort loading the URL, while returning + * {@code false} causes the WebView to continue loading the URL as usual. + * + * <p class="note"><b>Note:</b> Do not call {@link WebView#loadUrl(String)} with the same + * URL and then return {@code true}. This unnecessarily cancels the current load and starts a + * new load with the same URL. The correct way to continue loading a given URL is to simply + * return {@code false}, without calling {@link WebView#loadUrl(String)}. + * + * <p class="note"><b>Note:</b> This method is not called for POST requests. + * + * <p class="note"><b>Note:</b> This method may be called for subframes and with non-HTTP(S) + * schemes; calling {@link WebView#loadUrl(String)} with such a URL will fail. * * @param view The WebView that is initiating the callback. - * @param url The url to be loaded. - * @return {@code true} if the host application wants to leave the current WebView - * and handle the url itself, otherwise return {@code false}. + * @param url The URL to be loaded. + * @return {@code true} to cancel the current load, otherwise return {@code false}. * @deprecated Use {@link #shouldOverrideUrlLoading(WebView, WebResourceRequest) * shouldOverrideUrlLoading(WebView, WebResourceRequest)} instead. */ @@ -52,26 +59,25 @@ public class WebViewClient { } /** - * Give the host application a chance to take over the control when a new - * url is about to be loaded in the current WebView. If WebViewClient is not - * provided, by default WebView will ask Activity Manager to choose the - * proper handler for the url. If WebViewClient is provided, return {@code true} - * means the host application handles the url, while return {@code false} means the - * current WebView handles the url. - * - * <p>Notes: - * <ul> - * <li>This method is not called for requests using the POST "method".</li> - * <li>This method is also called for subframes with non-http schemes, thus it is - * strongly disadvised to unconditionally call {@link WebView#loadUrl(String)} - * with the request's url from inside the method and then return {@code true}, - * as this will make WebView to attempt loading a non-http url, and thus fail.</li> - * </ul> + * Give the host application a chance to take control when a URL is about to be loaded in the + * current WebView. If a WebViewClient is not provided, by default WebView will ask Activity + * Manager to choose the proper handler for the URL. If a WebViewClient is provided, returning + * {@code true} causes the current WebView to abort loading the URL, while returning + * {@code false} causes the WebView to continue loading the URL as usual. + * + * <p class="note"><b>Note:</b> Do not call {@link WebView#loadUrl(String)} with the request's + * URL and then return {@code true}. This unnecessarily cancels the current load and starts a + * new load with the same URL. The correct way to continue loading a given URL is to simply + * return {@code false}, without calling {@link WebView#loadUrl(String)}. + * + * <p class="note"><b>Note:</b> This method is not called for POST requests. + * + * <p class="note"><b>Note:</b> This method may be called for subframes and with non-HTTP(S) + * schemes; calling {@link WebView#loadUrl(String)} with such a URL will fail. * * @param view The WebView that is initiating the callback. * @param request Object containing the details of the request. - * @return {@code true} if the host application wants to leave the current WebView - * and handle the url itself, otherwise return {@code false}. + * @return {@code true} to cancel the current load, otherwise return {@code false}. */ public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { return shouldOverrideUrlLoading(view, request.getUrl().toString()); diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 3956215b6f83..66ce0eeafc96 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -812,7 +812,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te * @param firstVisibleItem the index of the first visible cell (ignore if * visibleItemCount == 0) * @param visibleItemCount the number of visible cells - * @param totalItemCount the number of items in the list adaptor + * @param totalItemCount the number of items in the list adapter */ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount); diff --git a/core/java/com/android/internal/app/AssistUtils.java b/core/java/com/android/internal/app/AssistUtils.java index 9171959537c8..fed0a89a4d75 100644 --- a/core/java/com/android/internal/app/AssistUtils.java +++ b/core/java/com/android/internal/app/AssistUtils.java @@ -32,6 +32,8 @@ import android.os.ServiceManager; import android.provider.Settings; import android.util.Log; +import com.android.internal.R; + /** * Utility method for dealing with the assistant aspects of * {@link com.android.internal.app.IVoiceInteractionManagerService IVoiceInteractionManagerService}. @@ -40,6 +42,14 @@ public class AssistUtils { private static final String TAG = "AssistUtils"; + /** + * Sentinel value for "no default assistant specified." + * + * Empty string is already used to represent an explicit setting of No Assistant. null cannot + * be used because we can't represent a null value in XML. + */ + private static final String UNSET = "#+UNSET"; + private final Context mContext; private final IVoiceInteractionManagerService mVoiceInteractionManagerService; @@ -152,10 +162,21 @@ public class AssistUtils { return ComponentName.unflattenFromString(setting); } + final String defaultSetting = mContext.getResources().getString( + R.string.config_defaultAssistantComponentName); + if (defaultSetting != null && !defaultSetting.equals(UNSET)) { + return ComponentName.unflattenFromString(defaultSetting); + } + // Fallback to keep backward compatible behavior when there is no user setting. if (activeServiceSupportsAssistGesture()) { return getActiveServiceComponentName(); } + + if (UNSET.equals(defaultSetting)) { + return null; + } + final SearchManager searchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE); if (searchManager == null) { diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java index 398d08791b5c..4728124c17c5 100644 --- a/core/java/com/android/internal/app/IntentForwarderActivity.java +++ b/core/java/com/android/internal/app/IntentForwarderActivity.java @@ -16,14 +16,21 @@ package com.android.internal.app; +import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY; + +import android.annotation.Nullable; +import android.annotation.StringRes; import android.app.Activity; import android.app.ActivityManager; import android.app.ActivityThread; import android.app.AppGlobals; import android.app.admin.DevicePolicyManager; import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; import android.os.Bundle; import android.os.RemoteException; @@ -31,12 +38,11 @@ import android.os.UserHandle; import android.os.UserManager; import android.util.Slog; import android.widget.Toast; - import com.android.internal.annotations.VisibleForTesting; - +import java.util.Arrays; +import java.util.HashSet; import java.util.List; - -import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY; +import java.util.Set; /** * This is used in conjunction with @@ -44,7 +50,6 @@ import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY; * be passed in and out of a managed profile. */ public class IntentForwarderActivity extends Activity { - public static String TAG = "IntentForwarderActivity"; public static String FORWARD_INTENT_TO_PARENT @@ -53,6 +58,9 @@ public class IntentForwarderActivity extends Activity { public static String FORWARD_INTENT_TO_MANAGED_PROFILE = "com.android.internal.app.ForwardIntentToManagedProfile"; + private static final Set<String> ALLOWED_TEXT_MESSAGE_SCHEME + = new HashSet<>(Arrays.asList("sms", "smsto", "mms", "mmsto")); + private Injector mInjector; @Override @@ -93,19 +101,8 @@ public class IntentForwarderActivity extends Activity { newIntent.prepareToLeaveUser(callingUserId); } - final android.content.pm.ResolveInfo ri = - mInjector.getPackageManager().resolveActivityAsUser( - newIntent, - MATCH_DEFAULT_ONLY, - targetUserId); - - // Don't show the disclosure if next activity is ResolverActivity or ChooserActivity - // as those will already have shown work / personal as neccesary etc. - final boolean shouldShowDisclosure = ri == null || ri.activityInfo == null || - !"android".equals(ri.activityInfo.packageName) || - !(ResolverActivity.class.getName().equals(ri.activityInfo.name) - || ChooserActivity.class.getName().equals(ri.activityInfo.name)); - + final ResolveInfo ri = mInjector.resolveActivityAsUser(newIntent, MATCH_DEFAULT_ONLY, + targetUserId); try { startActivityAsCaller(newIntent, null, false, targetUserId); } catch (RuntimeException e) { @@ -124,8 +121,8 @@ public class IntentForwarderActivity extends Activity { + ActivityThread.currentProcessName(), e); } - if (shouldShowDisclosure) { - Toast.makeText(this, getString(userMessageId), Toast.LENGTH_LONG).show(); + if (shouldShowDisclosure(ri, intentReceived)) { + mInjector.showToast(userMessageId, Toast.LENGTH_LONG); } } else { Slog.wtf(TAG, "the intent: " + intentReceived + " cannot be forwarded from user " @@ -134,6 +131,35 @@ public class IntentForwarderActivity extends Activity { finish(); } + private boolean shouldShowDisclosure(@Nullable ResolveInfo ri, Intent intent) { + if (ri == null || ri.activityInfo == null) { + return true; + } + if (ri.activityInfo.applicationInfo.isSystemApp() + && (isDialerIntent(intent) || isTextMessageIntent(intent))) { + return false; + } + return !isTargetResolverOrChooserActivity(ri.activityInfo); + } + + private boolean isTextMessageIntent(Intent intent) { + return Intent.ACTION_SENDTO.equals(intent.getAction()) && intent.getData() != null + && ALLOWED_TEXT_MESSAGE_SCHEME.contains(intent.getData().getScheme()); + } + + private boolean isDialerIntent(Intent intent) { + return Intent.ACTION_DIAL.equals(intent.getAction()) + || Intent.ACTION_CALL.equals(intent.getAction()); + } + + private boolean isTargetResolverOrChooserActivity(ActivityInfo activityInfo) { + if (!"android".equals(activityInfo.packageName)) { + return false; + } + return ResolverActivity.class.getName().equals(activityInfo.name) + || ChooserActivity.class.getName().equals(activityInfo.name); + } + /** * Check whether the intent can be forwarded to target user. Return the intent used for * forwarding if it can be forwarded, {@code null} otherwise. @@ -241,6 +267,16 @@ public class IntentForwarderActivity extends Activity { public PackageManager getPackageManager() { return IntentForwarderActivity.this.getPackageManager(); } + + @Override + public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) { + return getPackageManager().resolveActivityAsUser(intent, flags, userId); + } + + @Override + public void showToast(int messageId, int duration) { + Toast.makeText(IntentForwarderActivity.this, getString(messageId), duration).show(); + } } public interface Injector { @@ -249,5 +285,9 @@ public class IntentForwarderActivity extends Activity { UserManager getUserManager(); PackageManager getPackageManager(); + + ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId); + + void showToast(@StringRes int messageId, int duration); } } diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 486c836279ce..8b06c47c60d1 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -4031,7 +4031,9 @@ public class BatteryStatsImpl extends BatteryStats { try { IBatteryPropertiesRegistrar registrar = IBatteryPropertiesRegistrar.Stub.asInterface( ServiceManager.getService("batteryproperties")); - registrar.scheduleUpdate(); + if (registrar != null) { + registrar.scheduleUpdate(); + } } catch (RemoteException e) { // Ignore. } diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 8bdb000aad0e..c2c6ae6712ab 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -536,9 +536,11 @@ public class ZygoteInit { 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/MessagingLinearLayout.java b/core/java/com/android/internal/widget/MessagingLinearLayout.java index 64b1f241464b..0c8613b460f6 100644 --- a/core/java/com/android/internal/widget/MessagingLinearLayout.java +++ b/core/java/com/android/internal/widget/MessagingLinearLayout.java @@ -111,14 +111,16 @@ public class MessagingLinearLayout extends ViewGroup { final int childHeight = child.getMeasuredHeight(); int newHeight = Math.max(totalHeight, totalHeight + childHeight + lp.topMargin + lp.bottomMargin + spacing); - first = false; int measureType = MessagingChild.MEASURED_NORMAL; if (messagingChild != null) { measureType = messagingChild.getMeasuredType(); linesRemaining -= messagingChild.getConsumedLines(); } - boolean isShortened = measureType == MessagingChild.MEASURED_SHORTENED; - boolean isTooSmall = measureType == MessagingChild.MEASURED_TOO_SMALL; + + // We never measure the first item as too small, we want to at least show something. + boolean isTooSmall = measureType == MessagingChild.MEASURED_TOO_SMALL && !first; + boolean isShortened = measureType == MessagingChild.MEASURED_SHORTENED + || measureType == MessagingChild.MEASURED_TOO_SMALL && first; if (newHeight <= targetHeight && !isTooSmall) { totalHeight = newHeight; measuredWidth = Math.max(measuredWidth, @@ -131,6 +133,7 @@ public class MessagingLinearLayout extends ViewGroup { } else { break; } + first = false; } setMeasuredDimension( diff --git a/core/java/com/android/internal/widget/NumericTextView.java b/core/java/com/android/internal/widget/NumericTextView.java index 27c583457a41..d2156704a655 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 @@ public class NumericTextView extends TextView { private OnValueChangedListener mListener; + @UnsupportedAppUsage public NumericTextView(Context context, AttributeSet attrs) { super(context, attrs); diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java index 45069ca1d3e2..a07c96ceba2e 100644 --- a/core/java/com/android/server/SystemConfig.java +++ b/core/java/com/android/server/SystemConfig.java @@ -25,6 +25,7 @@ import android.content.pm.PackageManager; import android.os.Build; import android.os.Environment; import android.os.Process; +import android.os.SystemProperties; import android.os.storage.StorageManager; import android.text.TextUtils; import android.util.ArrayMap; @@ -67,6 +68,9 @@ public class SystemConfig { private static final int ALLOW_HIDDENAPI_WHITELISTING = 0x40; private static final int ALLOW_ALL = ~0; + // property for runtime configuration differentiation + private static final String SKU_PROPERTY = "ro.boot.product.hardware.sku"; + // Group-ids that are given to all packages as read from etc/permissions/*.xml. int[] mGlobalGids; @@ -312,6 +316,17 @@ public class SystemConfig { readPermissions(Environment.buildPath( Environment.getOdmDirectory(), "etc", "permissions"), odmPermissionFlag); + String skuProperty = SystemProperties.get(SKU_PROPERTY, ""); + if (!skuProperty.isEmpty()) { + String skuDir = "sku_" + skuProperty; + + readPermissions(Environment.buildPath( + Environment.getOdmDirectory(), "etc", "sysconfig", skuDir), odmPermissionFlag); + readPermissions(Environment.buildPath( + Environment.getOdmDirectory(), "etc", "permissions", skuDir), + odmPermissionFlag); + } + // Allow OEM to customize features and OEM permissions int oemPermissionFlag = ALLOW_FEATURES | ALLOW_OEM_PERMISSIONS; readPermissions(Environment.buildPath( @@ -342,6 +357,10 @@ public class SystemConfig { // Iterate over the files in the directory and scan .xml files File platformFile = null; for (File f : libraryDir.listFiles()) { + if (!f.isFile()) { + continue; + } + // We'll read platform.xml last if (f.getPath().endsWith("etc/permissions/platform.xml")) { platformFile = f; diff --git a/core/java/com/android/server/net/BaseNetdEventCallback.java b/core/java/com/android/server/net/BaseNetdEventCallback.java index 97247aada49d..a65214a1edca 100644 --- a/core/java/com/android/server/net/BaseNetdEventCallback.java +++ b/core/java/com/android/server/net/BaseNetdEventCallback.java @@ -32,6 +32,12 @@ public class BaseNetdEventCallback extends INetdEventCallback.Stub { } @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 ec24980a2e6e..c81a77d4c16e 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -41,6 +41,7 @@ cc_library_shared { "com_google_android_gles_jni_EGLImpl.cpp", "com_google_android_gles_jni_GLImpl.cpp", // TODO: .arm "android_app_Activity.cpp", + "android_app_ActivityThread.cpp", "android_app_NativeActivity.cpp", "android_app_admin_SecurityLog.cpp", "android_opengl_EGL14.cpp", @@ -263,7 +264,7 @@ cc_library_shared { "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 5a74a2473b32..b085bc93f5dd 100755 --- a/core/jni/android/graphics/Bitmap.cpp +++ b/core/jni/android/graphics/Bitmap.cpp @@ -48,7 +48,7 @@ namespace android { 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 9eaaa4964b66..30fdf2478887 100644 --- a/core/jni/android/graphics/FontUtils.h +++ b/core/jni/android/graphics/FontUtils.h @@ -27,7 +27,7 @@ class FontFamily; 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 dd99b377988f..f84a4bd09073 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_app_ActivityThread.cpp b/core/jni/android_app_ActivityThread.cpp new file mode 100644 index 000000000000..d56e4c51124d --- /dev/null +++ b/core/jni/android_app_ActivityThread.cpp @@ -0,0 +1,55 @@ +/* + * 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 "jni.h" +#include "GraphicsJNI.h" +#include <nativehelper/JNIHelp.h> + +#include <minikin/Layout.h> +#include <renderthread/RenderProxy.h> + +#include "core_jni_helpers.h" +#include <unistd.h> + +namespace android { + +static void android_app_ActivityThread_purgePendingResources(JNIEnv* env, jobject clazz) { + // Don't care about return values. + mallopt(M_PURGE, 0); +} + +static void +android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) { + int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor); + android::uirenderer::renderthread::RenderProxy::dumpGraphicsMemory(fd); + minikin::Layout::dumpMinikinStats(fd); +} + + +static JNINativeMethod gActivityThreadMethods[] = { + // ------------ Regular JNI ------------------ + { "nPurgePendingResources", "()V", + (void*) android_app_ActivityThread_purgePendingResources }, + { "nDumpGraphicsInfo", "(Ljava/io/FileDescriptor;)V", + (void*) android_app_ActivityThread_dumpGraphics } +}; + +int register_android_app_ActivityThread(JNIEnv* env) { + return RegisterMethodsOrDie(env, "android/app/ActivityThread", + gActivityThreadMethods, NELEM(gActivityThreadMethods)); +} + +}; diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp index 6c9f463e118d..9963a4536659 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 108fa00fe510..a1a035110caf 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 f6e5c7a48c4c..c33405def25e 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 @@ static void throwErrnoException(JNIEnv* env, const char* functionName, int error 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 @@ static jobject SharedMemory_create(JNIEnv* env, jobject, jstring jname, jint siz 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 @@ static jint SharedMemory_getSize(JNIEnv* env, jobject, jobject fileDescriptor) { 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 @@ static jint SharedMemory_setProt(JNIEnv* env, jobject, jobject fileDescriptor, j 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 4ab8db4395f6..182a621c6978 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 jobject newZipEntry(JNIEnv* env, const ZipEntry& entry, jstring entryName 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 @@ class IterationHandle { }; -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 @@ static jlong StrictJarFile_nativeStartIteration(JNIEnv* env, jobject, jlong nati 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 @@ static jobject StrictJarFile_nativeNextEntry(JNIEnv* env, jobject, jlong iterati 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 @@ static jobject StrictJarFile_nativeFindEntry(JNIEnv* env, jobject, jlong nativeH 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 @@ static JNINativeMethod gMethods[] = { NATIVE_METHOD(StrictJarFile, nativeClose, "(J)V"), }; -int register_android_util_jar_StrictJarFile(JNIEnv* env) { - jniRegisterNativeMethods(env, "android/util/jar/StrictJarFile", gMethods, NELEM(gMethods)); +} // namespace - 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>"); +namespace android { - return 0; +int register_android_util_jar_StrictJarFile(JNIEnv* env) { + 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/android_view_DisplayListCanvas.cpp b/core/jni/android_view_DisplayListCanvas.cpp index 7956bf4ee222..5197e7d481eb 100644 --- a/core/jni/android_view_DisplayListCanvas.cpp +++ b/core/jni/android_view_DisplayListCanvas.cpp @@ -88,17 +88,6 @@ private: sp<InvokeRunnableMessage> mMessage; }; - -// ---------------- Regular JNI ----------------------------- - -static void -android_app_ActivityThread_dumpGraphics(JNIEnv* env, jobject clazz, jobject javaFileDescriptor) { - int fd = jniGetFDFromFileDescriptor(env, javaFileDescriptor); - android::uirenderer::renderthread::RenderProxy::dumpGraphicsMemory(fd); - minikin::Layout::dumpMinikinStats(fd); -} - - // ---------------- @FastNative ----------------------------- static void android_view_DisplayListCanvas_callDrawGLFunction(JNIEnv* env, jobject clazz, @@ -215,12 +204,6 @@ static JNINativeMethod gMethods[] = { { "nDrawRoundRect", "(JJJJJJJJ)V",(void*) android_view_DisplayListCanvas_drawRoundRectProps }, }; -static JNINativeMethod gActivityThreadMethods[] = { - // ------------ Regular JNI ------------------ - { "nDumpGraphicsInfo", "(Ljava/io/FileDescriptor;)V", - (void*) android_app_ActivityThread_dumpGraphics } -}; - int register_android_view_DisplayListCanvas(JNIEnv* env) { jclass runnableClass = FindClassOrDie(env, "java/lang/Runnable"); gRunnableMethodId = GetMethodIDOrDie(env, runnableClass, "run", "()V"); @@ -228,9 +211,4 @@ int register_android_view_DisplayListCanvas(JNIEnv* env) { return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); } -int register_android_app_ActivityThread(JNIEnv* env) { - return RegisterMethodsOrDie(env, "android/app/ActivityThread", - gActivityThreadMethods, NELEM(gActivityThreadMethods)); -} - }; diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp index b708735616c4..24bafca9c386 100644 --- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp +++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp @@ -35,7 +35,6 @@ #include "bpf/BpfUtils.h" #include "netdbpf/BpfNetworkStats.h" -using android::bpf::hasBpfSupport; using android::bpf::parseBpfNetworkStatsDetail; using android::bpf::stats_line; diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp index 7a3f49a3efac..d4fe1edf0e7a 100644 --- a/core/jni/com_android_internal_os_Zygote.cpp +++ b/core/jni/com_android_internal_os_Zygote.cpp @@ -273,15 +273,17 @@ static void EnableDebugger() { } } - // We don't want core dumps, though, so set the soft limit on core dump size - // to 0 without changing the hard limit. - rlimit rl; - if (getrlimit(RLIMIT_CORE, &rl) == -1) { - ALOGE("getrlimit(RLIMIT_CORE) failed"); - } else { - rl.rlim_cur = 0; - if (setrlimit(RLIMIT_CORE, &rl) == -1) { - ALOGE("setrlimit(RLIMIT_CORE) failed"); + // Set the core dump size to zero unless wanted (see also coredump_setup in build/envsetup.sh). + if (!GetBoolProperty("persist.zygote.core_dump", false)) { + // Set the soft limit on core dump size to 0 without changing the hard limit. + rlimit rl; + if (getrlimit(RLIMIT_CORE, &rl) == -1) { + ALOGE("getrlimit(RLIMIT_CORE) failed"); + } else { + rl.rlim_cur = 0; + if (setrlimit(RLIMIT_CORE, &rl) == -1) { + ALOGE("setrlimit(RLIMIT_CORE) failed"); + } } } } @@ -412,7 +414,7 @@ static int UnmountTree(const char* path) { } 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)); } @@ -915,6 +917,13 @@ static jlong CalculateCapabilities(JNIEnv* env, jint uid, jint gid, jintArray gi 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 d457a1b48e38..d8d919df6c24 100644 --- a/core/jni/fd_utils.cpp +++ b/core/jni/fd_utils.cpp @@ -148,7 +148,7 @@ class FileDescriptorInfo { 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 @@ bool FileDescriptorInfo::ReopenOrDetach(std::string* error_msg) const { 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 a3570d7ed1fb..09022a2e2408 100644 --- a/core/jni/fd_utils.h +++ b/core/jni/fd_utils.h @@ -86,7 +86,7 @@ class FileDescriptorTable { 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 000000000000..dbd0e038c40c --- /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 9ce6044bcf3e..344b74c6e9ab 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1230,7 +1230,7 @@ <!-- ================================== --> <eat-comment /> - <!-- @SystemApi Allows an application (Phone) to send a request to other applications + <!-- Allows an application (Phone) to send a request to other applications to handle the respond-via-message action during incoming calls. <p>Not for use by third-party applications. --> <permission android:name="android.permission.SEND_RESPOND_VIA_MESSAGE" @@ -1314,7 +1314,7 @@ android:description="@string/permdesc_accessLocationExtraCommands" android:protectionLevel="normal" /> - <!-- @SystemApi Allows an application to install a location provider into the Location Manager. + <!-- Allows an application to install a location provider into the Location Manager. <p>Not for use by third-party applications. --> <permission android:name="android.permission.INSTALL_LOCATION_PROVIDER" android:protectionLevel="signature|privileged" /> @@ -1325,7 +1325,7 @@ <permission android:name="android.permission.HDMI_CEC" android:protectionLevel="signature|privileged" /> - <!-- @SystemApi Allows an application to use location features in hardware, + <!-- Allows an application to use location features in hardware, such as the geofencing api. <p>Not for use by third-party applications. --> <permission android:name="android.permission.LOCATION_HARDWARE" @@ -1512,7 +1512,7 @@ android:label="@string/permlab_bluetoothAdmin" android:protectionLevel="normal" /> - <!-- @SystemApi Allows applications to pair bluetooth devices without user interaction, and to + <!-- Allows applications to pair bluetooth devices without user interaction, and to allow or disallow phonebook access or message access. This is not available to third party applications. --> <permission android:name="android.permission.BLUETOOTH_PRIVILEGED" @@ -1602,7 +1602,7 @@ android:label="@string/permlab_getAccounts" /> <uses-permission android:name="android.permission.GET_ACCOUNTS"/> - <!-- @SystemApi Allows applications to call into AccountAuthenticators. + <!-- Allows applications to call into AccountAuthenticators. <p>Not for use by third-party applications. --> <permission android:name="android.permission.ACCOUNT_MANAGER" android:protectionLevel="signature" /> @@ -1775,7 +1775,7 @@ <!-- =========================================== --> <eat-comment /> - <!-- @SystemApi Allows modification of the telephony state - power on, mmi, etc. + <!-- Allows modification of the telephony state - power on, mmi, etc. Does not include placing calls. <p>Not for use by third-party applications. --> <permission android:name="android.permission.MODIFY_PHONE_STATE" @@ -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 @@ -2206,7 +2215,7 @@ <!-- ============================================ --> <eat-comment /> - <!-- @SystemApi Allows applications to set the system time. + <!-- Allows applications to set the system time. <p>Not for use by third-party applications. --> <permission android:name="android.permission.SET_TIME" android:protectionLevel="signature|privileged" /> @@ -2296,7 +2305,7 @@ <permission android:name="android.permission.SET_SCREEN_COMPATIBILITY" android:protectionLevel="signature" /> - <!-- @SystemApi Allows an application to modify the current configuration, such + <!-- Allows an application to modify the current configuration, such as locale. --> <permission android:name="android.permission.CHANGE_CONFIGURATION" android:protectionLevel="signature|privileged|development" /> @@ -2318,7 +2327,7 @@ android:description="@string/permdesc_writeSettings" android:protectionLevel="signature|preinstalled|appop|pre23" /> - <!-- @SystemApi Allows an application to modify the Google service map. + <!-- Allows an application to modify the Google service map. <p>Not for use by third-party applications. --> <permission android:name="android.permission.WRITE_GSERVICES" android:protectionLevel="signature|privileged" /> @@ -2334,7 +2343,7 @@ <permission android:name="android.permission.RETRIEVE_WINDOW_CONTENT" android:protectionLevel="signature|privileged" /> - <!-- @SystemApi Modify the global animation scaling factor. + <!-- Modify the global animation scaling factor. <p>Not for use by third-party applications. --> <permission android:name="android.permission.SET_ANIMATION_SCALE" android:protectionLevel="signature|privileged|development" /> @@ -2389,12 +2398,12 @@ android:description="@string/permdesc_broadcastSticky" android:protectionLevel="normal" /> - <!-- @SystemApi Allows mounting and unmounting file systems for removable storage. + <!-- Allows mounting and unmounting file systems for removable storage. <p>Not for use by third-party applications.--> <permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" android:protectionLevel="signature|privileged" /> - <!-- @SystemApi Allows formatting file systems for removable storage. + <!-- Allows formatting file systems for removable storage. <p>Not for use by third-party applications. --> <permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS" android:protectionLevel="signature|privileged" /> @@ -2428,7 +2437,7 @@ <permission android:name="android.permission.ASEC_RENAME" android:protectionLevel="signature" /> - <!-- @SystemApi Allows applications to write the apn settings and read sensitive fields of + <!-- Allows applications to write the apn settings and read sensitive fields of an existing apn settings like user and password. <p>Not for use by third-party applications. --> <permission android:name="android.permission.WRITE_APN_SETTINGS" @@ -2529,40 +2538,40 @@ <!-- ========================================= --> <eat-comment /> - <!-- @SystemApi Allows an application to read or write the secure system settings. + <!-- Allows an application to read or write the secure system settings. <p>Not for use by third-party applications. --> <permission android:name="android.permission.WRITE_SECURE_SETTINGS" android:protectionLevel="signature|privileged|development" /> - <!-- @SystemApi Allows an application to retrieve state dump information from system services. + <!-- Allows an application to retrieve state dump information from system services. <p>Not for use by third-party applications. --> <permission android:name="android.permission.DUMP" android:protectionLevel="signature|privileged|development" /> - <!-- @SystemApi Allows an application to read the low-level system log files. + <!-- Allows an application to read the low-level system log files. <p>Not for use by third-party applications, because Log entries can contain the user's private information. --> <permission android:name="android.permission.READ_LOGS" android:protectionLevel="signature|privileged|development" /> - <!-- @SystemApi Configure an application for debugging. + <!-- Configure an application for debugging. <p>Not for use by third-party applications. --> <permission android:name="android.permission.SET_DEBUG_APP" android:protectionLevel="signature|privileged|development" /> - <!-- @SystemApi Allows an application to set the maximum number of (not needed) + <!-- Allows an application to set the maximum number of (not needed) application processes that can be running. <p>Not for use by third-party applications. --> <permission android:name="android.permission.SET_PROCESS_LIMIT" android:protectionLevel="signature|privileged|development" /> - <!-- @SystemApi Allows an application to control whether activities are immediately + <!-- Allows an application to control whether activities are immediately finished when put in the background. <p>Not for use by third-party applications. --> <permission android:name="android.permission.SET_ALWAYS_FINISH" android:protectionLevel="signature|privileged|development" /> - <!-- @SystemApi Allow an application to request that a signal be sent to all persistent processes. + <!-- Allow an application to request that a signal be sent to all persistent processes. <p>Not for use by third-party applications. --> <permission android:name="android.permission.SIGNAL_PERSISTENT_PROCESSES" android:protectionLevel="signature|privileged|development" /> @@ -2572,7 +2581,7 @@ <!-- ==================================== --> <eat-comment /> - <!-- @SystemApi Allows access to the list of accounts in the Accounts Service. --> + <!-- Allows access to the list of accounts in the Accounts Service. --> <permission android:name="android.permission.GET_ACCOUNTS_PRIVILEGED" android:protectionLevel="signature|privileged" /> @@ -2581,12 +2590,12 @@ <permission android:name="android.permission.GET_PASSWORD" android:protectionLevel="signature" /> - <!-- @SystemApi Allows applications to RW to diagnostic resources. + <!-- Allows applications to RW to diagnostic resources. <p>Not for use by third-party applications. --> <permission android:name="android.permission.DIAGNOSTIC" android:protectionLevel="signature" /> - <!-- @SystemApi Allows an application to open, close, or disable the status bar + <!-- Allows an application to open, close, or disable the status bar and its icons. <p>Not for use by third-party applications. --> <permission android:name="android.permission.STATUS_BAR" @@ -2611,7 +2620,7 @@ <permission android:name="android.permission.FORCE_BACK" android:protectionLevel="signature" /> - <!-- @SystemApi Allows an application to update device statistics. + <!-- Allows an application to update device statistics. <p>Not for use by third-party applications. --> <permission android:name="android.permission.UPDATE_DEVICE_STATS" android:protectionLevel="signature|privileged" /> @@ -3017,7 +3026,7 @@ android:description="@string/permdesc_requestDeletePackages" android:protectionLevel="normal" /> - <!-- @SystemApi Allows an application to install packages. + <!-- Allows an application to install packages. <p>Not for use by third-party applications. --> <permission android:name="android.permission.INSTALL_PACKAGES" android:protectionLevel="signature|privileged" /> @@ -3090,7 +3099,7 @@ <permission android:name="android.permission.FORCE_PERSISTABLE_URI_PERMISSIONS" android:protectionLevel="signature" /> - <!-- @SystemApi Old permission for deleting an app's cache files, no longer used, + <!-- Old permission for deleting an app's cache files, no longer used, but signals for us to quietly ignore calls instead of throwing an exception. --> <permission android:name="android.permission.DELETE_CACHE_FILES" android:protectionLevel="signature|privileged" /> @@ -3100,7 +3109,7 @@ <permission android:name="android.permission.INTERNAL_DELETE_CACHE_FILES" android:protectionLevel="signature" /> - <!-- @SystemApi Allows an application to delete packages. + <!-- Allows an application to delete packages. <p>Not for use by third-party applications. <p>Starting in {@link android.os.Build.VERSION_CODES#N}, user confirmation is requested when the application deleting the package is not the same application that installed the @@ -3113,7 +3122,7 @@ <permission android:name="android.permission.MOVE_PACKAGE" android:protectionLevel="signature|privileged" /> - <!-- @SystemApi Allows an application to change whether an application component (other than its own) is + <!-- Allows an application to change whether an application component (other than its own) is enabled or not. <p>Not for use by third-party applications. --> <permission android:name="android.permission.CHANGE_COMPONENT_ENABLED_STATE" @@ -3146,7 +3155,7 @@ <permission android:name="android.permission.ACCESS_SURFACE_FLINGER" android:protectionLevel="signature" /> - <!-- @SystemApi Allows an application to take screen shots and more generally + <!-- Allows an application to take screen shots and more generally get access to the frame buffer data. <p>Not for use by third-party applications. --> <permission android:name="android.permission.READ_FRAME_BUFFER" @@ -3222,7 +3231,7 @@ android:protectionLevel="signature|privileged" /> <uses-permission android:name="android.permission.CONTROL_VPN" /> - <!-- @SystemApi Allows an application to capture audio output. + <!-- Allows an application to capture audio output. <p>Not for use by third-party applications.</p> --> <permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT" android:protectionLevel="signature|privileged" /> @@ -3239,17 +3248,17 @@ <permission android:name="android.permission.MODIFY_AUDIO_ROUTING" android:protectionLevel="signature|privileged" /> - <!-- @SystemApi Allows an application to capture video output. + <!-- Allows an application to capture video output. <p>Not for use by third-party applications.</p> --> <permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT" android:protectionLevel="signature|privileged" /> - <!-- @SystemApi Allows an application to capture secure video output. + <!-- Allows an application to capture secure video output. <p>Not for use by third-party applications.</p> --> <permission android:name="android.permission.CAPTURE_SECURE_VIDEO_OUTPUT" android:protectionLevel="signature|privileged" /> - <!-- @SystemApi Allows an application to know what content is playing and control its playback. + <!-- Allows an application to know what content is playing and control its playback. <p>Not for use by third-party applications due to privacy of media consumption</p> --> <permission android:name="android.permission.MEDIA_CONTENT_CONTROL" android:protectionLevel="signature|privileged" /> @@ -3276,7 +3285,7 @@ <permission android:name="android.permission.BRICK" android:protectionLevel="signature" /> - <!-- @SystemApi Required to be able to reboot the device. + <!-- Required to be able to reboot the device. <p>Not for use by third-party applications. --> <permission android:name="android.permission.REBOOT" android:protectionLevel="signature|privileged" /> @@ -3331,11 +3340,11 @@ <permission android:name="android.permission.BROADCAST_NETWORK_PRIVILEGED" android:protectionLevel="signature|privileged" /> - <!-- @SystemApi Not for use by third-party applications. --> + <!-- Not for use by third-party applications. --> <permission android:name="android.permission.MASTER_CLEAR" android:protectionLevel="signature|privileged" /> - <!-- @SystemApi Allows an application to call any phone number, including emergency + <!-- Allows an application to call any phone number, including emergency numbers, without going through the Dialer user interface for the user to confirm the call being placed. <p>Not for use by third-party applications. --> @@ -3350,19 +3359,19 @@ <permission android:name="android.permission.PERFORM_SIM_ACTIVATION" android:protectionLevel="signature|privileged" /> - <!-- @SystemApi Allows enabling/disabling location update notifications from + <!-- Allows enabling/disabling location update notifications from the radio. <p>Not for use by third-party applications. --> <permission android:name="android.permission.CONTROL_LOCATION_UPDATES" android:protectionLevel="signature|privileged" /> - <!-- @SystemApi Allows read/write access to the "properties" table in the checkin + <!-- Allows read/write access to the "properties" table in the checkin database, to change values that get uploaded. <p>Not for use by third-party applications. --> <permission android:name="android.permission.ACCESS_CHECKIN_PROPERTIES" android:protectionLevel="signature|privileged" /> - <!-- @SystemApi Allows an application to collect component usage + <!-- Allows an application to collect component usage statistics <p>Declaring the permission implies intention to use the API and the user of the device can grant permission through the Settings application. --> @@ -3395,7 +3404,7 @@ android:description="@string/permdesc_requestIgnoreBatteryOptimizations" android:protectionLevel="normal" /> - <!-- @SystemApi Allows an application to collect battery statistics --> + <!-- Allows an application to collect battery statistics --> <permission android:name="android.permission.BATTERY_STATS" android:protectionLevel="signature|privileged|development" /> @@ -3424,12 +3433,12 @@ <permission android:name="android.permission.CONFIRM_FULL_BACKUP" android:protectionLevel="signature" /> - <!-- @SystemApi Must be required by a {@link android.widget.RemoteViewsService}, + <!-- Must be required by a {@link android.widget.RemoteViewsService}, to ensure that only the system can bind to it. --> <permission android:name="android.permission.BIND_REMOTEVIEWS" android:protectionLevel="signature|privileged" /> - <!-- @SystemApi Allows an application to tell the AppWidget service which application + <!-- Allows an application to tell the AppWidget service which application can access AppWidget's data. The normal user flow is that a user picks an AppWidget to go into a particular host, thereby giving that host application access to the private data from the AppWidget app. @@ -3460,7 +3469,7 @@ <permission android:name="android.permission.CHANGE_BACKGROUND_DATA_SETTING" android:protectionLevel="signature" /> - <!-- @SystemApi This permission can be used on content providers to allow the global + <!-- This permission can be used on content providers to allow the global search system to access their data. Typically it used when the provider has some permissions protecting it (which global search would not be expected to hold), and added as a read-only permission diff --git a/core/res/res/values-mcc214-mnc01/config.xml b/core/res/res/values-mcc214-mnc01/config.xml index 876c26e7f629..b34696b14d94 100644 --- a/core/res/res/values-mcc214-mnc01/config.xml +++ b/core/res/res/values-mcc214-mnc01/config.xml @@ -30,4 +30,8 @@ <item>7</item> <item>9</item> </integer-array> + + <!-- Whether safe headphone volume warning dialog is disabled on Vol+ (operator specific). --> + <bool name="config_safe_media_disable_on_volume_up">false</bool> + </resources> diff --git a/telephony/java/android/telephony/rcs/RcsThread.aidl b/core/res/res/values-mcc234-mnc15/config.xml index e2e0da5da347..84e779d240d1 100644 --- a/telephony/java/android/telephony/rcs/RcsThread.aidl +++ b/core/res/res/values-mcc234-mnc15/config.xml @@ -1,5 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- /* -** ** Copyright 2018, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,7 +15,11 @@ ** See the License for the specific language governing permissions and ** limitations under the License. */ +--> + +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> -package android.telephony; + <!-- Whether safe headphone volume warning dialog is disabled on Vol+ (operator specific). --> + <bool name="config_safe_media_disable_on_volume_up">false</bool> -parcelable RcsThread;
\ No newline at end of file +</resources> diff --git a/core/res/res/values-mcc234-mnc91/config.xml b/core/res/res/values-mcc234-mnc91/config.xml new file mode 100644 index 000000000000..84e779d240d1 --- /dev/null +++ b/core/res/res/values-mcc234-mnc91/config.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 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. +*/ +--> + +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Whether safe headphone volume warning dialog is disabled on Vol+ (operator specific). --> + <bool name="config_safe_media_disable_on_volume_up">false</bool> + +</resources> diff --git a/core/res/res/values-mcc302-mnc220/config.xml b/core/res/res/values-mcc302-mnc220/config.xml index 7289b4f8135a..36efd0a28b91 100644 --- a/core/res/res/values-mcc302-mnc220/config.xml +++ b/core/res/res/values-mcc302-mnc220/config.xml @@ -29,7 +29,7 @@ <item>SUPL_PORT=7275</item> <item>SUPL_VER=0x20000</item> <item>SUPL_MODE=1</item> - <item>SUPL_ES=0</item> + <item>SUPL_ES=1</item> <item>LPP_PROFILE=3</item> <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item> <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item> diff --git a/core/res/res/values-mcc302-mnc221/config.xml b/core/res/res/values-mcc302-mnc221/config.xml index ff140756e96a..a11dd95174a2 100644 --- a/core/res/res/values-mcc302-mnc221/config.xml +++ b/core/res/res/values-mcc302-mnc221/config.xml @@ -26,7 +26,7 @@ <item>SUPL_PORT=7275</item> <item>SUPL_VER=0x20000</item> <item>SUPL_MODE=1</item> - <item>SUPL_ES=0</item> + <item>SUPL_ES=1</item> <item>LPP_PROFILE=3</item> <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item> <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item> diff --git a/core/res/res/values-mcc302-mnc370/config.xml b/core/res/res/values-mcc302-mnc370/config.xml index ad3a654a0390..8d29ec15bf6b 100644 --- a/core/res/res/values-mcc302-mnc370/config.xml +++ b/core/res/res/values-mcc302-mnc370/config.xml @@ -30,7 +30,7 @@ <item>SUPL_PORT=7275</item> <item>SUPL_VER=0x20000</item> <item>SUPL_MODE=1</item> - <item>SUPL_ES=0</item> + <item>SUPL_ES=1</item> <item>LPP_PROFILE=2</item> <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item> <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item> diff --git a/core/res/res/values-mcc302-mnc610/config.xml b/core/res/res/values-mcc302-mnc610/config.xml index 232f14969ad1..650aa62b4a4e 100644 --- a/core/res/res/values-mcc302-mnc610/config.xml +++ b/core/res/res/values-mcc302-mnc610/config.xml @@ -28,7 +28,7 @@ <item>SUPL_PORT=7275</item> <item>SUPL_VER=0x20000</item> <item>SUPL_MODE=1</item> - <item>SUPL_ES=0</item> + <item>SUPL_ES=1</item> <item>LPP_PROFILE=2</item> <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item> <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item> diff --git a/core/res/res/values-mcc302-mnc640/config.xml b/core/res/res/values-mcc302-mnc640/config.xml index 1d2e625952f8..4bb68dcf04be 100644 --- a/core/res/res/values-mcc302-mnc640/config.xml +++ b/core/res/res/values-mcc302-mnc640/config.xml @@ -24,7 +24,7 @@ <item>SUPL_PORT=7275</item> <item>SUPL_VER=0x20000</item> <item>SUPL_MODE=1</item> - <item>SUPL_ES=0</item> + <item>SUPL_ES=1</item> <item>LPP_PROFILE=2</item> <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item> <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item> diff --git a/core/res/res/values-mcc302-mnc720/config.xml b/core/res/res/values-mcc302-mnc720/config.xml index cfcf1f849ec5..735a8c80e4e8 100644 --- a/core/res/res/values-mcc302-mnc720/config.xml +++ b/core/res/res/values-mcc302-mnc720/config.xml @@ -30,7 +30,7 @@ <item>SUPL_PORT=7275</item> <item>SUPL_VER=0x20000</item> <item>SUPL_MODE=1</item> - <item>SUPL_ES=0</item> + <item>SUPL_ES=1</item> <item>LPP_PROFILE=2</item> <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item> <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 98cb640e7196..31e799dc31db 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -659,6 +659,10 @@ <!-- Boolean indicating whether framework needs to set the tx power limit for meeting SAR requirements --> <bool translatable="false" name="config_wifi_framework_enable_sar_tx_power_limit">false</bool> + <!-- Boolean indicating whether framework should use detection of softAP mode to set the tx + power limit for meeting SAR requirements --> + <bool translatable="false" name="config_wifi_framework_enable_soft_ap_sar_tx_power_limit">false</bool> + <!-- Boolean indicating whether framework needs to use body proximity to set the tx power limit for meeting SAR requirements --> <bool translatable="false" name="config_wifi_framework_enable_body_proximity_sar_tx_power_limit">false</bool> @@ -2346,6 +2350,9 @@ <!-- Whether safe headphone volume is enabled or not (country specific). --> <bool name="config_safe_media_volume_enabled">true</bool> + <!-- Whether safe headphone volume warning dialog is disabled on Vol+ (operator specific). --> + <bool name="config_safe_media_disable_on_volume_up">true</bool> + <!-- Set to true if the wifi display supports compositing content stored in gralloc protected buffers. For this to be true, there must exist a protected hardware path for surface flinger to composite and send @@ -2768,7 +2775,7 @@ <item>SUPL_PORT=7275</item> <item>SUPL_VER=0x20000</item> <item>SUPL_MODE=1</item> - <item>SUPL_ES=0</item> + <item>SUPL_ES=1</item> <item>LPP_PROFILE=0</item> <item>USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL=1</item> <item>A_GLONASS_POS_PROTOCOL_SELECT=0</item> @@ -2968,6 +2975,10 @@ --> <bool name="config_fillMainBuiltInDisplayCutout">false</bool> + <!-- If true, and there is a cutout on the main built in display, the cutout will be masked + by shrinking the display such that it does not overlap the cutout area. --> + <bool name="config_maskMainBuiltInDisplayCutout">false</bool> + <!-- Ultrasound support for Mic/speaker path --> <!-- Whether the default microphone audio source supports near-ultrasound frequencies (range of 18 - 21 kHz). --> @@ -3492,6 +3503,13 @@ <!-- Whether or not we should show the option to show battery percentage --> <bool name="config_battery_percentage_setting_available">true</bool> + <!-- Model of potentially misprovisioned devices. If none is specified in an overlay, an + empty string is passed in. --> + <string name="config_misprovisionedDeviceModel" translatable="false"></string> + + <!-- Brand value for attestation of misprovisioned device. --> + <string name="config_misprovisionedBrandValue" translatable="false"></string> + <!-- Pre-scale volume at volume step 1 for Absolute Volume --> <fraction name="config_prescaleAbsoluteVolume_index1">50%</fraction> @@ -3500,4 +3518,8 @@ <!-- Pre-scale volume at volume step 3 for Absolute Volume --> <fraction name="config_prescaleAbsoluteVolume_index3">85%</fraction> + + <!-- Component name for default assistant on this device --> + <string name="config_defaultAssistantComponentName"></string> + </resources> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 471170bbe93b..73cb59e84644 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -61,6 +61,15 @@ <!-- Margin at the edge of the screen to ignore touch events for in the windowshade. --> <dimen name="status_bar_edge_ignore">5dp</dimen> + <!-- Default radius of the software rounded corners. --> + <dimen name="rounded_corner_radius">0dp</dimen> + <!-- Radius of the software rounded corners at the top of the display in its natural + orientation. If zero, the value of rounded_corner_radius is used. --> + <dimen name="rounded_corner_radius_top">0dp</dimen> + <!-- Radius of the software rounded corners at the bottom of the display in its natural + orientation. If zero, the value of rounded_corner_radius is used. --> + <dimen name="rounded_corner_radius_bottom">0dp</dimen> + <!-- Width of the window of the divider bar used to resize docked stacks. --> <dimen name="docked_stack_divider_thickness">48dp</dimen> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 4d5ef68468e3..310aaf4bce8a 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -310,6 +310,7 @@ <java-symbol type="bool" name="config_allowAnimationsInLowPowerMode" /> <java-symbol type="bool" name="config_useDevInputEventForAudioJack" /> <java-symbol type="bool" name="config_safe_media_volume_enabled" /> + <java-symbol type="bool" name="config_safe_media_disable_on_volume_up" /> <java-symbol type="bool" name="config_camera_sound_forced" /> <java-symbol type="bool" name="config_dontPreferApn" /> <java-symbol type="bool" name="config_restartRadioAfterProvisioning" /> @@ -338,6 +339,7 @@ <java-symbol type="bool" name="config_wifi_framework_use_single_radio_chain_scan_results_network_selection" /> <java-symbol type="bool" name="config_wifi_only_link_same_credential_configurations" /> <java-symbol type="bool" name="config_wifi_framework_enable_sar_tx_power_limit" /> + <java-symbol type="bool" name="config_wifi_framework_enable_soft_ap_sar_tx_power_limit" /> <java-symbol type="bool" name="config_wifi_framework_enable_body_proximity_sar_tx_power_limit" /> <java-symbol type="string" name="config_wifi_sar_sensor_type" /> <java-symbol type="integer" name="config_wifi_framework_sar_free_space_event_id" /> @@ -3406,11 +3408,18 @@ <java-symbol type="integer" name="config_defaultHapticFeedbackIntensity" /> <java-symbol type="integer" name="config_defaultNotificationVibrationIntensity" /> + <java-symbol type="bool" name="config_maskMainBuiltInDisplayCutout" /> + <java-symbol type="array" name="config_disableApksUnlessMatchedSku_apk_list" /> <java-symbol type="array" name="config_disableApkUnlessMatchedSku_skus_list" /> + <java-symbol type="string" name="config_misprovisionedDeviceModel" /> + <java-symbol type="string" name="config_misprovisionedBrandValue" /> + <!-- For Bluetooth AbsoluteVolume --> <java-symbol type="fraction" name="config_prescaleAbsoluteVolume_index1" /> <java-symbol type="fraction" name="config_prescaleAbsoluteVolume_index2" /> <java-symbol type="fraction" name="config_prescaleAbsoluteVolume_index3" /> + + <java-symbol type="string" name="config_defaultAssistantComponentName" /> </resources> diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index 483381660655..090f9afb551e 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -306,6 +306,7 @@ please see themes_device_defaults.xml. <item name="quickContactBadgeStyleSmallWindowLarge">@style/Widget.QuickContactBadgeSmall.WindowLarge</item> <item name="listPopupWindowStyle">@style/Widget.ListPopupWindow</item> <item name="popupMenuStyle">@style/Widget.PopupMenu</item> + <item name="popupTheme">@null</item> <item name="activityChooserViewStyle">@style/Widget.ActivityChooserView</item> <item name="fragmentBreadCrumbsStyle">@style/Widget.FragmentBreadCrumbs</item> <item name="contextPopupMenuStyle">?attr/popupMenuStyle</item> diff --git a/core/res/res/values/themes_holo.xml b/core/res/res/values/themes_holo.xml index cb5b93dd7df4..33832d4eb689 100644 --- a/core/res/res/values/themes_holo.xml +++ b/core/res/res/values/themes_holo.xml @@ -296,6 +296,7 @@ please see themes_device_defaults.xml. <item name="quickContactBadgeStyleSmallWindowLarge">@style/Widget.Holo.QuickContactBadgeSmall.WindowLarge</item> <item name="listPopupWindowStyle">@style/Widget.Holo.ListPopupWindow</item> <item name="popupMenuStyle">@style/Widget.Holo.PopupMenu</item> + <item name="popupTheme">@null</item> <item name="stackViewStyle">@style/Widget.Holo.StackView</item> <item name="activityChooserViewStyle">@style/Widget.Holo.ActivityChooserView</item> <item name="fragmentBreadCrumbsStyle">@style/Widget.Holo.FragmentBreadCrumbs</item> @@ -658,9 +659,11 @@ please see themes_device_defaults.xml. <item name="quickContactBadgeStyleSmallWindowLarge">@style/Widget.Holo.QuickContactBadgeSmall.WindowLarge</item> <item name="listPopupWindowStyle">@style/Widget.Holo.Light.ListPopupWindow</item> <item name="popupMenuStyle">@style/Widget.Holo.Light.PopupMenu</item> + <item name="popupTheme">@null</item> <item name="stackViewStyle">@style/Widget.Holo.StackView</item> <item name="activityChooserViewStyle">@style/Widget.Holo.Light.ActivityChooserView</item> <item name="fragmentBreadCrumbsStyle">@style/Widget.Holo.Light.FragmentBreadCrumbs</item> + <item name="contextPopupMenuStyle">?attr/popupMenuStyle</item> <!-- Preference styles --> <item name="preferenceScreenStyle">@style/Preference.Holo.PreferenceScreen</item> diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java index f2f28937bb50..7f23edf27094 100644 --- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java +++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java @@ -99,6 +99,7 @@ public class SettingsBackupTest { private static final Set<String> BACKUP_BLACKLISTED_GLOBAL_SETTINGS = newHashSet( Settings.Global.ACTIVITY_MANAGER_CONSTANTS, + Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED, Settings.Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED, Settings.Global.ADB_ENABLED, Settings.Global.ADD_USERS_WHEN_LOCKED, diff --git a/core/tests/coretests/src/android/view/DisplayCutoutTest.java b/core/tests/coretests/src/android/view/DisplayCutoutTest.java index 6ee74cb9a742..fe45fe7d3aaf 100644 --- a/core/tests/coretests/src/android/view/DisplayCutoutTest.java +++ b/core/tests/coretests/src/android/view/DisplayCutoutTest.java @@ -19,6 +19,7 @@ package android.view; import static android.view.DisplayCutout.NO_CUTOUT; import static android.view.DisplayCutout.fromSpec; +import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.sameInstance; import static org.junit.Assert.assertEquals; @@ -220,6 +221,19 @@ public class DisplayCutoutTest { } @Test + public void fromSpec_setsSafeInsets_top() { + DisplayCutout cutout = fromSpec("M -50,0 v 20 h 100 v -20 z", 200, 400, 2f); + assertThat(cutout.getSafeInsets(), equalTo(new Rect(0, 20, 0, 0))); + } + + @Test + public void fromSpec_setsSafeInsets_top_and_bottom() { + DisplayCutout cutout = fromSpec("M -50,0 v 20 h 100 v -20 z" + + "@bottom M -50,0 v -10,0 h 100 v 20 z", 200, 400, 2f); + assertThat(cutout.getSafeInsets(), equalTo(new Rect(0, 20, 0, 10))); + } + + @Test public void parcel_unparcel_nocutout() { Parcel p = Parcel.obtain(); diff --git a/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java b/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java index b18fa747557d..c165b6be525e 100644 --- a/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java +++ b/core/tests/coretests/src/com/android/internal/app/IntentForwarderActivityTest.java @@ -16,46 +16,50 @@ package com.android.internal.app; +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.nullable; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + import android.annotation.Nullable; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; +import android.net.Uri; import android.os.Bundle; +import android.os.RemoteException; import android.os.UserHandle; import android.os.UserManager; import android.support.test.InstrumentationRegistry; import android.support.test.rule.ActivityTestRule; import android.support.test.runner.AndroidJUnit4; -import android.util.Log; - +import java.util.ArrayList; +import java.util.List; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.MockitoAnnotations; -import java.util.ArrayList; -import java.util.List; - -import static junit.framework.Assert.assertEquals; -import static junit.framework.Assert.assertNotNull; -import static junit.framework.Assert.assertNull; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - @RunWith(AndroidJUnit4.class) public class IntentForwarderActivityTest { + private static final ComponentName FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME = new ComponentName( "android", @@ -77,22 +81,26 @@ public class IntentForwarderActivityTest { private static IntentForwarderActivity.Injector sInjector; private static ComponentName sComponentName; + private static String sActivityName; + private static String sPackageName; @Mock private IPackageManager mIPm; @Mock private PackageManager mPm; @Mock private UserManager mUserManager; + @Mock private ApplicationInfo mApplicationInfo; @Rule public ActivityTestRule<IntentForwarderWrapperActivity> mActivityRule = new ActivityTestRule<>(IntentForwarderWrapperActivity.class, true, false); private Context mContext; + public static final String PHONE_NUMBER = "123-456-789"; @Before public void setup() { MockitoAnnotations.initMocks(this); mContext = InstrumentationRegistry.getTargetContext(); - sInjector = new TestInjector(); + sInjector = spy(new TestInjector()); } @Test @@ -252,6 +260,149 @@ public class IntentForwarderActivityTest { assertEquals(MANAGED_PROFILE_INFO.id, activity.mUserIdActivityLaunchedIn); } + @Test + public void shouldSkipDisclosure_notWhitelisted() throws RemoteException { + setupShouldSkipDisclosureTest(); + Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) + .setAction(Intent.ACTION_SEND) + .setType(TYPE_PLAIN_TEXT); + + mActivityRule.launchActivity(intent); + + verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); + verify(sInjector).showToast(anyInt(), anyInt()); + } + + @Test + public void shouldSkipDisclosure_withResolverActivity() throws RemoteException { + setupShouldSkipDisclosureTest(); + sActivityName = ResolverActivity.class.getName(); + sPackageName = "android"; + Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) + .setAction(Intent.ACTION_SEND) + .setType(TYPE_PLAIN_TEXT); + + mActivityRule.launchActivity(intent); + + verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); + verify(sInjector, never()).showToast(anyInt(), anyInt()); + } + + @Test + public void shouldSkipDisclosure_callIntent_call() throws RemoteException { + setupShouldSkipDisclosureTest(); + Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) + .setAction(Intent.ACTION_CALL); + + mActivityRule.launchActivity(intent); + + verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); + verify(sInjector, never()).showToast(anyInt(), anyInt()); + } + + @Test + public void shouldSkipDisclosure_callIntent_dial() throws RemoteException { + setupShouldSkipDisclosureTest(); + Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) + .setAction(Intent.ACTION_DIAL); + + mActivityRule.launchActivity(intent); + + verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); + verify(sInjector, never()).showToast(anyInt(), anyInt()); + } + + @Test + public void shouldSkipDisclosure_callIntent_notCallOrDial() throws RemoteException { + setupShouldSkipDisclosureTest(); + Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) + .setAction(Intent.ACTION_ALARM_CHANGED); + + mActivityRule.launchActivity(intent); + + verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); + verify(sInjector).showToast(anyInt(), anyInt()); + } + + @Test + public void shouldSkipDisclosure_textMessageIntent_sms() throws RemoteException { + setupShouldSkipDisclosureTest(); + Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) + .setAction(Intent.ACTION_SENDTO) + .setData(Uri.fromParts("sms", PHONE_NUMBER, null)); + + mActivityRule.launchActivity(intent); + + verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); + verify(sInjector, never()).showToast(anyInt(), anyInt()); + } + + @Test + public void shouldSkipDisclosure_textMessageIntent_smsto() throws RemoteException { + setupShouldSkipDisclosureTest(); + Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) + .setAction(Intent.ACTION_SENDTO) + .setData(Uri.fromParts("smsto", PHONE_NUMBER, null)); + + mActivityRule.launchActivity(intent); + + verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); + verify(sInjector, never()).showToast(anyInt(), anyInt()); + } + + @Test + public void shouldSkipDisclosure_textMessageIntent_mms() throws RemoteException { + setupShouldSkipDisclosureTest(); + Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) + .setAction(Intent.ACTION_SENDTO) + .setData(Uri.fromParts("mms", PHONE_NUMBER, null)); + + mActivityRule.launchActivity(intent); + + verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); + verify(sInjector, never()).showToast(anyInt(), anyInt()); + } + + @Test + public void shouldSkipDisclosure_textMessageIntent_mmsto() throws RemoteException { + setupShouldSkipDisclosureTest(); + Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) + .setAction(Intent.ACTION_SENDTO) + .setData(Uri.fromParts("mmsto", PHONE_NUMBER, null)); + + mActivityRule.launchActivity(intent); + + verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); + verify(sInjector, never()).showToast(anyInt(), anyInt()); + } + + @Test + public void shouldSkipDisclosure_textMessageIntent_invalidUri() throws RemoteException { + setupShouldSkipDisclosureTest(); + Intent intent = new Intent(mContext, IntentForwarderWrapperActivity.class) + .setAction(Intent.ACTION_SENDTO) + .setData(Uri.fromParts("invalid", PHONE_NUMBER, null)); + + mActivityRule.launchActivity(intent); + + verify(mIPm).canForwardTo(any(), any(), anyInt(), anyInt()); + verify(sInjector).showToast(anyInt(), anyInt()); + } + + private void setupShouldSkipDisclosureTest() throws RemoteException { + sComponentName = FORWARD_TO_MANAGED_PROFILE_COMPONENT_NAME; + sActivityName = "MyTestActivity"; + sPackageName = "test.package.name"; + when(mApplicationInfo.isSystemApp()).thenReturn(true); + // Managed profile exists. + List<UserInfo> profiles = new ArrayList<>(); + profiles.add(CURRENT_USER_INFO); + profiles.add(MANAGED_PROFILE_INFO); + when(mUserManager.getProfiles(anyInt())).thenReturn(profiles); + // Intent can be forwarded. + when(mIPm.canForwardTo( + any(Intent.class), nullable(String.class), anyInt(), anyInt())).thenReturn(true); + } public static class IntentForwarderWrapperActivity extends IntentForwarderActivity { private Intent mStartActivityIntent; @@ -276,7 +427,7 @@ public class IntentForwarderActivityTest { } } - class TestInjector implements IntentForwarderActivity.Injector { + public class TestInjector implements IntentForwarderActivity.Injector { @Override public IPackageManager getIPackageManager() { @@ -292,5 +443,21 @@ public class IntentForwarderActivityTest { public PackageManager getPackageManager() { return mPm; } + + @Override + public ResolveInfo resolveActivityAsUser(Intent intent, int flags, int userId) { + ActivityInfo activityInfo = new ActivityInfo(); + activityInfo.packageName = sPackageName; + activityInfo.name = sActivityName; + activityInfo.applicationInfo = mApplicationInfo; + + ResolveInfo resolveInfo = new ResolveInfo(); + resolveInfo.activityInfo = activityInfo; + + return resolveInfo; + } + + @Override + public void showToast(int messageId, int duration) {} } }
\ No newline at end of file diff --git a/data/etc/OWNERS b/data/etc/OWNERS index bbec474c20fd..ea66ee373785 100644 --- a/data/etc/OWNERS +++ b/data/etc/OWNERS @@ -1 +1 @@ -per-file privapp-permissions-platform.xml = hackbod@android.com, jsharkey@android.com, svetoslavganov@google.com, toddke@google.com, yamasani@google.com +per-file privapp-permissions-platform.xml = hackbod@android.com, jsharkey@android.com, svetoslavganov@google.com, toddke@google.com, yamasani@google.com, cbrubaker@google.com, jeffv@google.com, moltmann@google.com diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml index 0082f4bb0002..c8bd847ad8da 100644 --- a/data/etc/privapp-permissions-platform.xml +++ b/data/etc/privapp-permissions-platform.xml @@ -33,6 +33,10 @@ applications that come with the platform <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 @@ applications that come with the platform <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/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java index 66f4db318e02..36c1c2133c2c 100644 --- a/graphics/java/android/graphics/Canvas.java +++ b/graphics/java/android/graphics/Canvas.java @@ -1600,9 +1600,9 @@ public class Canvas extends BaseCanvas { * Draw the specified circle using the specified paint. If radius is <= 0, then nothing will be * drawn. The circle will be filled or framed based on the Style in the paint. * - * @param cx The x-coordinate of the center of the cirle to be drawn - * @param cy The y-coordinate of the center of the cirle to be drawn - * @param radius The radius of the cirle to be drawn + * @param cx The x-coordinate of the center of the circle to be drawn + * @param cy The y-coordinate of the center of the circle to be drawn + * @param radius The radius of the circle to be drawn * @param paint The paint used to draw the circle */ public void drawCircle(float cx, float cy, float radius, @NonNull Paint paint) { diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index 6ac52d109032..36b7e37635ca 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -54,6 +54,7 @@ import java.math.BigInteger; 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 @@ public class KeyStore { } /** - * 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 @@ public class KeyStore { 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 419eb24e1cc1..aa2917484a05 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyGeneratorSpi.java @@ -210,6 +210,10 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { 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 @@ -301,6 +305,9 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng( mRng, (mKeySizeBits + 7) / 8); int flags = 0; + if (spec.isStrongBoxBacked()) { + flags |= KeyStore.FLAG_STRONGBOX; + } String keyAliasInKeystore = Credentials.USER_PRIVATE_KEY + spec.getKeystoreAlias(); KeyCharacteristics resultingKeyCharacteristics = new KeyCharacteristics(); boolean success = false; @@ -314,8 +321,12 @@ public abstract class AndroidKeyStoreKeyGeneratorSpi extends KeyGeneratorSpi { flags, resultingKeyCharacteristics); if (errorCode != KeyStore.NO_ERROR) { - throw new ProviderException( - "Keystore operation failed", KeyStore.getKeyStoreException(errorCode)); + if (errorCode == KeyStore.HARDWARE_TYPE_UNAVAILABLE) { + throw new StrongBoxUnavailableException("Failed to generate key"); + } else { + throw new ProviderException( + "Keystore operation failed", KeyStore.getKeyStoreException(errorCode)); + } } @KeyProperties.KeyAlgorithmEnum String keyAlgorithmJCA; try { diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java index 5fc742afeaeb..d44c894fa573 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreKeyPairGeneratorSpi.java @@ -303,7 +303,7 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato 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 @@ public abstract class AndroidKeyStoreKeyPairGeneratorSpi extends KeyPairGenerato } } - 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/keystore/java/android/security/keystore/AttestationUtils.java b/keystore/java/android/security/keystore/AttestationUtils.java index 1be8309bcf5a..f7993eff6b08 100644 --- a/keystore/java/android/security/keystore/AttestationUtils.java +++ b/keystore/java/android/security/keystore/AttestationUtils.java @@ -22,9 +22,9 @@ import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.TestApi; import android.content.Context; +import android.content.res.Resources; import android.os.Build; import android.security.KeyStore; -import android.security.KeyStoreException; import android.security.keymaster.KeymasterArguments; import android.security.keymaster.KeymasterCertificateChain; import android.security.keymaster.KeymasterDefs; @@ -117,6 +117,40 @@ public abstract class AttestationUtils { @NonNull public static KeymasterArguments prepareAttestationArguments(Context context, @NonNull int[] idTypes, @NonNull byte[] attestationChallenge) throws DeviceIdAttestationException { + return prepareAttestationArguments(context, idTypes,attestationChallenge, Build.BRAND); + } + + /** + * Prepares Keymaster Arguments with attestation data for misprovisioned Pixel 2 device. + * See http://go/keyAttestationFailure and http://b/69471841 for more info. + * @hide should only be used by KeyChain. + */ + @NonNull public static KeymasterArguments prepareAttestationArgumentsIfMisprovisioned( + Context context, @NonNull int[] idTypes, @NonNull byte[] attestationChallenge) throws + DeviceIdAttestationException { + if (!isPotentiallyMisprovisionedDevice(context)) { + return null; + } + Resources resources = context.getResources(); + String misprovisionedBrand = resources.getString( + com.android.internal.R.string.config_misprovisionedBrandValue); + return prepareAttestationArguments( + context, idTypes, attestationChallenge, misprovisionedBrand); + } + + @NonNull private static boolean isPotentiallyMisprovisionedDevice(Context context) { + Resources resources = context.getResources(); + String misprovisionedModel = resources.getString( + com.android.internal.R.string.config_misprovisionedDeviceModel); + String misprovisionedBrand = resources.getString( + com.android.internal.R.string.config_misprovisionedBrandValue); + + return (Build.MODEL.equals(misprovisionedModel)); + } + + @NonNull private static KeymasterArguments prepareAttestationArguments(Context context, + @NonNull int[] idTypes, @NonNull byte[] attestationChallenge, String brand) throws + DeviceIdAttestationException { // Check method arguments, retrieve requested device IDs and prepare attestation arguments. if (attestationChallenge == null) { throw new NullPointerException("Missing attestation challenge"); @@ -169,7 +203,7 @@ public abstract class AttestationUtils { } } attestArgs.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_BRAND, - Build.BRAND.getBytes(StandardCharsets.UTF_8)); + brand.getBytes(StandardCharsets.UTF_8)); attestArgs.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_DEVICE, Build.DEVICE.getBytes(StandardCharsets.UTF_8)); attestArgs.addBytes(KeymasterDefs.KM_TAG_ATTESTATION_ID_PRODUCT, diff --git a/libs/androidfw/LocaleData.cpp b/libs/androidfw/LocaleData.cpp index 889d166d853b..020cef6012e9 100644 --- a/libs/androidfw/LocaleData.cpp +++ b/libs/androidfw/LocaleData.cpp @@ -34,11 +34,11 @@ inline uint32_t packLocale(const char* language, const char* region) { } inline uint32_t dropRegion(uint32_t packed_locale) { - return packed_locale & 0xFFFF0000lu; + return packed_locale & 0xFFFF0000LU; } inline bool hasRegion(uint32_t packed_locale) { - return (packed_locale & 0x0000FFFFlu) != 0; + return (packed_locale & 0x0000FFFFLU) != 0; } const size_t SCRIPT_LENGTH = 4; @@ -122,9 +122,9 @@ inline bool isRepresentative(uint32_t language_and_region, const char* script) { return (REPRESENTATIVE_LOCALES.count(packed_locale) != 0); } -const uint32_t US_SPANISH = 0x65735553lu; // es-US -const uint32_t MEXICAN_SPANISH = 0x65734D58lu; // es-MX -const uint32_t LATIN_AMERICAN_SPANISH = 0x6573A424lu; // es-419 +const uint32_t US_SPANISH = 0x65735553LU; // es-US +const uint32_t MEXICAN_SPANISH = 0x65734D58LU; // es-MX +const uint32_t LATIN_AMERICAN_SPANISH = 0x6573A424LU; // es-419 // The two locales es-US and es-MX are treated as special fallbacks for es-419. // If there is no es-419, they are considered its equivalent. @@ -225,8 +225,8 @@ void localeDataComputeScript(char out[4], const char* language, const char* regi } const uint32_t ENGLISH_STOP_LIST[2] = { - 0x656E0000lu, // en - 0x656E8400lu, // en-001 + 0x656E0000LU, // en + 0x656E8400LU, // en-001 }; const char ENGLISH_CHARS[2] = {'e', 'n'}; const char LATIN_CHARS[4] = {'L', 'a', 't', 'n'}; diff --git a/libs/androidfw/LocaleDataTables.cpp b/libs/androidfw/LocaleDataTables.cpp index 7c381efec7ec..c276a238e2e1 100644 --- a/libs/androidfw/LocaleDataTables.cpp +++ b/libs/androidfw/LocaleDataTables.cpp @@ -1446,733 +1446,733 @@ const std::unordered_map<uint32_t, uint8_t> LIKELY_SCRIPTS({ }); std::unordered_set<uint64_t> REPRESENTATIVE_LOCALES({ - 0x616145544C61746Ellu, // aa_Latn_ET - 0x616247454379726Cllu, // ab_Cyrl_GE - 0xC42047484C61746Ellu, // abr_Latn_GH - 0x904049444C61746Ellu, // ace_Latn_ID - 0x9C4055474C61746Ellu, // ach_Latn_UG - 0x806047484C61746Ellu, // ada_Latn_GH - 0xE06052554379726Cllu, // ady_Cyrl_RU - 0x6165495241767374llu, // ae_Avst_IR - 0x8480544E41726162llu, // aeb_Arab_TN - 0x61665A414C61746Ellu, // af_Latn_ZA - 0xC0C0434D4C61746Ellu, // agq_Latn_CM - 0xB8E0494E41686F6Dllu, // aho_Ahom_IN - 0x616B47484C61746Ellu, // ak_Latn_GH - 0xA940495158737578llu, // akk_Xsux_IQ - 0xB560584B4C61746Ellu, // aln_Latn_XK - 0xCD6052554379726Cllu, // alt_Cyrl_RU - 0x616D455445746869llu, // am_Ethi_ET - 0xB9804E474C61746Ellu, // amo_Latn_NG - 0xE5C049444C61746Ellu, // aoz_Latn_ID - 0x8DE0544741726162llu, // apd_Arab_TG - 0x6172454741726162llu, // ar_Arab_EG - 0x8A20495241726D69llu, // arc_Armi_IR - 0x8A204A4F4E626174llu, // arc_Nbat_JO - 0x8A20535950616C6Dllu, // arc_Palm_SY - 0xB620434C4C61746Ellu, // arn_Latn_CL - 0xBA20424F4C61746Ellu, // aro_Latn_BO - 0xC220445A41726162llu, // arq_Arab_DZ - 0xE2204D4141726162llu, // ary_Arab_MA - 0xE620454741726162llu, // arz_Arab_EG - 0x6173494E42656E67llu, // as_Beng_IN - 0x8240545A4C61746Ellu, // asa_Latn_TZ - 0x9240555353676E77llu, // ase_Sgnw_US - 0xCE4045534C61746Ellu, // ast_Latn_ES - 0xA66043414C61746Ellu, // atj_Latn_CA - 0x617652554379726Cllu, // av_Cyrl_RU - 0x82C0494E44657661llu, // awa_Deva_IN - 0x6179424F4C61746Ellu, // ay_Latn_BO - 0x617A495241726162llu, // az_Arab_IR - 0x617A415A4C61746Ellu, // az_Latn_AZ - 0x626152554379726Cllu, // ba_Cyrl_RU - 0xAC01504B41726162llu, // bal_Arab_PK - 0xB40149444C61746Ellu, // ban_Latn_ID - 0xBC014E5044657661llu, // bap_Deva_NP - 0xC40141544C61746Ellu, // bar_Latn_AT - 0xC801434D4C61746Ellu, // bas_Latn_CM - 0xDC01434D42616D75llu, // bax_Bamu_CM - 0x882149444C61746Ellu, // bbc_Latn_ID - 0xA421434D4C61746Ellu, // bbj_Latn_CM - 0xA04143494C61746Ellu, // bci_Latn_CI - 0x626542594379726Cllu, // be_Cyrl_BY - 0xA481534441726162llu, // bej_Arab_SD - 0xB0815A4D4C61746Ellu, // bem_Latn_ZM - 0xD88149444C61746Ellu, // bew_Latn_ID - 0xE481545A4C61746Ellu, // bez_Latn_TZ - 0x8CA1434D4C61746Ellu, // bfd_Latn_CM - 0xC0A1494E54616D6Cllu, // bfq_Taml_IN - 0xCCA1504B41726162llu, // bft_Arab_PK - 0xE0A1494E44657661llu, // bfy_Deva_IN - 0x626742474379726Cllu, // bg_Cyrl_BG - 0x88C1494E44657661llu, // bgc_Deva_IN - 0xB4C1504B41726162llu, // bgn_Arab_PK - 0xDCC154524772656Bllu, // bgx_Grek_TR - 0x84E1494E44657661llu, // bhb_Deva_IN - 0xA0E1494E44657661llu, // bhi_Deva_IN - 0xA8E150484C61746Ellu, // bhk_Latn_PH - 0xB8E1494E44657661llu, // bho_Deva_IN - 0x626956554C61746Ellu, // bi_Latn_VU - 0xA90150484C61746Ellu, // bik_Latn_PH - 0xB5014E474C61746Ellu, // bin_Latn_NG - 0xA521494E44657661llu, // bjj_Deva_IN - 0xB52149444C61746Ellu, // bjn_Latn_ID - 0xB141434D4C61746Ellu, // bkm_Latn_CM - 0xD14150484C61746Ellu, // bku_Latn_PH - 0xCD61564E54617674llu, // blt_Tavt_VN - 0x626D4D4C4C61746Ellu, // bm_Latn_ML - 0xC1814D4C4C61746Ellu, // bmq_Latn_ML - 0x626E424442656E67llu, // bn_Beng_BD - 0x626F434E54696274llu, // bo_Tibt_CN - 0xE1E1494E42656E67llu, // bpy_Beng_IN - 0xA201495241726162llu, // bqi_Arab_IR - 0xD60143494C61746Ellu, // bqv_Latn_CI - 0x627246524C61746Ellu, // br_Latn_FR - 0x8221494E44657661llu, // bra_Deva_IN - 0x9E21504B41726162llu, // brh_Arab_PK - 0xDE21494E44657661llu, // brx_Deva_IN - 0x627342414C61746Ellu, // bs_Latn_BA - 0xC2414C5242617373llu, // bsq_Bass_LR - 0xCA41434D4C61746Ellu, // bss_Latn_CM - 0xBA6150484C61746Ellu, // bto_Latn_PH - 0xD661504B44657661llu, // btv_Deva_PK - 0x828152554379726Cllu, // bua_Cyrl_RU - 0x8A8159544C61746Ellu, // buc_Latn_YT - 0x9A8149444C61746Ellu, // bug_Latn_ID - 0xB281434D4C61746Ellu, // bum_Latn_CM - 0x86A147514C61746Ellu, // bvb_Latn_GQ - 0xB701455245746869llu, // byn_Ethi_ER - 0xD701434D4C61746Ellu, // byv_Latn_CM - 0x93214D4C4C61746Ellu, // bze_Latn_ML - 0x636145534C61746Ellu, // ca_Latn_ES - 0x9C424E474C61746Ellu, // cch_Latn_NG - 0xBC42494E42656E67llu, // ccp_Beng_IN - 0xBC42424443616B6Dllu, // ccp_Cakm_BD - 0x636552554379726Cllu, // ce_Cyrl_RU - 0x848250484C61746Ellu, // ceb_Latn_PH - 0x98C255474C61746Ellu, // cgg_Latn_UG - 0x636847554C61746Ellu, // ch_Latn_GU - 0xA8E2464D4C61746Ellu, // chk_Latn_FM - 0xB0E252554379726Cllu, // chm_Cyrl_RU - 0xB8E255534C61746Ellu, // cho_Latn_US - 0xBCE243414C61746Ellu, // chp_Latn_CA - 0xC4E2555343686572llu, // chr_Cher_US - 0x81224B4841726162llu, // cja_Arab_KH - 0xB122564E4368616Dllu, // cjm_Cham_VN - 0x8542495141726162llu, // ckb_Arab_IQ - 0x636F46524C61746Ellu, // co_Latn_FR - 0xBDC24547436F7074llu, // cop_Copt_EG - 0xC9E250484C61746Ellu, // cps_Latn_PH - 0x6372434143616E73llu, // cr_Cans_CA - 0xA622434143616E73llu, // crj_Cans_CA - 0xAA22434143616E73llu, // crk_Cans_CA - 0xAE22434143616E73llu, // crl_Cans_CA - 0xB222434143616E73llu, // crm_Cans_CA - 0xCA2253434C61746Ellu, // crs_Latn_SC - 0x6373435A4C61746Ellu, // cs_Latn_CZ - 0x8642504C4C61746Ellu, // csb_Latn_PL - 0xDA42434143616E73llu, // csw_Cans_CA - 0x8E624D4D50617563llu, // ctd_Pauc_MM - 0x637552554379726Cllu, // cu_Cyrl_RU - 0x63754247476C6167llu, // cu_Glag_BG - 0x637652554379726Cllu, // cv_Cyrl_RU - 0x637947424C61746Ellu, // cy_Latn_GB - 0x6461444B4C61746Ellu, // da_Latn_DK - 0xA80355534C61746Ellu, // dak_Latn_US - 0xC40352554379726Cllu, // dar_Cyrl_RU - 0xD4034B454C61746Ellu, // dav_Latn_KE - 0x8843494E41726162llu, // dcc_Arab_IN - 0x646544454C61746Ellu, // de_Latn_DE - 0xB48343414C61746Ellu, // den_Latn_CA - 0xC4C343414C61746Ellu, // dgr_Latn_CA - 0x91234E454C61746Ellu, // dje_Latn_NE - 0xA5A343494C61746Ellu, // dnj_Latn_CI - 0xA1C3494E41726162llu, // doi_Arab_IN - 0x864344454C61746Ellu, // dsb_Latn_DE - 0xB2634D4C4C61746Ellu, // dtm_Latn_ML - 0xBE634D594C61746Ellu, // dtp_Latn_MY - 0xE2634E5044657661llu, // dty_Deva_NP - 0x8283434D4C61746Ellu, // dua_Latn_CM - 0x64764D5654686161llu, // dv_Thaa_MV - 0xBB03534E4C61746Ellu, // dyo_Latn_SN - 0xD30342464C61746Ellu, // dyu_Latn_BF - 0x647A425454696274llu, // dz_Tibt_BT - 0xD0244B454C61746Ellu, // ebu_Latn_KE - 0x656547484C61746Ellu, // ee_Latn_GH - 0xA0A44E474C61746Ellu, // efi_Latn_NG - 0xACC449544C61746Ellu, // egl_Latn_IT - 0xE0C4454745677970llu, // egy_Egyp_EG - 0xE1444D4D4B616C69llu, // eky_Kali_MM - 0x656C47524772656Bllu, // el_Grek_GR - 0x656E47424C61746Ellu, // en_Latn_GB - 0x656E55534C61746Ellu, // en_Latn_US - 0x656E474253686177llu, // en_Shaw_GB - 0x657345534C61746Ellu, // es_Latn_ES - 0x65734D584C61746Ellu, // es_Latn_MX - 0x657355534C61746Ellu, // es_Latn_US - 0xD24455534C61746Ellu, // esu_Latn_US - 0x657445454C61746Ellu, // et_Latn_EE - 0xCE6449544974616Cllu, // ett_Ital_IT - 0x657545534C61746Ellu, // eu_Latn_ES - 0xBAC4434D4C61746Ellu, // ewo_Latn_CM - 0xCEE445534C61746Ellu, // ext_Latn_ES - 0x6661495241726162llu, // fa_Arab_IR - 0xB40547514C61746Ellu, // fan_Latn_GQ - 0x6666474E41646C6Dllu, // ff_Adlm_GN - 0x6666534E4C61746Ellu, // ff_Latn_SN - 0xB0A54D4C4C61746Ellu, // ffm_Latn_ML - 0x666946494C61746Ellu, // fi_Latn_FI - 0x8105534441726162llu, // fia_Arab_SD - 0xAD0550484C61746Ellu, // fil_Latn_PH - 0xCD0553454C61746Ellu, // fit_Latn_SE - 0x666A464A4C61746Ellu, // fj_Latn_FJ - 0x666F464F4C61746Ellu, // fo_Latn_FO - 0xB5C5424A4C61746Ellu, // fon_Latn_BJ - 0x667246524C61746Ellu, // fr_Latn_FR - 0x8A2555534C61746Ellu, // frc_Latn_US - 0xBE2546524C61746Ellu, // frp_Latn_FR - 0xC62544454C61746Ellu, // frr_Latn_DE - 0xCA2544454C61746Ellu, // frs_Latn_DE - 0x8685434D41726162llu, // fub_Arab_CM - 0x8E8557464C61746Ellu, // fud_Latn_WF - 0x9685474E4C61746Ellu, // fuf_Latn_GN - 0xC2854E454C61746Ellu, // fuq_Latn_NE - 0xC68549544C61746Ellu, // fur_Latn_IT - 0xD6854E474C61746Ellu, // fuv_Latn_NG - 0xC6A553444C61746Ellu, // fvr_Latn_SD - 0x66794E4C4C61746Ellu, // fy_Latn_NL - 0x676149454C61746Ellu, // ga_Latn_IE - 0x800647484C61746Ellu, // gaa_Latn_GH - 0x98064D444C61746Ellu, // gag_Latn_MD - 0xB406434E48616E73llu, // gan_Hans_CN - 0xE00649444C61746Ellu, // gay_Latn_ID - 0xB026494E44657661llu, // gbm_Deva_IN - 0xE426495241726162llu, // gbz_Arab_IR - 0xC44647464C61746Ellu, // gcr_Latn_GF - 0x676447424C61746Ellu, // gd_Latn_GB - 0xE486455445746869llu, // gez_Ethi_ET - 0xB4C64E5044657661llu, // ggn_Deva_NP - 0xAD064B494C61746Ellu, // gil_Latn_KI - 0xA926504B41726162llu, // gjk_Arab_PK - 0xD126504B41726162llu, // gju_Arab_PK - 0x676C45534C61746Ellu, // gl_Latn_ES - 0xA966495241726162llu, // glk_Arab_IR - 0x676E50594C61746Ellu, // gn_Latn_PY - 0xB1C6494E44657661llu, // gom_Deva_IN - 0xB5C6494E54656C75llu, // gon_Telu_IN - 0xC5C649444C61746Ellu, // gor_Latn_ID - 0xC9C64E4C4C61746Ellu, // gos_Latn_NL - 0xCDC65541476F7468llu, // got_Goth_UA - 0x8A26435943707274llu, // grc_Cprt_CY - 0x8A2647524C696E62llu, // grc_Linb_GR - 0xCE26494E42656E67llu, // grt_Beng_IN - 0xDA4643484C61746Ellu, // gsw_Latn_CH - 0x6775494E47756A72llu, // gu_Gujr_IN - 0x868642524C61746Ellu, // gub_Latn_BR - 0x8A86434F4C61746Ellu, // guc_Latn_CO - 0xC68647484C61746Ellu, // gur_Latn_GH - 0xE6864B454C61746Ellu, // guz_Latn_KE - 0x6776494D4C61746Ellu, // gv_Latn_IM - 0xC6A64E5044657661llu, // gvr_Deva_NP - 0xA2C643414C61746Ellu, // gwi_Latn_CA - 0x68614E474C61746Ellu, // ha_Latn_NG - 0xA807434E48616E73llu, // hak_Hans_CN - 0xD80755534C61746Ellu, // haw_Latn_US - 0xE407414641726162llu, // haz_Arab_AF - 0x6865494C48656272llu, // he_Hebr_IL - 0x6869494E44657661llu, // hi_Deva_IN - 0x9507464A4C61746Ellu, // hif_Latn_FJ - 0xAD0750484C61746Ellu, // hil_Latn_PH - 0xD1675452486C7577llu, // hlu_Hluw_TR - 0x8D87434E506C7264llu, // hmd_Plrd_CN - 0x8DA7504B41726162llu, // hnd_Arab_PK - 0x91A7494E44657661llu, // hne_Deva_IN - 0xA5A74C41486D6E67llu, // hnj_Hmng_LA - 0xB5A750484C61746Ellu, // hnn_Latn_PH - 0xB9A7504B41726162llu, // hno_Arab_PK - 0x686F50474C61746Ellu, // ho_Latn_PG - 0x89C7494E44657661llu, // hoc_Deva_IN - 0xA5C7494E44657661llu, // hoj_Deva_IN - 0x687248524C61746Ellu, // hr_Latn_HR - 0x864744454C61746Ellu, // hsb_Latn_DE - 0xB647434E48616E73llu, // hsn_Hans_CN - 0x687448544C61746Ellu, // ht_Latn_HT - 0x687548554C61746Ellu, // hu_Latn_HU - 0x6879414D41726D6Ellu, // hy_Armn_AM - 0x687A4E414C61746Ellu, // hz_Latn_NA - 0x696146524C61746Ellu, // ia_Latn_FR - 0x80284D594C61746Ellu, // iba_Latn_MY - 0x84284E474C61746Ellu, // ibb_Latn_NG - 0x696449444C61746Ellu, // id_Latn_ID - 0x69674E474C61746Ellu, // ig_Latn_NG - 0x6969434E59696969llu, // ii_Yiii_CN - 0x696B55534C61746Ellu, // ik_Latn_US - 0xCD4843414C61746Ellu, // ikt_Latn_CA - 0xB96850484C61746Ellu, // ilo_Latn_PH - 0x696E49444C61746Ellu, // in_Latn_ID - 0x9DA852554379726Cllu, // inh_Cyrl_RU - 0x697349534C61746Ellu, // is_Latn_IS - 0x697449544C61746Ellu, // it_Latn_IT - 0x6975434143616E73llu, // iu_Cans_CA - 0x6977494C48656272llu, // iw_Hebr_IL - 0x9F2852554C61746Ellu, // izh_Latn_RU - 0x6A614A504A70616Ellu, // ja_Jpan_JP - 0xB0094A4D4C61746Ellu, // jam_Latn_JM - 0xB8C9434D4C61746Ellu, // jgo_Latn_CM - 0x8989545A4C61746Ellu, // jmc_Latn_TZ - 0xAD894E5044657661llu, // jml_Deva_NP - 0xCE89444B4C61746Ellu, // jut_Latn_DK - 0x6A7649444C61746Ellu, // jv_Latn_ID - 0x6A7749444C61746Ellu, // jw_Latn_ID - 0x6B61474547656F72llu, // ka_Geor_GE - 0x800A555A4379726Cllu, // kaa_Cyrl_UZ - 0x840A445A4C61746Ellu, // kab_Latn_DZ - 0x880A4D4D4C61746Ellu, // kac_Latn_MM - 0xA40A4E474C61746Ellu, // kaj_Latn_NG - 0xB00A4B454C61746Ellu, // kam_Latn_KE - 0xB80A4D4C4C61746Ellu, // kao_Latn_ML - 0x8C2A52554379726Cllu, // kbd_Cyrl_RU - 0xE02A4E4541726162llu, // kby_Arab_NE - 0x984A4E474C61746Ellu, // kcg_Latn_NG - 0xA84A5A574C61746Ellu, // kck_Latn_ZW - 0x906A545A4C61746Ellu, // kde_Latn_TZ - 0x9C6A544741726162llu, // kdh_Arab_TG - 0xCC6A544854686169llu, // kdt_Thai_TH - 0x808A43564C61746Ellu, // kea_Latn_CV - 0xB48A434D4C61746Ellu, // ken_Latn_CM - 0xB8AA43494C61746Ellu, // kfo_Latn_CI - 0xC4AA494E44657661llu, // kfr_Deva_IN - 0xE0AA494E44657661llu, // kfy_Deva_IN - 0x6B6743444C61746Ellu, // kg_Latn_CD - 0x90CA49444C61746Ellu, // kge_Latn_ID - 0xBCCA42524C61746Ellu, // kgp_Latn_BR - 0x80EA494E4C61746Ellu, // kha_Latn_IN - 0x84EA434E54616C75llu, // khb_Talu_CN - 0xB4EA494E44657661llu, // khn_Deva_IN - 0xC0EA4D4C4C61746Ellu, // khq_Latn_ML - 0xCCEA494E4D796D72llu, // kht_Mymr_IN - 0xD8EA504B41726162llu, // khw_Arab_PK - 0x6B694B454C61746Ellu, // ki_Latn_KE - 0xD10A54524C61746Ellu, // kiu_Latn_TR - 0x6B6A4E414C61746Ellu, // kj_Latn_NA - 0x992A4C414C616F6Fllu, // kjg_Laoo_LA - 0x6B6B434E41726162llu, // kk_Arab_CN - 0x6B6B4B5A4379726Cllu, // kk_Cyrl_KZ - 0xA54A434D4C61746Ellu, // kkj_Latn_CM - 0x6B6C474C4C61746Ellu, // kl_Latn_GL - 0xB56A4B454C61746Ellu, // kln_Latn_KE - 0x6B6D4B484B686D72llu, // km_Khmr_KH - 0x858A414F4C61746Ellu, // kmb_Latn_AO - 0x6B6E494E4B6E6461llu, // kn_Knda_IN - 0x6B6F4B524B6F7265llu, // ko_Kore_KR - 0xA1CA52554379726Cllu, // koi_Cyrl_RU - 0xA9CA494E44657661llu, // kok_Deva_IN - 0xC9CA464D4C61746Ellu, // kos_Latn_FM - 0x91EA4C524C61746Ellu, // kpe_Latn_LR - 0x8A2A52554379726Cllu, // krc_Cyrl_RU - 0xA22A534C4C61746Ellu, // kri_Latn_SL - 0xA62A50484C61746Ellu, // krj_Latn_PH - 0xAE2A52554C61746Ellu, // krl_Latn_RU - 0xD22A494E44657661llu, // kru_Deva_IN - 0x6B73494E41726162llu, // ks_Arab_IN - 0x864A545A4C61746Ellu, // ksb_Latn_TZ - 0x964A434D4C61746Ellu, // ksf_Latn_CM - 0x9E4A44454C61746Ellu, // ksh_Latn_DE - 0x6B75495141726162llu, // ku_Arab_IQ - 0x6B7554524C61746Ellu, // ku_Latn_TR - 0xB28A52554379726Cllu, // kum_Cyrl_RU - 0x6B7652554379726Cllu, // kv_Cyrl_RU - 0xC6AA49444C61746Ellu, // kvr_Latn_ID - 0xDEAA504B41726162llu, // kvx_Arab_PK - 0x6B7747424C61746Ellu, // kw_Latn_GB - 0xB2EA544854686169llu, // kxm_Thai_TH - 0xBEEA504B41726162llu, // kxp_Arab_PK - 0x6B79434E41726162llu, // ky_Arab_CN - 0x6B794B474379726Cllu, // ky_Cyrl_KG - 0x6B7954524C61746Ellu, // ky_Latn_TR - 0x6C6156414C61746Ellu, // la_Latn_VA - 0x840B47524C696E61llu, // lab_Lina_GR - 0x8C0B494C48656272llu, // lad_Hebr_IL - 0x980B545A4C61746Ellu, // lag_Latn_TZ - 0x9C0B504B41726162llu, // lah_Arab_PK - 0xA40B55474C61746Ellu, // laj_Latn_UG - 0x6C624C554C61746Ellu, // lb_Latn_LU - 0x902B52554379726Cllu, // lbe_Cyrl_RU - 0xD82B49444C61746Ellu, // lbw_Latn_ID - 0xBC4B434E54686169llu, // lcp_Thai_CN - 0xBC8B494E4C657063llu, // lep_Lepc_IN - 0xE48B52554379726Cllu, // lez_Cyrl_RU - 0x6C6755474C61746Ellu, // lg_Latn_UG - 0x6C694E4C4C61746Ellu, // li_Latn_NL - 0x950B4E5044657661llu, // lif_Deva_NP - 0x950B494E4C696D62llu, // lif_Limb_IN - 0xA50B49544C61746Ellu, // lij_Latn_IT - 0xC90B434E4C697375llu, // lis_Lisu_CN - 0xBD2B49444C61746Ellu, // ljp_Latn_ID - 0xA14B495241726162llu, // lki_Arab_IR - 0xCD4B55534C61746Ellu, // lkt_Latn_US - 0xB58B494E54656C75llu, // lmn_Telu_IN - 0xB98B49544C61746Ellu, // lmo_Latn_IT - 0x6C6E43444C61746Ellu, // ln_Latn_CD - 0x6C6F4C414C616F6Fllu, // lo_Laoo_LA - 0xADCB43444C61746Ellu, // lol_Latn_CD - 0xE5CB5A4D4C61746Ellu, // loz_Latn_ZM - 0x8A2B495241726162llu, // lrc_Arab_IR - 0x6C744C544C61746Ellu, // lt_Latn_LT - 0x9A6B4C564C61746Ellu, // ltg_Latn_LV - 0x6C7543444C61746Ellu, // lu_Latn_CD - 0x828B43444C61746Ellu, // lua_Latn_CD - 0xBA8B4B454C61746Ellu, // luo_Latn_KE - 0xE28B4B454C61746Ellu, // luy_Latn_KE - 0xE68B495241726162llu, // luz_Arab_IR - 0x6C764C564C61746Ellu, // lv_Latn_LV - 0xAECB544854686169llu, // lwl_Thai_TH - 0x9F2B434E48616E73llu, // lzh_Hans_CN - 0xE72B54524C61746Ellu, // lzz_Latn_TR - 0x8C0C49444C61746Ellu, // mad_Latn_ID - 0x940C434D4C61746Ellu, // maf_Latn_CM - 0x980C494E44657661llu, // mag_Deva_IN - 0xA00C494E44657661llu, // mai_Deva_IN - 0xA80C49444C61746Ellu, // mak_Latn_ID - 0xB40C474D4C61746Ellu, // man_Latn_GM - 0xB40C474E4E6B6F6Fllu, // man_Nkoo_GN - 0xC80C4B454C61746Ellu, // mas_Latn_KE - 0xE40C4D584C61746Ellu, // maz_Latn_MX - 0x946C52554379726Cllu, // mdf_Cyrl_RU - 0x9C6C50484C61746Ellu, // mdh_Latn_PH - 0xC46C49444C61746Ellu, // mdr_Latn_ID - 0xB48C534C4C61746Ellu, // men_Latn_SL - 0xC48C4B454C61746Ellu, // mer_Latn_KE - 0x80AC544841726162llu, // mfa_Arab_TH - 0x90AC4D554C61746Ellu, // mfe_Latn_MU - 0x6D674D474C61746Ellu, // mg_Latn_MG - 0x9CCC4D5A4C61746Ellu, // mgh_Latn_MZ - 0xB8CC434D4C61746Ellu, // mgo_Latn_CM - 0xBCCC4E5044657661llu, // mgp_Deva_NP - 0xE0CC545A4C61746Ellu, // mgy_Latn_TZ - 0x6D684D484C61746Ellu, // mh_Latn_MH - 0x6D694E5A4C61746Ellu, // mi_Latn_NZ - 0xB50C49444C61746Ellu, // min_Latn_ID - 0xC90C495148617472llu, // mis_Hatr_IQ - 0x6D6B4D4B4379726Cllu, // mk_Cyrl_MK - 0x6D6C494E4D6C796Dllu, // ml_Mlym_IN - 0xC96C53444C61746Ellu, // mls_Latn_SD - 0x6D6E4D4E4379726Cllu, // mn_Cyrl_MN - 0x6D6E434E4D6F6E67llu, // mn_Mong_CN - 0xA1AC494E42656E67llu, // mni_Beng_IN - 0xD9AC4D4D4D796D72llu, // mnw_Mymr_MM - 0x91CC43414C61746Ellu, // moe_Latn_CA - 0x9DCC43414C61746Ellu, // moh_Latn_CA - 0xC9CC42464C61746Ellu, // mos_Latn_BF - 0x6D72494E44657661llu, // mr_Deva_IN - 0x8E2C4E5044657661llu, // mrd_Deva_NP - 0xA62C52554379726Cllu, // mrj_Cyrl_RU - 0xBA2C42444D726F6Fllu, // mro_Mroo_BD - 0x6D734D594C61746Ellu, // ms_Latn_MY - 0x6D744D544C61746Ellu, // mt_Latn_MT - 0xC66C494E44657661llu, // mtr_Deva_IN - 0x828C434D4C61746Ellu, // mua_Latn_CM - 0xCA8C55534C61746Ellu, // mus_Latn_US - 0xE2AC504B41726162llu, // mvy_Arab_PK - 0xAACC4D4C4C61746Ellu, // mwk_Latn_ML - 0xC6CC494E44657661llu, // mwr_Deva_IN - 0xD6CC49444C61746Ellu, // mwv_Latn_ID - 0x8AEC5A574C61746Ellu, // mxc_Latn_ZW - 0x6D794D4D4D796D72llu, // my_Mymr_MM - 0xD70C52554379726Cllu, // myv_Cyrl_RU - 0xDF0C55474C61746Ellu, // myx_Latn_UG - 0xE70C49524D616E64llu, // myz_Mand_IR - 0xB72C495241726162llu, // mzn_Arab_IR - 0x6E614E524C61746Ellu, // na_Latn_NR - 0xB40D434E48616E73llu, // nan_Hans_CN - 0xBC0D49544C61746Ellu, // nap_Latn_IT - 0xC00D4E414C61746Ellu, // naq_Latn_NA - 0x6E624E4F4C61746Ellu, // nb_Latn_NO - 0x9C4D4D584C61746Ellu, // nch_Latn_MX - 0x6E645A574C61746Ellu, // nd_Latn_ZW - 0x886D4D5A4C61746Ellu, // ndc_Latn_MZ - 0xC86D44454C61746Ellu, // nds_Latn_DE - 0x6E654E5044657661llu, // ne_Deva_NP - 0xD88D4E5044657661llu, // new_Deva_NP - 0x6E674E414C61746Ellu, // ng_Latn_NA - 0xACCD4D5A4C61746Ellu, // ngl_Latn_MZ - 0x90ED4D584C61746Ellu, // nhe_Latn_MX - 0xD8ED4D584C61746Ellu, // nhw_Latn_MX - 0xA50D49444C61746Ellu, // nij_Latn_ID - 0xD10D4E554C61746Ellu, // niu_Latn_NU - 0xB92D494E4C61746Ellu, // njo_Latn_IN - 0x6E6C4E4C4C61746Ellu, // nl_Latn_NL - 0x998D434D4C61746Ellu, // nmg_Latn_CM - 0x6E6E4E4F4C61746Ellu, // nn_Latn_NO - 0x9DAD434D4C61746Ellu, // nnh_Latn_CM - 0x6E6F4E4F4C61746Ellu, // no_Latn_NO - 0x8DCD54484C616E61llu, // nod_Lana_TH - 0x91CD494E44657661llu, // noe_Deva_IN - 0xB5CD534552756E72llu, // non_Runr_SE - 0xBA0D474E4E6B6F6Fllu, // nqo_Nkoo_GN - 0x6E725A414C61746Ellu, // nr_Latn_ZA - 0xAA4D434143616E73llu, // nsk_Cans_CA - 0xBA4D5A414C61746Ellu, // nso_Latn_ZA - 0xCA8D53534C61746Ellu, // nus_Latn_SS - 0x6E7655534C61746Ellu, // nv_Latn_US - 0xC2ED434E4C61746Ellu, // nxq_Latn_CN - 0x6E794D574C61746Ellu, // ny_Latn_MW - 0xB30D545A4C61746Ellu, // nym_Latn_TZ - 0xB70D55474C61746Ellu, // nyn_Latn_UG - 0xA32D47484C61746Ellu, // nzi_Latn_GH - 0x6F6346524C61746Ellu, // oc_Latn_FR - 0x6F6D45544C61746Ellu, // om_Latn_ET - 0x6F72494E4F727961llu, // or_Orya_IN - 0x6F7347454379726Cllu, // os_Cyrl_GE - 0x824E55534F736765llu, // osa_Osge_US - 0xAA6E4D4E4F726B68llu, // otk_Orkh_MN - 0x7061504B41726162llu, // pa_Arab_PK - 0x7061494E47757275llu, // pa_Guru_IN - 0x980F50484C61746Ellu, // pag_Latn_PH - 0xAC0F495250686C69llu, // pal_Phli_IR - 0xAC0F434E50686C70llu, // pal_Phlp_CN - 0xB00F50484C61746Ellu, // pam_Latn_PH - 0xBC0F41574C61746Ellu, // pap_Latn_AW - 0xD00F50574C61746Ellu, // pau_Latn_PW - 0x8C4F46524C61746Ellu, // pcd_Latn_FR - 0xB04F4E474C61746Ellu, // pcm_Latn_NG - 0x886F55534C61746Ellu, // pdc_Latn_US - 0xCC6F43414C61746Ellu, // pdt_Latn_CA - 0xB88F49525870656Fllu, // peo_Xpeo_IR - 0xACAF44454C61746Ellu, // pfl_Latn_DE - 0xB4EF4C4250686E78llu, // phn_Phnx_LB - 0x814F494E42726168llu, // pka_Brah_IN - 0xB94F4B454C61746Ellu, // pko_Latn_KE - 0x706C504C4C61746Ellu, // pl_Latn_PL - 0xC98F49544C61746Ellu, // pms_Latn_IT - 0xCDAF47524772656Bllu, // pnt_Grek_GR - 0xB5CF464D4C61746Ellu, // pon_Latn_FM - 0x822F504B4B686172llu, // pra_Khar_PK - 0x8E2F495241726162llu, // prd_Arab_IR - 0x7073414641726162llu, // ps_Arab_AF - 0x707442524C61746Ellu, // pt_Latn_BR - 0xD28F47414C61746Ellu, // puu_Latn_GA - 0x717550454C61746Ellu, // qu_Latn_PE - 0x8A9047544C61746Ellu, // quc_Latn_GT - 0x9A9045434C61746Ellu, // qug_Latn_EC - 0xA411494E44657661llu, // raj_Deva_IN - 0x945152454C61746Ellu, // rcf_Latn_RE - 0xA49149444C61746Ellu, // rej_Latn_ID - 0xB4D149544C61746Ellu, // rgn_Latn_IT - 0x8111494E4C61746Ellu, // ria_Latn_IN - 0x95114D4154666E67llu, // rif_Tfng_MA - 0xC9314E5044657661llu, // rjs_Deva_NP - 0xCD51424442656E67llu, // rkt_Beng_BD - 0x726D43484C61746Ellu, // rm_Latn_CH - 0x959146494C61746Ellu, // rmf_Latn_FI - 0xB99143484C61746Ellu, // rmo_Latn_CH - 0xCD91495241726162llu, // rmt_Arab_IR - 0xD19153454C61746Ellu, // rmu_Latn_SE - 0x726E42494C61746Ellu, // rn_Latn_BI - 0x99B14D5A4C61746Ellu, // rng_Latn_MZ - 0x726F524F4C61746Ellu, // ro_Latn_RO - 0x85D149444C61746Ellu, // rob_Latn_ID - 0x95D1545A4C61746Ellu, // rof_Latn_TZ - 0xB271464A4C61746Ellu, // rtm_Latn_FJ - 0x727552554379726Cllu, // ru_Cyrl_RU - 0x929155414379726Cllu, // rue_Cyrl_UA - 0x9A9153424C61746Ellu, // rug_Latn_SB - 0x727752574C61746Ellu, // rw_Latn_RW - 0xAAD1545A4C61746Ellu, // rwk_Latn_TZ - 0xD3114A504B616E61llu, // ryu_Kana_JP - 0x7361494E44657661llu, // sa_Deva_IN - 0x941247484C61746Ellu, // saf_Latn_GH - 0x9C1252554379726Cllu, // sah_Cyrl_RU - 0xC0124B454C61746Ellu, // saq_Latn_KE - 0xC81249444C61746Ellu, // sas_Latn_ID - 0xCC12494E4C61746Ellu, // sat_Latn_IN - 0xE412494E53617572llu, // saz_Saur_IN - 0xBC32545A4C61746Ellu, // sbp_Latn_TZ - 0x736349544C61746Ellu, // sc_Latn_IT - 0xA852494E44657661llu, // sck_Deva_IN - 0xB45249544C61746Ellu, // scn_Latn_IT - 0xB85247424C61746Ellu, // sco_Latn_GB - 0xC85243414C61746Ellu, // scs_Latn_CA - 0x7364504B41726162llu, // sd_Arab_PK - 0x7364494E44657661llu, // sd_Deva_IN - 0x7364494E4B686F6Allu, // sd_Khoj_IN - 0x7364494E53696E64llu, // sd_Sind_IN - 0x887249544C61746Ellu, // sdc_Latn_IT - 0x9C72495241726162llu, // sdh_Arab_IR - 0x73654E4F4C61746Ellu, // se_Latn_NO - 0x949243494C61746Ellu, // sef_Latn_CI - 0x9C924D5A4C61746Ellu, // seh_Latn_MZ - 0xA0924D584C61746Ellu, // sei_Latn_MX - 0xC8924D4C4C61746Ellu, // ses_Latn_ML - 0x736743464C61746Ellu, // sg_Latn_CF - 0x80D249454F67616Dllu, // sga_Ogam_IE - 0xC8D24C544C61746Ellu, // sgs_Latn_LT - 0xA0F24D4154666E67llu, // shi_Tfng_MA - 0xB4F24D4D4D796D72llu, // shn_Mymr_MM - 0x73694C4B53696E68llu, // si_Sinh_LK - 0x8D1245544C61746Ellu, // sid_Latn_ET - 0x736B534B4C61746Ellu, // sk_Latn_SK - 0xC552504B41726162llu, // skr_Arab_PK - 0x736C53494C61746Ellu, // sl_Latn_SI - 0xA172504C4C61746Ellu, // sli_Latn_PL - 0xE17249444C61746Ellu, // sly_Latn_ID - 0x736D57534C61746Ellu, // sm_Latn_WS - 0x819253454C61746Ellu, // sma_Latn_SE - 0xA59253454C61746Ellu, // smj_Latn_SE - 0xB59246494C61746Ellu, // smn_Latn_FI - 0xBD92494C53616D72llu, // smp_Samr_IL - 0xC99246494C61746Ellu, // sms_Latn_FI - 0x736E5A574C61746Ellu, // sn_Latn_ZW - 0xA9B24D4C4C61746Ellu, // snk_Latn_ML - 0x736F534F4C61746Ellu, // so_Latn_SO - 0xD1D2544854686169llu, // sou_Thai_TH - 0x7371414C4C61746Ellu, // sq_Latn_AL - 0x737252534379726Cllu, // sr_Cyrl_RS - 0x737252534C61746Ellu, // sr_Latn_RS - 0x8632494E536F7261llu, // srb_Sora_IN - 0xB63253524C61746Ellu, // srn_Latn_SR - 0xC632534E4C61746Ellu, // srr_Latn_SN - 0xDE32494E44657661llu, // srx_Deva_IN - 0x73735A414C61746Ellu, // ss_Latn_ZA - 0xE25245524C61746Ellu, // ssy_Latn_ER - 0x73745A414C61746Ellu, // st_Latn_ZA - 0xC27244454C61746Ellu, // stq_Latn_DE - 0x737549444C61746Ellu, // su_Latn_ID - 0xAA92545A4C61746Ellu, // suk_Latn_TZ - 0xCA92474E4C61746Ellu, // sus_Latn_GN - 0x737653454C61746Ellu, // sv_Latn_SE - 0x7377545A4C61746Ellu, // sw_Latn_TZ - 0x86D2595441726162llu, // swb_Arab_YT - 0x8AD243444C61746Ellu, // swc_Latn_CD - 0x9AD244454C61746Ellu, // swg_Latn_DE - 0xD6D2494E44657661llu, // swv_Deva_IN - 0xB6F249444C61746Ellu, // sxn_Latn_ID - 0xAF12424442656E67llu, // syl_Beng_BD - 0xC712495153797263llu, // syr_Syrc_IQ - 0xAF32504C4C61746Ellu, // szl_Latn_PL - 0x7461494E54616D6Cllu, // ta_Taml_IN - 0xA4134E5044657661llu, // taj_Deva_NP - 0xD83350484C61746Ellu, // tbw_Latn_PH - 0xE053494E4B6E6461llu, // tcy_Knda_IN - 0x8C73434E54616C65llu, // tdd_Tale_CN - 0x98734E5044657661llu, // tdg_Deva_NP - 0x9C734E5044657661llu, // tdh_Deva_NP - 0x7465494E54656C75llu, // te_Telu_IN - 0xB093534C4C61746Ellu, // tem_Latn_SL - 0xB89355474C61746Ellu, // teo_Latn_UG - 0xCC93544C4C61746Ellu, // tet_Latn_TL - 0x7467504B41726162llu, // tg_Arab_PK - 0x7467544A4379726Cllu, // tg_Cyrl_TJ - 0x7468544854686169llu, // th_Thai_TH - 0xACF34E5044657661llu, // thl_Deva_NP - 0xC0F34E5044657661llu, // thq_Deva_NP - 0xC4F34E5044657661llu, // thr_Deva_NP - 0x7469455445746869llu, // ti_Ethi_ET - 0x9913455245746869llu, // tig_Ethi_ER - 0xD5134E474C61746Ellu, // tiv_Latn_NG - 0x746B544D4C61746Ellu, // tk_Latn_TM - 0xAD53544B4C61746Ellu, // tkl_Latn_TK - 0xC553415A4C61746Ellu, // tkr_Latn_AZ - 0xCD534E5044657661llu, // tkt_Deva_NP - 0x746C50484C61746Ellu, // tl_Latn_PH - 0xE173415A4C61746Ellu, // tly_Latn_AZ - 0x9D934E454C61746Ellu, // tmh_Latn_NE - 0x746E5A414C61746Ellu, // tn_Latn_ZA - 0x746F544F4C61746Ellu, // to_Latn_TO - 0x99D34D574C61746Ellu, // tog_Latn_MW - 0xA1F350474C61746Ellu, // tpi_Latn_PG - 0x747254524C61746Ellu, // tr_Latn_TR - 0xD23354524C61746Ellu, // tru_Latn_TR - 0xD63354574C61746Ellu, // trv_Latn_TW - 0x74735A414C61746Ellu, // ts_Latn_ZA - 0x8E5347524772656Bllu, // tsd_Grek_GR - 0x96534E5044657661llu, // tsf_Deva_NP - 0x9A5350484C61746Ellu, // tsg_Latn_PH - 0xA653425454696274llu, // tsj_Tibt_BT - 0x747452554379726Cllu, // tt_Cyrl_RU - 0xA67355474C61746Ellu, // ttj_Latn_UG - 0xCA73544854686169llu, // tts_Thai_TH - 0xCE73415A4C61746Ellu, // ttt_Latn_AZ - 0xB2934D574C61746Ellu, // tum_Latn_MW - 0xAEB354564C61746Ellu, // tvl_Latn_TV - 0xC2D34E454C61746Ellu, // twq_Latn_NE - 0x9AF3434E54616E67llu, // txg_Tang_CN - 0x747950464C61746Ellu, // ty_Latn_PF - 0xD71352554379726Cllu, // tyv_Cyrl_RU - 0xB3334D414C61746Ellu, // tzm_Latn_MA - 0xB07452554379726Cllu, // udm_Cyrl_RU - 0x7567434E41726162llu, // ug_Arab_CN - 0x75674B5A4379726Cllu, // ug_Cyrl_KZ - 0x80D4535955676172llu, // uga_Ugar_SY - 0x756B55414379726Cllu, // uk_Cyrl_UA - 0xA174464D4C61746Ellu, // uli_Latn_FM - 0x8594414F4C61746Ellu, // umb_Latn_AO - 0xC5B4494E42656E67llu, // unr_Beng_IN - 0xC5B44E5044657661llu, // unr_Deva_NP - 0xDDB4494E42656E67llu, // unx_Beng_IN - 0x7572504B41726162llu, // ur_Arab_PK - 0x757A414641726162llu, // uz_Arab_AF - 0x757A555A4C61746Ellu, // uz_Latn_UZ - 0xA0154C5256616969llu, // vai_Vaii_LR - 0x76655A414C61746Ellu, // ve_Latn_ZA - 0x889549544C61746Ellu, // vec_Latn_IT - 0xBC9552554C61746Ellu, // vep_Latn_RU - 0x7669564E4C61746Ellu, // vi_Latn_VN - 0x891553584C61746Ellu, // vic_Latn_SX - 0xC97542454C61746Ellu, // vls_Latn_BE - 0x959544454C61746Ellu, // vmf_Latn_DE - 0xD9954D5A4C61746Ellu, // vmw_Latn_MZ - 0xCDD552554C61746Ellu, // vot_Latn_RU - 0xBA3545454C61746Ellu, // vro_Latn_EE - 0xB695545A4C61746Ellu, // vun_Latn_TZ - 0x776142454C61746Ellu, // wa_Latn_BE - 0x901643484C61746Ellu, // wae_Latn_CH - 0xAC16455445746869llu, // wal_Ethi_ET - 0xC41650484C61746Ellu, // war_Latn_PH - 0xBC3641554C61746Ellu, // wbp_Latn_AU - 0xC036494E54656C75llu, // wbq_Telu_IN - 0xC436494E44657661llu, // wbr_Deva_IN - 0xC97657464C61746Ellu, // wls_Latn_WF - 0xA1B64B4D41726162llu, // wni_Arab_KM - 0x776F534E4C61746Ellu, // wo_Latn_SN - 0xB276494E44657661llu, // wtm_Deva_IN - 0xD296434E48616E73llu, // wuu_Hans_CN - 0xD41742524C61746Ellu, // xav_Latn_BR - 0xC457545243617269llu, // xcr_Cari_TR - 0x78685A414C61746Ellu, // xh_Latn_ZA - 0x897754524C796369llu, // xlc_Lyci_TR - 0x8D7754524C796469llu, // xld_Lydi_TR - 0x9597474547656F72llu, // xmf_Geor_GE - 0xB597434E4D616E69llu, // xmn_Mani_CN - 0xC59753444D657263llu, // xmr_Merc_SD - 0x81B753414E617262llu, // xna_Narb_SA - 0xC5B7494E44657661llu, // xnr_Deva_IN - 0x99D755474C61746Ellu, // xog_Latn_UG - 0xC5F7495250727469llu, // xpr_Prti_IR - 0x8257594553617262llu, // xsa_Sarb_YE - 0xC6574E5044657661llu, // xsr_Deva_NP - 0xB8184D5A4C61746Ellu, // yao_Latn_MZ - 0xBC18464D4C61746Ellu, // yap_Latn_FM - 0xD418434D4C61746Ellu, // yav_Latn_CM - 0x8438434D4C61746Ellu, // ybb_Latn_CM - 0x796F4E474C61746Ellu, // yo_Latn_NG - 0xAE3842524C61746Ellu, // yrl_Latn_BR - 0x82984D584C61746Ellu, // yua_Latn_MX - 0x9298434E48616E73llu, // yue_Hans_CN - 0x9298484B48616E74llu, // yue_Hant_HK - 0x7A61434E4C61746Ellu, // za_Latn_CN - 0x981953444C61746Ellu, // zag_Latn_SD - 0xA4794B4D41726162llu, // zdj_Arab_KM - 0x80994E4C4C61746Ellu, // zea_Latn_NL - 0x9CD94D4154666E67llu, // zgh_Tfng_MA - 0x7A685457426F706Fllu, // zh_Bopo_TW - 0x7A68545748616E62llu, // zh_Hanb_TW - 0x7A68434E48616E73llu, // zh_Hans_CN - 0x7A68545748616E74llu, // zh_Hant_TW - 0xB17954474C61746Ellu, // zlm_Latn_TG - 0xA1994D594C61746Ellu, // zmi_Latn_MY - 0x7A755A414C61746Ellu, // zu_Latn_ZA - 0x833954524C61746Ellu, // zza_Latn_TR + 0x616145544C61746ELLU, // aa_Latn_ET + 0x616247454379726CLLU, // ab_Cyrl_GE + 0xC42047484C61746ELLU, // abr_Latn_GH + 0x904049444C61746ELLU, // ace_Latn_ID + 0x9C4055474C61746ELLU, // ach_Latn_UG + 0x806047484C61746ELLU, // ada_Latn_GH + 0xE06052554379726CLLU, // ady_Cyrl_RU + 0x6165495241767374LLU, // ae_Avst_IR + 0x8480544E41726162LLU, // aeb_Arab_TN + 0x61665A414C61746ELLU, // af_Latn_ZA + 0xC0C0434D4C61746ELLU, // agq_Latn_CM + 0xB8E0494E41686F6DLLU, // aho_Ahom_IN + 0x616B47484C61746ELLU, // ak_Latn_GH + 0xA940495158737578LLU, // akk_Xsux_IQ + 0xB560584B4C61746ELLU, // aln_Latn_XK + 0xCD6052554379726CLLU, // alt_Cyrl_RU + 0x616D455445746869LLU, // am_Ethi_ET + 0xB9804E474C61746ELLU, // amo_Latn_NG + 0xE5C049444C61746ELLU, // aoz_Latn_ID + 0x8DE0544741726162LLU, // apd_Arab_TG + 0x6172454741726162LLU, // ar_Arab_EG + 0x8A20495241726D69LLU, // arc_Armi_IR + 0x8A204A4F4E626174LLU, // arc_Nbat_JO + 0x8A20535950616C6DLLU, // arc_Palm_SY + 0xB620434C4C61746ELLU, // arn_Latn_CL + 0xBA20424F4C61746ELLU, // aro_Latn_BO + 0xC220445A41726162LLU, // arq_Arab_DZ + 0xE2204D4141726162LLU, // ary_Arab_MA + 0xE620454741726162LLU, // arz_Arab_EG + 0x6173494E42656E67LLU, // as_Beng_IN + 0x8240545A4C61746ELLU, // asa_Latn_TZ + 0x9240555353676E77LLU, // ase_Sgnw_US + 0xCE4045534C61746ELLU, // ast_Latn_ES + 0xA66043414C61746ELLU, // atj_Latn_CA + 0x617652554379726CLLU, // av_Cyrl_RU + 0x82C0494E44657661LLU, // awa_Deva_IN + 0x6179424F4C61746ELLU, // ay_Latn_BO + 0x617A495241726162LLU, // az_Arab_IR + 0x617A415A4C61746ELLU, // az_Latn_AZ + 0x626152554379726CLLU, // ba_Cyrl_RU + 0xAC01504B41726162LLU, // bal_Arab_PK + 0xB40149444C61746ELLU, // ban_Latn_ID + 0xBC014E5044657661LLU, // bap_Deva_NP + 0xC40141544C61746ELLU, // bar_Latn_AT + 0xC801434D4C61746ELLU, // bas_Latn_CM + 0xDC01434D42616D75LLU, // bax_Bamu_CM + 0x882149444C61746ELLU, // bbc_Latn_ID + 0xA421434D4C61746ELLU, // bbj_Latn_CM + 0xA04143494C61746ELLU, // bci_Latn_CI + 0x626542594379726CLLU, // be_Cyrl_BY + 0xA481534441726162LLU, // bej_Arab_SD + 0xB0815A4D4C61746ELLU, // bem_Latn_ZM + 0xD88149444C61746ELLU, // bew_Latn_ID + 0xE481545A4C61746ELLU, // bez_Latn_TZ + 0x8CA1434D4C61746ELLU, // bfd_Latn_CM + 0xC0A1494E54616D6CLLU, // bfq_Taml_IN + 0xCCA1504B41726162LLU, // bft_Arab_PK + 0xE0A1494E44657661LLU, // bfy_Deva_IN + 0x626742474379726CLLU, // bg_Cyrl_BG + 0x88C1494E44657661LLU, // bgc_Deva_IN + 0xB4C1504B41726162LLU, // bgn_Arab_PK + 0xDCC154524772656BLLU, // bgx_Grek_TR + 0x84E1494E44657661LLU, // bhb_Deva_IN + 0xA0E1494E44657661LLU, // bhi_Deva_IN + 0xA8E150484C61746ELLU, // bhk_Latn_PH + 0xB8E1494E44657661LLU, // bho_Deva_IN + 0x626956554C61746ELLU, // bi_Latn_VU + 0xA90150484C61746ELLU, // bik_Latn_PH + 0xB5014E474C61746ELLU, // bin_Latn_NG + 0xA521494E44657661LLU, // bjj_Deva_IN + 0xB52149444C61746ELLU, // bjn_Latn_ID + 0xB141434D4C61746ELLU, // bkm_Latn_CM + 0xD14150484C61746ELLU, // bku_Latn_PH + 0xCD61564E54617674LLU, // blt_Tavt_VN + 0x626D4D4C4C61746ELLU, // bm_Latn_ML + 0xC1814D4C4C61746ELLU, // bmq_Latn_ML + 0x626E424442656E67LLU, // bn_Beng_BD + 0x626F434E54696274LLU, // bo_Tibt_CN + 0xE1E1494E42656E67LLU, // bpy_Beng_IN + 0xA201495241726162LLU, // bqi_Arab_IR + 0xD60143494C61746ELLU, // bqv_Latn_CI + 0x627246524C61746ELLU, // br_Latn_FR + 0x8221494E44657661LLU, // bra_Deva_IN + 0x9E21504B41726162LLU, // brh_Arab_PK + 0xDE21494E44657661LLU, // brx_Deva_IN + 0x627342414C61746ELLU, // bs_Latn_BA + 0xC2414C5242617373LLU, // bsq_Bass_LR + 0xCA41434D4C61746ELLU, // bss_Latn_CM + 0xBA6150484C61746ELLU, // bto_Latn_PH + 0xD661504B44657661LLU, // btv_Deva_PK + 0x828152554379726CLLU, // bua_Cyrl_RU + 0x8A8159544C61746ELLU, // buc_Latn_YT + 0x9A8149444C61746ELLU, // bug_Latn_ID + 0xB281434D4C61746ELLU, // bum_Latn_CM + 0x86A147514C61746ELLU, // bvb_Latn_GQ + 0xB701455245746869LLU, // byn_Ethi_ER + 0xD701434D4C61746ELLU, // byv_Latn_CM + 0x93214D4C4C61746ELLU, // bze_Latn_ML + 0x636145534C61746ELLU, // ca_Latn_ES + 0x9C424E474C61746ELLU, // cch_Latn_NG + 0xBC42494E42656E67LLU, // ccp_Beng_IN + 0xBC42424443616B6DLLU, // ccp_Cakm_BD + 0x636552554379726CLLU, // ce_Cyrl_RU + 0x848250484C61746ELLU, // ceb_Latn_PH + 0x98C255474C61746ELLU, // cgg_Latn_UG + 0x636847554C61746ELLU, // ch_Latn_GU + 0xA8E2464D4C61746ELLU, // chk_Latn_FM + 0xB0E252554379726CLLU, // chm_Cyrl_RU + 0xB8E255534C61746ELLU, // cho_Latn_US + 0xBCE243414C61746ELLU, // chp_Latn_CA + 0xC4E2555343686572LLU, // chr_Cher_US + 0x81224B4841726162LLU, // cja_Arab_KH + 0xB122564E4368616DLLU, // cjm_Cham_VN + 0x8542495141726162LLU, // ckb_Arab_IQ + 0x636F46524C61746ELLU, // co_Latn_FR + 0xBDC24547436F7074LLU, // cop_Copt_EG + 0xC9E250484C61746ELLU, // cps_Latn_PH + 0x6372434143616E73LLU, // cr_Cans_CA + 0xA622434143616E73LLU, // crj_Cans_CA + 0xAA22434143616E73LLU, // crk_Cans_CA + 0xAE22434143616E73LLU, // crl_Cans_CA + 0xB222434143616E73LLU, // crm_Cans_CA + 0xCA2253434C61746ELLU, // crs_Latn_SC + 0x6373435A4C61746ELLU, // cs_Latn_CZ + 0x8642504C4C61746ELLU, // csb_Latn_PL + 0xDA42434143616E73LLU, // csw_Cans_CA + 0x8E624D4D50617563LLU, // ctd_Pauc_MM + 0x637552554379726CLLU, // cu_Cyrl_RU + 0x63754247476C6167LLU, // cu_Glag_BG + 0x637652554379726CLLU, // cv_Cyrl_RU + 0x637947424C61746ELLU, // cy_Latn_GB + 0x6461444B4C61746ELLU, // da_Latn_DK + 0xA80355534C61746ELLU, // dak_Latn_US + 0xC40352554379726CLLU, // dar_Cyrl_RU + 0xD4034B454C61746ELLU, // dav_Latn_KE + 0x8843494E41726162LLU, // dcc_Arab_IN + 0x646544454C61746ELLU, // de_Latn_DE + 0xB48343414C61746ELLU, // den_Latn_CA + 0xC4C343414C61746ELLU, // dgr_Latn_CA + 0x91234E454C61746ELLU, // dje_Latn_NE + 0xA5A343494C61746ELLU, // dnj_Latn_CI + 0xA1C3494E41726162LLU, // doi_Arab_IN + 0x864344454C61746ELLU, // dsb_Latn_DE + 0xB2634D4C4C61746ELLU, // dtm_Latn_ML + 0xBE634D594C61746ELLU, // dtp_Latn_MY + 0xE2634E5044657661LLU, // dty_Deva_NP + 0x8283434D4C61746ELLU, // dua_Latn_CM + 0x64764D5654686161LLU, // dv_Thaa_MV + 0xBB03534E4C61746ELLU, // dyo_Latn_SN + 0xD30342464C61746ELLU, // dyu_Latn_BF + 0x647A425454696274LLU, // dz_Tibt_BT + 0xD0244B454C61746ELLU, // ebu_Latn_KE + 0x656547484C61746ELLU, // ee_Latn_GH + 0xA0A44E474C61746ELLU, // efi_Latn_NG + 0xACC449544C61746ELLU, // egl_Latn_IT + 0xE0C4454745677970LLU, // egy_Egyp_EG + 0xE1444D4D4B616C69LLU, // eky_Kali_MM + 0x656C47524772656BLLU, // el_Grek_GR + 0x656E47424C61746ELLU, // en_Latn_GB + 0x656E55534C61746ELLU, // en_Latn_US + 0x656E474253686177LLU, // en_Shaw_GB + 0x657345534C61746ELLU, // es_Latn_ES + 0x65734D584C61746ELLU, // es_Latn_MX + 0x657355534C61746ELLU, // es_Latn_US + 0xD24455534C61746ELLU, // esu_Latn_US + 0x657445454C61746ELLU, // et_Latn_EE + 0xCE6449544974616CLLU, // ett_Ital_IT + 0x657545534C61746ELLU, // eu_Latn_ES + 0xBAC4434D4C61746ELLU, // ewo_Latn_CM + 0xCEE445534C61746ELLU, // ext_Latn_ES + 0x6661495241726162LLU, // fa_Arab_IR + 0xB40547514C61746ELLU, // fan_Latn_GQ + 0x6666474E41646C6DLLU, // ff_Adlm_GN + 0x6666534E4C61746ELLU, // ff_Latn_SN + 0xB0A54D4C4C61746ELLU, // ffm_Latn_ML + 0x666946494C61746ELLU, // fi_Latn_FI + 0x8105534441726162LLU, // fia_Arab_SD + 0xAD0550484C61746ELLU, // fil_Latn_PH + 0xCD0553454C61746ELLU, // fit_Latn_SE + 0x666A464A4C61746ELLU, // fj_Latn_FJ + 0x666F464F4C61746ELLU, // fo_Latn_FO + 0xB5C5424A4C61746ELLU, // fon_Latn_BJ + 0x667246524C61746ELLU, // fr_Latn_FR + 0x8A2555534C61746ELLU, // frc_Latn_US + 0xBE2546524C61746ELLU, // frp_Latn_FR + 0xC62544454C61746ELLU, // frr_Latn_DE + 0xCA2544454C61746ELLU, // frs_Latn_DE + 0x8685434D41726162LLU, // fub_Arab_CM + 0x8E8557464C61746ELLU, // fud_Latn_WF + 0x9685474E4C61746ELLU, // fuf_Latn_GN + 0xC2854E454C61746ELLU, // fuq_Latn_NE + 0xC68549544C61746ELLU, // fur_Latn_IT + 0xD6854E474C61746ELLU, // fuv_Latn_NG + 0xC6A553444C61746ELLU, // fvr_Latn_SD + 0x66794E4C4C61746ELLU, // fy_Latn_NL + 0x676149454C61746ELLU, // ga_Latn_IE + 0x800647484C61746ELLU, // gaa_Latn_GH + 0x98064D444C61746ELLU, // gag_Latn_MD + 0xB406434E48616E73LLU, // gan_Hans_CN + 0xE00649444C61746ELLU, // gay_Latn_ID + 0xB026494E44657661LLU, // gbm_Deva_IN + 0xE426495241726162LLU, // gbz_Arab_IR + 0xC44647464C61746ELLU, // gcr_Latn_GF + 0x676447424C61746ELLU, // gd_Latn_GB + 0xE486455445746869LLU, // gez_Ethi_ET + 0xB4C64E5044657661LLU, // ggn_Deva_NP + 0xAD064B494C61746ELLU, // gil_Latn_KI + 0xA926504B41726162LLU, // gjk_Arab_PK + 0xD126504B41726162LLU, // gju_Arab_PK + 0x676C45534C61746ELLU, // gl_Latn_ES + 0xA966495241726162LLU, // glk_Arab_IR + 0x676E50594C61746ELLU, // gn_Latn_PY + 0xB1C6494E44657661LLU, // gom_Deva_IN + 0xB5C6494E54656C75LLU, // gon_Telu_IN + 0xC5C649444C61746ELLU, // gor_Latn_ID + 0xC9C64E4C4C61746ELLU, // gos_Latn_NL + 0xCDC65541476F7468LLU, // got_Goth_UA + 0x8A26435943707274LLU, // grc_Cprt_CY + 0x8A2647524C696E62LLU, // grc_Linb_GR + 0xCE26494E42656E67LLU, // grt_Beng_IN + 0xDA4643484C61746ELLU, // gsw_Latn_CH + 0x6775494E47756A72LLU, // gu_Gujr_IN + 0x868642524C61746ELLU, // gub_Latn_BR + 0x8A86434F4C61746ELLU, // guc_Latn_CO + 0xC68647484C61746ELLU, // gur_Latn_GH + 0xE6864B454C61746ELLU, // guz_Latn_KE + 0x6776494D4C61746ELLU, // gv_Latn_IM + 0xC6A64E5044657661LLU, // gvr_Deva_NP + 0xA2C643414C61746ELLU, // gwi_Latn_CA + 0x68614E474C61746ELLU, // ha_Latn_NG + 0xA807434E48616E73LLU, // hak_Hans_CN + 0xD80755534C61746ELLU, // haw_Latn_US + 0xE407414641726162LLU, // haz_Arab_AF + 0x6865494C48656272LLU, // he_Hebr_IL + 0x6869494E44657661LLU, // hi_Deva_IN + 0x9507464A4C61746ELLU, // hif_Latn_FJ + 0xAD0750484C61746ELLU, // hil_Latn_PH + 0xD1675452486C7577LLU, // hlu_Hluw_TR + 0x8D87434E506C7264LLU, // hmd_Plrd_CN + 0x8DA7504B41726162LLU, // hnd_Arab_PK + 0x91A7494E44657661LLU, // hne_Deva_IN + 0xA5A74C41486D6E67LLU, // hnj_Hmng_LA + 0xB5A750484C61746ELLU, // hnn_Latn_PH + 0xB9A7504B41726162LLU, // hno_Arab_PK + 0x686F50474C61746ELLU, // ho_Latn_PG + 0x89C7494E44657661LLU, // hoc_Deva_IN + 0xA5C7494E44657661LLU, // hoj_Deva_IN + 0x687248524C61746ELLU, // hr_Latn_HR + 0x864744454C61746ELLU, // hsb_Latn_DE + 0xB647434E48616E73LLU, // hsn_Hans_CN + 0x687448544C61746ELLU, // ht_Latn_HT + 0x687548554C61746ELLU, // hu_Latn_HU + 0x6879414D41726D6ELLU, // hy_Armn_AM + 0x687A4E414C61746ELLU, // hz_Latn_NA + 0x696146524C61746ELLU, // ia_Latn_FR + 0x80284D594C61746ELLU, // iba_Latn_MY + 0x84284E474C61746ELLU, // ibb_Latn_NG + 0x696449444C61746ELLU, // id_Latn_ID + 0x69674E474C61746ELLU, // ig_Latn_NG + 0x6969434E59696969LLU, // ii_Yiii_CN + 0x696B55534C61746ELLU, // ik_Latn_US + 0xCD4843414C61746ELLU, // ikt_Latn_CA + 0xB96850484C61746ELLU, // ilo_Latn_PH + 0x696E49444C61746ELLU, // in_Latn_ID + 0x9DA852554379726CLLU, // inh_Cyrl_RU + 0x697349534C61746ELLU, // is_Latn_IS + 0x697449544C61746ELLU, // it_Latn_IT + 0x6975434143616E73LLU, // iu_Cans_CA + 0x6977494C48656272LLU, // iw_Hebr_IL + 0x9F2852554C61746ELLU, // izh_Latn_RU + 0x6A614A504A70616ELLU, // ja_Jpan_JP + 0xB0094A4D4C61746ELLU, // jam_Latn_JM + 0xB8C9434D4C61746ELLU, // jgo_Latn_CM + 0x8989545A4C61746ELLU, // jmc_Latn_TZ + 0xAD894E5044657661LLU, // jml_Deva_NP + 0xCE89444B4C61746ELLU, // jut_Latn_DK + 0x6A7649444C61746ELLU, // jv_Latn_ID + 0x6A7749444C61746ELLU, // jw_Latn_ID + 0x6B61474547656F72LLU, // ka_Geor_GE + 0x800A555A4379726CLLU, // kaa_Cyrl_UZ + 0x840A445A4C61746ELLU, // kab_Latn_DZ + 0x880A4D4D4C61746ELLU, // kac_Latn_MM + 0xA40A4E474C61746ELLU, // kaj_Latn_NG + 0xB00A4B454C61746ELLU, // kam_Latn_KE + 0xB80A4D4C4C61746ELLU, // kao_Latn_ML + 0x8C2A52554379726CLLU, // kbd_Cyrl_RU + 0xE02A4E4541726162LLU, // kby_Arab_NE + 0x984A4E474C61746ELLU, // kcg_Latn_NG + 0xA84A5A574C61746ELLU, // kck_Latn_ZW + 0x906A545A4C61746ELLU, // kde_Latn_TZ + 0x9C6A544741726162LLU, // kdh_Arab_TG + 0xCC6A544854686169LLU, // kdt_Thai_TH + 0x808A43564C61746ELLU, // kea_Latn_CV + 0xB48A434D4C61746ELLU, // ken_Latn_CM + 0xB8AA43494C61746ELLU, // kfo_Latn_CI + 0xC4AA494E44657661LLU, // kfr_Deva_IN + 0xE0AA494E44657661LLU, // kfy_Deva_IN + 0x6B6743444C61746ELLU, // kg_Latn_CD + 0x90CA49444C61746ELLU, // kge_Latn_ID + 0xBCCA42524C61746ELLU, // kgp_Latn_BR + 0x80EA494E4C61746ELLU, // kha_Latn_IN + 0x84EA434E54616C75LLU, // khb_Talu_CN + 0xB4EA494E44657661LLU, // khn_Deva_IN + 0xC0EA4D4C4C61746ELLU, // khq_Latn_ML + 0xCCEA494E4D796D72LLU, // kht_Mymr_IN + 0xD8EA504B41726162LLU, // khw_Arab_PK + 0x6B694B454C61746ELLU, // ki_Latn_KE + 0xD10A54524C61746ELLU, // kiu_Latn_TR + 0x6B6A4E414C61746ELLU, // kj_Latn_NA + 0x992A4C414C616F6FLLU, // kjg_Laoo_LA + 0x6B6B434E41726162LLU, // kk_Arab_CN + 0x6B6B4B5A4379726CLLU, // kk_Cyrl_KZ + 0xA54A434D4C61746ELLU, // kkj_Latn_CM + 0x6B6C474C4C61746ELLU, // kl_Latn_GL + 0xB56A4B454C61746ELLU, // kln_Latn_KE + 0x6B6D4B484B686D72LLU, // km_Khmr_KH + 0x858A414F4C61746ELLU, // kmb_Latn_AO + 0x6B6E494E4B6E6461LLU, // kn_Knda_IN + 0x6B6F4B524B6F7265LLU, // ko_Kore_KR + 0xA1CA52554379726CLLU, // koi_Cyrl_RU + 0xA9CA494E44657661LLU, // kok_Deva_IN + 0xC9CA464D4C61746ELLU, // kos_Latn_FM + 0x91EA4C524C61746ELLU, // kpe_Latn_LR + 0x8A2A52554379726CLLU, // krc_Cyrl_RU + 0xA22A534C4C61746ELLU, // kri_Latn_SL + 0xA62A50484C61746ELLU, // krj_Latn_PH + 0xAE2A52554C61746ELLU, // krl_Latn_RU + 0xD22A494E44657661LLU, // kru_Deva_IN + 0x6B73494E41726162LLU, // ks_Arab_IN + 0x864A545A4C61746ELLU, // ksb_Latn_TZ + 0x964A434D4C61746ELLU, // ksf_Latn_CM + 0x9E4A44454C61746ELLU, // ksh_Latn_DE + 0x6B75495141726162LLU, // ku_Arab_IQ + 0x6B7554524C61746ELLU, // ku_Latn_TR + 0xB28A52554379726CLLU, // kum_Cyrl_RU + 0x6B7652554379726CLLU, // kv_Cyrl_RU + 0xC6AA49444C61746ELLU, // kvr_Latn_ID + 0xDEAA504B41726162LLU, // kvx_Arab_PK + 0x6B7747424C61746ELLU, // kw_Latn_GB + 0xB2EA544854686169LLU, // kxm_Thai_TH + 0xBEEA504B41726162LLU, // kxp_Arab_PK + 0x6B79434E41726162LLU, // ky_Arab_CN + 0x6B794B474379726CLLU, // ky_Cyrl_KG + 0x6B7954524C61746ELLU, // ky_Latn_TR + 0x6C6156414C61746ELLU, // la_Latn_VA + 0x840B47524C696E61LLU, // lab_Lina_GR + 0x8C0B494C48656272LLU, // lad_Hebr_IL + 0x980B545A4C61746ELLU, // lag_Latn_TZ + 0x9C0B504B41726162LLU, // lah_Arab_PK + 0xA40B55474C61746ELLU, // laj_Latn_UG + 0x6C624C554C61746ELLU, // lb_Latn_LU + 0x902B52554379726CLLU, // lbe_Cyrl_RU + 0xD82B49444C61746ELLU, // lbw_Latn_ID + 0xBC4B434E54686169LLU, // lcp_Thai_CN + 0xBC8B494E4C657063LLU, // lep_Lepc_IN + 0xE48B52554379726CLLU, // lez_Cyrl_RU + 0x6C6755474C61746ELLU, // lg_Latn_UG + 0x6C694E4C4C61746ELLU, // li_Latn_NL + 0x950B4E5044657661LLU, // lif_Deva_NP + 0x950B494E4C696D62LLU, // lif_Limb_IN + 0xA50B49544C61746ELLU, // lij_Latn_IT + 0xC90B434E4C697375LLU, // lis_Lisu_CN + 0xBD2B49444C61746ELLU, // ljp_Latn_ID + 0xA14B495241726162LLU, // lki_Arab_IR + 0xCD4B55534C61746ELLU, // lkt_Latn_US + 0xB58B494E54656C75LLU, // lmn_Telu_IN + 0xB98B49544C61746ELLU, // lmo_Latn_IT + 0x6C6E43444C61746ELLU, // ln_Latn_CD + 0x6C6F4C414C616F6FLLU, // lo_Laoo_LA + 0xADCB43444C61746ELLU, // lol_Latn_CD + 0xE5CB5A4D4C61746ELLU, // loz_Latn_ZM + 0x8A2B495241726162LLU, // lrc_Arab_IR + 0x6C744C544C61746ELLU, // lt_Latn_LT + 0x9A6B4C564C61746ELLU, // ltg_Latn_LV + 0x6C7543444C61746ELLU, // lu_Latn_CD + 0x828B43444C61746ELLU, // lua_Latn_CD + 0xBA8B4B454C61746ELLU, // luo_Latn_KE + 0xE28B4B454C61746ELLU, // luy_Latn_KE + 0xE68B495241726162LLU, // luz_Arab_IR + 0x6C764C564C61746ELLU, // lv_Latn_LV + 0xAECB544854686169LLU, // lwl_Thai_TH + 0x9F2B434E48616E73LLU, // lzh_Hans_CN + 0xE72B54524C61746ELLU, // lzz_Latn_TR + 0x8C0C49444C61746ELLU, // mad_Latn_ID + 0x940C434D4C61746ELLU, // maf_Latn_CM + 0x980C494E44657661LLU, // mag_Deva_IN + 0xA00C494E44657661LLU, // mai_Deva_IN + 0xA80C49444C61746ELLU, // mak_Latn_ID + 0xB40C474D4C61746ELLU, // man_Latn_GM + 0xB40C474E4E6B6F6FLLU, // man_Nkoo_GN + 0xC80C4B454C61746ELLU, // mas_Latn_KE + 0xE40C4D584C61746ELLU, // maz_Latn_MX + 0x946C52554379726CLLU, // mdf_Cyrl_RU + 0x9C6C50484C61746ELLU, // mdh_Latn_PH + 0xC46C49444C61746ELLU, // mdr_Latn_ID + 0xB48C534C4C61746ELLU, // men_Latn_SL + 0xC48C4B454C61746ELLU, // mer_Latn_KE + 0x80AC544841726162LLU, // mfa_Arab_TH + 0x90AC4D554C61746ELLU, // mfe_Latn_MU + 0x6D674D474C61746ELLU, // mg_Latn_MG + 0x9CCC4D5A4C61746ELLU, // mgh_Latn_MZ + 0xB8CC434D4C61746ELLU, // mgo_Latn_CM + 0xBCCC4E5044657661LLU, // mgp_Deva_NP + 0xE0CC545A4C61746ELLU, // mgy_Latn_TZ + 0x6D684D484C61746ELLU, // mh_Latn_MH + 0x6D694E5A4C61746ELLU, // mi_Latn_NZ + 0xB50C49444C61746ELLU, // min_Latn_ID + 0xC90C495148617472LLU, // mis_Hatr_IQ + 0x6D6B4D4B4379726CLLU, // mk_Cyrl_MK + 0x6D6C494E4D6C796DLLU, // ml_Mlym_IN + 0xC96C53444C61746ELLU, // mls_Latn_SD + 0x6D6E4D4E4379726CLLU, // mn_Cyrl_MN + 0x6D6E434E4D6F6E67LLU, // mn_Mong_CN + 0xA1AC494E42656E67LLU, // mni_Beng_IN + 0xD9AC4D4D4D796D72LLU, // mnw_Mymr_MM + 0x91CC43414C61746ELLU, // moe_Latn_CA + 0x9DCC43414C61746ELLU, // moh_Latn_CA + 0xC9CC42464C61746ELLU, // mos_Latn_BF + 0x6D72494E44657661LLU, // mr_Deva_IN + 0x8E2C4E5044657661LLU, // mrd_Deva_NP + 0xA62C52554379726CLLU, // mrj_Cyrl_RU + 0xBA2C42444D726F6FLLU, // mro_Mroo_BD + 0x6D734D594C61746ELLU, // ms_Latn_MY + 0x6D744D544C61746ELLU, // mt_Latn_MT + 0xC66C494E44657661LLU, // mtr_Deva_IN + 0x828C434D4C61746ELLU, // mua_Latn_CM + 0xCA8C55534C61746ELLU, // mus_Latn_US + 0xE2AC504B41726162LLU, // mvy_Arab_PK + 0xAACC4D4C4C61746ELLU, // mwk_Latn_ML + 0xC6CC494E44657661LLU, // mwr_Deva_IN + 0xD6CC49444C61746ELLU, // mwv_Latn_ID + 0x8AEC5A574C61746ELLU, // mxc_Latn_ZW + 0x6D794D4D4D796D72LLU, // my_Mymr_MM + 0xD70C52554379726CLLU, // myv_Cyrl_RU + 0xDF0C55474C61746ELLU, // myx_Latn_UG + 0xE70C49524D616E64LLU, // myz_Mand_IR + 0xB72C495241726162LLU, // mzn_Arab_IR + 0x6E614E524C61746ELLU, // na_Latn_NR + 0xB40D434E48616E73LLU, // nan_Hans_CN + 0xBC0D49544C61746ELLU, // nap_Latn_IT + 0xC00D4E414C61746ELLU, // naq_Latn_NA + 0x6E624E4F4C61746ELLU, // nb_Latn_NO + 0x9C4D4D584C61746ELLU, // nch_Latn_MX + 0x6E645A574C61746ELLU, // nd_Latn_ZW + 0x886D4D5A4C61746ELLU, // ndc_Latn_MZ + 0xC86D44454C61746ELLU, // nds_Latn_DE + 0x6E654E5044657661LLU, // ne_Deva_NP + 0xD88D4E5044657661LLU, // new_Deva_NP + 0x6E674E414C61746ELLU, // ng_Latn_NA + 0xACCD4D5A4C61746ELLU, // ngl_Latn_MZ + 0x90ED4D584C61746ELLU, // nhe_Latn_MX + 0xD8ED4D584C61746ELLU, // nhw_Latn_MX + 0xA50D49444C61746ELLU, // nij_Latn_ID + 0xD10D4E554C61746ELLU, // niu_Latn_NU + 0xB92D494E4C61746ELLU, // njo_Latn_IN + 0x6E6C4E4C4C61746ELLU, // nl_Latn_NL + 0x998D434D4C61746ELLU, // nmg_Latn_CM + 0x6E6E4E4F4C61746ELLU, // nn_Latn_NO + 0x9DAD434D4C61746ELLU, // nnh_Latn_CM + 0x6E6F4E4F4C61746ELLU, // no_Latn_NO + 0x8DCD54484C616E61LLU, // nod_Lana_TH + 0x91CD494E44657661LLU, // noe_Deva_IN + 0xB5CD534552756E72LLU, // non_Runr_SE + 0xBA0D474E4E6B6F6FLLU, // nqo_Nkoo_GN + 0x6E725A414C61746ELLU, // nr_Latn_ZA + 0xAA4D434143616E73LLU, // nsk_Cans_CA + 0xBA4D5A414C61746ELLU, // nso_Latn_ZA + 0xCA8D53534C61746ELLU, // nus_Latn_SS + 0x6E7655534C61746ELLU, // nv_Latn_US + 0xC2ED434E4C61746ELLU, // nxq_Latn_CN + 0x6E794D574C61746ELLU, // ny_Latn_MW + 0xB30D545A4C61746ELLU, // nym_Latn_TZ + 0xB70D55474C61746ELLU, // nyn_Latn_UG + 0xA32D47484C61746ELLU, // nzi_Latn_GH + 0x6F6346524C61746ELLU, // oc_Latn_FR + 0x6F6D45544C61746ELLU, // om_Latn_ET + 0x6F72494E4F727961LLU, // or_Orya_IN + 0x6F7347454379726CLLU, // os_Cyrl_GE + 0x824E55534F736765LLU, // osa_Osge_US + 0xAA6E4D4E4F726B68LLU, // otk_Orkh_MN + 0x7061504B41726162LLU, // pa_Arab_PK + 0x7061494E47757275LLU, // pa_Guru_IN + 0x980F50484C61746ELLU, // pag_Latn_PH + 0xAC0F495250686C69LLU, // pal_Phli_IR + 0xAC0F434E50686C70LLU, // pal_Phlp_CN + 0xB00F50484C61746ELLU, // pam_Latn_PH + 0xBC0F41574C61746ELLU, // pap_Latn_AW + 0xD00F50574C61746ELLU, // pau_Latn_PW + 0x8C4F46524C61746ELLU, // pcd_Latn_FR + 0xB04F4E474C61746ELLU, // pcm_Latn_NG + 0x886F55534C61746ELLU, // pdc_Latn_US + 0xCC6F43414C61746ELLU, // pdt_Latn_CA + 0xB88F49525870656FLLU, // peo_Xpeo_IR + 0xACAF44454C61746ELLU, // pfl_Latn_DE + 0xB4EF4C4250686E78LLU, // phn_Phnx_LB + 0x814F494E42726168LLU, // pka_Brah_IN + 0xB94F4B454C61746ELLU, // pko_Latn_KE + 0x706C504C4C61746ELLU, // pl_Latn_PL + 0xC98F49544C61746ELLU, // pms_Latn_IT + 0xCDAF47524772656BLLU, // pnt_Grek_GR + 0xB5CF464D4C61746ELLU, // pon_Latn_FM + 0x822F504B4B686172LLU, // pra_Khar_PK + 0x8E2F495241726162LLU, // prd_Arab_IR + 0x7073414641726162LLU, // ps_Arab_AF + 0x707442524C61746ELLU, // pt_Latn_BR + 0xD28F47414C61746ELLU, // puu_Latn_GA + 0x717550454C61746ELLU, // qu_Latn_PE + 0x8A9047544C61746ELLU, // quc_Latn_GT + 0x9A9045434C61746ELLU, // qug_Latn_EC + 0xA411494E44657661LLU, // raj_Deva_IN + 0x945152454C61746ELLU, // rcf_Latn_RE + 0xA49149444C61746ELLU, // rej_Latn_ID + 0xB4D149544C61746ELLU, // rgn_Latn_IT + 0x8111494E4C61746ELLU, // ria_Latn_IN + 0x95114D4154666E67LLU, // rif_Tfng_MA + 0xC9314E5044657661LLU, // rjs_Deva_NP + 0xCD51424442656E67LLU, // rkt_Beng_BD + 0x726D43484C61746ELLU, // rm_Latn_CH + 0x959146494C61746ELLU, // rmf_Latn_FI + 0xB99143484C61746ELLU, // rmo_Latn_CH + 0xCD91495241726162LLU, // rmt_Arab_IR + 0xD19153454C61746ELLU, // rmu_Latn_SE + 0x726E42494C61746ELLU, // rn_Latn_BI + 0x99B14D5A4C61746ELLU, // rng_Latn_MZ + 0x726F524F4C61746ELLU, // ro_Latn_RO + 0x85D149444C61746ELLU, // rob_Latn_ID + 0x95D1545A4C61746ELLU, // rof_Latn_TZ + 0xB271464A4C61746ELLU, // rtm_Latn_FJ + 0x727552554379726CLLU, // ru_Cyrl_RU + 0x929155414379726CLLU, // rue_Cyrl_UA + 0x9A9153424C61746ELLU, // rug_Latn_SB + 0x727752574C61746ELLU, // rw_Latn_RW + 0xAAD1545A4C61746ELLU, // rwk_Latn_TZ + 0xD3114A504B616E61LLU, // ryu_Kana_JP + 0x7361494E44657661LLU, // sa_Deva_IN + 0x941247484C61746ELLU, // saf_Latn_GH + 0x9C1252554379726CLLU, // sah_Cyrl_RU + 0xC0124B454C61746ELLU, // saq_Latn_KE + 0xC81249444C61746ELLU, // sas_Latn_ID + 0xCC12494E4C61746ELLU, // sat_Latn_IN + 0xE412494E53617572LLU, // saz_Saur_IN + 0xBC32545A4C61746ELLU, // sbp_Latn_TZ + 0x736349544C61746ELLU, // sc_Latn_IT + 0xA852494E44657661LLU, // sck_Deva_IN + 0xB45249544C61746ELLU, // scn_Latn_IT + 0xB85247424C61746ELLU, // sco_Latn_GB + 0xC85243414C61746ELLU, // scs_Latn_CA + 0x7364504B41726162LLU, // sd_Arab_PK + 0x7364494E44657661LLU, // sd_Deva_IN + 0x7364494E4B686F6ALLU, // sd_Khoj_IN + 0x7364494E53696E64LLU, // sd_Sind_IN + 0x887249544C61746ELLU, // sdc_Latn_IT + 0x9C72495241726162LLU, // sdh_Arab_IR + 0x73654E4F4C61746ELLU, // se_Latn_NO + 0x949243494C61746ELLU, // sef_Latn_CI + 0x9C924D5A4C61746ELLU, // seh_Latn_MZ + 0xA0924D584C61746ELLU, // sei_Latn_MX + 0xC8924D4C4C61746ELLU, // ses_Latn_ML + 0x736743464C61746ELLU, // sg_Latn_CF + 0x80D249454F67616DLLU, // sga_Ogam_IE + 0xC8D24C544C61746ELLU, // sgs_Latn_LT + 0xA0F24D4154666E67LLU, // shi_Tfng_MA + 0xB4F24D4D4D796D72LLU, // shn_Mymr_MM + 0x73694C4B53696E68LLU, // si_Sinh_LK + 0x8D1245544C61746ELLU, // sid_Latn_ET + 0x736B534B4C61746ELLU, // sk_Latn_SK + 0xC552504B41726162LLU, // skr_Arab_PK + 0x736C53494C61746ELLU, // sl_Latn_SI + 0xA172504C4C61746ELLU, // sli_Latn_PL + 0xE17249444C61746ELLU, // sly_Latn_ID + 0x736D57534C61746ELLU, // sm_Latn_WS + 0x819253454C61746ELLU, // sma_Latn_SE + 0xA59253454C61746ELLU, // smj_Latn_SE + 0xB59246494C61746ELLU, // smn_Latn_FI + 0xBD92494C53616D72LLU, // smp_Samr_IL + 0xC99246494C61746ELLU, // sms_Latn_FI + 0x736E5A574C61746ELLU, // sn_Latn_ZW + 0xA9B24D4C4C61746ELLU, // snk_Latn_ML + 0x736F534F4C61746ELLU, // so_Latn_SO + 0xD1D2544854686169LLU, // sou_Thai_TH + 0x7371414C4C61746ELLU, // sq_Latn_AL + 0x737252534379726CLLU, // sr_Cyrl_RS + 0x737252534C61746ELLU, // sr_Latn_RS + 0x8632494E536F7261LLU, // srb_Sora_IN + 0xB63253524C61746ELLU, // srn_Latn_SR + 0xC632534E4C61746ELLU, // srr_Latn_SN + 0xDE32494E44657661LLU, // srx_Deva_IN + 0x73735A414C61746ELLU, // ss_Latn_ZA + 0xE25245524C61746ELLU, // ssy_Latn_ER + 0x73745A414C61746ELLU, // st_Latn_ZA + 0xC27244454C61746ELLU, // stq_Latn_DE + 0x737549444C61746ELLU, // su_Latn_ID + 0xAA92545A4C61746ELLU, // suk_Latn_TZ + 0xCA92474E4C61746ELLU, // sus_Latn_GN + 0x737653454C61746ELLU, // sv_Latn_SE + 0x7377545A4C61746ELLU, // sw_Latn_TZ + 0x86D2595441726162LLU, // swb_Arab_YT + 0x8AD243444C61746ELLU, // swc_Latn_CD + 0x9AD244454C61746ELLU, // swg_Latn_DE + 0xD6D2494E44657661LLU, // swv_Deva_IN + 0xB6F249444C61746ELLU, // sxn_Latn_ID + 0xAF12424442656E67LLU, // syl_Beng_BD + 0xC712495153797263LLU, // syr_Syrc_IQ + 0xAF32504C4C61746ELLU, // szl_Latn_PL + 0x7461494E54616D6CLLU, // ta_Taml_IN + 0xA4134E5044657661LLU, // taj_Deva_NP + 0xD83350484C61746ELLU, // tbw_Latn_PH + 0xE053494E4B6E6461LLU, // tcy_Knda_IN + 0x8C73434E54616C65LLU, // tdd_Tale_CN + 0x98734E5044657661LLU, // tdg_Deva_NP + 0x9C734E5044657661LLU, // tdh_Deva_NP + 0x7465494E54656C75LLU, // te_Telu_IN + 0xB093534C4C61746ELLU, // tem_Latn_SL + 0xB89355474C61746ELLU, // teo_Latn_UG + 0xCC93544C4C61746ELLU, // tet_Latn_TL + 0x7467504B41726162LLU, // tg_Arab_PK + 0x7467544A4379726CLLU, // tg_Cyrl_TJ + 0x7468544854686169LLU, // th_Thai_TH + 0xACF34E5044657661LLU, // thl_Deva_NP + 0xC0F34E5044657661LLU, // thq_Deva_NP + 0xC4F34E5044657661LLU, // thr_Deva_NP + 0x7469455445746869LLU, // ti_Ethi_ET + 0x9913455245746869LLU, // tig_Ethi_ER + 0xD5134E474C61746ELLU, // tiv_Latn_NG + 0x746B544D4C61746ELLU, // tk_Latn_TM + 0xAD53544B4C61746ELLU, // tkl_Latn_TK + 0xC553415A4C61746ELLU, // tkr_Latn_AZ + 0xCD534E5044657661LLU, // tkt_Deva_NP + 0x746C50484C61746ELLU, // tl_Latn_PH + 0xE173415A4C61746ELLU, // tly_Latn_AZ + 0x9D934E454C61746ELLU, // tmh_Latn_NE + 0x746E5A414C61746ELLU, // tn_Latn_ZA + 0x746F544F4C61746ELLU, // to_Latn_TO + 0x99D34D574C61746ELLU, // tog_Latn_MW + 0xA1F350474C61746ELLU, // tpi_Latn_PG + 0x747254524C61746ELLU, // tr_Latn_TR + 0xD23354524C61746ELLU, // tru_Latn_TR + 0xD63354574C61746ELLU, // trv_Latn_TW + 0x74735A414C61746ELLU, // ts_Latn_ZA + 0x8E5347524772656BLLU, // tsd_Grek_GR + 0x96534E5044657661LLU, // tsf_Deva_NP + 0x9A5350484C61746ELLU, // tsg_Latn_PH + 0xA653425454696274LLU, // tsj_Tibt_BT + 0x747452554379726CLLU, // tt_Cyrl_RU + 0xA67355474C61746ELLU, // ttj_Latn_UG + 0xCA73544854686169LLU, // tts_Thai_TH + 0xCE73415A4C61746ELLU, // ttt_Latn_AZ + 0xB2934D574C61746ELLU, // tum_Latn_MW + 0xAEB354564C61746ELLU, // tvl_Latn_TV + 0xC2D34E454C61746ELLU, // twq_Latn_NE + 0x9AF3434E54616E67LLU, // txg_Tang_CN + 0x747950464C61746ELLU, // ty_Latn_PF + 0xD71352554379726CLLU, // tyv_Cyrl_RU + 0xB3334D414C61746ELLU, // tzm_Latn_MA + 0xB07452554379726CLLU, // udm_Cyrl_RU + 0x7567434E41726162LLU, // ug_Arab_CN + 0x75674B5A4379726CLLU, // ug_Cyrl_KZ + 0x80D4535955676172LLU, // uga_Ugar_SY + 0x756B55414379726CLLU, // uk_Cyrl_UA + 0xA174464D4C61746ELLU, // uli_Latn_FM + 0x8594414F4C61746ELLU, // umb_Latn_AO + 0xC5B4494E42656E67LLU, // unr_Beng_IN + 0xC5B44E5044657661LLU, // unr_Deva_NP + 0xDDB4494E42656E67LLU, // unx_Beng_IN + 0x7572504B41726162LLU, // ur_Arab_PK + 0x757A414641726162LLU, // uz_Arab_AF + 0x757A555A4C61746ELLU, // uz_Latn_UZ + 0xA0154C5256616969LLU, // vai_Vaii_LR + 0x76655A414C61746ELLU, // ve_Latn_ZA + 0x889549544C61746ELLU, // vec_Latn_IT + 0xBC9552554C61746ELLU, // vep_Latn_RU + 0x7669564E4C61746ELLU, // vi_Latn_VN + 0x891553584C61746ELLU, // vic_Latn_SX + 0xC97542454C61746ELLU, // vls_Latn_BE + 0x959544454C61746ELLU, // vmf_Latn_DE + 0xD9954D5A4C61746ELLU, // vmw_Latn_MZ + 0xCDD552554C61746ELLU, // vot_Latn_RU + 0xBA3545454C61746ELLU, // vro_Latn_EE + 0xB695545A4C61746ELLU, // vun_Latn_TZ + 0x776142454C61746ELLU, // wa_Latn_BE + 0x901643484C61746ELLU, // wae_Latn_CH + 0xAC16455445746869LLU, // wal_Ethi_ET + 0xC41650484C61746ELLU, // war_Latn_PH + 0xBC3641554C61746ELLU, // wbp_Latn_AU + 0xC036494E54656C75LLU, // wbq_Telu_IN + 0xC436494E44657661LLU, // wbr_Deva_IN + 0xC97657464C61746ELLU, // wls_Latn_WF + 0xA1B64B4D41726162LLU, // wni_Arab_KM + 0x776F534E4C61746ELLU, // wo_Latn_SN + 0xB276494E44657661LLU, // wtm_Deva_IN + 0xD296434E48616E73LLU, // wuu_Hans_CN + 0xD41742524C61746ELLU, // xav_Latn_BR + 0xC457545243617269LLU, // xcr_Cari_TR + 0x78685A414C61746ELLU, // xh_Latn_ZA + 0x897754524C796369LLU, // xlc_Lyci_TR + 0x8D7754524C796469LLU, // xld_Lydi_TR + 0x9597474547656F72LLU, // xmf_Geor_GE + 0xB597434E4D616E69LLU, // xmn_Mani_CN + 0xC59753444D657263LLU, // xmr_Merc_SD + 0x81B753414E617262LLU, // xna_Narb_SA + 0xC5B7494E44657661LLU, // xnr_Deva_IN + 0x99D755474C61746ELLU, // xog_Latn_UG + 0xC5F7495250727469LLU, // xpr_Prti_IR + 0x8257594553617262LLU, // xsa_Sarb_YE + 0xC6574E5044657661LLU, // xsr_Deva_NP + 0xB8184D5A4C61746ELLU, // yao_Latn_MZ + 0xBC18464D4C61746ELLU, // yap_Latn_FM + 0xD418434D4C61746ELLU, // yav_Latn_CM + 0x8438434D4C61746ELLU, // ybb_Latn_CM + 0x796F4E474C61746ELLU, // yo_Latn_NG + 0xAE3842524C61746ELLU, // yrl_Latn_BR + 0x82984D584C61746ELLU, // yua_Latn_MX + 0x9298434E48616E73LLU, // yue_Hans_CN + 0x9298484B48616E74LLU, // yue_Hant_HK + 0x7A61434E4C61746ELLU, // za_Latn_CN + 0x981953444C61746ELLU, // zag_Latn_SD + 0xA4794B4D41726162LLU, // zdj_Arab_KM + 0x80994E4C4C61746ELLU, // zea_Latn_NL + 0x9CD94D4154666E67LLU, // zgh_Tfng_MA + 0x7A685457426F706FLLU, // zh_Bopo_TW + 0x7A68545748616E62LLU, // zh_Hanb_TW + 0x7A68434E48616E73LLU, // zh_Hans_CN + 0x7A68545748616E74LLU, // zh_Hant_TW + 0xB17954474C61746ELLU, // zlm_Latn_TG + 0xA1994D594C61746ELLU, // zmi_Latn_MY + 0x7A755A414C61746ELLU, // zu_Latn_ZA + 0x833954524C61746ELLU, // zza_Latn_TR }); const std::unordered_map<uint32_t, uint32_t> ARAB_PARENTS({ diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp index 263d249d20e9..c6ef090c1f76 100644 --- a/libs/hwui/hwui/Bitmap.cpp +++ b/libs/hwui/hwui/Bitmap.cpp @@ -223,6 +223,7 @@ Bitmap::~Bitmap() { break; case PixelStorageType::Heap: free(mPixelStorage.heap.address); + mallopt(M_PURGE, 0); break; case PixelStorageType::Hardware: auto buffer = mPixelStorage.hardware.buffer; @@ -230,7 +231,6 @@ Bitmap::~Bitmap() { mPixelStorage.hardware.buffer = nullptr; break; } - android::uirenderer::renderthread::RenderProxy::onBitmapDestroyed(getStableID()); } diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h index 38ad9c09a8aa..e9fba3a56cab 100644 --- a/libs/hwui/pipeline/skia/SkiaPipeline.h +++ b/libs/hwui/pipeline/skia/SkiaPipeline.h @@ -30,7 +30,7 @@ namespace skiapipeline { 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 5ae7d6b0b607..3233c8d4ea7e 100644 --- a/libs/hwui/pipeline/skia/SkiaProfileRenderer.h +++ b/libs/hwui/pipeline/skia/SkiaProfileRenderer.h @@ -23,7 +23,7 @@ namespace uirenderer { 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 03b4c79f2beb..3d00386bf5cd 100644 --- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h +++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h @@ -25,7 +25,7 @@ namespace skiapipeline { 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 74e48cea2a87..5e892aa7e92c 100644 --- a/libs/hwui/pipeline/skia/VectorDrawableAtlas.h +++ b/libs/hwui/pipeline/skia/VectorDrawableAtlas.h @@ -62,8 +62,8 @@ class VectorDrawableAtlas : public virtual RefBase { 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 7d733525194f..78d2539a733f 100644 --- a/libs/hwui/renderthread/CacheManager.h +++ b/libs/hwui/renderthread/CacheManager.h @@ -59,7 +59,7 @@ public: 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 c319c9ec209f..ea6970469e03 100644 --- a/libs/hwui/renderthread/VulkanManager.h +++ b/libs/hwui/renderthread/VulkanManager.h @@ -127,6 +127,7 @@ private: 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 0d87776e083e..d189a9379c33 100644 --- a/libs/hwui/tests/common/scenes/ShapeAnimation.cpp +++ b/libs/hwui/tests/common/scenes/ShapeAnimation.cpp @@ -76,7 +76,7 @@ public: 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 02f740cee096..4f299e377f09 100644 --- a/libs/hwui/tests/unit/VectorDrawableTests.cpp +++ b/libs/hwui/tests/unit/VectorDrawableTests.cpp @@ -251,7 +251,7 @@ static bool hasSameVerbs(const PathData& from, const PathData& to) { } 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(PathParser, parseStringForData) { } TEST(VectorDrawableUtils, createSkPathFromPathData) { - for (TestData testData : sTestDataSet) { + for (const TestData& testData : sTestDataSet) { SkPath expectedPath; testData.skPathLamda(&expectedPath); SkPath actualPath; @@ -281,7 +281,7 @@ TEST(VectorDrawableUtils, createSkPathFromPathData) { } 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(PathParser, parseAsciiStringForSkPath) { } 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, morphPathData) { 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 @@ TEST(VectorDrawableUtils, interpolatePathData) { 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 c56f689b7419..ee1e33c43b89 100644 --- a/libs/incident/include/android/os/IncidentReportArgs.h +++ b/libs/incident/include/android/os/IncidentReportArgs.h @@ -40,7 +40,7 @@ const uint8_t DEST_AUTOMATIC = 200; 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/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java index 3643ca4a02f7..8a02a82194df 100644 --- a/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java +++ b/location/java/com/android/internal/location/gnssmetrics/GnssMetrics.java @@ -18,6 +18,7 @@ package com.android.internal.location.gnssmetrics; import android.os.SystemClock; import android.os.connectivity.GpsBatteryStats; +import android.os.SystemProperties; import android.text.format.DateUtils; import android.util.Base64; @@ -175,6 +176,7 @@ public class GnssMetrics { = topFourAverageCn0Statistics.getStandardDeviation(); } msg.powerMetrics = mGnssPowerMetrics.buildProto(); + msg.hardwareRevision = SystemProperties.get("ro.boot.revision", ""); String s = Base64.encodeToString(GnssLog.toByteArray(msg), Base64.DEFAULT); reset(); return s; @@ -239,6 +241,7 @@ public class GnssMetrics { s.append(" Energy consumed while on battery (mAh): ").append( stats.getEnergyConsumedMaMs() / ((double) DateUtils.HOUR_IN_MILLIS)).append("\n"); } + s.append("Hardware Version: " + SystemProperties.get("ro.boot.revision", "")).append("\n"); return s.toString(); } diff --git a/media/java/android/media/AudioFocusInfo.java b/media/java/android/media/AudioFocusInfo.java index 5467a69ea0bb..0a9ca025e2b0 100644 --- a/media/java/android/media/AudioFocusInfo.java +++ b/media/java/android/media/AudioFocusInfo.java @@ -80,16 +80,12 @@ public final class AudioFocusInfo implements Parcelable { * The audio attributes for the audio focus request. * @return non-null {@link AudioAttributes}. */ - @SystemApi public AudioAttributes getAttributes() { return mAttributes; } - @SystemApi public int getClientUid() { return mClientUid; } - @SystemApi public String getClientId() { return mClientId; } - @SystemApi public String getPackageName() { return mPackageName; } /** @@ -99,7 +95,6 @@ public final class AudioFocusInfo implements Parcelable { * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}, * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}. */ - @SystemApi public int getGainRequest() { return mGainRequest; } /** @@ -109,7 +104,6 @@ public final class AudioFocusInfo implements Parcelable { * {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT} or * {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}. */ - @SystemApi public int getLossReceived() { return mLossReceived; } /** @hide */ @@ -124,7 +118,6 @@ public final class AudioFocusInfo implements Parcelable { * {@link AudioManager#AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS}, and * {@link AudioManager#AUDIOFOCUS_FLAG_LOCK}. */ - @SystemApi public int getFlags() { return mFlags; } @Override diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java index 2443b739dfa4..d1d605fc8399 100644 --- a/media/java/android/media/MediaCodec.java +++ b/media/java/android/media/MediaCodec.java @@ -406,7 +406,7 @@ import java.util.Map; <p> The codec in turn will return a read-only output buffer via the {@link Callback#onOutputBufferAvailable onOutputBufferAvailable} callback in asynchronous mode, or in - response to a {@link #dequeueOutputBuffer dequeuOutputBuffer} call in synchronous mode. After the + response to a {@link #dequeueOutputBuffer dequeueOutputBuffer} call in synchronous mode. After the output buffer has been processed, call one of the {@link #releaseOutputBuffer releaseOutputBuffer} methods to return the buffer to the codec. <p> diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java index 8bc1d35fef36..7fb3aa6d79f9 100644 --- a/media/java/android/media/audiopolicy/AudioMix.java +++ b/media/java/android/media/audiopolicy/AudioMix.java @@ -81,14 +81,12 @@ public class AudioMix { * An audio mix behavior where the output of the mix is sent to the original destination of * the audio signal, i.e. an output device for an output mix, or a recording for an input mix. */ - @SystemApi public static final int ROUTE_FLAG_RENDER = 0x1; /** * An audio mix behavior where the output of the mix is rerouted back to the framework and * is accessible for injection or capture through the {@link AudioTrack} and {@link AudioRecord} * APIs. */ - @SystemApi public static final int ROUTE_FLAG_LOOP_BACK = 0x1 << 1; private static final int ROUTE_FLAG_SUPPORTED = ROUTE_FLAG_RENDER | ROUTE_FLAG_LOOP_BACK; @@ -113,31 +111,23 @@ public class AudioMix { // MIX_STATE_* values to keep in sync with frameworks/av/include/media/AudioPolicy.h /** - * @hide * State of a mix before its policy is enabled. */ - @SystemApi public static final int MIX_STATE_DISABLED = -1; /** - * @hide * State of a mix when there is no audio to mix. */ - @SystemApi public static final int MIX_STATE_IDLE = 0; /** - * @hide * State of a mix that is actively mixing audio. */ - @SystemApi public static final int MIX_STATE_MIXING = 1; /** - * @hide * The current mixing state. * @return one of {@link #MIX_STATE_DISABLED}, {@link #MIX_STATE_IDLE}, * {@link #MIX_STATE_MIXING}. */ - @SystemApi public int getMixState() { return mMixState; } @@ -201,9 +191,7 @@ public class AudioMix { /** * Builder class for {@link AudioMix} objects - * */ - @SystemApi public static class Builder { private AudioMixingRule mRule = null; private AudioFormat mFormat = null; @@ -224,7 +212,6 @@ public class AudioMix { * @param rule a non-null {@link AudioMixingRule} instance. * @throws IllegalArgumentException */ - @SystemApi public Builder(AudioMixingRule rule) throws IllegalArgumentException { if (rule == null) { @@ -284,7 +271,6 @@ public class AudioMix { * @return the same Builder instance. * @throws IllegalArgumentException */ - @SystemApi public Builder setFormat(AudioFormat format) throws IllegalArgumentException { if (format == null) { @@ -302,7 +288,6 @@ public class AudioMix { * @return the same Builder instance. * @throws IllegalArgumentException */ - @SystemApi public Builder setRouteFlags(@RouteFlags int routeFlags) throws IllegalArgumentException { if (routeFlags == 0) { @@ -329,7 +314,6 @@ public class AudioMix { * @return the same Builder instance * @throws IllegalArgumentException */ - @SystemApi public Builder setDevice(@NonNull AudioDeviceInfo device) throws IllegalArgumentException { if (device == null) { throw new IllegalArgumentException("Illegal null AudioDeviceInfo argument"); @@ -347,7 +331,6 @@ public class AudioMix { * @return a new {@link AudioMix} object * @throws IllegalArgumentException if no {@link AudioMixingRule} has been set. */ - @SystemApi public AudioMix build() throws IllegalArgumentException { if (mRule == null) { throw new IllegalArgumentException("Illegal null AudioMixingRule"); diff --git a/media/java/android/media/audiopolicy/AudioMixingRule.java b/media/java/android/media/audiopolicy/AudioMixingRule.java index fbee62a86dcd..6c48cdb7b643 100644 --- a/media/java/android/media/audiopolicy/AudioMixingRule.java +++ b/media/java/android/media/audiopolicy/AudioMixingRule.java @@ -54,7 +54,6 @@ public class AudioMixingRule { * {@link Builder#addMixRule(int, Object)} where the Object parameter is an instance of * {@link AudioAttributes}. */ - @SystemApi public static final int RULE_MATCH_ATTRIBUTE_USAGE = 0x1; /** * A rule requiring the capture preset information of the {@link AudioAttributes} to match. @@ -62,14 +61,12 @@ public class AudioMixingRule { * {@link Builder#addMixRule(int, Object)} where the Object parameter is an instance of * {@link AudioAttributes}. */ - @SystemApi public static final int RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET = 0x1 << 1; /** * A rule requiring the UID of the audio stream to match that specified. * This mixing rule can be added with {@link Builder#addMixRule(int, Object)} where the Object * parameter is an instance of {@link java.lang.Integer}. */ - @SystemApi public static final int RULE_MATCH_UID = 0x1 << 2; private final static int RULE_EXCLUSION_MASK = 0x8000; @@ -239,7 +236,6 @@ public class AudioMixingRule { /** * Builder class for {@link AudioMixingRule} objects */ - @SystemApi public static class Builder { private ArrayList<AudioMixMatchCriterion> mCriteria; private int mTargetMixType = AudioMix.MIX_TYPE_INVALID; @@ -247,7 +243,6 @@ public class AudioMixingRule { /** * Constructs a new Builder with no rules. */ - @SystemApi public Builder() { mCriteria = new ArrayList<AudioMixMatchCriterion>(); } @@ -262,7 +257,6 @@ public class AudioMixingRule { * @throws IllegalArgumentException * @see #excludeRule(AudioAttributes, int) */ - @SystemApi public Builder addRule(AudioAttributes attrToMatch, int rule) throws IllegalArgumentException { if (!isValidAttributesSystemApiRule(rule)) { @@ -291,7 +285,6 @@ public class AudioMixingRule { * @throws IllegalArgumentException * @see #addRule(AudioAttributes, int) */ - @SystemApi public Builder excludeRule(AudioAttributes attrToMatch, int rule) throws IllegalArgumentException { if (!isValidAttributesSystemApiRule(rule)) { @@ -313,7 +306,6 @@ public class AudioMixingRule { * @throws IllegalArgumentException * @see #excludeMixRule(int, Object) */ - @SystemApi public Builder addMixRule(int rule, Object property) throws IllegalArgumentException { if (!isValidSystemApiRule(rule)) { throw new IllegalArgumentException("Illegal rule value " + rule); @@ -343,7 +335,6 @@ public class AudioMixingRule { * @return the same Builder instance. * @throws IllegalArgumentException */ - @SystemApi public Builder excludeMixRule(int rule, Object property) throws IllegalArgumentException { if (!isValidSystemApiRule(rule)) { throw new IllegalArgumentException("Illegal rule value " + rule); diff --git a/media/java/android/media/audiopolicy/AudioPolicy.java b/media/java/android/media/audiopolicy/AudioPolicy.java index 11107e2dd420..6103f55745f9 100644 --- a/media/java/android/media/audiopolicy/AudioPolicy.java +++ b/media/java/android/media/audiopolicy/AudioPolicy.java @@ -58,12 +58,10 @@ public class AudioPolicy { /** * The status of an audio policy that is valid but cannot be used because it is not registered. */ - @SystemApi public static final int POLICY_STATUS_UNREGISTERED = 1; /** * The status of an audio policy that is valid, successfully registered and thus active. */ - @SystemApi public static final int POLICY_STATUS_REGISTERED = 2; private int mStatus; @@ -75,7 +73,6 @@ public class AudioPolicy { * The behavior of a policy with regards to audio focus where it relies on the application * to do the ducking, the is the legacy and default behavior. */ - @SystemApi public static final int FOCUS_POLICY_DUCKING_IN_APP = 0; public static final int FOCUS_POLICY_DUCKING_DEFAULT = FOCUS_POLICY_DUCKING_IN_APP; /** @@ -85,7 +82,6 @@ public class AudioPolicy { * <br>Can only be used after having set a listener with * {@link AudioPolicy#setAudioPolicyFocusListener(AudioPolicyFocusListener)}. */ - @SystemApi public static final int FOCUS_POLICY_DUCKING_IN_POLICY = 1; private AudioPolicyFocusListener mFocusListener; @@ -133,7 +129,6 @@ public class AudioPolicy { * Builder class for {@link AudioPolicy} objects. * By default the policy to be created doesn't govern audio focus decisions. */ - @SystemApi public static class Builder { private ArrayList<AudioMix> mMixes; private Context mContext; @@ -147,7 +142,6 @@ public class AudioPolicy { * Constructs a new Builder with no audio mixes. * @param context the context for the policy */ - @SystemApi public Builder(Context context) { mMixes = new ArrayList<AudioMix>(); mContext = context; @@ -159,7 +153,6 @@ public class AudioPolicy { * @return the same Builder instance. * @throws IllegalArgumentException */ - @SystemApi public Builder addMix(@NonNull AudioMix mix) throws IllegalArgumentException { if (mix == null) { throw new IllegalArgumentException("Illegal null AudioMix argument"); @@ -174,7 +167,6 @@ public class AudioPolicy { * @return the same Builder instance. * @throws IllegalArgumentException */ - @SystemApi public Builder setLooper(@NonNull Looper looper) throws IllegalArgumentException { if (looper == null) { throw new IllegalArgumentException("Illegal null Looper argument"); @@ -187,7 +179,6 @@ public class AudioPolicy { * Sets the audio focus listener for the policy. * @param l a {@link AudioPolicy.AudioPolicyFocusListener} */ - @SystemApi public void setAudioPolicyFocusListener(AudioPolicyFocusListener l) { mFocusListener = l; } @@ -201,7 +192,6 @@ public class AudioPolicy { * @param enforce true if the policy will govern audio focus decisions. * @return the same Builder instance. */ - @SystemApi public Builder setIsAudioFocusPolicy(boolean isFocusPolicy) { mIsFocusPolicy = isFocusPolicy; return this; @@ -211,12 +201,10 @@ public class AudioPolicy { * Sets the audio policy status listener. * @param l a {@link AudioPolicy.AudioPolicyStatusListener} */ - @SystemApi public void setAudioPolicyStatusListener(AudioPolicyStatusListener l) { mStatusListener = l; } - @SystemApi /** * Sets the callback to receive all volume key-related events. * The callback will only be called if the device is configured to handle volume events @@ -240,7 +228,6 @@ public class AudioPolicy { * {@link AudioPolicy.AudioPolicyStatusListener} but the policy was configured * as an audio focus policy with {@link #setIsAudioFocusPolicy(boolean)}. */ - @SystemApi public AudioPolicy build() { if (mStatusListener != null) { // the AudioPolicy status listener includes updates on each mix activity state @@ -258,7 +245,6 @@ public class AudioPolicy { } /** - * @hide * Update the current configuration of the set of audio mixes by adding new ones, while * keeping the policy registered. * This method can only be called on a registered policy. @@ -266,7 +252,6 @@ public class AudioPolicy { * @return {@link AudioManager#SUCCESS} if the change was successful, {@link AudioManager#ERROR} * otherwise. */ - @SystemApi public int attachMixes(@NonNull List<AudioMix> mixes) { if (mixes == null) { throw new IllegalArgumentException("Illegal null list of AudioMix"); @@ -299,7 +284,6 @@ public class AudioPolicy { } /** - * @hide * Update the current configuration of the set of audio mixes by removing some, while * keeping the policy registered. * This method can only be called on a registered policy. @@ -307,7 +291,6 @@ public class AudioPolicy { * @return {@link AudioManager#SUCCESS} if the change was successful, {@link AudioManager#ERROR} * otherwise. */ - @SystemApi public int detachMixes(@NonNull List<AudioMix> mixes) { if (mixes == null) { throw new IllegalArgumentException("Illegal null list of AudioMix"); @@ -405,7 +388,6 @@ public class AudioPolicy { * Returns the current behavior for audio focus-related ducking. * @return {@link #FOCUS_POLICY_DUCKING_IN_APP} or {@link #FOCUS_POLICY_DUCKING_IN_POLICY} */ - @SystemApi public int getFocusDuckingBehavior() { return mConfig.mDuckingPolicy; } @@ -422,7 +404,6 @@ public class AudioPolicy { * @throws IllegalArgumentException * @throws IllegalStateException */ - @SystemApi public int setFocusDuckingBehavior(int behavior) throws IllegalArgumentException, IllegalStateException { if ((behavior != FOCUS_POLICY_DUCKING_IN_APP) @@ -466,7 +447,6 @@ public class AudioPolicy { * with {@link AudioManager#registerAudioPolicy(AudioPolicy)}. * @throws IllegalArgumentException */ - @SystemApi public AudioRecord createAudioRecordSink(AudioMix mix) throws IllegalArgumentException { if (!policyReadyToUse()) { Log.e(TAG, "Cannot create AudioRecord sink for AudioMix"); @@ -506,7 +486,6 @@ public class AudioPolicy { * with {@link AudioManager#registerAudioPolicy(AudioPolicy)}. * @throws IllegalArgumentException */ - @SystemApi public AudioTrack createAudioTrackSource(AudioMix mix) throws IllegalArgumentException { if (!policyReadyToUse()) { Log.e(TAG, "Cannot create AudioTrack source for AudioMix"); @@ -528,18 +507,15 @@ public class AudioPolicy { return at; } - @SystemApi public int getStatus() { return mStatus; } - @SystemApi public static abstract class AudioPolicyStatusListener { public void onStatusChange() {} public void onMixStateUpdate(AudioMix mix) {} } - @SystemApi public static abstract class AudioPolicyFocusListener { public void onAudioFocusGrant(AudioFocusInfo afi, int requestResult) {} public void onAudioFocusLoss(AudioFocusInfo afi, boolean wasNotified) {} @@ -563,7 +539,6 @@ public class AudioPolicy { public void onAudioFocusAbandon(AudioFocusInfo afi) {} } - @SystemApi /** * Callback class to receive volume change-related events. * See {@link #Builder.setAudioPolicyVolumeCallback(AudioPolicyCallback)} to configure the diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java index 143182f83ace..a5121a0d7f5e 100644 --- a/media/java/android/media/tv/TvInputManager.java +++ b/media/java/android/media/tv/TvInputManager.java @@ -1330,7 +1330,6 @@ public final class TvInputManager { * * @return the list of content ratings blocked by the user. */ - @SystemApi public List<TvContentRating> getBlockedRatings() { try { List<TvContentRating> ratings = new ArrayList<>(); diff --git a/media/jni/android_media_MediaExtractor.cpp b/media/jni/android_media_MediaExtractor.cpp index 15957c6a9c5e..dad0e53963b0 100644 --- a/media/jni/android_media_MediaExtractor.cpp +++ b/media/jni/android_media_MediaExtractor.cpp @@ -494,17 +494,17 @@ static jlong android_media_MediaExtractor_getSampleTime( if (extractor == NULL) { jniThrowException(env, "java/lang/IllegalStateException", NULL); - return -1ll; + return -1LL; } int64_t sampleTimeUs; status_t err = extractor->getSampleTime(&sampleTimeUs); if (err == ERROR_END_OF_STREAM) { - return -1ll; + return -1LL; } else if (err != OK) { jniThrowException(env, "java/lang/IllegalArgumentException", NULL); - return -1ll; + return -1LL; } return (jlong) sampleTimeUs; @@ -516,17 +516,17 @@ static jlong android_media_MediaExtractor_getSampleSize( if (extractor == NULL) { jniThrowException(env, "java/lang/IllegalStateException", NULL); - return -1ll; + return -1LL; } size_t sampleSize; status_t err = extractor->getSampleSize(&sampleSize); if (err == ERROR_END_OF_STREAM) { - return -1ll; + return -1LL; } else if (err != OK) { jniThrowException(env, "java/lang/IllegalArgumentException", NULL); - return -1ll; + return -1LL; } return (jlong) sampleSize; @@ -828,13 +828,13 @@ static jlong android_media_MediaExtractor_getCachedDurationUs( if (extractor == NULL) { jniThrowException(env, "java/lang/IllegalStateException", NULL); - return -1ll; + return -1LL; } int64_t cachedDurationUs; bool eos; if (!extractor->getCachedDuration(&cachedDurationUs, &eos)) { - return -1ll; + return -1LL; } return (jlong) cachedDurationUs; diff --git a/media/jni/audioeffect/android_media_Visualizer.cpp b/media/jni/audioeffect/android_media_Visualizer.cpp index b7d7b0339376..45de36ed3e4d 100644 --- a/media/jni/audioeffect/android_media_Visualizer.cpp +++ b/media/jni/audioeffect/android_media_Visualizer.cpp @@ -440,6 +440,7 @@ static void android_media_visualizer_native_release(JNIEnv *env, jobject thiz) if (lpVisualizer == 0) { return; } + lpVisualizer->release(); } // delete the JNI data VisualizerJniStorage* lpJniStorage = diff --git a/native/android/libandroid.map.txt b/native/android/libandroid.map.txt index ac5ded60bf6b..f840d5e2f968 100644 --- a/native/android/libandroid.map.txt +++ b/native/android/libandroid.map.txt @@ -218,6 +218,10 @@ LIBANDROID { android_getaddrinfofornetwork; # introduced=23 android_setprocnetwork; # introduced=23 android_setsocknetwork; # introduced=23 + android_res_cancel; # introduced=29 + android_res_nquery; # introduced=29 + android_res_nresult; # introduced=29 + android_res_nsend; # introduced=29 local: *; }; diff --git a/native/android/libandroid_net.map.txt b/native/android/libandroid_net.map.txt index 9b5a5a1f4b52..be3531da462d 100644 --- a/native/android/libandroid_net.map.txt +++ b/native/android/libandroid_net.map.txt @@ -1,10 +1,15 @@ -# These functions have been part of the NDK since API 24. # They are also all available to vendor code. LIBANDROID_NET { global: + # These functions have been part of the NDK since API 24. + android_getaddrinfofornetwork; # vndk android_setsocknetwork; # vndk android_setprocnetwork; # vndk - android_getaddrinfofornetwork; # vndk + # These functions have been part of the NDK since API 29. + android_res_cancel; # vndk + android_res_nquery; # vndk + android_res_nresult; # vndk + android_res_nsend; # vndk local: *; }; diff --git a/native/android/net.c b/native/android/net.c index 60296a7bd00c..4cac371f313b 100644 --- a/native/android/net.c +++ b/native/android/net.c @@ -83,3 +83,29 @@ int android_getaddrinfofornetwork(net_handle_t network, 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) { + unsigned netid; + if (!getnetidfromhandle(network, &netid)) { + return -ENONET; + } + + return resNetworkQuery(netid, dname, ns_class, ns_type); +} + +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 uint8_t *msg, size_t msglen) { + unsigned netid; + if (!getnetidfromhandle(network, &netid)) { + return -ENONET; + } + + return resNetworkSend(netid, msg, msglen); +} + +void android_res_cancel(int nsend_fd) { + resNetworkCancel(nsend_fd); +} diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp new file mode 100644 index 000000000000..55bb5175c28d --- /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 000000000000..d1c5cb67197e --- /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 000000000000..5afaf586f74d --- /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/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java index a3c1fc6ff265..fd80edf839bc 100644 --- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java +++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java @@ -62,6 +62,7 @@ import java.io.File; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.ref.WeakReference; import java.text.Collator; import java.text.Normalizer; import java.text.Normalizer.Form; @@ -132,7 +133,7 @@ public class ApplicationsState { boolean mSessionsChanged; // Temporary for dispatching session callbacks. Only touched by main thread. - final ArrayList<Session> mActiveSessions = new ArrayList<Session>(); + final ArrayList<WeakReference<Session>> mActiveSessions = new ArrayList<>(); final HandlerThread mThread; final BackgroundHandler mBackgroundHandler; @@ -618,7 +619,7 @@ public class ApplicationsState { for (int i=0; i<mSessions.size(); i++) { Session s = mSessions.get(i); if (s.mResumed) { - mActiveSessions.add(s); + mActiveSessions.add(new WeakReference<>(s)); } } } @@ -830,46 +831,70 @@ public class ApplicationsState { rebuildActiveSessions(); switch (msg.what) { case MSG_REBUILD_COMPLETE: { - Session s = (Session)msg.obj; - if (mActiveSessions.contains(s)) { - s.mCallbacks.onRebuildComplete(s.mLastAppList); + Session s = (Session) msg.obj; + for (WeakReference<Session> sessionRef : mActiveSessions) { + final Session session = sessionRef.get(); + if (session != null && session == s) { + s.mCallbacks.onRebuildComplete(s.mLastAppList); + } } } break; case MSG_PACKAGE_LIST_CHANGED: { - for (int i=0; i<mActiveSessions.size(); i++) { - mActiveSessions.get(i).mCallbacks.onPackageListChanged(); + for (WeakReference<Session> sessionRef : mActiveSessions) { + final Session session = sessionRef.get(); + if (session != null) { + session.mCallbacks.onPackageListChanged(); + } } } break; case MSG_PACKAGE_ICON_CHANGED: { - for (int i=0; i<mActiveSessions.size(); i++) { - mActiveSessions.get(i).mCallbacks.onPackageIconChanged(); + for (WeakReference<Session> sessionRef : mActiveSessions) { + final Session session = sessionRef.get(); + if (session != null) { + session.mCallbacks.onPackageIconChanged(); + } } } break; case MSG_PACKAGE_SIZE_CHANGED: { - for (int i=0; i<mActiveSessions.size(); i++) { - mActiveSessions.get(i).mCallbacks.onPackageSizeChanged( - (String)msg.obj); + for (WeakReference<Session> sessionRef : mActiveSessions) { + final Session session = sessionRef.get(); + if (session != null) { + session.mCallbacks.onPackageSizeChanged( + (String) msg.obj); + } } } break; case MSG_ALL_SIZES_COMPUTED: { - for (int i=0; i<mActiveSessions.size(); i++) { - mActiveSessions.get(i).mCallbacks.onAllSizesComputed(); + for (WeakReference<Session> sessionRef : mActiveSessions) { + final Session session = sessionRef.get(); + if (session != null) { + session.mCallbacks.onAllSizesComputed(); + } } } break; case MSG_RUNNING_STATE_CHANGED: { - for (int i=0; i<mActiveSessions.size(); i++) { - mActiveSessions.get(i).mCallbacks.onRunningStateChanged( - msg.arg1 != 0); + for (WeakReference<Session> sessionRef : mActiveSessions) { + final Session session = sessionRef.get(); + if (session != null) { + session.mCallbacks.onRunningStateChanged( + msg.arg1 != 0); + } } } break; case MSG_LAUNCHER_INFO_CHANGED: { - for (int i=0; i<mActiveSessions.size(); i++) { - mActiveSessions.get(i).mCallbacks.onLauncherInfoChanged(); + for (WeakReference<Session> sessionRef : mActiveSessions) { + final Session session = sessionRef.get(); + if (session != null) { + session.mCallbacks.onLauncherInfoChanged(); + } } } break; case MSG_LOAD_ENTRIES_COMPLETE: { - for (int i=0; i<mActiveSessions.size(); i++) { - mActiveSessions.get(i).mCallbacks.onLoadEntriesCompleted(); + for (WeakReference<Session> sessionRef : mActiveSessions) { + final Session session = sessionRef.get(); + if (session != null) { + session.mCallbacks.onLoadEntriesCompleted(); + } } } break; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothManager.java index 373247162563..1c50953bac12 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothManager.java @@ -19,6 +19,8 @@ package com.android.settingslib.bluetooth; import android.content.Context; import android.util.Log; +import java.lang.ref.WeakReference; + /** * LocalBluetoothManager provides a simplified interface on top of a subset of * the Bluetooth API. Note that {@link #getInstance} will return null @@ -34,7 +36,7 @@ public class LocalBluetoothManager { private final Context mContext; /** If a BT-related activity is in the foreground, this will be it. */ - private Context mForegroundActivity; + private WeakReference<Context> mForegroundActivity; private final LocalBluetoothAdapter mLocalAdapter; @@ -85,17 +87,19 @@ public class LocalBluetoothManager { } public Context getForegroundActivity() { - return mForegroundActivity; + return mForegroundActivity == null + ? null + : mForegroundActivity.get(); } public boolean isForegroundActivity() { - return mForegroundActivity != null; + return mForegroundActivity != null && mForegroundActivity.get() != null; } public synchronized void setForegroundActivity(Context context) { if (context != null) { Log.d(TAG, "setting foreground activity to non-null context"); - mForegroundActivity = context; + mForegroundActivity = new WeakReference<>(context); } else { if (mForegroundActivity != null) { Log.d(TAG, "setting foreground activity to null"); diff --git a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java index 988060eac64d..e5d97c9b4a7b 100644 --- a/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java +++ b/packages/SettingsLib/src/com/android/settingslib/dream/DreamBackend.java @@ -36,12 +36,12 @@ import android.util.AttributeSet; import android.util.Log; import android.util.Xml; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -97,15 +97,15 @@ public class DreamBackend { } public DreamBackend(Context context) { - mContext = context; + mContext = context.getApplicationContext(); mDreamManager = IDreamManager.Stub.asInterface( ServiceManager.getService(DreamService.DREAM_SERVICE)); mComparator = new DreamInfoComparator(getDefaultDream()); - mDreamsEnabledByDefault = context.getResources() + mDreamsEnabledByDefault = mContext.getResources() .getBoolean(com.android.internal.R.bool.config_dreamsEnabledByDefault); - mDreamsActivatedOnSleepByDefault = context.getResources() + mDreamsActivatedOnSleepByDefault = mContext.getResources() .getBoolean(com.android.internal.R.bool.config_dreamsActivatedOnSleepByDefault); - mDreamsActivatedOnDockByDefault = context.getResources() + mDreamsActivatedOnDockByDefault = mContext.getResources() .getBoolean(com.android.internal.R.bool.config_dreamsActivatedOnDockByDefault); } diff --git a/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java b/packages/SettingsLib/src/com/android/settingslib/users/UserManagerHelper.java index 4c45a75d876a..cb2a088f738b 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.content.pm.UserInfo; 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 @@ import java.util.List; @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 @@ public final class UserManagerHelper { * @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 adeff5dd28b9..9306219415cd 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/plugin/src/com/android/systemui/plugins/qs/QSTile.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java index bc9f52c2f88b..bca353050c46 100644 --- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java +++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java @@ -43,7 +43,7 @@ public interface QSTile { boolean isAvailable(); void setTileSpec(String tileSpec); - void clearState(); + @Deprecated default void clearState() {} void refreshState(); void addCallback(Callback callback); diff --git a/packages/SystemUI/res/layout/navigation_layout.xml b/packages/SystemUI/res/layout/navigation_layout.xml index baaf699c278a..d72021e27e0b 100644 --- a/packages/SystemUI/res/layout/navigation_layout.xml +++ b/packages/SystemUI/res/layout/navigation_layout.xml @@ -18,14 +18,16 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:systemui="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:layout_marginStart="@dimen/rounded_corner_content_padding" + android:layout_marginEnd="@dimen/rounded_corner_content_padding" + android:paddingStart="@dimen/nav_content_padding" + android:paddingEnd="@dimen/nav_content_padding"> <com.android.systemui.statusbar.phone.NearestTouchFrame android:id="@+id/nav_buttons" android:layout_width="match_parent" android:layout_height="match_parent" - android:paddingStart="@dimen/rounded_corner_content_padding" - android:paddingEnd="@dimen/rounded_corner_content_padding" android:clipChildren="false" android:clipToPadding="false"> @@ -34,8 +36,6 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" - android:paddingStart="@dimen/nav_content_padding" - android:paddingEnd="@dimen/nav_content_padding" android:clipToPadding="false" android:clipChildren="false" /> @@ -46,8 +46,6 @@ android:layout_gravity="center" android:gravity="center" android:orientation="horizontal" - android:paddingStart="@dimen/nav_content_padding" - android:paddingEnd="@dimen/nav_content_padding" android:clipToPadding="false" android:clipChildren="false" /> diff --git a/packages/SystemUI/res/layout/navigation_layout_rot90.xml b/packages/SystemUI/res/layout/navigation_layout_rot90.xml index 6d5b77885a09..24a0c71f3bad 100644 --- a/packages/SystemUI/res/layout/navigation_layout_rot90.xml +++ b/packages/SystemUI/res/layout/navigation_layout_rot90.xml @@ -18,14 +18,16 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:systemui="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" - android:layout_height="match_parent"> + android:layout_height="match_parent" + android:layout_marginTop="@dimen/rounded_corner_content_padding" + android:layout_marginBottom="@dimen/rounded_corner_content_padding" + android:paddingTop="@dimen/nav_content_padding" + android:paddingBottom="@dimen/nav_content_padding"> <com.android.systemui.statusbar.phone.NearestTouchFrame android:id="@+id/nav_buttons" android:layout_width="match_parent" android:layout_height="match_parent" - android:paddingTop="@dimen/rounded_corner_content_padding" - android:paddingBottom="@dimen/rounded_corner_content_padding" android:clipChildren="false" android:clipToPadding="false"> @@ -34,10 +36,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - android:paddingTop="@dimen/nav_content_padding" - android:paddingBottom="@dimen/nav_content_padding" - android:clipChildren="false" - android:clipToPadding="false" /> + android:clipToPadding="false" + android:clipChildren="false" /> <com.android.systemui.statusbar.phone.ReverseLinearLayout android:id="@+id/center_group" @@ -45,10 +45,8 @@ android:layout_height="match_parent" android:gravity="center" android:orientation="vertical" - android:paddingTop="@dimen/nav_content_padding" - android:paddingBottom="@dimen/nav_content_padding" - android:clipChildren="false" - android:clipToPadding="false" /> + android:clipToPadding="false" + android:clipChildren="false" /> </com.android.systemui.statusbar.phone.NearestTouchFrame> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index be80d52f2a57..79e1fae98c21 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -943,9 +943,9 @@ <dimen name="bottom_padding">48dp</dimen> <dimen name="edge_margin">8dp</dimen> - <dimen name="rounded_corner_radius">0dp</dimen> - <dimen name="rounded_corner_radius_top">0dp</dimen> - <dimen name="rounded_corner_radius_bottom">0dp</dimen> + <dimen name="rounded_corner_radius">@*android:dimen/rounded_corner_radius</dimen> + <dimen name="rounded_corner_radius_top">@*android:dimen/rounded_corner_radius_top</dimen> + <dimen name="rounded_corner_radius_bottom">@*android:dimen/rounded_corner_radius_bottom</dimen> <dimen name="rounded_corner_content_padding">0dp</dimen> <dimen name="nav_content_padding">0dp</dimen> <dimen name="nav_quick_scrub_track_edge_padding">24dp</dimen> diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java index 35abb0a523a1..03fb9bbdbd4e 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java @@ -15,7 +15,6 @@ */ package com.android.keyguard; -import android.R.style; import android.app.Activity; import android.app.AlertDialog; import android.app.admin.DevicePolicyManager; @@ -26,7 +25,6 @@ import android.util.AttributeSet; import android.util.Log; import android.util.Slog; import android.util.StatsLog; -import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.View; import android.view.WindowManager; @@ -142,6 +140,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe mSecurityViewFlipper.addView(v); updateSecurityView(v); view = (KeyguardSecurityView)v; + view.reset(); } return view; @@ -209,7 +208,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe if (messageId != 0) { final String message = mContext.getString(messageId, - KeyguardUpdateMonitor.getInstance(mContext).getFailedUnlockAttempts(userId), + mLockPatternUtils.getCurrentFailedPasswordAttempts(userId), timeoutInSeconds); showDialog(null, message); } @@ -254,8 +253,8 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe } private void reportFailedUnlockAttempt(int userId, int timeoutMs) { - final KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext); - final int failedAttempts = monitor.getFailedUnlockAttempts(userId) + 1; // +1 for this time + // +1 for this time + final int failedAttempts = mLockPatternUtils.getCurrentFailedPasswordAttempts(userId) + 1; if (DEBUG) Log.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts); @@ -289,7 +288,6 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe showWipeDialog(failedAttempts, userType); } } - monitor.reportFailedStrongAuthUnlockAttempt(userId); mLockPatternUtils.reportFailedPasswordAttempt(userId); if (timeoutMs > 0) { mLockPatternUtils.reportPasswordLockout(timeoutMs, userId); @@ -432,7 +430,6 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe if (success) { StatsLog.write(StatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED, StatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED__RESULT__SUCCESS); - monitor.clearFailedUnlockAttempts(); mLockPatternUtils.reportSuccessfulPasswordAttempt(userId); } else { StatsLog.write(StatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED, diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java index ef3aa42727e9..0e2181532630 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -209,9 +209,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { // Battery status private BatteryStatus mBatteryStatus; - // Password attempts - private SparseIntArray mFailedAttempts = new SparseIntArray(); - private final StrongAuthTracker mStrongAuthTracker; private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>> @@ -1800,22 +1797,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { return mDeviceProvisioned; } - public void clearFailedUnlockAttempts() { - mFailedAttempts.delete(sCurrentUser); - } - public ServiceState getServiceState(int subId) { return mServiceStates.get(subId); } - public int getFailedUnlockAttempts(int userId) { - return mFailedAttempts.get(userId, 0); - } - - public void reportFailedStrongAuthUnlockAttempt(int userId) { - mFailedAttempts.put(userId, getFailedUnlockAttempts(userId) + 1); - } - public void clearFingerprintRecognized() { mUserFingerprintAuthenticated.clear(); mTrustManager.clearAllFingerprints(); diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java index 79302f2aa2ff..16b54b4cea5b 100644 --- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java +++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java @@ -39,10 +39,13 @@ import android.graphics.PixelFormat; import android.graphics.Rect; import android.graphics.Region; import android.hardware.display.DisplayManager; +import android.os.Handler; +import android.os.HandlerThread; import android.os.SystemProperties; import android.provider.Settings.Secure; import androidx.annotation.VisibleForTesting; import android.util.DisplayMetrics; +import android.util.Log; import android.view.DisplayCutout; import android.view.DisplayInfo; import android.view.Gravity; @@ -57,6 +60,7 @@ import android.view.WindowManager; import android.widget.FrameLayout; import android.widget.ImageView; +import com.android.internal.util.Preconditions; import com.android.systemui.RegionInterceptingFrameLayout.RegionInterceptableView; import com.android.systemui.fragments.FragmentHostManager; import com.android.systemui.fragments.FragmentHostManager.FragmentListener; @@ -74,6 +78,9 @@ import com.android.systemui.util.leak.RotationUtils; * for antialiasing and emulation purposes. */ public class ScreenDecorations extends SystemUI implements Tunable { + private static final boolean DEBUG = false; + private static final String TAG = "ScreenDecorations"; + public static final String SIZE = "sysui_rounded_size"; public static final String PADDING = "sysui_rounded_content_padding"; private static final boolean DEBUG_SCREENSHOT_ROUNDED_CORNERS = @@ -82,9 +89,9 @@ public class ScreenDecorations extends SystemUI implements Tunable { private DisplayManager mDisplayManager; private DisplayManager.DisplayListener mDisplayListener; - private int mRoundedDefault; - private int mRoundedDefaultTop; - private int mRoundedDefaultBottom; + @VisibleForTesting protected int mRoundedDefault; + @VisibleForTesting protected int mRoundedDefaultTop; + @VisibleForTesting protected int mRoundedDefaultBottom; private View mOverlay; private View mBottomOverlay; private float mDensity; @@ -93,26 +100,30 @@ public class ScreenDecorations extends SystemUI implements Tunable { private DisplayCutoutView mCutoutTop; private DisplayCutoutView mCutoutBottom; private boolean mPendingRotationChange; + private Handler mHandler; @Override public void start() { + mHandler = startHandlerThread(); + mHandler.post(this::startOnScreenDecorationsThread); + setupStatusBarPaddingIfNeeded(); + } + + @VisibleForTesting + Handler startHandlerThread() { + HandlerThread thread = new HandlerThread("ScreenDecorations"); + thread.start(); + return thread.getThreadHandler(); + } + + private void startOnScreenDecorationsThread() { + mRotation = RotationUtils.getExactRotation(mContext); mWindowManager = mContext.getSystemService(WindowManager.class); - mRoundedDefault = mContext.getResources().getDimensionPixelSize( - R.dimen.rounded_corner_radius); - mRoundedDefaultTop = mContext.getResources().getDimensionPixelSize( - R.dimen.rounded_corner_radius_top); - mRoundedDefaultBottom = mContext.getResources().getDimensionPixelSize( - R.dimen.rounded_corner_radius_bottom); + updateRoundedCornerRadii(); if (hasRoundedCorners() || shouldDrawCutout()) { setupDecorations(); } - int padding = mContext.getResources().getDimensionPixelSize( - R.dimen.rounded_corner_content_padding); - if (padding != 0) { - setupPadding(padding); - } - mDisplayListener = new DisplayManager.DisplayListener() { @Override public void onDisplayAdded(int displayId) { @@ -126,8 +137,8 @@ public class ScreenDecorations extends SystemUI implements Tunable { @Override public void onDisplayChanged(int displayId) { - if (mOverlay != null && mBottomOverlay != null - && mRotation != RotationUtils.getExactRotation(mContext)) { + final int newRotation = RotationUtils.getExactRotation(mContext); + if (mOverlay != null && mBottomOverlay != null && mRotation != newRotation) { // We cannot immediately update the orientation. Otherwise // WindowManager is still deferring layout until it has finished dispatching // the config changes, which may cause divergence between what we draw @@ -136,20 +147,24 @@ public class ScreenDecorations extends SystemUI implements Tunable { // - we are trying to redraw. This because WM resized our window and told us to. // - the config change has been dispatched, so WM is no longer deferring layout. mPendingRotationChange = true; + if (DEBUG) { + Log.i(TAG, "Rotation changed, deferring " + newRotation + ", staying at " + + mRotation); + } + mOverlay.getViewTreeObserver().addOnPreDrawListener( - new RestartingPreDrawListener(mOverlay)); + new RestartingPreDrawListener(mOverlay, newRotation)); mBottomOverlay.getViewTreeObserver().addOnPreDrawListener( - new RestartingPreDrawListener(mBottomOverlay)); - + new RestartingPreDrawListener(mBottomOverlay, newRotation)); } updateOrientation(); } }; - mRotation = -1; mDisplayManager = (DisplayManager) mContext.getSystemService( Context.DISPLAY_SERVICE); - mDisplayManager.registerDisplayListener(mDisplayListener, null); + mDisplayManager.registerDisplayListener(mDisplayListener, mHandler); + updateOrientation(); } private void setupDecorations() { @@ -179,10 +194,11 @@ public class ScreenDecorations extends SystemUI implements Tunable { mWindowManager.getDefaultDisplay().getMetrics(metrics); mDensity = metrics.density; - Dependency.get(TunerService.class).addTunable(this, SIZE); + Dependency.get(Dependency.MAIN_HANDLER).post( + () -> Dependency.get(TunerService.class).addTunable(this, SIZE)); // Watch color inversion and invert the overlay as needed. - SecureSetting setting = new SecureSetting(mContext, Dependency.get(Dependency.MAIN_HANDLER), + SecureSetting setting = new SecureSetting(mContext, mHandler, Secure.ACCESSIBILITY_DISPLAY_INVERSION_ENABLED) { @Override protected void handleValueChanged(int value, boolean observedChange) { @@ -215,18 +231,38 @@ public class ScreenDecorations extends SystemUI implements Tunable { .start(); } }); + + mOverlay.getViewTreeObserver().addOnPreDrawListener( + new ValidatingPreDrawListener(mOverlay)); + mBottomOverlay.getViewTreeObserver().addOnPreDrawListener( + new ValidatingPreDrawListener(mBottomOverlay)); } @Override protected void onConfigurationChanged(Configuration newConfig) { - mPendingRotationChange = false; - updateOrientation(); - if (shouldDrawCutout() && mOverlay == null) { - setupDecorations(); - } + mHandler.post(() -> { + int oldRotation = mRotation; + mPendingRotationChange = false; + updateOrientation(); + updateRoundedCornerRadii(); + if (DEBUG) Log.i(TAG, "onConfigChanged from rot " + oldRotation + " to " + mRotation); + if (shouldDrawCutout() && mOverlay == null) { + setupDecorations(); + } + if (mOverlay != null) { + // Updating the layout params ensures that ViewRootImpl will call relayoutWindow(), + // which ensures that the forced seamless rotation will end, even if we updated + // the rotation before window manager was ready (and was still waiting for sending + // the updated rotation). + updateLayoutParams(); + } + }); } - protected void updateOrientation() { + private void updateOrientation() { + Preconditions.checkState(mHandler.getLooper().getThread() == Thread.currentThread(), + "must call on " + mHandler.getLooper().getThread() + + ", but was " + Thread.currentThread()); if (mPendingRotationChange) { return; } @@ -241,6 +277,26 @@ public class ScreenDecorations extends SystemUI implements Tunable { } } + private void updateRoundedCornerRadii() { + final int newRoundedDefault = mContext.getResources().getDimensionPixelSize( + R.dimen.rounded_corner_radius); + final int newRoundedDefaultTop = mContext.getResources().getDimensionPixelSize( + R.dimen.rounded_corner_radius_top); + final int newRoundedDefaultBottom = mContext.getResources().getDimensionPixelSize( + R.dimen.rounded_corner_radius_bottom); + + final boolean roundedCornersChanged = mRoundedDefault != newRoundedDefault + || mRoundedDefaultBottom != newRoundedDefaultBottom + || mRoundedDefaultTop != newRoundedDefaultTop; + + if (roundedCornersChanged) { + mRoundedDefault = newRoundedDefault; + mRoundedDefaultTop = newRoundedDefaultTop; + mRoundedDefaultBottom = newRoundedDefaultBottom; + onTuningChanged(SIZE, null); + } + } + private void updateViews() { View topLeft = mOverlay.findViewById(R.id.left); View topRight = mOverlay.findViewById(R.id.right); @@ -306,7 +362,19 @@ public class ScreenDecorations extends SystemUI implements Tunable { com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout); } - private void setupPadding(int padding) { + + private void setupStatusBarPaddingIfNeeded() { + // TODO: This should be moved to a more appropriate place, as it is not related to the + // screen decorations overlay. + int padding = mContext.getResources().getDimensionPixelSize( + R.dimen.rounded_corner_content_padding); + if (padding != 0) { + setupStatusBarPadding(padding); + } + + } + + private void setupStatusBarPadding(int padding) { // Add some padding to all the content near the edge of the screen. StatusBar sb = getComponent(StatusBar.class); View statusBar = (sb != null ? sb.getStatusBarWindow() : null); @@ -375,30 +443,32 @@ public class ScreenDecorations extends SystemUI implements Tunable { @Override public void onTuningChanged(String key, String newValue) { - if (mOverlay == null) return; - if (SIZE.equals(key)) { - int size = mRoundedDefault; - int sizeTop = mRoundedDefaultTop; - int sizeBottom = mRoundedDefaultBottom; - if (newValue != null) { - try { - size = (int) (Integer.parseInt(newValue) * mDensity); - } catch (Exception e) { + mHandler.post(() -> { + if (mOverlay == null) return; + if (SIZE.equals(key)) { + int size = mRoundedDefault; + int sizeTop = mRoundedDefaultTop; + int sizeBottom = mRoundedDefaultBottom; + if (newValue != null) { + try { + size = (int) (Integer.parseInt(newValue) * mDensity); + } catch (Exception e) { + } } - } - if (sizeTop == 0) { - sizeTop = size; - } - if (sizeBottom == 0) { - sizeBottom = size; - } + if (sizeTop == 0) { + sizeTop = size; + } + if (sizeBottom == 0) { + sizeBottom = size; + } - setSize(mOverlay.findViewById(R.id.left), sizeTop); - setSize(mOverlay.findViewById(R.id.right), sizeTop); - setSize(mBottomOverlay.findViewById(R.id.left), sizeBottom); - setSize(mBottomOverlay.findViewById(R.id.right), sizeBottom); - } + setSize(mOverlay.findViewById(R.id.left), sizeTop); + setSize(mOverlay.findViewById(R.id.right), sizeTop); + setSize(mBottomOverlay.findViewById(R.id.left), sizeBottom); + setSize(mBottomOverlay.findViewById(R.id.right), sizeBottom); + } + }); } private void setSize(View view, int pixelSize) { @@ -457,6 +527,11 @@ public class ScreenDecorations extends SystemUI implements Tunable { mVisibilityChangedListener = visibilityChangedListener; mDecorations = decorations; setId(R.id.display_cutout); + if (DEBUG) { + getViewTreeObserver().addOnDrawListener(() -> Log.i(TAG, + (mInitialStart ? "OverlayTop" : "OverlayBottom") + + " drawn in rot " + mRotation)); + } } public void setColor(int color) { @@ -692,20 +767,66 @@ public class ScreenDecorations extends SystemUI implements Tunable { private class RestartingPreDrawListener implements ViewTreeObserver.OnPreDrawListener { private final View mView; + private final int mTargetRotation; - private RestartingPreDrawListener(View view) { + private RestartingPreDrawListener(View view, int targetRotation) { mView = view; + mTargetRotation = targetRotation; } @Override public boolean onPreDraw() { - mPendingRotationChange = false; mView.getViewTreeObserver().removeOnPreDrawListener(this); + + if (mTargetRotation == mRotation) { + if (DEBUG) { + Log.i(TAG, (mView == mOverlay ? "OverlayTop" : "OverlayBottom") + + " already in target rot " + + mTargetRotation + ", allow draw without restarting it"); + } + return true; + } + + mPendingRotationChange = false; // This changes the window attributes - we need to restart the traversal for them to // take effect. updateOrientation(); + if (DEBUG) { + Log.i(TAG, (mView == mOverlay ? "OverlayTop" : "OverlayBottom") + + " restarting listener fired, restarting draw for rot " + mRotation); + } mView.invalidate(); return false; } } + + /** + * A pre-draw listener, that validates that the rotation we draw in matches the displays + * rotation before continuing the draw. + * + * This is to prevent a race condition, where we have not received the display changed event + * yet, and would thus draw in an old orientation. + */ + private class ValidatingPreDrawListener implements ViewTreeObserver.OnPreDrawListener { + + private final View mView; + + public ValidatingPreDrawListener(View view) { + mView = view; + } + + @Override + public boolean onPreDraw() { + final int displayRotation = RotationUtils.getExactRotation(mContext); + if (displayRotation != mRotation && !mPendingRotationChange) { + if (DEBUG) { + Log.i(TAG, "Drawing rot " + mRotation + ", but display is at rot " + + displayRotation + ". Restarting draw"); + } + mView.invalidate(); + return false; + } + return true; + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 89688fba1cc6..33db2c8bc16f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -1647,7 +1647,6 @@ public class KeyguardViewMediator extends SystemUI { resetKeyguardDonePendingLocked(); } - mUpdateMonitor.clearFailedUnlockAttempts(); mUpdateMonitor.clearFingerprintRecognized(); if (mGoingToSleep) { diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java index da41136767aa..2e5eb342347b 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java @@ -266,9 +266,12 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { || mEstimate.estimateMillis < mSevereWarningThreshold) { nb.setColor(Utils.getColorAttr(mContext, android.R.attr.colorError)); } - nb.addAction(0, - mContext.getString(R.string.battery_saver_start_action), - pendingBroadcast(ACTION_START_SAVER)); + + if (!mPowerMan.isPowerSaveMode()) { + nb.addAction(0, + mContext.getString(R.string.battery_saver_start_action), + pendingBroadcast(ACTION_START_SAVER)); + } nb.setOnlyAlertOnce(!mPlaySound); mPlaySound = false; SystemUI.overrideNotificationAppName(mContext, nb, false); diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java index 9a648d17c4ff..0b9067e5dc1f 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java @@ -333,10 +333,11 @@ public class PowerUI extends SystemUI { @VisibleForTesting boolean shouldDismissLowBatteryWarning(boolean plugged, int oldBucket, int bucket, long timeRemaining, boolean isPowerSaver) { - final boolean hybridWouldDismiss = mEnhancedEstimates.isHybridNotificationEnabled() + final boolean hybridEnabled = mEnhancedEstimates.isHybridNotificationEnabled(); + final boolean hybridWouldDismiss = hybridEnabled && timeRemaining > mEnhancedEstimates.getLowWarningThreshold(); final boolean standardWouldDismiss = (bucket > oldBucket && bucket > 0); - return isPowerSaver + return (isPowerSaver && !hybridEnabled) || plugged || (standardWouldDismiss && (!mEnhancedEstimates.isHybridNotificationEnabled() || hybridWouldDismiss)); @@ -344,14 +345,14 @@ public class PowerUI extends SystemUI { private boolean isEnhancedTrigger(boolean plugged, long timeRemaining, boolean isPowerSaver, int batteryStatus) { - if (plugged || isPowerSaver || batteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN) { + if (plugged || batteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN) { return false; } int warnLevel = mLowBatteryReminderLevels[0]; int critLevel = mLowBatteryReminderLevels[1]; - // Only show the low warning once per charge cycle - final boolean canShowWarning = !mLowWarningShownThisChargeCycle + // Only show the low warning once per charge cycle & no battery saver + final boolean canShowWarning = !mLowWarningShownThisChargeCycle && !isPowerSaver && (timeRemaining < mEnhancedEstimates.getLowWarningThreshold() || mBatteryLevel <= warnLevel); diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java index 0876a5d3f456..3fc258b1e8e9 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java @@ -285,9 +285,6 @@ public class QSPanel extends LinearLayout implements Tunable, Callback, Brightne updatePageIndicator(); - for (TileRecord r : mRecords) { - r.tile.clearState(); - } if (mListening) { refreshAllTiles(); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java index 53a576d3519d..591e9e015897 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java @@ -95,7 +95,6 @@ public class TileQueryHelper { continue; } tile.setListening(this, true); - tile.clearState(); tile.refreshState(); tile.setListening(this, false); tile.setTileSpec(spec); diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java index 834feb7781ea..022a2b4a5fbf 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileImpl.java @@ -211,10 +211,6 @@ public abstract class QSTileImpl<TState extends State> implements QSTile { mHandler.obtainMessage(H.REFRESH_STATE, arg).sendToTarget(); } - public void clearState() { - mHandler.sendEmptyMessage(H.CLEAR_STATE); - } - public void userSwitch(int newUserId) { mHandler.obtainMessage(H.USER_SWITCH, newUserId, 0).sendToTarget(); } @@ -266,11 +262,6 @@ public abstract class QSTileImpl<TState extends State> implements QSTile { public abstract Intent getLongClickIntent(); - protected void handleClearState() { - mTmpState = newTileState(); - mState = newTileState(); - } - protected void handleRefreshState(Object arg) { handleUpdateState(mTmpState, arg); final boolean changed = mTmpState.copyTo(mState); @@ -409,11 +400,10 @@ public abstract class QSTileImpl<TState extends State> implements QSTile { private static final int TOGGLE_STATE_CHANGED = 8; private static final int SCAN_STATE_CHANGED = 9; private static final int DESTROY = 10; - private static final int CLEAR_STATE = 11; - private static final int REMOVE_CALLBACKS = 12; - private static final int REMOVE_CALLBACK = 13; - private static final int SET_LISTENING = 14; - private static final int STALE = 15; + private static final int REMOVE_CALLBACKS = 11; + private static final int REMOVE_CALLBACK = 12; + private static final int SET_LISTENING = 13; + private static final int STALE = 14; @VisibleForTesting protected H(Looper looper) { @@ -467,9 +457,6 @@ public abstract class QSTileImpl<TState extends State> implements QSTile { } else if (msg.what == DESTROY) { name = "handleDestroy"; handleDestroy(); - } else if (msg.what == CLEAR_STATE) { - name = "handleClearState"; - handleClearState(); } else if (msg.what == SET_LISTENING) { name = "handleSetListeningInternal"; handleSetListeningInternal(msg.obj, msg.arg1 != 0); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java index 06f26c9cbc7c..469c3c2c60b1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationEntryManager.java @@ -667,9 +667,15 @@ public class NotificationEntryManager implements Dumpable, NotificationInflater. entry.row.getNotificationChildren(); for (int i = 0; i < notificationChildren.size(); i++) { ExpandableNotificationRow row = notificationChildren.get(i); - if ((row.getStatusBarNotification().getNotification().flags - & Notification.FLAG_FOREGROUND_SERVICE) != 0) { - // the child is a foreground service notification which we can't remove! + NotificationData.Entry childEntry = row.getEntry(); + boolean isForeground = (row.getStatusBarNotification().getNotification().flags + & Notification.FLAG_FOREGROUND_SERVICE) != 0; + boolean keepForReply = FORCE_REMOTE_INPUT_HISTORY + && (shouldKeepForRemoteInput(childEntry) + || shouldKeepForSmartReply(childEntry)); + if (isForeground || keepForReply) { + // the child is a foreground service notification which we can't remove or it's + // a child we're keeping around for reply! continue; } row.setKeepInParent(true); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java index 306319903ecb..a215ec6ecafa 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java @@ -151,12 +151,11 @@ public class NotificationShelf extends ActivatableNotificationView implements } public void fadeInTranslating() { - float translation = mShelfIcons.getTranslationY(); - mShelfIcons.setTranslationY(translation - mShelfAppearTranslation); + mShelfIcons.setTranslationY(-mShelfAppearTranslation); mShelfIcons.setAlpha(0); mShelfIcons.animate() .setInterpolator(Interpolators.DECELERATE_QUINT) - .translationY(translation) + .translationY(0) .setDuration(SHELF_IN_TRANSLATION_DURATION) .start(); mShelfIcons.animate() 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 83021ca51a55..be46d2c7e4ae 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 @@ package com.android.systemui.statusbar.car; 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 @@ public class CarStatusBar extends StatusBar implements 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/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java index 7e6abe95e226..5c18782727df 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -1358,9 +1358,7 @@ public class NotificationPanelView extends PanelView implements mQsExpansionHeight = height; updateQsExpansion(); requestScrollerTopPaddingUpdate(false /* animate */); - if (mKeyguardShowing) { - updateHeaderKeyguardAlpha(); - } + updateHeaderKeyguardAlpha(); if (mStatusBarState == StatusBarState.SHADE_LOCKED || mStatusBarState == StatusBarState.KEYGUARD) { updateKeyguardBottomAreaAlpha(); @@ -1763,6 +1761,9 @@ public class NotificationPanelView extends PanelView implements } private void updateHeaderKeyguardAlpha() { + if (!mKeyguardShowing) { + return; + } float alphaQsExpansion = 1 - Math.min(1, getQsExpansionFraction() * 2); mKeyguardStatusBar.setAlpha(Math.min(getKeyguardContentsAlpha(), alphaQsExpansion) * mKeyguardStatusBarAnimateAlpha); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java index bd73a4064908..d68e2fa34cbc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStepController.java @@ -189,7 +189,7 @@ public class QuickStepController implements GestureHelper { mNavigationBarView.getDownHitTarget() == HIT_TARGET_DEAD_ZONE; if (mOverviewEventSender.getProxy() == null || (!mNavigationBarView.isQuickScrubEnabled() && !mNavigationBarView.isQuickStepSwipeUpEnabled())) { - return false; + return deadZoneConsumed; } mNavigationBarView.requestUnbufferedDispatch(event); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java index fadc0eac9e73..a38328a8161e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java @@ -180,6 +180,15 @@ public class StatusBarWindowManager implements RemoteInputController.Callback, D mLpChanged.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; } + private void applyExpandedFlag(State state) { + if (state.panelExpanded || state.isKeyguardShowingAndNotOccluded() || state.bouncerShowing + || ENABLE_REMOTE_INPUT && state.remoteInputActive) { + mLpChanged.privateFlags |= LayoutParams.PRIVATE_FLAG_STATUS_BAR_EXPANDED; + } else { + mLpChanged.privateFlags &= ~LayoutParams.PRIVATE_FLAG_STATUS_BAR_EXPANDED; + } + } + private void applyHeight(State state) { boolean expanded = isExpanded(state); if (state.forcePluginOpen) { @@ -234,6 +243,7 @@ public class StatusBarWindowManager implements RemoteInputController.Callback, D applyKeyguardFlags(state); applyForceStatusBarVisibleFlag(state); applyFocusableFlag(state); + applyExpandedFlag(state); adjustScreenOrientation(state); applyHeight(state); applyUserActivityTimeout(state); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EncryptionHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EncryptionHelper.java index 639e50cf4e58..9c099f91bc8d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EncryptionHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EncryptionHelper.java @@ -16,7 +16,7 @@ package com.android.systemui.statusbar.policy; -import android.os.SystemProperties; +import android.sysprop.VoldProperties; /** * Helper for determining whether the phone is decrypted yet. @@ -26,7 +26,7 @@ public class EncryptionHelper { public static final boolean IS_DATA_ENCRYPTED = isDataEncrypted(); private static boolean isDataEncrypted() { - String voldState = SystemProperties.get("vold.decrypt"); + String voldState = VoldProperties.decrypt().orElse(""); return "1".equals(voldState) || "trigger_restart_min_framework".equals(voldState); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java index d6d0673e2c0b..3c16329e6f19 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java @@ -134,6 +134,10 @@ public class HotspotControllerImpl implements HotspotController, WifiManager.Sof @Override public void setHotspotEnabled(boolean enabled) { + if (mWaitingForCallback) { + if (DEBUG) Log.d(TAG, "Ignoring setHotspotEnabled; waiting for callback."); + return; + } if (enabled) { OnStartTetheringCallback callback = new OnStartTetheringCallback(); mWaitingForCallback = true; diff --git a/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java b/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java index d7c4bbf3ea1d..c97095e1860b 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java +++ b/packages/SystemUI/src/com/android/systemui/volume/SafetyWarningDialog.java @@ -21,11 +21,13 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; +import android.content.res.Resources.NotFoundException; import android.media.AudioManager; import android.util.Log; import android.view.KeyEvent; import android.view.WindowManager; + import com.android.systemui.statusbar.phone.SystemUIDialog; abstract public class SafetyWarningDialog extends SystemUIDialog @@ -40,12 +42,18 @@ abstract public class SafetyWarningDialog extends SystemUIDialog private long mShowTime; private boolean mNewVolumeUp; + private boolean mDisableOnVolumeUp; public SafetyWarningDialog(Context context, AudioManager audioManager) { super(context); mContext = context; mAudioManager = audioManager; - + try { + mDisableOnVolumeUp = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_safe_media_disable_on_volume_up); + } catch (NotFoundException e) { + mDisableOnVolumeUp = true; + } getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR); setShowForAllUsers(true); setMessage(mContext.getString(com.android.internal.R.string.safe_media_volume_warning)); @@ -63,7 +71,8 @@ abstract public class SafetyWarningDialog extends SystemUIDialog @Override public boolean onKeyDown(int keyCode, KeyEvent event) { - if (keyCode == KeyEvent.KEYCODE_VOLUME_UP && event.getRepeatCount() == 0) { + if (mDisableOnVolumeUp && keyCode == KeyEvent.KEYCODE_VOLUME_UP + && event.getRepeatCount() == 0) { mNewVolumeUp = true; } return super.onKeyDown(keyCode, event); diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java index f1bf31d7a58a..cc969177ab2e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java @@ -21,6 +21,7 @@ import static com.android.systemui.tuner.TunablePadding.FLAG_START; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertEquals; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.anyString; @@ -34,8 +35,10 @@ import static org.mockito.Mockito.when; import android.app.Fragment; import android.content.res.Configuration; +import android.os.Handler; import android.support.test.filters.SmallTest; import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; import android.testing.TestableLooper.RunWithLooper; import android.view.Display; import android.view.View; @@ -60,6 +63,7 @@ import org.junit.runner.RunWith; @SmallTest public class ScreenDecorationsTest extends SysuiTestCase { + private TestableLooper mTestableLooper; private ScreenDecorations mScreenDecorations; private StatusBar mStatusBar; private WindowManager mWindowManager; @@ -71,6 +75,10 @@ public class ScreenDecorationsTest extends SysuiTestCase { @Before public void setup() { + mTestableLooper = TestableLooper.get(this); + mDependency.injectTestDependency(Dependency.MAIN_HANDLER, + new Handler(mTestableLooper.getLooper())); + mStatusBar = mock(StatusBar.class); mWindowManager = mock(WindowManager.class); mView = spy(new StatusBarWindowView(mContext, null)); @@ -88,7 +96,31 @@ public class ScreenDecorationsTest extends SysuiTestCase { mTunerService = mDependency.injectMockDependency(TunerService.class); - mScreenDecorations = new ScreenDecorations(); + + mScreenDecorations = new ScreenDecorations() { + @Override + public void start() { + super.start(); + mTestableLooper.processAllMessages(); + } + + @Override + Handler startHandlerThread() { + return new Handler(mTestableLooper.getLooper()); + } + + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + mTestableLooper.processAllMessages(); + } + + @Override + public void onTuningChanged(String key, String newValue) { + super.onTuningChanged(key, newValue); + mTestableLooper.processAllMessages(); + } + }; mScreenDecorations.mContext = mContext; mScreenDecorations.mComponents = mContext.getComponents(); @@ -195,4 +227,17 @@ public class ScreenDecorationsTest extends SysuiTestCase { verify(padding).destroy(); } + @Test + public void testUpdateRoundedCorners() { + mContext.getOrCreateTestableResources().addOverride( + com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, false); + mContext.getOrCreateTestableResources().addOverride(dimen.rounded_corner_radius, 20); + + mScreenDecorations.start(); + assertEquals(mScreenDecorations.mRoundedDefault, 20); + + mContext.getOrCreateTestableResources().addOverride(dimen.rounded_corner_radius, 5); + mScreenDecorations.onConfigurationChanged(null); + assertEquals(mScreenDecorations.mRoundedDefault, 5); + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java index 5ecf0c04aeb1..a9d49f91e44e 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java @@ -323,9 +323,9 @@ public class PowerUITest extends SysuiTestCase { } @Test - public void testShouldDismissLowBatteryWarning_dismissWhenPowerSaverEnabled() { + public void testShouldDismissLowBatteryWarning_dismissWhenPowerSaverEnabledLegacy() { mPowerUI.start(); - when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true); + when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(false); when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS); when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS); @@ -337,6 +337,20 @@ public class PowerUITest extends SysuiTestCase { } @Test + public void testShouldNotDismissLowBatteryWarning_dismissWhenPowerSaverEnabledHybrid() { + mPowerUI.start(); + when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true); + when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS); + when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS); + + // device that gets power saver turned on should dismiss + boolean shouldDismiss = + mPowerUI.shouldDismissLowBatteryWarning(UNPLUGGED, BELOW_WARNING_BUCKET, + BELOW_WARNING_BUCKET, ABOVE_HYBRID_THRESHOLD, !POWER_SAVER_OFF); + assertFalse(shouldDismiss); + } + + @Test public void testShouldDismissLowBatteryWarning_dismissWhenPlugged() { mPowerUI.start(); when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true); diff --git a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values/strings.xml b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values/strings.xml index 754ba722d081..b08924b8adb6 100644 --- a/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values/strings.xml +++ b/packages/overlays/DisplayCutoutEmulationCornerOverlay/res/values/strings.xml @@ -16,7 +16,7 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="display_cutout_emulation_overlay">Corner display cutout</string> + <string name="display_cutout_emulation_overlay">Corner cutout</string> </resources> diff --git a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values/strings.xml b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values/strings.xml index 68c2dcbbe3f6..0a106fa0c08f 100644 --- a/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values/strings.xml +++ b/packages/overlays/DisplayCutoutEmulationDoubleOverlay/res/values/strings.xml @@ -16,7 +16,7 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="display_cutout_emulation_overlay">Double display cutout</string> + <string name="display_cutout_emulation_overlay">Double cutout</string> </resources> diff --git a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/strings.xml b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/strings.xml index 49896773ac55..0bf83306f875 100644 --- a/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/strings.xml +++ b/packages/overlays/DisplayCutoutEmulationNarrowOverlay/res/values/strings.xml @@ -18,7 +18,7 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="display_cutout_emulation_overlay">Narrow display cutout</string> + <string name="display_cutout_emulation_overlay">Narrow cutout</string> </resources> diff --git a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/strings.xml b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/strings.xml index 6dcbbd923601..bcc7c9756a6e 100644 --- a/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/strings.xml +++ b/packages/overlays/DisplayCutoutEmulationTallOverlay/res/values/strings.xml @@ -16,7 +16,7 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="display_cutout_emulation_overlay">Tall display cutout</string> + <string name="display_cutout_emulation_overlay">Tall cutout</string> </resources> diff --git a/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/strings.xml b/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/strings.xml index f4b9f7ea7c37..0fcbdebbd345 100644 --- a/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/strings.xml +++ b/packages/overlays/DisplayCutoutEmulationWideOverlay/res/values/strings.xml @@ -16,7 +16,7 @@ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="display_cutout_emulation_overlay">Wide display cutout</string> + <string name="display_cutout_emulation_overlay">Wide cutout</string> </resources> diff --git a/proto/src/gnss.proto b/proto/src/gnss.proto index 016839232255..1509fc00fb1d 100644 --- a/proto/src/gnss.proto +++ b/proto/src/gnss.proto @@ -45,6 +45,9 @@ message GnssLog { // Power metrics optional PowerMetrics power_metrics = 12; + + // Hardware revision (EVT, DVT, PVT etc.) + optional string hardware_revision = 13; } // Power metrics diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index 03ab60c33f51..b990175fd616 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -941,9 +941,10 @@ message MetricsEvent { // OS: 6.0 NOTIFICATION_ZEN_MODE_EVENT_RULE = 146; - // ACTION: App notification settings > Block Notifications + // ACTION: App notification settings > Block Notifications or long press on + // notification blocks. // CATEGORY: SETTINGS - // OS: 6.0 + // OS: 9.0 ACTION_BAN_APP_NOTES = 147; // ACTION: Notification shade > Dismiss all button @@ -6129,6 +6130,305 @@ message MetricsEvent { // CATEGORY: NOTIFICATION NOTIFICATION_INTERRUPTION = 1501; + // OPEN: Settings + // CATEGORY: SETTINGS + // OS: Q + SETTINGS_HOMEPAGE = 1502; + + // OPEN: Settings > Create shortcut(widget) + // CATEGORY: SETTINGS + // OS: Q + SETTINGS_CREATE_SHORTCUT = 1503; + + // ACTION: Authenticate using fingerprint + // CATEGORY: SETTINGS + // OS: Q + ACTION_FACE_AUTH = 1504; + + // ACTION: Add fingerprint > Enroll fingerprint + // CATEGORY: SETTINGS + // OS: Q + ACTION_FACE_ENROLL = 1505; + + // OPEN: Face Enroll introduction + // CATEGORY: SETTINGS + // OS: Q + FACE_ENROLL_INTRO = 1506; + + // OPEN: Face Enroll introduction + // CATEGORY: SETTINGS + // OS: Q + FACE_ENROLL_ENROLLING = 1507; + + // OPEN: Face Enroll introduction + // CATEGORY: SETTINGS + // OS: Q + FACE_ENROLL_FINISHED = 1508; + + // OPEN: Face Enroll sidecar + // CATEGORY: SETTINGS + // OS: Q + FACE_ENROLL_SIDECAR = 1509; + + // OPEN: Settings > Add face > Error dialog + // OS: Q + DIALOG_FACE_ERROR = 1510; + + // OPEN: Settings > Security > Face + // CATEGORY: SETTINGS + // OS: Q + FACE = 1511; + + // OPEN: Settings > Acessibility > HearingAid pairing instructions dialog + // CATEGORY: SETTINGS + // OS: Q + DIALOG_ACCESSIBILITY_HEARINGAID = 1512; + + // ACTION: Activity start + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + ACTION_ACTIVITY_START = 1513; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Calling UID + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_CALLING_UID = 1514; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Calling package name + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_CALLING_PACKAGE_NAME = 1515; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Calling UID proc state + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_CALLING_UID_PROC_STATE = 1516; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Calling UID has any visible window + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_CALLING_UID_HAS_ANY_VISIBLE_WINDOW = 1517; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Real calling UID + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_REAL_CALLING_UID = 1518; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Real calling UID proc state + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_REAL_CALLING_UID_PROC_STATE = 1519; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Real calling UID has any visible window + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_REAL_CALLING_UID_HAS_ANY_VISIBLE_WINDOW = 1520; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Target UID + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_TARGET_UID = 1521; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Target UID package name + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_TARGET_PACKAGE_NAME = 1522; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Target UID proc state + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_TARGET_UID_PROC_STATE = 1523; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Target UID has any visible window + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_TARGET_UID_HAS_ANY_VISIBLE_WINDOW = 1524; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Target doze whitelist tag + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_TARGET_WHITELIST_TAG = 1525; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Target short component name + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_TARGET_SHORT_COMPONENT_NAME = 1526; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Coming from pending intent + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_COMING_FROM_PENDING_INTENT = 1527; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Intent action + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_INTENT_ACTION = 1528; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Caller app process record process name + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_PROCESS_RECORD_PROCESS_NAME = 1529; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Caller app process record current proc state + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_PROCESS_RECORD_CUR_PROC_STATE = 1530; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Caller app process record has client activities + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_PROCESS_RECORD_HAS_CLIENT_ACTIVITIES = 1531; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Caller app process record has foreground services + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_PROCESS_RECORD_HAS_FOREGROUND_SERVICES = 1532; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Caller app process record has foreground activities + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_PROCESS_RECORD_HAS_FOREGROUND_ACTIVITIES = 1533; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Caller app process record has top UI + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_PROCESS_RECORD_HAS_TOP_UI = 1534; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Caller app process record has overlay UI + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_PROCESS_RECORD_HAS_OVERLAY_UI = 1535; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Caller app process record pending UI clean + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_PROCESS_RECORD_PENDING_UI_CLEAN = 1536; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Millis since caller app's process record last interaction event + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_PROCESS_RECORD_MILLIS_SINCE_LAST_INTERACTION_EVENT = 1537; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Millis since caller app's process record fg interaction + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_PROCESS_RECORD_MILLIS_SINCE_FG_INTERACTION = 1538; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Millis since caller app's process record last became unimportant + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_PROCESS_RECORD_MILLIS_SINCE_UNIMPORTANT = 1539; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Activity record launch mode + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_ACTIVITY_RECORD_LAUNCH_MODE = 1540; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Activity record target activity + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_ACTIVITY_RECORD_TARGET_ACTIVITY = 1541; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Activity record flags + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_ACTIVITY_RECORD_FLAGS = 1542; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Activity record real activity + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_ACTIVITY_RECORD_REAL_ACTIVITY = 1543; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Activity record short component name + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_ACTIVITY_RECORD_SHORT_COMPONENT_NAME = 1544; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Activity record process name + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_ACTIVITY_RECORD_PROCESS_NAME = 1545; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Activity record is fullscreen + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_ACTIVITY_RECORD_IS_FULLSCREEN = 1546; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Activity record is no display + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_ACTIVITY_RECORD_IS_NO_DISPLAY = 1547; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Millis since activity was last visible + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_VISIBLE = 1548; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Activity record's resultTo packageName + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_ACTIVITY_RECORD_RESULT_TO_PKG_NAME = 1549; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Activity record's resultTo shortComponentName + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_ACTIVITY_RECORD_RESULT_TO_SHORT_COMPONENT_NAME = 1550; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Activity record is visible + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_ACTIVITY_RECORD_IS_VISIBLE = 1551; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Activity record is visible ignoring keyguard + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_ACTIVITY_RECORD_IS_VISIBLE_IGNORING_KEYGUARD = 1552; + + // Tagged data for ACTION_ACTIVITY_START. + // FIELD: Millis since activity's last launch + // CATEGORY: OTHER + // OS: Q (will also ship in PQ1A) + FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH = 1553; + // OPEN: Emergency dialer opened // CLOSE: Emergency dialer closed // SUBTYPE: The entry type that user opened emergency dialer diff --git a/proto/src/wifi.proto b/proto/src/wifi.proto index 72f11e0a63c1..b29c992120d4 100644 --- a/proto/src/wifi.proto +++ b/proto/src/wifi.proto @@ -457,6 +457,11 @@ message WifiLog { // Identifier for experimental scoring parameter settings. optional string score_experiment_id = 117; + // Histogram of the EAP method type of all installed Passpoint profiles + repeated PasspointProfileTypeCount installed_passpoint_profile_type = 123; + + // Hardware revision (EVT, DVT, PVT etc.) + optional string hardware_revision = 124; } // Information that gets logged for every WiFi connection. @@ -1503,3 +1508,31 @@ message WifiRttLog { optional int32 count = 2; } } + +message PasspointProfileTypeCount { + enum EapMethod { + // Unknown Type + TYPE_UNKNOWN = 0; + + // EAP_TLS (13) + TYPE_EAP_TLS = 1; + + // EAP_TTLS (21) + TYPE_EAP_TTLS = 2; + + // EAP_SIM (18) + TYPE_EAP_SIM = 3; + + // EAP_AKA (23) + TYPE_EAP_AKA = 4; + + // EAP_AKA_PRIME (50) + TYPE_EAP_AKA_PRIME = 5; + } + + // Eap method type set in Passpoint profile + optional EapMethod eap_method_type = 1; + + // Num of installed Passpoint profile with same eap method + optional int32 count = 2; +} diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java index c9c7adc45697..f69b6387a605 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetService.java @@ -48,11 +48,6 @@ public class AppWidgetService extends SystemService { } @Override - public void onUnlockUser(int userHandle) { - FgThread.getHandler().post(() -> mImpl.onUserUnlocked(userHandle)); - } - - @Override public void onStopUser(int userHandle) { mImpl.onUserStopped(userHandle); } diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index db8ad12cfdf8..b71d7a726b28 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -19,7 +19,6 @@ package com.android.server.appwidget; import static android.content.Context.KEYGUARD_SERVICE; import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; - import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME; import android.annotation.UserIdInt; @@ -2697,7 +2696,12 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } } - void onUserUnlocked(int userId) { + /** + * This does not use the usual onUserUnlocked() listener mechanism because it is + * invoked at a choreographed point in the middle of the user unlock sequence, + * before the boot-completed broadcast is issued and the listeners notified. + */ + void handleUserUnlocked(int userId) { if (isProfileWithLockedParent(userId)) { return; } @@ -2734,7 +2738,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } } } - Slog.i(TAG, "Async processing of onUserUnlocked u" + userId + " took " + Slog.i(TAG, "Processing of handleUserUnlocked u" + userId + " took " + (SystemClock.elapsedRealtime() - time) + " ms"); } @@ -4801,5 +4805,11 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku return widgetPackages; } } + + @Override + public void unlockUser(int userId) { + handleUserUnlocked(userId); + } + } } diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java index dc84498353ea..58823036212d 100644 --- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java +++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java @@ -81,6 +81,13 @@ final class SaveUi { void onDestroy(); } + /** + * Wrapper that guarantees that only one callback is triggered by ignoring further calls after + * it's destroyed. + * + * <p>It's needed becase {@link #onCancel(IntentSender)} is always called when the Save UI + * dialog is dismissed. + */ private class OneTimeListener implements OnSaveListener { private final OnSaveListener mRealListener; @@ -96,7 +103,6 @@ final class SaveUi { if (mDone) { return; } - mDone = true; mRealListener.onSave(); } @@ -106,7 +112,6 @@ final class SaveUi { if (mDone) { return; } - mDone = true; mRealListener.onCancel(listener); } diff --git a/services/core/Android.bp b/services/core/Android.bp index 43469fff3088..9b8f51e49b26 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -6,7 +6,6 @@ java_library_static { "frameworks/native/aidl/binder", "frameworks/native/cmds/dumpstate/binder", "system/core/storaged/binder", - "system/netd/server/binder", "system/vold/binder", ], }, @@ -19,7 +18,6 @@ java_library_static { ":mediaupdateservice_aidl", "java/com/android/server/EventLogTags.logtags", "java/com/android/server/am/EventLogTags.logtags", - ":netd_metrics_aidl", ], libs: [ @@ -49,6 +47,7 @@ java_library_static { "android.hardware.contexthub-V1.0-java", "android.hidl.manager-V1.0-java", "netd_aidl_interface-java", + "netd_event_listener_interface-java", ], } diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java index 5c14459da566..50f15ca0739f 100644 --- a/services/core/java/com/android/server/BatteryService.java +++ b/services/core/java/com/android/server/BatteryService.java @@ -624,7 +624,7 @@ public final class BatteryService extends SystemService { // them will get the new sequence number at that point. (See for example how testing // of JobScheduler's BatteryController works.) sendBatteryChangedIntentLocked(); - if (mLastBatteryLevel != mHealthInfo.batteryLevel) { + if (mLastBatteryLevel != mHealthInfo.batteryLevel || mLastPlugType != mPlugType) { sendBatteryLevelChangedIntentLocked(); } diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java index 49de4b157776..555e89947a64 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.HashMap; 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 @@ class BluetoothManagerService extends IBluetoothManager.Stub { 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 14503f9d7379..66ceae432c6e 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -902,6 +902,7 @@ public class ConnectivityService extends IConnectivityManager.Stub // Listen to package add and removal events for all users. intentFilter = new IntentFilter(); intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED); + intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED); intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); intentFilter.addDataScheme("package"); mContext.registerReceiverAsUser( @@ -1967,6 +1968,7 @@ public class ConnectivityService extends IConnectivityManager.Stub void systemReady() { mProxyTracker.loadGlobalProxy(); registerNetdEventCallback(); + mTethering.systemReady(); synchronized (this) { mSystemReady = true; @@ -4203,12 +4205,46 @@ public class ConnectivityService extends IConnectivityManager.Stub mPermissionMonitor.onPackageAdded(packageName, uid); } - private void onPackageRemoved(String packageName, int uid) { + private void onPackageReplaced(String packageName, int uid) { + if (TextUtils.isEmpty(packageName) || uid < 0) { + Slog.wtf(TAG, "Invalid package in onPackageReplaced: " + packageName + " | " + uid); + return; + } + final int userId = UserHandle.getUserId(uid); + synchronized (mVpns) { + final Vpn vpn = mVpns.get(userId); + if (vpn == null) { + return; + } + // Legacy always-on VPN won't be affected since the package name is not set. + if (TextUtils.equals(vpn.getAlwaysOnPackage(), packageName)) { + Slog.d(TAG, "Restarting always-on VPN package " + packageName + " for user " + + userId); + vpn.startAlwaysOnVpn(); + } + } + } + + private void onPackageRemoved(String packageName, int uid, boolean isReplacing) { if (TextUtils.isEmpty(packageName) || uid < 0) { Slog.wtf(TAG, "Invalid package in onPackageRemoved: " + packageName + " | " + uid); return; } mPermissionMonitor.onPackageRemoved(uid); + + final int userId = UserHandle.getUserId(uid); + synchronized (mVpns) { + final Vpn vpn = mVpns.get(userId); + if (vpn == null) { + return; + } + // Legacy always-on VPN won't be affected since the package name is not set. + if (TextUtils.equals(vpn.getAlwaysOnPackage(), packageName) && !isReplacing) { + Slog.d(TAG, "Removing always-on VPN package " + packageName + " for user " + + userId); + vpn.setAlwaysOnPackage(null, false); + } + } } private void onUserUnlocked(int userId) { @@ -4245,8 +4281,12 @@ public class ConnectivityService extends IConnectivityManager.Stub onUserUnlocked(userId); } else if (Intent.ACTION_PACKAGE_ADDED.equals(action)) { onPackageAdded(packageName, uid); + } else if (Intent.ACTION_PACKAGE_REPLACED.equals(action)) { + onPackageReplaced(packageName, uid); } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action)) { - onPackageRemoved(packageName, uid); + final boolean isReplacing = intent.getBooleanExtra( + Intent.EXTRA_REPLACING, false); + onPackageRemoved(packageName, uid, isReplacing); } } }; @@ -5674,7 +5714,6 @@ public class ConnectivityService extends IConnectivityManager.Stub // 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 fc1e1f016c4d..00b13207de2c 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -163,8 +163,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub 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)}. @@ -951,23 +949,10 @@ public class NetworkManagementService extends INetworkManagementService.Stub // INetworkManagementService members // @Override - public INetd getNetdService() throws RemoteException { - final CountDownLatch connectedSignal = mConnectedSignal; - if (connectedSignal != null) { - try { - connectedSignal.await(); - } catch (InterruptedException ignored) {} - } - - return mNetdService; - } - - @Override 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); } @@ -1259,8 +1244,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub 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); } @@ -1283,8 +1267,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub 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); } @@ -2325,11 +2308,11 @@ public class NetworkManagementService extends INetworkManagementService.Stub } @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/PinnerService.java b/services/core/java/com/android/server/PinnerService.java index f5b29e9b76b8..0deaee7f7878 100644 --- a/services/core/java/com/android/server/PinnerService.java +++ b/services/core/java/com/android/server/PinnerService.java @@ -43,6 +43,7 @@ import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.UserHandle; +import android.os.UserManager; import android.provider.MediaStore; import android.provider.Settings; import android.system.ErrnoException; @@ -69,6 +70,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.List; import java.util.ArrayList; import java.util.zip.ZipFile; @@ -103,6 +105,7 @@ public final class PinnerService extends SystemService { private final Context mContext; private final ActivityManagerInternal mAmInternal; private final IActivityManager mAm; + private final UserManager mUserManager; /** The list of the statically pinned files. */ @GuardedBy("this") @@ -164,6 +167,8 @@ public final class PinnerService extends SystemService { mAmInternal = LocalServices.getService(ActivityManagerInternal.class); mAm = ActivityManager.getService(); + mUserManager = mContext.getSystemService(UserManager.class); + IntentFilter filter = new IntentFilter(); filter.addAction(Intent.ACTION_PACKAGE_REPLACED); filter.addDataScheme("package"); @@ -194,12 +199,16 @@ public final class PinnerService extends SystemService { */ @Override public void onSwitchUser(int userHandle) { - sendPinAppsMessage(userHandle); + if (!mUserManager.isManagedProfile(userHandle)) { + sendPinAppsMessage(userHandle); + } } @Override public void onUnlockUser(int userHandle) { - sendPinAppsMessage(userHandle); + if (!mUserManager.isManagedProfile(userHandle)) { + sendPinAppsMessage(userHandle); + } } /** @@ -345,31 +354,76 @@ public final class PinnerService extends SystemService { } private ApplicationInfo getCameraInfo(int userHandle) { - // find the camera via an intent - // use INTENT_ACTION_STILL_IMAGE_CAMERA instead of _SECURE. On a - // device without a fbe enabled, the _SECURE intent will never get set. Intent cameraIntent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA); - return getApplicationInfoForIntent(cameraIntent, userHandle); + ApplicationInfo info = getApplicationInfoForIntent(cameraIntent, userHandle, + false /* defaultToSystemApp */); + + // If the STILL_IMAGE_CAMERA intent doesn't resolve, try the _SECURE intent. + // We don't use _SECURE first because it will never get set on a device + // without File-based Encryption. But if the user has only set the intent + // before unlocking their device, we may still be able to identify their + // preference using this intent. + if (info == null) { + cameraIntent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE); + info = getApplicationInfoForIntent(cameraIntent, userHandle, + false /* defaultToSystemApp */); + } + + // If the _SECURE intent doesn't resolve, try the original intent but request + // the system app for camera if there was more than one result. + if (info == null) { + cameraIntent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA); + info = getApplicationInfoForIntent(cameraIntent, userHandle, + true /* defaultToSystemApp */); + } + return info; } private ApplicationInfo getHomeInfo(int userHandle) { Intent intent = mAmInternal.getHomeIntent(); - return getApplicationInfoForIntent(intent, userHandle); + return getApplicationInfoForIntent(intent, userHandle, false); } - private ApplicationInfo getApplicationInfoForIntent(Intent intent, int userHandle) { + private ApplicationInfo getApplicationInfoForIntent(Intent intent, int userHandle, + boolean defaultToSystemApp) { if (intent == null) { return null; } - ResolveInfo info = mContext.getPackageManager().resolveActivityAsUser(intent, + + ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivityAsUser(intent, MATCH_FLAGS, userHandle); - if (info == null) { + + // If this intent can resolve to only one app, choose that one. + // Otherwise, if we've requested to default to the system app, return it; + // if we have not requested that default, return null if there's more than one option. + // If there's more than one system app, return null since we don't know which to pick. + if (resolveInfo == null) { return null; } - if (isResolverActivity(info.activityInfo)) { - return null; + + if (!isResolverActivity(resolveInfo.activityInfo)) { + return resolveInfo.activityInfo.applicationInfo; } - return info.activityInfo.applicationInfo; + + if (defaultToSystemApp) { + List<ResolveInfo> infoList = mContext.getPackageManager() + .queryIntentActivitiesAsUser(intent, MATCH_FLAGS, userHandle); + ApplicationInfo systemAppInfo = null; + for (ResolveInfo info : infoList) { + if ((info.activityInfo.applicationInfo.flags + & ApplicationInfo.FLAG_SYSTEM) != 0) { + if (systemAppInfo == null) { + systemAppInfo = info.activityInfo.applicationInfo; + } else { + // If there's more than one system app, return null due to ambiguity. + return null; + } + } + } + return systemAppInfo; + } + + return null; } private void sendPinAppsMessage(int userHandle) { diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index a3e6ea2518a6..371e5177ede3 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -99,6 +99,7 @@ import android.os.storage.VolumeInfo; import android.os.storage.VolumeRecord; import android.provider.MediaStore; import android.provider.Settings; +import android.sysprop.VoldProperties; import android.text.TextUtils; import android.text.format.DateUtils; import android.util.ArrayMap; @@ -973,7 +974,7 @@ class StorageManagerService extends IStorageManager.Stub // On an encrypted device we can't see system properties yet, so pull // the system locale out of the mount service. - if ("".equals(SystemProperties.get("vold.encrypt_progress"))) { + if ("".equals(VoldProperties.encrypt_progress().orElse(""))) { copyLocaleFromMountService(); } } diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 66ae47cece19..7b29fe5b1c4e 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -210,6 +210,10 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { 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 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { 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 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } 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 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { 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 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } handleRemoveListLocked(); } - broadcastPreciseCallStateChanged(mRingingCallState, mForegroundCallState, - mBackgroundCallState, disconnectCause, preciseDisconnectCause); } public void notifyPreciseDataConnectionFailed(String reason, String apnType, @@ -1703,6 +1714,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } 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 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } 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 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { } + 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/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java index 6550d06b8a12..d14c1a1adf77 100644 --- a/services/core/java/com/android/server/am/ActivityManagerConstants.java +++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java @@ -67,6 +67,7 @@ final class ActivityManagerConstants extends ContentObserver { static final String KEY_BOUND_SERVICE_CRASH_RESTART_DURATION = "service_crash_restart_duration"; static final String KEY_BOUND_SERVICE_CRASH_MAX_RETRY = "service_crash_max_retry"; static final String KEY_PROCESS_START_ASYNC = "process_start_async"; + static final String KEY_TOP_TO_FGS_GRACE_DURATION = "top_to_fgs_grace_duration"; private static final int DEFAULT_MAX_CACHED_PROCESSES = 32; private static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60*1000; @@ -95,7 +96,7 @@ final class ActivityManagerConstants extends ContentObserver { private static final long DEFAULT_BOUND_SERVICE_CRASH_RESTART_DURATION = 30*60_000; private static final int DEFAULT_BOUND_SERVICE_CRASH_MAX_RETRY = 16; private static final boolean DEFAULT_PROCESS_START_ASYNC = true; - + private static final long DEFAULT_TOP_TO_FGS_GRACE_DURATION = 15 * 1000; // Maximum number of cached processes we will allow. public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES; @@ -207,6 +208,14 @@ final class ActivityManagerConstants extends ContentObserver { // Indicates if the processes need to be started asynchronously. public boolean FLAG_PROCESS_START_ASYNC = DEFAULT_PROCESS_START_ASYNC; + // Allow app just moving from TOP to FOREGROUND_SERVICE to stay in a higher adj value for + // this long. + public long TOP_TO_FGS_GRACE_DURATION = DEFAULT_TOP_TO_FGS_GRACE_DURATION; + + // Indicates whether the activity starts logging is enabled. + // Controlled by Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED + boolean mFlagActivityStartsLoggingEnabled; + private final ActivityManagerService mService; private ContentResolver mResolver; private final KeyValueListParser mParser = new KeyValueListParser(','); @@ -235,6 +244,12 @@ final class ActivityManagerConstants extends ContentObserver { // memory trimming. public int CUR_TRIM_CACHED_PROCESSES; + private static final Uri ACTIVITY_MANAGER_CONSTANTS_URI = Settings.Global.getUriFor( + Settings.Global.ACTIVITY_MANAGER_CONSTANTS); + + private static final Uri ACTIVITY_STARTS_LOGGING_ENABLED_URI = Settings.Global.getUriFor( + Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED); + public ActivityManagerConstants(ActivityManagerService service, Handler handler) { super(handler); mService = service; @@ -243,9 +258,10 @@ final class ActivityManagerConstants extends ContentObserver { public void start(ContentResolver resolver) { mResolver = resolver; - mResolver.registerContentObserver(Settings.Global.getUriFor( - Settings.Global.ACTIVITY_MANAGER_CONSTANTS), false, this); + mResolver.registerContentObserver(ACTIVITY_MANAGER_CONSTANTS_URI, false, this); + mResolver.registerContentObserver(ACTIVITY_STARTS_LOGGING_ENABLED_URI, false, this); updateConstants(); + updateActivityStartsLoggingEnabled(); } public void setOverrideMaxCachedProcesses(int value) { @@ -263,7 +279,12 @@ final class ActivityManagerConstants extends ContentObserver { @Override public void onChange(boolean selfChange, Uri uri) { - updateConstants(); + if (uri == null) return; + if (ACTIVITY_MANAGER_CONSTANTS_URI.equals(uri)) { + updateConstants(); + } else if (ACTIVITY_STARTS_LOGGING_ENABLED_URI.equals(uri)) { + updateActivityStartsLoggingEnabled(); + } } private void updateConstants() { @@ -332,11 +353,18 @@ final class ActivityManagerConstants extends ContentObserver { DEFAULT_BOUND_SERVICE_CRASH_MAX_RETRY); FLAG_PROCESS_START_ASYNC = mParser.getBoolean(KEY_PROCESS_START_ASYNC, DEFAULT_PROCESS_START_ASYNC); + TOP_TO_FGS_GRACE_DURATION = mParser.getDurationMillis(KEY_TOP_TO_FGS_GRACE_DURATION, + DEFAULT_TOP_TO_FGS_GRACE_DURATION); updateMaxCachedProcesses(); } } + private void updateActivityStartsLoggingEnabled() { + mFlagActivityStartsLoggingEnabled = Settings.Global.getInt(mResolver, + Settings.Global.ACTIVITY_STARTS_LOGGING_ENABLED, 0) == 1; + } + private void updateMaxCachedProcesses() { CUR_MAX_CACHED_PROCESSES = mOverrideMaxCachedProcesses < 0 ? MAX_CACHED_PROCESSES : mOverrideMaxCachedProcesses; @@ -402,6 +430,8 @@ final class ActivityManagerConstants extends ContentObserver { pw.println(MAX_SERVICE_INACTIVITY); pw.print(" "); pw.print(KEY_BG_START_TIMEOUT); pw.print("="); pw.println(BG_START_TIMEOUT); + pw.print(" "); pw.print(KEY_TOP_TO_FGS_GRACE_DURATION); pw.print("="); + pw.println(TOP_TO_FGS_GRACE_DURATION); pw.println(); if (mOverrideMaxCachedProcesses >= 0) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index a411af254510..514c9f62387f 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -364,6 +364,7 @@ import android.provider.Downloads; import android.provider.Settings; import android.service.voice.IVoiceInteractionSession; import android.service.voice.VoiceInteractionManagerInternal; +import android.sysprop.VoldProperties; import android.telecom.TelecomManager; import android.text.TextUtils; import android.text.format.DateUtils; @@ -5578,7 +5579,7 @@ public class ActivityManagerService extends IActivityManager.Stub // TODO: Switch to user app stacks here. int ret = mActivityStartController.startActivities(caller, -1, callingPackage, intents, resolvedTypes, resultTo, SafeActivityOptions.fromBundle(bOptions), userId, - reason); + reason, null /* originatingPendingIntent */); return ret; } @@ -7958,8 +7959,8 @@ public class ActivityManagerService extends IActivityManager.Stub SystemProperties.set("sys.boot_completed", "1"); // And trigger dev.bootcomplete if we are not showing encryption progress - if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt")) - || "".equals(SystemProperties.get("vold.encrypt_progress"))) { + if (!"trigger_restart_min_framework".equals(VoldProperties.decrypt().orElse("")) + || "".equals(VoldProperties.encrypt_progress().orElse(""))){ SystemProperties.set("dev.bootcomplete", "1"); } mUserController.sendBootCompleted( @@ -10935,6 +10936,20 @@ public class ActivityManagerService extends IActivityManager.Stub } } + /** + * @return whitelist tag for a uid from mPendingTempWhitelist, null if not currently on + * the whitelist + */ + String getPendingTempWhitelistTagForUidLocked(int uid) { + final PendingTempWhitelist ptw = mPendingTempWhitelist.get(uid); + return ptw != null ? ptw.tag : null; + } + + @VisibleForTesting + boolean isActivityStartsLoggingEnabled() { + return mConstants.mFlagActivityStartsLoggingEnabled; + } + @Override public void moveStackToDisplay(int stackId, int displayId) { enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()"); @@ -13646,7 +13661,7 @@ public class ActivityManagerService extends IActivityManager.Stub String extraOptions = null; switch (bugreportType) { case ActivityManager.BUGREPORT_OPTION_FULL: - // Default options. + extraOptions = "bugreportfull"; break; case ActivityManager.BUGREPORT_OPTION_INTERACTIVE: extraOptions = "bugreportplus"; @@ -23244,6 +23259,19 @@ public class ActivityManagerService extends IActivityManager.Stub } } + // If the app was recently in the foreground and moved to a foreground service status, + // allow it to get a higher rank in memory for some time, compared to other foreground + // services so that it can finish performing any persistence/processing of in-memory state. + if (app.foregroundServices && adj > ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + && (app.lastTopTime + mConstants.TOP_TO_FGS_GRACE_DURATION > now + || app.setProcState <= ActivityManager.PROCESS_STATE_TOP)) { + adj = ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ; + app.adjType = "fg-service-act"; + if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { + reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to recent fg: " + app); + } + } + if (adj > ProcessList.PERCEPTIBLE_APP_ADJ || procState > ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) { if (app.forcingToImportant != null) { @@ -23508,6 +23536,10 @@ public class ActivityManagerService extends IActivityManager.Stub schedGroup = ProcessList.SCHED_GROUP_DEFAULT; procState = ActivityManager.PROCESS_STATE_PERSISTENT; } + } else if ((cr.flags & Context.BIND_ADJUST_BELOW_PERCEPTIBLE) != 0 + && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ + && adj > ProcessList.PERCEPTIBLE_APP_ADJ + 1) { + newAdj = ProcessList.PERCEPTIBLE_APP_ADJ + 1; } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ && adj > ProcessList.PERCEPTIBLE_APP_ADJ) { @@ -24478,6 +24510,8 @@ public class ActivityManagerService extends IActivityManager.Stub // Must be called before updating setProcState maybeUpdateUsageStatsLocked(app, nowElapsed); + maybeUpdateLastTopTime(app, now); + app.setProcState = app.curProcState; if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) { app.notCachedSinceIdle = false; @@ -24702,6 +24736,13 @@ public class ActivityManagerService extends IActivityManager.Stub } } + private void maybeUpdateLastTopTime(ProcessRecord app, long nowUptime) { + if (app.setProcState <= ActivityManager.PROCESS_STATE_TOP + && app.curProcState > ActivityManager.PROCESS_STATE_TOP) { + app.lastTopTime = nowUptime; + } + } + private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) { if (proc.thread != null) { if (proc.baseProcessTracker != null) { @@ -26399,7 +26440,7 @@ public class ActivityManagerService extends IActivityManager.Stub packageUid, packageName, intents, resolvedTypes, null /* resultTo */, SafeActivityOptions.fromBundle(bOptions), userId, - false /* validateIncomingUser */); + false /* validateIncomingUser */, null /* originatingPendingIntent */); } } @@ -26738,6 +26779,18 @@ public class ActivityManagerService extends IActivityManager.Stub return ActivityManagerService.this.getHomeIntent(); } } + + @Override + public void notifyDefaultDisplaySizeChanged() { + synchronized (ActivityManagerService.this) { + if (mSystemServiceManager.isBootCompleted() && mHomeProcess != null) { + + // TODO: Ugly hack to unblock the release + Slog.i(TAG, "Killing home process because of display size change"); + removeProcessLocked(mHomeProcess, false, true, "kill home screen size"); + } + } + } } /** diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index 7fb161c8c4ae..843699ccf191 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -2849,6 +2849,7 @@ final class ActivityManagerShellCommand extends ShellCommand { pw.println(" --checkin: output checkin format, resetting data."); pw.println(" --C: output checkin format, not resetting data."); pw.println(" --proto: output dump in protocol buffer format."); + pw.println(" --autofill: dump just the autofill-related state of an activity"); } else { pw.println("Activity manager (activity) commands:"); pw.println(" help"); diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java index 47d0423550c4..9ffa6627836f 100644 --- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java +++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java @@ -2,6 +2,7 @@ package com.android.server.am; import static android.app.ActivityManager.START_SUCCESS; import static android.app.ActivityManager.START_TASK_TO_FRONT; +import static android.app.ActivityManager.processStateAmToProto; import static android.app.ActivityManagerInternal.APP_TRANSITION_TIMEOUT; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY; import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; @@ -9,6 +10,7 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_ACTIVITY_START; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_BIND_APPLICATION_DELAY_MS; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_CALLING_PACKAGE_NAME; @@ -21,8 +23,48 @@ import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TR import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_REPORTED_DRAWN_MS; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_STARTING_WINDOW_DELAY_MS; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.APP_TRANSITION_WINDOWS_DRAWN_DELAY_MS; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_FLAGS; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_FULLSCREEN; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_NO_DISPLAY; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_VISIBLE; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_IS_VISIBLE_IGNORING_KEYGUARD; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_VISIBLE; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_LAUNCH_MODE; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_PROCESS_NAME; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_REAL_ACTIVITY; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_RESULT_TO_PKG_NAME; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_RESULT_TO_SHORT_COMPONENT_NAME; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_SHORT_COMPONENT_NAME; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_ACTIVITY_RECORD_TARGET_ACTIVITY; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_PACKAGE_NAME; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_UID; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_UID_HAS_ANY_VISIBLE_WINDOW; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CALLING_UID_PROC_STATE; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_CLASS_NAME; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_COMING_FROM_PENDING_INTENT; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_INSTANT_APP_LAUNCH_TOKEN; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_INTENT_ACTION; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_CUR_PROC_STATE; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_HAS_CLIENT_ACTIVITIES; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_HAS_FOREGROUND_ACTIVITIES; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_HAS_FOREGROUND_SERVICES; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_HAS_OVERLAY_UI; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_HAS_TOP_UI; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_MILLIS_SINCE_FG_INTERACTION; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_MILLIS_SINCE_LAST_INTERACTION_EVENT; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_MILLIS_SINCE_UNIMPORTANT; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_PENDING_UI_CLEAN; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_PROCESS_RECORD_PROCESS_NAME; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID_PROC_STATE; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_REAL_CALLING_UID_HAS_ANY_VISIBLE_WINDOW; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_PACKAGE_NAME; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_SHORT_COMPONENT_NAME; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID_HAS_ANY_VISIBLE_WINDOW; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_UID_PROC_STATE; +import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.FIELD_TARGET_WHITELIST_TAG; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PACKAGE_OPTIMIZATION_COMPILATION_REASON; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.PACKAGE_OPTIMIZATION_COMPILATION_FILTER; import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.TYPE_TRANSITION_COLD_LAUNCH; @@ -37,6 +79,7 @@ import static com.android.server.am.MemoryStatUtil.MemoryStat; import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem; import android.content.Context; +import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.dex.ArtManagerInternal; import android.content.pm.dex.PackageOptimizationInfo; @@ -622,6 +665,95 @@ class ActivityMetricsLogger { startupTimeMs); } + void logActivityStart(Intent intent, ProcessRecord callerApp, ActivityRecord r, + int callingUid, String callingPackage, int callingUidProcState, + boolean callingUidHasAnyVisibleWindow, + int realCallingUid, int realCallingUidProcState, + boolean realCallingUidHasAnyVisibleWindow, + int targetUid, String targetPackage, int targetUidProcState, + boolean targetUidHasAnyVisibleWindow, String targetWhitelistTag, + boolean comingFromPendingIntent) { + + final long nowElapsed = SystemClock.elapsedRealtime(); + final long nowUptime = SystemClock.uptimeMillis(); + final LogMaker builder = new LogMaker(ACTION_ACTIVITY_START); + builder.setTimestamp(System.currentTimeMillis()); + builder.addTaggedData(FIELD_CALLING_UID, callingUid); + builder.addTaggedData(FIELD_CALLING_PACKAGE_NAME, callingPackage); + builder.addTaggedData(FIELD_CALLING_UID_PROC_STATE, + processStateAmToProto(callingUidProcState)); + builder.addTaggedData(FIELD_CALLING_UID_HAS_ANY_VISIBLE_WINDOW, + callingUidHasAnyVisibleWindow ? 1 : 0); + builder.addTaggedData(FIELD_REAL_CALLING_UID, realCallingUid); + builder.addTaggedData(FIELD_REAL_CALLING_UID_PROC_STATE, + processStateAmToProto(realCallingUidProcState)); + builder.addTaggedData(FIELD_REAL_CALLING_UID_HAS_ANY_VISIBLE_WINDOW, + realCallingUidHasAnyVisibleWindow ? 1 : 0); + builder.addTaggedData(FIELD_TARGET_UID, targetUid); + builder.addTaggedData(FIELD_TARGET_PACKAGE_NAME, targetPackage); + builder.addTaggedData(FIELD_TARGET_UID_PROC_STATE, + processStateAmToProto(targetUidProcState)); + builder.addTaggedData(FIELD_TARGET_UID_HAS_ANY_VISIBLE_WINDOW, + targetUidHasAnyVisibleWindow ? 1 : 0); + builder.addTaggedData(FIELD_TARGET_WHITELIST_TAG, targetWhitelistTag); + builder.addTaggedData(FIELD_TARGET_SHORT_COMPONENT_NAME, r.shortComponentName); + builder.addTaggedData(FIELD_COMING_FROM_PENDING_INTENT, comingFromPendingIntent ? 1 : 0); + builder.addTaggedData(FIELD_INTENT_ACTION, intent.getAction()); + if (callerApp != null) { + builder.addTaggedData(FIELD_PROCESS_RECORD_PROCESS_NAME, callerApp.processName); + builder.addTaggedData(FIELD_PROCESS_RECORD_CUR_PROC_STATE, + processStateAmToProto(callerApp.curProcState)); + builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_CLIENT_ACTIVITIES, + callerApp.hasClientActivities ? 1 : 0); + builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_FOREGROUND_SERVICES, + callerApp.hasForegroundServices() ? 1 : 0); + builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_FOREGROUND_ACTIVITIES, + callerApp.foregroundActivities ? 1 : 0); + builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_TOP_UI, callerApp.hasTopUi ? 1 : 0); + builder.addTaggedData(FIELD_PROCESS_RECORD_HAS_OVERLAY_UI, + callerApp.hasOverlayUi ? 1 : 0); + builder.addTaggedData(FIELD_PROCESS_RECORD_PENDING_UI_CLEAN, + callerApp.pendingUiClean ? 1 : 0); + if (callerApp.interactionEventTime != 0) { + builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_LAST_INTERACTION_EVENT, + (nowElapsed - callerApp.interactionEventTime)); + } + if (callerApp.fgInteractionTime != 0) { + builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_FG_INTERACTION, + (nowElapsed - callerApp.fgInteractionTime)); + } + if (callerApp.whenUnimportant != 0) { + builder.addTaggedData(FIELD_PROCESS_RECORD_MILLIS_SINCE_UNIMPORTANT, + (nowUptime - callerApp.whenUnimportant)); + } + } + builder.addTaggedData(FIELD_ACTIVITY_RECORD_LAUNCH_MODE, r.info.launchMode); + builder.addTaggedData(FIELD_ACTIVITY_RECORD_TARGET_ACTIVITY, r.info.targetActivity); + builder.addTaggedData(FIELD_ACTIVITY_RECORD_FLAGS, r.info.flags); + builder.addTaggedData(FIELD_ACTIVITY_RECORD_REAL_ACTIVITY, r.realActivity.toShortString()); + builder.addTaggedData(FIELD_ACTIVITY_RECORD_SHORT_COMPONENT_NAME, r.shortComponentName); + builder.addTaggedData(FIELD_ACTIVITY_RECORD_PROCESS_NAME, r.processName); + builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_FULLSCREEN, r.fullscreen ? 1 : 0); + builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_NO_DISPLAY, r.noDisplay ? 1 : 0); + if (r.lastVisibleTime != 0) { + builder.addTaggedData(FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_VISIBLE, + (nowUptime - r.lastVisibleTime)); + } + if (r.resultTo != null) { + builder.addTaggedData(FIELD_ACTIVITY_RECORD_RESULT_TO_PKG_NAME, r.resultTo.packageName); + builder.addTaggedData(FIELD_ACTIVITY_RECORD_RESULT_TO_SHORT_COMPONENT_NAME, + r.resultTo.shortComponentName); + } + builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_VISIBLE, r.visible ? 1 : 0); + builder.addTaggedData(FIELD_ACTIVITY_RECORD_IS_VISIBLE_IGNORING_KEYGUARD, + r.visibleIgnoringKeyguard ? 1 : 0); + if (r.lastLaunchTime != 0) { + builder.addTaggedData(FIELD_ACTIVITY_RECORD_MILLIS_SINCE_LAST_LAUNCH, + (nowUptime - r.lastLaunchTime)); + } + mMetricsLogger.write(builder); + } + private int getTransitionType(WindowingModeTransitionInfo info) { if (info.currentTransitionProcessRunning) { if (info.startResult == START_SUCCESS) { diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 75f27231c976..60f79f720242 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -694,9 +694,13 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo final boolean inPictureInPictureMode = inPinnedWindowingMode() && targetStackBounds != null; if (inPictureInPictureMode != mLastReportedPictureInPictureMode || forceUpdate) { // Picture-in-picture mode changes also trigger a multi-window mode change as well, so - // update that here in order + // update that here in order. Set the last reported MW state to the same as the PiP + // state since we haven't yet actually resized the task (these callbacks need to + // preceed the configuration change from the resiez. + // TODO(110009072): Once we move these callbacks to the client, remove all logic related + // to forcing the update of the picture-in-picture mode as a part of the PiP animation. mLastReportedPictureInPictureMode = inPictureInPictureMode; - mLastReportedMultiWindowMode = inMultiWindowMode(); + mLastReportedMultiWindowMode = inPictureInPictureMode; final Configuration newConfig = task.computeNewOverrideConfigurationForBounds( targetStackBounds, null); schedulePictureInPictureModeChanged(newConfig); diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index c520101d3ff4..2ae056fe18a5 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -4853,7 +4853,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D return mService.getActivityStartController().startActivityInPackage( task.mCallingUid, callingPid, callingUid, callingPackage, intent, null, null, null, 0, 0, options, userId, task, "startActivityFromRecents", - false /* validateIncomingUser */); + false /* validateIncomingUser */, null /* originatingPendingIntent */); } finally { if (windowingMode == WINDOWING_MODE_SPLIT_SCREEN_PRIMARY && task != null) { // If we are launching the task in the docked stack, put it into resizing mode so diff --git a/services/core/java/com/android/server/am/ActivityStartController.java b/services/core/java/com/android/server/am/ActivityStartController.java index a7c32009a4c4..edcf6e7bd516 100644 --- a/services/core/java/com/android/server/am/ActivityStartController.java +++ b/services/core/java/com/android/server/am/ActivityStartController.java @@ -248,7 +248,8 @@ public class ActivityStartController { final int startActivityInPackage(int uid, int realCallingPid, int realCallingUid, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, SafeActivityOptions options, - int userId, TaskRecord inTask, String reason, boolean validateIncomingUser) { + int userId, TaskRecord inTask, String reason, boolean validateIncomingUser, + PendingIntentRecord originatingPendingIntent) { userId = checkTargetUser(userId, validateIncomingUser, realCallingPid, realCallingUid, reason); @@ -267,6 +268,7 @@ public class ActivityStartController { .setActivityOptions(options) .setMayWait(userId) .setInTask(inTask) + .setOriginatingPendingIntent(originatingPendingIntent) .execute(); } @@ -278,10 +280,12 @@ public class ActivityStartController { * @param intents Intents to start. * @param userId Start the intents on this user. * @param validateIncomingUser Set true to skip checking {@code userId} with the calling UID. + * @param originatingPendingIntent PendingIntentRecord that originated this activity start or + * null if not originated by PendingIntent */ final int startActivitiesInPackage(int uid, String callingPackage, Intent[] intents, String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, int userId, - boolean validateIncomingUser) { + boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent) { final String reason = "startActivityInPackage"; @@ -290,12 +294,12 @@ public class ActivityStartController { // TODO: Switch to user app stacks here. return startActivities(null, uid, callingPackage, intents, resolvedTypes, resultTo, options, - userId, reason); + userId, reason, originatingPendingIntent); } int startActivities(IApplicationThread caller, int callingUid, String callingPackage, Intent[] intents, String[] resolvedTypes, IBinder resultTo, SafeActivityOptions options, - int userId, String reason) { + int userId, String reason, PendingIntentRecord originatingPendingIntent) { if (intents == null) { throw new NullPointerException("intents is null"); } @@ -374,6 +378,7 @@ public class ActivityStartController { // Top activity decides on animation being run, so we allow only for the // top one as otherwise an activity below might consume it. .setAllowPendingRemoteAnimationRegistryLookup(top /* allowLookup*/) + .setOriginatingPendingIntent(originatingPendingIntent) .execute(); if (res < 0) { diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java index 73e3d33073fc..00ba3a61d1d6 100644 --- a/services/core/java/com/android/server/am/ActivityStarter.java +++ b/services/core/java/com/android/server/am/ActivityStarter.java @@ -99,6 +99,7 @@ import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; import android.os.SystemClock; +import android.os.Trace; import android.os.UserHandle; import android.os.UserManager; import android.service.voice.IVoiceInteractionSession; @@ -313,6 +314,7 @@ class ActivityStarter { int userId; WaitResult waitResult; int filterCallingUid; + PendingIntentRecord originatingPendingIntent; /** * If set to {@code true}, allows this activity start to look into @@ -369,6 +371,7 @@ class ActivityStarter { avoidMoveToFront = false; allowPendingRemoteAnimationRegistryLookup = true; filterCallingUid = UserHandle.USER_NULL; + originatingPendingIntent = null; } /** @@ -407,6 +410,7 @@ class ActivityStarter { allowPendingRemoteAnimationRegistryLookup = request.allowPendingRemoteAnimationRegistryLookup; filterCallingUid = request.filterCallingUid; + originatingPendingIntent = request.originatingPendingIntent; } } @@ -490,7 +494,8 @@ class ActivityStarter { mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig, mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId, mRequest.inTask, mRequest.reason, - mRequest.allowPendingRemoteAnimationRegistryLookup); + mRequest.allowPendingRemoteAnimationRegistryLookup, + mRequest.originatingPendingIntent); } else { return startActivity(mRequest.caller, mRequest.intent, mRequest.ephemeralIntent, mRequest.resolvedType, mRequest.activityInfo, mRequest.resolveInfo, @@ -500,7 +505,8 @@ class ActivityStarter { mRequest.realCallingUid, mRequest.startFlags, mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.componentSpecified, mRequest.outActivity, mRequest.inTask, mRequest.reason, - mRequest.allowPendingRemoteAnimationRegistryLookup); + mRequest.allowPendingRemoteAnimationRegistryLookup, + mRequest.originatingPendingIntent); } } finally { onExecutionComplete(); @@ -532,7 +538,8 @@ class ActivityStarter { String callingPackage, int realCallingPid, int realCallingUid, int startFlags, SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, TaskRecord inTask, String reason, - boolean allowPendingRemoteAnimationRegistryLookup) { + boolean allowPendingRemoteAnimationRegistryLookup, + PendingIntentRecord originatingPendingIntent) { if (TextUtils.isEmpty(reason)) { throw new IllegalArgumentException("Need to specify a reason."); @@ -545,7 +552,7 @@ class ActivityStarter { aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord, - inTask, allowPendingRemoteAnimationRegistryLookup); + inTask, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent); if (outActivity != null) { // mLastStartActivityRecord[0] is set in the call to startActivity above. @@ -575,7 +582,8 @@ class ActivityStarter { String callingPackage, int realCallingPid, int realCallingUid, int startFlags, SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, - TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup) { + TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup, + PendingIntentRecord originatingPendingIntent) { int err = ActivityManager.START_SUCCESS; // Pull the optional Ephemeral Installer-only bundle out of the options early. final Bundle verificationBundle @@ -865,10 +873,58 @@ class ActivityStarter { mController.doPendingActivityLaunches(false); + maybeLogActivityStart(callingUid, callingPackage, realCallingUid, intent, callerApp, r, + originatingPendingIntent); + return startActivity(r, sourceRecord, voiceSession, voiceInteractor, startFlags, true /* doResume */, checkedOptions, inTask, outActivity); } + private void maybeLogActivityStart(int callingUid, String callingPackage, int realCallingUid, + Intent intent, ProcessRecord callerApp, ActivityRecord r, + PendingIntentRecord originatingPendingIntent) { + boolean callerAppHasForegroundActivity = (callerApp != null) + ? callerApp.foregroundActivities + : false; + if (!mService.isActivityStartsLoggingEnabled() || callerAppHasForegroundActivity + || r == null) { + // skip logging in this case + return; + } + + try { + Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "logActivityStart"); + final int callingUidProcState = mService.getUidStateLocked(callingUid); + final boolean callingUidHasAnyVisibleWindow = + mService.mWindowManager.isAnyWindowVisibleForUid(callingUid); + final int realCallingUidProcState = (callingUid == realCallingUid) + ? callingUidProcState + : mService.getUidStateLocked(realCallingUid); + final boolean realCallingUidHasAnyVisibleWindow = (callingUid == realCallingUid) + ? callingUidHasAnyVisibleWindow + : mService.mWindowManager.isAnyWindowVisibleForUid(realCallingUid); + final String targetPackage = r.packageName; + final int targetUid = (r.appInfo != null) ? r.appInfo.uid : -1; + final int targetUidProcState = mService.getUidStateLocked(targetUid); + final boolean targetUidHasAnyVisibleWindow = (targetUid != -1) + ? mService.mWindowManager.isAnyWindowVisibleForUid(targetUid) + : false; + final String targetWhitelistTag = (targetUid != -1) + ? mService.getPendingTempWhitelistTagForUidLocked(targetUid) + : null; + + mSupervisor.getActivityMetricsLogger().logActivityStart(intent, callerApp, r, + callingUid, callingPackage, callingUidProcState, + callingUidHasAnyVisibleWindow, + realCallingUid, realCallingUidProcState, + realCallingUidHasAnyVisibleWindow, + targetUid, targetPackage, targetUidProcState, + targetUidHasAnyVisibleWindow, targetWhitelistTag, + (originatingPendingIntent != null)); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); + } + } /** * Creates a launch intent for the given auxiliary resolution data. @@ -949,7 +1005,8 @@ class ActivityStarter { ProfilerInfo profilerInfo, WaitResult outResult, Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity, int userId, TaskRecord inTask, String reason, - boolean allowPendingRemoteAnimationRegistryLookup) { + boolean allowPendingRemoteAnimationRegistryLookup, + PendingIntentRecord originatingPendingIntent) { // Refuse possible leaked file descriptors if (intent != null && intent.hasFileDescriptors()) { throw new IllegalArgumentException("File descriptors passed in Intent"); @@ -1100,7 +1157,7 @@ class ActivityStarter { voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason, - allowPendingRemoteAnimationRegistryLookup); + allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent); Binder.restoreCallingIdentity(origId); @@ -2625,6 +2682,11 @@ class ActivityStarter { return this; } + ActivityStarter setOriginatingPendingIntent(PendingIntentRecord originatingPendingIntent) { + mRequest.originatingPendingIntent = originatingPendingIntent; + return this; + } + void dump(PrintWriter pw, String prefix) { prefix = prefix + " "; pw.print(prefix); diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index a6dafbb1db36..f0e2876b4761 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -484,7 +484,8 @@ class AppErrors { task.intent, null, null, null, 0, 0, new SafeActivityOptions(ActivityOptions.makeBasic()), task.userId, null, - "AppErrors", false /*validateIncomingUser*/); + "AppErrors", false /*validateIncomingUser*/, + null /* originatingPendingIntent */); } } } diff --git a/services/core/java/com/android/server/am/OWNERS b/services/core/java/com/android/server/am/OWNERS index 79c98e550774..2649807b5024 100644 --- a/services/core/java/com/android/server/am/OWNERS +++ b/services/core/java/com/android/server/am/OWNERS @@ -15,7 +15,7 @@ ogunwale@google.com 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/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java index e0aa2a261b3c..4e00304a9da6 100644 --- a/services/core/java/com/android/server/am/PendingIntentRecord.java +++ b/services/core/java/com/android/server/am/PendingIntentRecord.java @@ -307,7 +307,7 @@ final class PendingIntentRecord extends IIntentSender.Stub { } else if (finalIntent.getComponent() != null) { finalIntent.getComponent().appendShortString(tag); } else if (finalIntent.getData() != null) { - tag.append(finalIntent.getData()); + tag.append(finalIntent.getData().toSafeString()); } owner.tempWhitelistForPendingIntentLocked(callingPid, callingUid, uid, duration, tag.toString()); @@ -346,13 +346,15 @@ final class PendingIntentRecord extends IIntentSender.Stub { res = owner.getActivityStartController().startActivitiesInPackage( uid, key.packageName, allIntents, allResolvedTypes, resultTo, mergedOptions, userId, - false /* validateIncomingUser */); + false /* validateIncomingUser */, + this /* originatingPendingIntent */); } else { res = owner.getActivityStartController().startActivityInPackage(uid, callingPid, callingUid, key.packageName, finalIntent, resolvedType, resultTo, resultWho, requestCode, 0, mergedOptions, userId, null, "PendingIntentRecord", - false /* validateIncomingUser */); + false /* validateIncomingUser */, + this /* originatingPendingIntent */); } } catch (RuntimeException e) { Slog.w(TAG, "Unable to send startActivity intent", e); diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index 302e1950b9a9..9e7ce3204444 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -104,6 +104,11 @@ public final class ProcessList { static final int VISIBLE_APP_ADJ = 100; static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1; + // This is a process that was recently TOP and moved to FGS. Continue to treat it almost + // like a foreground app for a while. + // @see TOP_TO_FGS_GRACE_PERIOD + static final int PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50; + // This is the process running the current foreground app. We'd really // rather not kill it! static final int FOREGROUND_APP_ADJ = 0; diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index caf52e359548..e3e839f63172 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -163,6 +163,7 @@ final class ProcessRecord { long lastRequestedGc; // When we last asked the app to do a gc long lastLowMemory; // When we last told the app that memory is low long lastProviderTime; // The last time someone else was using a provider in this process. + long lastTopTime; // The last time the process was in the TOP state or greater. boolean reportLowMemory; // Set to true when waiting to report low mem boolean empty; // Is this an empty background process? boolean cached; // Is this a cached process? @@ -380,6 +381,11 @@ final class ProcessRecord { TimeUtils.formatDuration(lastProviderTime, nowUptime, pw); pw.println(); } + if (lastTopTime > 0) { + pw.print(prefix); pw.print("lastTopTime="); + TimeUtils.formatDuration(lastTopTime, nowUptime, pw); + pw.println(); + } if (hasStartedServices) { pw.print(prefix); pw.print("hasStartedServices="); pw.println(hasStartedServices); } @@ -856,4 +862,8 @@ final class ProcessRecord { } return list; } + + boolean hasForegroundServices() { + return foregroundServices; + } } diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 18c095725b09..415a822e3160 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -24,7 +24,6 @@ import static android.app.ActivityManager.USER_OP_IS_CURRENT; import static android.app.ActivityManager.USER_OP_SUCCESS; import static android.os.Process.SHELL_UID; import static android.os.Process.SYSTEM_UID; - import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU; import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; @@ -48,6 +47,7 @@ import android.app.IStopUserCallback; import android.app.IUserSwitchObserver; import android.app.KeyguardManager; import android.app.usage.UsageEvents; +import android.appwidget.AppWidgetManagerInternal; import android.content.Context; import android.content.IIntentReceiver; import android.content.Intent; @@ -87,8 +87,8 @@ import android.util.SparseArray; import android.util.SparseIntArray; import android.util.TimingsTraceLog; import android.util.proto.ProtoOutputStream; - import android.view.Window; + import com.android.internal.R; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; @@ -533,6 +533,9 @@ class UserController implements Handler.Callback { } } + // Spin up app widgets prior to boot-complete, so they can be ready promptly + mInjector.startUserWidgets(userId); + Slog.i(TAG, "Sending BOOT_COMPLETE user #" + userId); // Do not report secondary users, runtime restarts or first boot/upgrade if (userId == UserHandle.USER_SYSTEM @@ -2173,6 +2176,13 @@ class UserController implements Handler.Callback { } } + void startUserWidgets(int userId) { + AppWidgetManagerInternal awm = LocalServices.getService(AppWidgetManagerInternal.class); + if (awm != null) { + awm.unlockUser(userId); + } + } + void updateUserConfiguration() { synchronized (mService) { mService.updateUserConfigurationLocked(); diff --git a/services/core/java/com/android/server/connectivity/NetdEventListenerService.java b/services/core/java/com/android/server/connectivity/NetdEventListenerService.java index 422f5566eee1..e40949b785d9 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 @@ public class NetdEventListenerService extends INetdEventListener.Stub { @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 bf95210195b7..9684f4c4ae19 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 @@ public class NetworkMonitor extends StateMachine { 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 c370959dd2cf..3ea9810f2d76 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.IProxyCallback; 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 @@ public class PacManager { 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 @@ public class PacManager { * 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 @@ public class PacManager { mHasDownloaded = false; getAlarmManager().cancel(mPacRefreshIntent); bind(); - return true; + return ToSendOrNotToSendBroadcast.DONT_SEND_BROADCAST; } else { getAlarmManager().cancel(mPacRefreshIntent); synchronized (mProxyLock) { @@ -201,7 +204,7 @@ public class PacManager { } } } - return false; + return ToSendOrNotToSendBroadcast.DO_SEND_BROADCAST; } } @@ -296,7 +299,7 @@ public class PacManager { 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 15468ff05c08..fdddccd20714 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 class ProxyTracker { 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/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index 3c14393ca740..9dfdddbea18a 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -944,10 +944,11 @@ public class Tethering extends BaseNetworkObserver { public boolean hasTetherableConfiguration() { final TetheringConfiguration cfg = mConfig; final boolean hasDownstreamConfiguration = - (cfg.tetherableUsbRegexs.length != 0) || - (cfg.tetherableWifiRegexs.length != 0) || - (cfg.tetherableBluetoothRegexs.length != 0); - final boolean hasUpstreamConfiguration = !cfg.preferredUpstreamIfaceTypes.isEmpty(); + (cfg.tetherableUsbRegexs.length != 0) + || (cfg.tetherableWifiRegexs.length != 0) + || (cfg.tetherableBluetoothRegexs.length != 0); + final boolean hasUpstreamConfiguration = !cfg.preferredUpstreamIfaceTypes.isEmpty() + || cfg.chooseUpstreamAutomatically; return hasDownstreamConfiguration && hasUpstreamConfiguration; } @@ -1381,7 +1382,7 @@ public class Tethering extends BaseNetworkObserver { return; } - mUpstreamNetworkMonitor.start(mDeps.getDefaultNetworkRequest()); + mUpstreamNetworkMonitor.startObserveAllNetworks(); // TODO: De-duplicate with updateUpstreamWanted() below. if (upstreamWanted()) { @@ -1657,6 +1658,10 @@ public class Tethering extends BaseNetworkObserver { } } + public void systemReady() { + mUpstreamNetworkMonitor.startTrackDefaultNetwork(mDeps.getDefaultNetworkRequest()); + } + @Override public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { // Binder.java closes the resource for us. diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index b7ed2f9bd473..602aedbc2d00 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -206,45 +206,6 @@ public class Vpn { // Handle of the user initiating VPN. private final int mUserHandle; - // Listen to package removal and change events (update/uninstall) for this user - private final BroadcastReceiver mPackageIntentReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - final Uri data = intent.getData(); - final String packageName = data == null ? null : data.getSchemeSpecificPart(); - if (packageName == null) { - return; - } - - synchronized (Vpn.this) { - // Avoid race where always-on package has been unset - if (!packageName.equals(getAlwaysOnPackage())) { - return; - } - - final String action = intent.getAction(); - Log.i(TAG, "Received broadcast " + action + " for always-on VPN package " - + packageName + " in user " + mUserHandle); - - switch(action) { - case Intent.ACTION_PACKAGE_REPLACED: - // Start vpn after app upgrade - startAlwaysOnVpn(); - break; - case Intent.ACTION_PACKAGE_REMOVED: - final boolean isPackageRemoved = !intent.getBooleanExtra( - Intent.EXTRA_REPLACING, false); - if (isPackageRemoved) { - setAlwaysOnPackage(null, false); - } - break; - } - } - } - }; - - private boolean mIsPackageIntentReceiverRegistered = false; - public Vpn(Looper looper, Context context, INetworkManagementService netService, @UserIdInt int userHandle) { this(looper, context, netService, userHandle, new SystemServices(context)); @@ -500,7 +461,6 @@ public class Vpn { // Prepare this app. The notification will update as a side-effect of updateState(). prepareInternal(packageName); } - maybeRegisterPackageChangeReceiverLocked(packageName); setVpnForcedLocked(mLockdown); return true; } @@ -509,31 +469,6 @@ public class Vpn { return packageName == null || VpnConfig.LEGACY_VPN.equals(packageName); } - private void unregisterPackageChangeReceiverLocked() { - if (mIsPackageIntentReceiverRegistered) { - mContext.unregisterReceiver(mPackageIntentReceiver); - mIsPackageIntentReceiverRegistered = false; - } - } - - private void maybeRegisterPackageChangeReceiverLocked(String packageName) { - // Unregister IntentFilter listening for previous always-on package change - unregisterPackageChangeReceiverLocked(); - - if (!isNullOrLegacyVpn(packageName)) { - mIsPackageIntentReceiverRegistered = true; - - IntentFilter intentFilter = new IntentFilter(); - // Protected intent can only be sent by system. No permission required in register. - intentFilter.addAction(Intent.ACTION_PACKAGE_REPLACED); - intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); - intentFilter.addDataScheme("package"); - intentFilter.addDataSchemeSpecificPart(packageName, PatternMatcher.PATTERN_LITERAL); - mContext.registerReceiverAsUser( - mPackageIntentReceiver, UserHandle.of(mUserHandle), intentFilter, null, null); - } - } - /** * @return the package name of the VPN controller responsible for always-on VPN, * or {@code null} if none is set or always-on VPN is controlled through @@ -1302,7 +1237,6 @@ public class Vpn { setLockdown(false); mAlwaysOn = false; - unregisterPackageChangeReceiverLocked(); // Quit any active connections agentDisconnect(); } diff --git a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java index 3e5d5aa6ca54..3ac311b3e13a 100644 --- a/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java +++ b/services/core/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitor.java @@ -55,10 +55,13 @@ import java.util.Set; * A class to centralize all the network and link properties information * pertaining to the current and any potential upstream network. * - * Calling #start() registers two callbacks: one to track the system default - * network and a second to observe all networks. The latter is necessary - * while the expression of preferred upstreams remains a list of legacy - * connectivity types. In future, this can be revisited. + * The owner of UNM gets it to register network callbacks by calling the + * following methods : + * Calling #startTrackDefaultNetwork() to track the system default network. + * Calling #startObserveAllNetworks() to observe all networks. Listening all + * networks is necessary while the expression of preferred upstreams remains + * a list of legacy connectivity types. In future, this can be revisited. + * Calling #registerMobileNetworkRequest() to bring up mobile DUN/HIPRI network. * * The methods and data members of this class are only to be accessed and * modified from the tethering master state machine thread. Any other @@ -119,33 +122,31 @@ public class UpstreamNetworkMonitor { mCM = cm; } - public void start(NetworkRequest defaultNetworkRequest) { + public void startTrackDefaultNetwork(NetworkRequest defaultNetworkRequest) { + // This is not really a "request", just a way of tracking the system default network. + // It's guaranteed not to actually bring up any networks because it's the same request + // as the ConnectivityService default request, and thus shares fate with it. We can't + // use registerDefaultNetworkCallback because it will not track the system default + // network if there is a VPN that applies to our UID. + if (mDefaultNetworkCallback == null) { + final NetworkRequest trackDefaultRequest = new NetworkRequest(defaultNetworkRequest); + mDefaultNetworkCallback = new UpstreamNetworkCallback(CALLBACK_DEFAULT_INTERNET); + cm().requestNetwork(trackDefaultRequest, mDefaultNetworkCallback, mHandler); + } + } + + public void startObserveAllNetworks() { stop(); final NetworkRequest listenAllRequest = new NetworkRequest.Builder() .clearCapabilities().build(); mListenAllCallback = new UpstreamNetworkCallback(CALLBACK_LISTEN_ALL); cm().registerNetworkCallback(listenAllRequest, mListenAllCallback, mHandler); - - if (defaultNetworkRequest != null) { - // This is not really a "request", just a way of tracking the system default network. - // It's guaranteed not to actually bring up any networks because it's the same request - // as the ConnectivityService default request, and thus shares fate with it. We can't - // use registerDefaultNetworkCallback because it will not track the system default - // network if there is a VPN that applies to our UID. - final NetworkRequest trackDefaultRequest = new NetworkRequest(defaultNetworkRequest); - mDefaultNetworkCallback = new UpstreamNetworkCallback(CALLBACK_DEFAULT_INTERNET); - cm().requestNetwork(trackDefaultRequest, mDefaultNetworkCallback, mHandler); - } } public void stop() { releaseMobileNetworkRequest(); - releaseCallback(mDefaultNetworkCallback); - mDefaultNetworkCallback = null; - mDefaultInternetNetwork = null; - releaseCallback(mListenAllCallback); mListenAllCallback = null; @@ -264,9 +265,7 @@ public class UpstreamNetworkMonitor { mNetworkMap.put(network, new NetworkState(null, null, null, network, null, null)); } - private void handleNetCap(int callbackType, Network network, NetworkCapabilities newNc) { - if (callbackType == CALLBACK_DEFAULT_INTERNET) mDefaultInternetNetwork = network; - + private void handleNetCap(Network network, NetworkCapabilities newNc) { final NetworkState prev = mNetworkMap.get(network); if (prev == null || newNc.equals(prev.networkCapabilities)) { // Ignore notifications about networks for which we have not yet @@ -315,31 +314,25 @@ public class UpstreamNetworkMonitor { notifyTarget(EVENT_ON_LINKPROPERTIES, network); } - private void handleSuspended(int callbackType, Network network) { - if (callbackType != CALLBACK_LISTEN_ALL) return; + private void handleSuspended(Network network) { if (!network.equals(mTetheringUpstreamNetwork)) return; mLog.log("SUSPENDED current upstream: " + network); } - private void handleResumed(int callbackType, Network network) { - if (callbackType != CALLBACK_LISTEN_ALL) return; + private void handleResumed(Network network) { if (!network.equals(mTetheringUpstreamNetwork)) return; mLog.log("RESUMED current upstream: " + network); } - private void handleLost(int callbackType, Network network) { - if (network.equals(mDefaultInternetNetwork)) { - mDefaultInternetNetwork = null; - // There are few TODOs within ConnectivityService's rematching code - // pertaining to spurious onLost() notifications. - // - // TODO: simplify this, probably if favor of code that: - // - selects a new upstream if mTetheringUpstreamNetwork has - // been lost (by any callback) - // - deletes the entry from the map only when the LISTEN_ALL - // callback gets notified. - if (callbackType == CALLBACK_DEFAULT_INTERNET) return; - } + private void handleLost(Network network) { + // There are few TODOs within ConnectivityService's rematching code + // pertaining to spurious onLost() notifications. + // + // TODO: simplify this, probably if favor of code that: + // - selects a new upstream if mTetheringUpstreamNetwork has + // been lost (by any callback) + // - deletes the entry from the map only when the LISTEN_ALL + // callback gets notified. if (!mNetworkMap.containsKey(network)) { // Ignore loss of networks about which we had not previously @@ -393,11 +386,17 @@ public class UpstreamNetworkMonitor { @Override public void onCapabilitiesChanged(Network network, NetworkCapabilities newNc) { - handleNetCap(mCallbackType, network, newNc); + if (mCallbackType == CALLBACK_DEFAULT_INTERNET) { + mDefaultInternetNetwork = network; + return; + } + handleNetCap(network, newNc); } @Override public void onLinkPropertiesChanged(Network network, LinkProperties newLp) { + if (mCallbackType == CALLBACK_DEFAULT_INTERNET) return; + handleLinkProp(network, newLp); // Any non-LISTEN_ALL callback will necessarily concern a network that will // also match the LISTEN_ALL callback by construction of the LISTEN_ALL callback. @@ -409,17 +408,25 @@ public class UpstreamNetworkMonitor { @Override public void onNetworkSuspended(Network network) { - handleSuspended(mCallbackType, network); + if (mCallbackType == CALLBACK_LISTEN_ALL) { + handleSuspended(network); + } } @Override public void onNetworkResumed(Network network) { - handleResumed(mCallbackType, network); + if (mCallbackType == CALLBACK_LISTEN_ALL) { + handleResumed(network); + } } @Override public void onLost(Network network) { - handleLost(mCallbackType, network); + if (mCallbackType == CALLBACK_DEFAULT_INTERNET) { + mDefaultInternetNetwork = null; + return; + } + handleLost(network); // Any non-LISTEN_ALL callback will necessarily concern a network that will // also match the LISTEN_ALL callback by construction of the LISTEN_ALL callback. // So it's not useful to do this work for non-LISTEN_ALL callbacks. diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java index 349e1c8b713e..512e85192d36 100644 --- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java +++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java @@ -104,6 +104,12 @@ final class DisplayDeviceInfo { public static final int FLAG_DESTROY_CONTENT_ON_REMOVAL = 1 << 10; /** + * Flag: The display cutout of this display is masked. + * @hide + */ + public static final int FLAG_MASK_DISPLAY_CUTOUT = 1 << 11; + + /** * Touch attachment: Display does not receive touch. */ public static final int TOUCH_NONE = 0; @@ -453,6 +459,9 @@ final class DisplayDeviceInfo { if ((flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) { msg.append(", FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD"); } + if ((flags & FLAG_MASK_DISPLAY_CUTOUT) != 0) { + msg.append(", FLAG_MASK_DISPLAY_CUTOUT"); + } return msg.toString(); } } diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java index ddd8855f3199..cc5a8271eb5f 100644 --- a/services/core/java/com/android/server/display/DisplayManagerService.java +++ b/services/core/java/com/android/server/display/DisplayManagerService.java @@ -151,6 +151,8 @@ public final class DisplayManagerService extends SystemService { // Otherwise WFD is enabled according to the value of config_enableWifiDisplay. private static final String FORCE_WIFI_DISPLAY_ENABLE = "persist.debug.wfd.enable"; + private static final String PROP_DEFAULT_DISPLAY_TOP_INSET = "persist.sys.displayinset.top"; + private static final long WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT = 10000; private static final int MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS = 1; @@ -243,6 +245,15 @@ public final class DisplayManagerService extends SystemService { // device). private Point mStableDisplaySize = new Point(); + // Whether the system has finished booting or not. + private boolean mSystemReady; + + // The top inset of the default display. + // This gets persisted so that the boot animation knows how to transition from the display's + // full size to the size configured by the user. Right now we only persist and animate the top + // inset, but theoretically we could do it for all of them. + private int mDefaultDisplayTopInset; + // Viewports of the default display and the display that should receive touch // input from an external source. Used by the input system. private final DisplayViewport mDefaultViewport = new DisplayViewport(); @@ -301,6 +312,7 @@ public final class DisplayManagerService extends SystemService { Resources resources = mContext.getResources(); mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger( com.android.internal.R.integer.config_defaultDisplayDefaultColorMode); + mDefaultDisplayTopInset = SystemProperties.getInt(PROP_DEFAULT_DISPLAY_TOP_INSET, -1); float[] lux = getFloatArray(resources.obtainTypedArray( com.android.internal.R.array.config_minimumBrightnessCurveLux)); float[] nits = getFloatArray(resources.obtainTypedArray( @@ -311,6 +323,8 @@ public final class DisplayManagerService extends SystemService { PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mGlobalDisplayBrightness = pm.getDefaultScreenBrightnessSetting(); mCurrentUserId = UserHandle.USER_SYSTEM; + + mSystemReady = false; } public void setupSchedulerPolicies() { @@ -400,6 +414,10 @@ public final class DisplayManagerService extends SystemService { synchronized (mSyncRoot) { mSafeMode = safeMode; mOnlyCore = onlyCore; + mSystemReady = true; + // Just in case the top inset changed before the system was ready. At this point, any + // relevant configuration should be in place. + recordTopInsetLocked(mLogicalDisplays.get(Display.DEFAULT_DISPLAY)); } mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS); @@ -457,7 +475,7 @@ public final class DisplayManagerService extends SystemService { LogicalDisplay display = mLogicalDisplays.get(displayId); if (display != null) { if (display.setDisplayInfoOverrideFromWindowManagerLocked(info)) { - sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED); + handleLogicalDisplayChanged(displayId, display); scheduleTraversalLocked(false); } } @@ -938,6 +956,13 @@ public final class DisplayManagerService extends SystemService { scheduleTraversalLocked(false); } + private void handleLogicalDisplayChanged(int displayId, @NonNull LogicalDisplay display) { + if (displayId == Display.DEFAULT_DISPLAY) { + recordTopInsetLocked(display); + } + sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED); + } + private void applyGlobalDisplayStateLocked(List<Runnable> workQueue) { final int count = mDisplayDevices.size(); for (int i = 0; i < count; i++) { @@ -991,6 +1016,7 @@ public final class DisplayManagerService extends SystemService { configureColorModeLocked(display, device); if (isDefault) { recordStableDisplayStatsIfNeededLocked(display); + recordTopInsetLocked(display); } mLogicalDisplays.put(displayId, display); @@ -1039,6 +1065,21 @@ public final class DisplayManagerService extends SystemService { } } + private void recordTopInsetLocked(@Nullable LogicalDisplay d) { + // We must only persist the inset after boot has completed, otherwise we will end up + // overwriting the persisted value before the masking flag has been loaded from the + // resource overlay. + if (!mSystemReady || d == null) { + return; + } + int topInset = d.getInsets().top; + if (topInset == mDefaultDisplayTopInset) { + return; + } + mDefaultDisplayTopInset = topInset; + SystemProperties.set(PROP_DEFAULT_DISPLAY_TOP_INSET, Integer.toString(topInset)); + } + private void setStableDisplaySizeLocked(int width, int height) { mStableDisplaySize = new Point(width, height); try { @@ -1118,7 +1159,7 @@ public final class DisplayManagerService extends SystemService { sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED); changed = true; } else if (!mTempDisplayInfo.equals(display.getDisplayInfoLocked())) { - sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_CHANGED); + handleLogicalDisplayChanged(displayId, display); changed = true; } } diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index 21ae048e1d75..16d82df4dd5b 100644 --- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java @@ -402,6 +402,10 @@ final class LocalDisplayAdapter extends DisplayAdapter { && SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false))) { mInfo.flags |= DisplayDeviceInfo.FLAG_ROUND; } + if (res.getBoolean( + com.android.internal.R.bool.config_maskMainBuiltInDisplayCutout)) { + mInfo.flags |= DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT; + } mInfo.displayCutout = DisplayCutout.fromResourcesRectApproximation(res, mInfo.width, mInfo.height); mInfo.type = Display.TYPE_BUILT_IN; diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java index 23ee56b24b19..5b7c5205ce3a 100644 --- a/services/core/java/com/android/server/display/LogicalDisplay.java +++ b/services/core/java/com/android/server/display/LogicalDisplay.java @@ -18,11 +18,14 @@ package com.android.server.display; import android.graphics.Rect; import android.hardware.display.DisplayManagerInternal; +import android.os.SystemProperties; import android.view.Display; import android.view.DisplayInfo; import android.view.Surface; import android.view.SurfaceControl; +import com.android.server.wm.utils.InsetUtils; + import java.io.PrintWriter; import java.util.Arrays; import java.util.List; @@ -55,6 +58,8 @@ import java.util.Objects; * </p> */ final class LogicalDisplay { + private static final String PROP_MASKING_INSET_TOP = "persist.sys.displayinset.top"; + private final DisplayInfo mBaseDisplayInfo = new DisplayInfo(); // The layer stack we use when the display has been blanked to prevent any @@ -251,14 +256,18 @@ final class LogicalDisplay { if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) { mBaseDisplayInfo.flags |= Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD; } + Rect maskingInsets = getMaskingInsets(deviceInfo); + int maskedWidth = deviceInfo.width - maskingInsets.left - maskingInsets.right; + int maskedHeight = deviceInfo.height - maskingInsets.top - maskingInsets.bottom; + mBaseDisplayInfo.type = deviceInfo.type; mBaseDisplayInfo.address = deviceInfo.address; mBaseDisplayInfo.name = deviceInfo.name; mBaseDisplayInfo.uniqueId = deviceInfo.uniqueId; - mBaseDisplayInfo.appWidth = deviceInfo.width; - mBaseDisplayInfo.appHeight = deviceInfo.height; - mBaseDisplayInfo.logicalWidth = deviceInfo.width; - mBaseDisplayInfo.logicalHeight = deviceInfo.height; + mBaseDisplayInfo.appWidth = maskedWidth; + mBaseDisplayInfo.appHeight = maskedHeight; + mBaseDisplayInfo.logicalWidth = maskedWidth; + mBaseDisplayInfo.logicalHeight = maskedHeight; mBaseDisplayInfo.rotation = Surface.ROTATION_0; mBaseDisplayInfo.modeId = deviceInfo.modeId; mBaseDisplayInfo.defaultModeId = deviceInfo.defaultModeId; @@ -275,13 +284,15 @@ final class LogicalDisplay { mBaseDisplayInfo.appVsyncOffsetNanos = deviceInfo.appVsyncOffsetNanos; mBaseDisplayInfo.presentationDeadlineNanos = deviceInfo.presentationDeadlineNanos; mBaseDisplayInfo.state = deviceInfo.state; - mBaseDisplayInfo.smallestNominalAppWidth = deviceInfo.width; - mBaseDisplayInfo.smallestNominalAppHeight = deviceInfo.height; - mBaseDisplayInfo.largestNominalAppWidth = deviceInfo.width; - mBaseDisplayInfo.largestNominalAppHeight = deviceInfo.height; + mBaseDisplayInfo.smallestNominalAppWidth = maskedWidth; + mBaseDisplayInfo.smallestNominalAppHeight = maskedHeight; + mBaseDisplayInfo.largestNominalAppWidth = maskedWidth; + mBaseDisplayInfo.largestNominalAppHeight = maskedHeight; mBaseDisplayInfo.ownerUid = deviceInfo.ownerUid; mBaseDisplayInfo.ownerPackageName = deviceInfo.ownerPackageName; - mBaseDisplayInfo.displayCutout = deviceInfo.displayCutout; + boolean maskCutout = + (deviceInfo.flags & DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT) != 0; + mBaseDisplayInfo.displayCutout = maskCutout ? null : deviceInfo.displayCutout; mPrimaryDisplayDeviceInfo = deviceInfo; mInfo = null; @@ -289,6 +300,29 @@ final class LogicalDisplay { } /** + * Return the insets currently applied to the display. + * + * Note that the base DisplayInfo already takes these insets into account, so if you want to + * find out the <b>true</b> size of the display, you need to add them back to the logical + * dimensions. + */ + public Rect getInsets() { + return getMaskingInsets(mPrimaryDisplayDeviceInfo); + } + + /** + * Returns insets in ROTATION_0 for areas that are masked. + */ + private static Rect getMaskingInsets(DisplayDeviceInfo deviceInfo) { + boolean maskCutout = (deviceInfo.flags & DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT) != 0; + if (maskCutout && deviceInfo.displayCutout != null) { + return deviceInfo.displayCutout.getSafeInsets(); + } else { + return new Rect(); + } + } + + /** * Applies the layer stack and transformation to the given display device * so that it shows the contents of this logical display. * @@ -349,6 +383,12 @@ final class LogicalDisplay { int physWidth = rotated ? displayDeviceInfo.height : displayDeviceInfo.width; int physHeight = rotated ? displayDeviceInfo.width : displayDeviceInfo.height; + Rect maskingInsets = getMaskingInsets(displayDeviceInfo); + InsetUtils.rotateInsets(maskingInsets, orientation); + // Don't consider the masked area as available when calculating the scaling below. + physWidth -= maskingInsets.left + maskingInsets.right; + physHeight -= maskingInsets.top + maskingInsets.bottom; + // Determine whether the width or height is more constrained to be scaled. // physWidth / displayInfo.logicalWidth => letter box // or physHeight / displayInfo.logicalHeight => pillar box @@ -375,6 +415,9 @@ final class LogicalDisplay { mTempDisplayRect.set(displayRectLeft, displayRectTop, displayRectLeft + displayRectWidth, displayRectTop + displayRectHeight); + // Now add back the offset for the masked area. + mTempDisplayRect.offset(maskingInsets.left, maskingInsets.top); + mTempDisplayRect.left += mDisplayOffsetX; mTempDisplayRect.right += mDisplayOffsetX; mTempDisplayRect.top += mDisplayOffsetY; diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index de0f29851da5..25ca27836aa7 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -1082,13 +1082,14 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { assertRunOnServiceThread(); if (!canStartArcUpdateAction(message.getSource(), true)) { - if (getAvrDeviceInfo() == null) { + HdmiDeviceInfo avrDeviceInfo = getAvrDeviceInfo(); + if (avrDeviceInfo == null) { // AVR may not have been discovered yet. Delay the message processing. mDelayedMessageBuffer.add(message); return true; } mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED); - if (!isConnectedToArcPort(message.getSource())) { + if (!isConnectedToArcPort(avrDeviceInfo.getPhysicalAddress())) { displayOsd(OSD_MESSAGE_ARC_CONNECTED_INVALID_PORT); } return true; diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 268e844a7a0a..0120dc3aa6d8 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.io.PrintWriter; 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 @@ public final class HdmiControlService extends SystemService { 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 @@ public final class HdmiControlService extends SystemService { // 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/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index 383e1e0288ca..82371855bdda 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -955,7 +955,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub { @Override public long getIfaceStats(String iface, int type) { - return nativeGetIfaceStat(iface, type, checkBpfStatsEnable()); + // eBPF code doesn't provide per-interface TCP counters. Use xt_qtaguid for now. + // TODO: delete getMobileTcp(Rx|Tx)Packets entirely. See b/110443385 . + if (type == TYPE_TCP_TX_PACKETS || type == TYPE_TCP_RX_PACKETS) { + return nativeGetIfaceStat(iface, type, false); + } else { + return nativeGetIfaceStat(iface, type, checkBpfStatsEnable()); + } } @Override diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java index c0fbfbb20b95..18f4bc768632 100644 --- a/services/core/java/com/android/server/notification/ConditionProviders.java +++ b/services/core/java/com/android/server/notification/ConditionProviders.java @@ -150,6 +150,7 @@ public class ConditionProviders extends ManagedServices { try { provider.onConnected(); } catch (RemoteException e) { + Slog.e(TAG, "can't connect to service " + info, e); // we tried } if (mCallback != null) { diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java index f7becd518861..30fa7fe4ce87 100644 --- a/services/core/java/com/android/server/notification/ManagedServices.java +++ b/services/core/java/com/android/server/notification/ManagedServices.java @@ -175,6 +175,10 @@ abstract public class ManagedServices { } } + protected int getBindFlags() { + return BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE | BIND_ALLOW_WHITELIST_MANAGEMENT; + } + protected void onServiceRemovedLocked(ManagedServiceInfo removed) { } private ManagedServiceInfo newServiceInfo(IInterface service, @@ -1022,9 +1026,9 @@ abstract public class ManagedServices { } }; if (!mContext.bindServiceAsUser(intent, - serviceConnection, - BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE | BIND_ALLOW_WHITELIST_MANAGEMENT, - new UserHandle(userid))) { + serviceConnection, + getBindFlags(), + new UserHandle(userid))) { mServicesBinding.remove(servicesBindingTag); Slog.w(TAG, "Unable to bind " + getCaption() + " service: " + intent); return; diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 1284468947c2..f70ecd54c711 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -33,6 +33,10 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON; import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR; +import static android.content.Context.BIND_ADJUST_BELOW_PERCEPTIBLE; +import static android.content.Context.BIND_ALLOW_WHITELIST_MANAGEMENT; +import static android.content.Context.BIND_AUTO_CREATE; +import static android.content.Context.BIND_FOREGROUND_SERVICE; import static android.content.pm.PackageManager.FEATURE_LEANBACK; import static android.content.pm.PackageManager.FEATURE_TELEVISION; import static android.content.pm.PackageManager.PERMISSION_GRANTED; @@ -2122,6 +2126,10 @@ public class NotificationManagerService extends SystemService { enforceSystemOrSystemUI("setNotificationsEnabledForPackage"); mRankingHelper.setEnabled(pkg, uid, enabled); + mMetricsLogger.write(new LogMaker(MetricsEvent.ACTION_BAN_APP_NOTES) + .setType(MetricsEvent.TYPE_ACTION) + .setPackageName(pkg) + .setSubtype(enabled ? 1 : 0)); // Now, cancel any outstanding notifications that are part of a just-disabled app if (!enabled) { cancelAllNotificationsInt(MY_UID, MY_PID, pkg, null, 0, 0, true, @@ -6510,6 +6518,16 @@ public class NotificationManagerService extends SystemService { } @Override + protected int getBindFlags() { + // Most of the same flags as the base, but also add BIND_ADJUST_BELOW_PERCEPTIBLE + // because too many 3P apps could be kept in memory as notification listeners and + // cause extreme memory pressure. + // TODO: Change the binding lifecycle of NotificationListeners to avoid this situation. + return BIND_AUTO_CREATE | BIND_FOREGROUND_SERVICE + | BIND_ADJUST_BELOW_PERCEPTIBLE | BIND_ALLOW_WHITELIST_MANAGEMENT; + } + + @Override protected Config getConfig() { Config c = new Config(); c.caption = "notification listener"; diff --git a/services/core/java/com/android/server/notification/ZenLog.java b/services/core/java/com/android/server/notification/ZenLog.java index 67608753a2c3..b016fafa3d29 100644 --- a/services/core/java/com/android/server/notification/ZenLog.java +++ b/services/core/java/com/android/server/notification/ZenLog.java @@ -36,7 +36,8 @@ import java.util.List; public class ZenLog { private static final String TAG = "ZenLog"; - private static final boolean DEBUG = Build.IS_DEBUGGABLE; + // the ZenLog is *very* verbose, so be careful about setting this to true + private static final boolean DEBUG = false; private static final int SIZE = Build.IS_DEBUGGABLE ? 100 : 20; diff --git a/services/core/java/com/android/server/notification/ZenModeConditions.java b/services/core/java/com/android/server/notification/ZenModeConditions.java index 63c0bafe389d..b080a73c1e42 100644 --- a/services/core/java/com/android/server/notification/ZenModeConditions.java +++ b/services/core/java/com/android/server/notification/ZenModeConditions.java @@ -19,7 +19,6 @@ package com.android.server.notification; import android.content.ComponentName; import android.net.Uri; import android.service.notification.Condition; -import android.service.notification.IConditionListener; import android.service.notification.IConditionProvider; import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig.ZenRule; @@ -27,6 +26,8 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.Log; +import com.android.internal.annotations.VisibleForTesting; + import java.io.PrintWriter; import java.util.Objects; @@ -36,7 +37,9 @@ public class ZenModeConditions implements ConditionProviders.Callback { private final ZenModeHelper mHelper; private final ConditionProviders mConditionProviders; - private final ArrayMap<Uri, ComponentName> mSubscriptions = new ArrayMap<>(); + + @VisibleForTesting + protected final ArrayMap<Uri, ComponentName> mSubscriptions = new ArrayMap<>(); private boolean mFirstEvaluation = true; @@ -59,7 +62,8 @@ public class ZenModeConditions implements ConditionProviders.Callback { pw.print(prefix); pw.print("mSubscriptions="); pw.println(mSubscriptions); } - public void evaluateConfig(ZenModeConfig config, boolean processSubscriptions) { + public void evaluateConfig(ZenModeConfig config, ComponentName trigger, + boolean processSubscriptions) { if (config == null) return; if (config.manualRule != null && config.manualRule.condition != null && !config.manualRule.isTrueOrUnknown()) { @@ -67,9 +71,9 @@ public class ZenModeConditions implements ConditionProviders.Callback { config.manualRule = null; } final ArraySet<Uri> current = new ArraySet<>(); - evaluateRule(config.manualRule, current, processSubscriptions); + evaluateRule(config.manualRule, current, null, processSubscriptions); for (ZenRule automaticRule : config.automaticRules.values()) { - evaluateRule(automaticRule, current, processSubscriptions); + evaluateRule(automaticRule, current, trigger, processSubscriptions); updateSnoozing(automaticRule); } @@ -102,7 +106,7 @@ public class ZenModeConditions implements ConditionProviders.Callback { @Override public void onServiceAdded(ComponentName component) { if (DEBUG) Log.d(TAG, "onServiceAdded " + component); - mHelper.setConfig(mHelper.getConfig(), "zmc.onServiceAdded"); + mHelper.setConfig(mHelper.getConfig(), component, "zmc.onServiceAdded"); } @Override @@ -110,17 +114,22 @@ public class ZenModeConditions implements ConditionProviders.Callback { if (DEBUG) Log.d(TAG, "onConditionChanged " + id + " " + condition); ZenModeConfig config = mHelper.getConfig(); if (config == null) return; + ComponentName trigger = null; boolean updated = updateCondition(id, condition, config.manualRule); for (ZenRule automaticRule : config.automaticRules.values()) { updated |= updateCondition(id, condition, automaticRule); updated |= updateSnoozing(automaticRule); + if (updated) { + trigger = automaticRule.component; + } } if (updated) { - mHelper.setConfig(config, "conditionChanged"); + mHelper.setConfig(config, trigger, "conditionChanged"); } } - private void evaluateRule(ZenRule rule, ArraySet<Uri> current, boolean processSubscriptions) { + private void evaluateRule(ZenRule rule, ArraySet<Uri> current, ComponentName trigger, + boolean processSubscriptions) { if (rule == null || rule.conditionId == null) return; final Uri id = rule.conditionId; boolean isSystemCondition = false; @@ -146,7 +155,9 @@ public class ZenModeConditions implements ConditionProviders.Callback { if (current != null) { current.add(id); } - if (processSubscriptions) { + if (processSubscriptions && ((trigger != null && trigger.equals(rule.component)) + || isSystemCondition)) { + if (DEBUG) Log.d(TAG, "Subscribing to " + rule.component); if (mConditionProviders.subscribeIfNecessary(rule.component, rule.conditionId)) { synchronized (mSubscriptions) { mSubscriptions.put(rule.conditionId, rule.component); diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index 669d5565534d..0c42f8ab8345 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -102,7 +102,7 @@ public class ZenModeHelper { private final ZenModeFiltering mFiltering; protected final RingerModeDelegate mRingerModeDelegate = new RingerModeDelegate(); - private final ZenModeConditions mConditions; + @VisibleForTesting protected final ZenModeConditions mConditions; private final SparseArray<ZenModeConfig> mConfigs = new SparseArray<>(); private final Metrics mMetrics = new Metrics(); private final ConditionProviders.Config mServiceConfig; @@ -225,7 +225,7 @@ public class ZenModeHelper { config.user = user; } synchronized (mConfig) { - setConfigLocked(config, reason); + setConfigLocked(config, null, reason); } cleanUpZenRules(); } @@ -312,7 +312,7 @@ public class ZenModeHelper { ZenRule rule = new ZenRule(); populateZenRule(automaticZenRule, rule, true); newConfig.automaticRules.put(rule.id, rule); - if (setConfigLocked(newConfig, reason, true)) { + if (setConfigLocked(newConfig, reason, rule.component, true)) { return rule.id; } else { throw new AndroidRuntimeException("Could not create rule"); @@ -342,7 +342,7 @@ public class ZenModeHelper { } populateZenRule(automaticZenRule, rule, false); newConfig.automaticRules.put(ruleId, rule); - return setConfigLocked(newConfig, reason, true); + return setConfigLocked(newConfig, reason, rule.component, true); } } @@ -360,7 +360,7 @@ public class ZenModeHelper { throw new SecurityException( "Cannot delete rules not owned by your condition provider"); } - return setConfigLocked(newConfig, reason, true); + return setConfigLocked(newConfig, reason, null, true); } } @@ -376,7 +376,7 @@ public class ZenModeHelper { newConfig.automaticRules.removeAt(i); } } - return setConfigLocked(newConfig, reason, true); + return setConfigLocked(newConfig, reason, null, true); } } @@ -537,7 +537,7 @@ public class ZenModeHelper { newRule.enabler = caller; newConfig.manualRule = newRule; } - setConfigLocked(newConfig, reason, setRingerMode); + setConfigLocked(newConfig, reason, null, setRingerMode); } } @@ -644,7 +644,7 @@ public class ZenModeHelper { } if (DEBUG) Log.d(TAG, reason); synchronized (mConfig) { - setConfigLocked(config, reason); + setConfigLocked(config, null, reason); } } } @@ -673,7 +673,7 @@ public class ZenModeHelper { synchronized (mConfig) { final ZenModeConfig newConfig = mConfig.copy(); newConfig.applyNotificationPolicy(policy); - setConfigLocked(newConfig, "setNotificationPolicy"); + setConfigLocked(newConfig, null, "setNotificationPolicy"); } } @@ -697,7 +697,7 @@ public class ZenModeHelper { } } } - setConfigLocked(newConfig, "cleanUpZenRules"); + setConfigLocked(newConfig, null, "cleanUpZenRules"); } } @@ -710,17 +710,19 @@ public class ZenModeHelper { } } - public boolean setConfigLocked(ZenModeConfig config, String reason) { - return setConfigLocked(config, reason, true /*setRingerMode*/); + public boolean setConfigLocked(ZenModeConfig config, ComponentName triggeringComponent, + String reason) { + return setConfigLocked(config, reason, triggeringComponent, true /*setRingerMode*/); } - public void setConfig(ZenModeConfig config, String reason) { + public void setConfig(ZenModeConfig config, ComponentName triggeringComponent, String reason) { synchronized (mConfig) { - setConfigLocked(config, reason); + setConfigLocked(config, triggeringComponent, reason); } } - private boolean setConfigLocked(ZenModeConfig config, String reason, boolean setRingerMode) { + private boolean setConfigLocked(ZenModeConfig config, String reason, + ComponentName triggeringComponent, boolean setRingerMode) { final long identity = Binder.clearCallingIdentity(); try { if (config == null || !config.isValid()) { @@ -733,7 +735,8 @@ public class ZenModeHelper { if (DEBUG) Log.d(TAG, "setConfigLocked: store config for user " + config.user); return true; } - mConditions.evaluateConfig(config, false /*processSubscriptions*/); // may modify config + // may modify config + mConditions.evaluateConfig(config, null, false /*processSubscriptions*/); mConfigs.put(config.user, config); if (DEBUG) Log.d(TAG, "setConfigLocked reason=" + reason, new Throwable()); ZenLog.traceConfig(reason, mConfig, config); @@ -746,7 +749,7 @@ public class ZenModeHelper { dispatchOnPolicyChanged(); } mConfig = config; - mHandler.postApplyConfig(config, reason, setRingerMode); + mHandler.postApplyConfig(config, reason, triggeringComponent, setRingerMode); return true; } catch (SecurityException e) { Log.wtf(TAG, "Invalid rule in config", e); @@ -756,13 +759,14 @@ public class ZenModeHelper { } } - private void applyConfig(ZenModeConfig config, String reason, boolean setRingerMode) { + private void applyConfig(ZenModeConfig config, String reason, + ComponentName triggeringComponent, boolean setRingerMode) { final String val = Integer.toString(config.hashCode()); Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_CONFIG_ETAG, val); if (!evaluateZenMode(reason, setRingerMode)) { applyRestrictions(); // evaluateZenMode will also apply restrictions if changed } - mConditions.evaluateConfig(config, true /*processSubscriptions*/); + mConditions.evaluateConfig(config, triggeringComponent, true /*processSubscriptions*/); } private int getZenModeSetting() { @@ -1260,13 +1264,16 @@ public class ZenModeHelper { private final class ConfigMessageData { public final ZenModeConfig config; + public ComponentName triggeringComponent; public final String reason; public final boolean setRingerMode; - ConfigMessageData(ZenModeConfig config, String reason, boolean setRingerMode) { + ConfigMessageData(ZenModeConfig config, String reason, + ComponentName triggeringComponent, boolean setRingerMode) { this.config = config; this.reason = reason; this.setRingerMode = setRingerMode; + this.triggeringComponent = triggeringComponent; } } @@ -1286,9 +1293,10 @@ public class ZenModeHelper { sendEmptyMessageDelayed(MSG_METRICS, METRICS_PERIOD_MS); } - private void postApplyConfig(ZenModeConfig config, String reason, boolean setRingerMode) { + private void postApplyConfig(ZenModeConfig config, String reason, + ComponentName triggeringComponent, boolean setRingerMode) { sendMessage(obtainMessage(MSG_APPLY_CONFIG, - new ConfigMessageData(config, reason, setRingerMode))); + new ConfigMessageData(config, reason, triggeringComponent, setRingerMode))); } @Override @@ -1303,7 +1311,7 @@ public class ZenModeHelper { case MSG_APPLY_CONFIG: ConfigMessageData applyConfigData = (ConfigMessageData) msg.obj; applyConfig(applyConfigData.config, applyConfigData.reason, - applyConfigData.setRingerMode); + applyConfigData.triggeringComponent, applyConfigData.setRingerMode); } } } diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java index 350fb2f6c58a..f1b03d1fc9d6 100644 --- a/services/core/java/com/android/server/om/OverlayManagerService.java +++ b/services/core/java/com/android/server/om/OverlayManagerService.java @@ -22,11 +22,14 @@ import static android.content.Intent.ACTION_PACKAGE_CHANGED; import static android.content.Intent.ACTION_PACKAGE_REMOVED; import static android.content.Intent.ACTION_USER_ADDED; import static android.content.Intent.ACTION_USER_REMOVED; +import static android.content.pm.PackageManager.GET_SHARED_LIBRARY_FILES; +import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; import static android.content.pm.PackageManager.SIGNATURE_MATCH; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; +import android.app.ActivityThread; import android.app.IActivityManager; import android.content.BroadcastReceiver; import android.content.Context; @@ -34,6 +37,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.om.IOverlayManager; import android.content.om.OverlayInfo; +import android.content.pm.ApplicationInfo; import android.content.pm.IPackageManager; import android.content.pm.PackageInfo; import android.content.pm.PackageManagerInternal; @@ -269,13 +273,30 @@ public final class OverlayManagerService extends SystemService { @Override public void onBootPhase(int phase) { - if (phase == PHASE_SYSTEM_SERVICES_READY) { + if (phase == PHASE_SYSTEM_SERVICES_READY && mInitCompleteSignal != null) { ConcurrentUtils.waitForFutureNoInterrupt(mInitCompleteSignal, "Wait for OverlayManagerService init"); mInitCompleteSignal = null; } } + public void updateSystemUiContext() { + if (mInitCompleteSignal != null) { + ConcurrentUtils.waitForFutureNoInterrupt(mInitCompleteSignal, + "Wait for OverlayManagerService init"); + mInitCompleteSignal = null; + } + + final ApplicationInfo ai; + try { + ai = mPackageManager.mPackageManager.getApplicationInfo("android", + GET_SHARED_LIBRARY_FILES, UserHandle.USER_SYSTEM); + } catch (RemoteException e) { + throw e.rethrowAsRuntimeException(); + } + ActivityThread.currentActivityThread().handleSystemApplicationInfoChanged(ai); + } + private void initIfNeeded() { final UserManager um = getContext().getSystemService(UserManager.class); final List<UserInfo> users = um.getUsers(true /*excludeDying*/); diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java index c197d2302ebf..5e1ed0340973 100644 --- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java +++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java @@ -35,6 +35,7 @@ import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; import com.android.server.pm.Installer.InstallerException; +import com.android.server.pm.dex.ArtManagerService; import com.android.server.pm.dex.DexManager; import com.android.server.pm.dex.DexoptOptions; import com.android.server.pm.dex.DexoptUtils; @@ -291,7 +292,8 @@ public class PackageDexOptimizer { mInstaller.dexopt(path, uid, pkg.packageName, isa, dexoptNeeded, oatDir, dexoptFlags, compilerFilter, pkg.volumeUuid, classLoaderContext, pkg.applicationInfo.seInfo, false /* downgrade*/, pkg.applicationInfo.targetSdkVersion, - profileName, dexMetadataPath, getReasonName(compilationReason)); + profileName, dexMetadataPath, + getAugmentedReasonName(compilationReason, dexMetadataPath != null)); if (packageStats != null) { long endTime = System.currentTimeMillis(); @@ -304,6 +306,12 @@ public class PackageDexOptimizer { } } + private String getAugmentedReasonName(int compilationReason, boolean useDexMetadata) { + String annotation = useDexMetadata + ? ArtManagerService.DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION : ""; + return getReasonName(compilationReason) + annotation; + } + /** * Performs dexopt on the secondary dex {@code path} belonging to the app {@code info}. * @@ -396,12 +404,17 @@ public class PackageDexOptimizer { + " 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 52b6ffcd3d19..f4673a8fa7ba 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 @@ public class PackageManagerService extends IPackageManager.Stub 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 @@ public class PackageManagerService extends IPackageManager.Stub 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) { @@ -22060,9 +22063,6 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); //TODO: b/111402650 private void disableSkuSpecificApps() { - if (!mIsUpgrade && !mFirstBoot) { - return; - } String apkList[] = mContext.getResources().getStringArray( R.array.config_disableApksUnlessMatchedSku_apk_list); String skuArray[] = mContext.getResources().getStringArray( @@ -22076,7 +22076,9 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } for (String packageName : apkList) { setSystemAppHiddenUntilInstalled(packageName, true); - setSystemAppInstallState(packageName, false, ActivityManager.getCurrentUser()); + for (UserInfo user : sUserManager.getUsers(false)) { + setSystemAppInstallState(packageName, false, user.id); + } } } diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index 580126f5c330..e5b903024795 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -534,6 +534,7 @@ class PackageManagerShellCommand extends ShellCommand { boolean listInstaller = false; boolean showUid = false; boolean showVersionCode = false; + boolean listApexOnly = false; int uid = -1; int userId = UserHandle.USER_SYSTEM; try { @@ -573,6 +574,10 @@ class PackageManagerShellCommand extends ShellCommand { case "--show-versioncode": showVersionCode = true; break; + case "--apex-only": + getFlags |= PackageManager.MATCH_APEX; + listApexOnly = true; + break; case "--user": userId = UserHandle.parseUserArg(getNextArgRequired()); break; @@ -603,30 +608,38 @@ class PackageManagerShellCommand extends ShellCommand { if (filter != null && !info.packageName.contains(filter)) { continue; } - if (uid != -1 && info.applicationInfo.uid != uid) { + final boolean isApex = info.isApex; + if (uid != -1 && !isApex && info.applicationInfo.uid != uid) { continue; } - final boolean isSystem = + + final boolean isSystem = !isApex && (info.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0; - if ((!listDisabled || !info.applicationInfo.enabled) && - (!listEnabled || info.applicationInfo.enabled) && + final boolean isEnabled = !isApex && info.applicationInfo.enabled; + if ((!listDisabled || !isEnabled) && + (!listEnabled || isEnabled) && (!listSystem || isSystem) && - (!listThirdParty || !isSystem)) { + (!listThirdParty || !isSystem) && + (!listApexOnly || isApex)) { pw.print("package:"); - if (showSourceDir) { + if (showSourceDir && !isApex) { pw.print(info.applicationInfo.sourceDir); pw.print("="); } pw.print(info.packageName); 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) { + if (listInstaller && !isApex) { pw.print(" installer="); pw.print(mInterface.getInstallerPackageName(info.packageName)); } - if (showUid) { + if (showUid && !isApex) { pw.print(" uid:"); pw.print(info.applicationInfo.uid); } @@ -2692,11 +2705,11 @@ class PackageManagerShellCommand extends ShellCommand { pw.println(" Prints all system libraries."); pw.println(""); pw.println(" list packages [-f] [-d] [-e] [-s] [-3] [-i] [-l] [-u] [-U] "); - pw.println(" [--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"); - pw.println(" -a: all known packages"); + pw.println(" -a: all known packages (but excluding APEXes)"); pw.println(" -d: filter to only show disabled packages"); pw.println(" -e: filter to only show enabled packages"); pw.println(" -s: filter to only show system packages"); @@ -2705,6 +2718,8 @@ class PackageManagerShellCommand extends ShellCommand { 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"); pw.println(""); diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java index 1fb51b7fa0e8..1f05dc966555 100644 --- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java +++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java @@ -527,6 +527,11 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { private static final int TRON_COMPILATION_REASON_AB_OTA = 6; private static final int TRON_COMPILATION_REASON_INACTIVE = 7; private static final int TRON_COMPILATION_REASON_SHARED = 8; + private static final int TRON_COMPILATION_REASON_INSTALL_WITH_DEX_METADATA = 9; + + // The annotation to add as a suffix to the compilation reason when dexopt was + // performed with dex metadata. + public static final String DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION = "-dm"; /** * Convert the compilation reason to an int suitable to be logged to TRON. @@ -542,6 +547,10 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub { case "ab-ota" : return TRON_COMPILATION_REASON_AB_OTA; case "inactive" : return TRON_COMPILATION_REASON_INACTIVE; case "shared" : return TRON_COMPILATION_REASON_SHARED; + // This is a special marker for dex metadata installation that does not + // have an equivalent as a system property. + case "install" + DEXOPT_REASON_WITH_DEX_METADATA_ANNOTATION : + return TRON_COMPILATION_REASON_INSTALL_WITH_DEX_METADATA; default: return TRON_COMPILATION_REASON_UNKNOWN; } } 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 519a20d51ddb..a194f57ea700 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 class PackageDexUsage extends AbstractStatsBase<Void> { 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/policy/BarController.java b/services/core/java/com/android/server/policy/BarController.java index eca6f9f1ec47..14c985c090a3 100644 --- a/services/core/java/com/android/server/policy/BarController.java +++ b/services/core/java/com/android/server/policy/BarController.java @@ -196,7 +196,7 @@ public class BarController { } protected boolean skipAnimation() { - return false; + return !mWin.isDrawnLw(); } private int computeStateLw(boolean wasVis, boolean wasAnim, WindowState win, boolean change) { diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index dfb617999668..9a741bcfc3d6 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -76,6 +76,7 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CO import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; +import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_STATUS_BAR_EXPANDED; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_ERROR; import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_CROSSFADE; import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_JUMPCUT; @@ -4397,17 +4398,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (isKeyguardShowingAndNotOccluded()) { // don't launch home if keyguard showing return; - } else if (mKeyguardOccluded && mKeyguardDelegate.isShowing()) { - mKeyguardDelegate.dismiss(new KeyguardDismissCallback() { - @Override - public void onDismissSucceeded() throws RemoteException { - mHandler.post(() -> { - startDockOrHome(true /*fromHomeKey*/, awakenFromDreams); - }); - } - }, null /* message */); - return; - } else if (!mKeyguardOccluded && mKeyguardDelegate.isInputRestricted()) { + } + + if (!mKeyguardOccluded && mKeyguardDelegate.isInputRestricted()) { // when in keyguard restricted mode, must first verify unlock // before launching home mKeyguardDelegate.verifyUnlock(new OnKeyguardExitResult() { @@ -4692,8 +4685,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { navTranslucent &= areTranslucentBarsAllowed(); } boolean statusBarExpandedNotKeyguard = !isKeyguardShowing && mStatusBar != null - && mStatusBar.getAttrs().height == MATCH_PARENT - && mStatusBar.getAttrs().width == MATCH_PARENT; + && (mStatusBar.getAttrs().privateFlags & PRIVATE_FLAG_STATUS_BAR_EXPANDED) != 0; // When the navigation bar isn't visible, we put up a fake input window to catch all // touch events. This way we can detect when the user presses anywhere to bring back the @@ -5696,7 +5688,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } // Take note if a window wants to acquire a sleep token. - if (win.isVisibleLw() && (attrs.privateFlags & PRIVATE_FLAG_ACQUIRES_SLEEP_TOKEN) != 0 + if ((attrs.privateFlags & PRIVATE_FLAG_ACQUIRES_SLEEP_TOKEN) != 0 && win.canAcquireSleepToken()) { mWindowSleepTokenNeeded = true; } @@ -5752,9 +5744,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { mStatusBarController.setShowTransparent(true /* transparent */); } - WindowManager.LayoutParams statusBarAttrs = mStatusBar.getAttrs(); - boolean statusBarExpanded = statusBarAttrs.height == MATCH_PARENT - && statusBarAttrs.width == MATCH_PARENT; + boolean statusBarExpanded = + (mStatusBar.getAttrs().privateFlags & PRIVATE_FLAG_STATUS_BAR_EXPANDED) != 0; boolean topAppHidesStatusBar = topAppHidesStatusBar(); if (mForceStatusBar || mForceStatusBarFromKeyguard || mForceStatusBarTransparent || statusBarExpanded) { diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index 44136661bee5..f9f4bbfc8eb0 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -46,7 +46,6 @@ import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.os.UserManager; -import android.os.storage.StorageManager; import android.provider.Settings; import android.service.trust.TrustAgentService; import android.text.TextUtils; @@ -60,7 +59,6 @@ import android.view.IWindowManager; import android.view.WindowManagerGlobal; import com.android.internal.annotations.GuardedBy; import com.android.internal.content.PackageMonitor; -import com.android.internal.policy.IKeyguardDismissCallback; import com.android.internal.util.DumpUtils; import com.android.internal.widget.LockPatternUtils; import com.android.server.SystemService; @@ -431,13 +429,20 @@ public class TrustManagerService extends SystemService { for (int i = 0; i < userInfos.size(); i++) { UserInfo info = userInfos.get(i); - if (info == null || info.partial || !info.isEnabled() || info.guestToRemove - || !info.supportsSwitchToByUser()) { + if (info == null || info.partial || !info.isEnabled() || info.guestToRemove) { continue; } int id = info.id; boolean secure = mLockPatternUtils.isSecure(id); + + if (!info.supportsSwitchToByUser()) { + if (info.isManagedProfile() && !secure) { + setDeviceLockedForUser(id, false); + } + continue; + } + boolean trusted = aggregateIsTrusted(id); boolean showingKeyguard = true; boolean fingerprintAuthenticated = false; @@ -992,7 +997,8 @@ public class TrustManagerService extends SystemService { enforceReportPermission(); final long identity = Binder.clearCallingIdentity(); try { - if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) { + if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId) + && mLockPatternUtils.isSecure(userId)) { synchronized (mDeviceLockedForUser) { mDeviceLockedForUser.put(userId, locked); } diff --git a/services/core/java/com/android/server/wm/AppWindowThumbnail.java b/services/core/java/com/android/server/wm/AppWindowThumbnail.java index ad92f81f4dde..bef974ae1081 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 @@ class AppWindowThumbnail implements Animatable { .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/BoundsAnimationController.java b/services/core/java/com/android/server/wm/BoundsAnimationController.java index b2a12bef5283..86f328d248db 100644 --- a/services/core/java/com/android/server/wm/BoundsAnimationController.java +++ b/services/core/java/com/android/server/wm/BoundsAnimationController.java @@ -31,11 +31,13 @@ import android.os.IBinder; import android.os.Debug; import android.util.ArrayMap; import android.util.Slog; +import android.view.Choreographer; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.graphics.SfVsyncFrameCallbackProvider; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -112,6 +114,7 @@ public class BoundsAnimationController { private final Interpolator mFastOutSlowInInterpolator; private boolean mFinishAnimationAfterTransition = false; private final AnimationHandler mAnimationHandler; + private Choreographer mChoreographer; private static final int WAIT_FOR_DRAW_TIMEOUT_MS = 3000; @@ -123,6 +126,12 @@ public class BoundsAnimationController { mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context, com.android.internal.R.interpolator.fast_out_slow_in); mAnimationHandler = animationHandler; + if (animationHandler != null) { + // If an animation handler is provided, then ensure that it runs on the sf vsync tick + handler.runWithScissors(() -> mChoreographer = Choreographer.getSfInstance(), + 0 /* timeout */); + animationHandler.setProvider(new SfVsyncFrameCallbackProvider(mChoreographer)); + } } @VisibleForTesting diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 2887e5ef9061..6700a123e043 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 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo 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(); @@ -1775,8 +1776,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo final int newDensity = mDisplayInfo.logicalDensityDpi; final DisplayCutout newCutout = mDisplayInfo.displayCutout; - final boolean displayMetricsChanged = mInitialDisplayWidth != newWidth - || mInitialDisplayHeight != newHeight + final boolean sizeChanged = mInitialDisplayWidth != newWidth + || mInitialDisplayHeight != newHeight; + final boolean displayMetricsChanged = sizeChanged || mInitialDisplayDensity != mDisplayInfo.logicalDensityDpi || !Objects.equals(mInitialDisplayCutout, newCutout); @@ -1798,6 +1800,10 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo mInitialDisplayCutout = newCutout; mService.reconfigureDisplayLocked(this); } + + if (isDefaultDisplay && sizeChanged) { + mService.mH.post(mService.mAmInternal::notifyDefaultDisplaySizeChanged); + } } /** Sets the maximum width the screen resolution can be */ @@ -3885,7 +3891,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo 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/ForcedSeamlessRotator.java b/services/core/java/com/android/server/wm/ForcedSeamlessRotator.java index bebc5656c284..efb43a6b90cf 100644 --- a/services/core/java/com/android/server/wm/ForcedSeamlessRotator.java +++ b/services/core/java/com/android/server/wm/ForcedSeamlessRotator.java @@ -21,6 +21,7 @@ import static android.view.Surface.ROTATION_90; import android.graphics.Matrix; import android.view.DisplayInfo; +import android.view.Surface.Rotation; import com.android.server.wm.utils.CoordinateTransforms; @@ -65,6 +66,16 @@ public class ForcedSeamlessRotator { } /** + * Returns the rotation of the display before it started rotating. + * + * @return the old rotation of the display + */ + @Rotation + public int getOldRotation() { + return mOldRotation; + } + + /** * Removes the transform to the window token's surface that undoes the effect of the global * display rotation. * diff --git a/services/core/java/com/android/server/wm/OWNERS b/services/core/java/com/android/server/wm/OWNERS index fff42c5d0a5f..8dda48523c83 100644 --- a/services/core/java/com/android/server/wm/OWNERS +++ b/services/core/java/com/android/server/wm/OWNERS @@ -2,6 +2,6 @@ ogunwale@google.com 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/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java index fa8a5c66aeea..755a571cf5f7 100644 --- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java +++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java @@ -37,6 +37,7 @@ import android.view.DisplayInfo; import android.view.Surface; import android.view.Surface.OutOfResourcesException; import android.view.SurfaceControl; +import android.view.SurfaceControl.Transaction; import android.view.SurfaceSession; import android.view.animation.Animation; import android.view.animation.AnimationUtils; @@ -268,6 +269,12 @@ class ScreenRotationAnimation { .setSecure(isSecure) .build(); + // In case display bounds change, screenshot buffer and surface may mismatch so set a + // scaling mode. + Transaction t2 = new Transaction(); + t2.setOverrideScalingMode(mSurfaceControl, Surface.SCALING_MODE_SCALE_TO_WINDOW); + t2.apply(true /* sync */); + // capture a screenshot into the surface we just created // TODO(multidisplay): we should use the proper display final int displayId = SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN; diff --git a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java index a642e6ab744a..d1c0443c58e1 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotPersister.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotPersister.java @@ -360,6 +360,7 @@ class TaskSnapshotPersister { // For snapshots with reduced resolution, do not create or save full sized bitmaps if (mSnapshot.isReducedResolution()) { + swBitmap.recycle(); return true; } @@ -372,6 +373,8 @@ class TaskSnapshotPersister { Slog.e(TAG, "Unable to open " + file + " for persisting.", e); return false; } + reduced.recycle(); + swBitmap.recycle(); return true; } } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 8bc224636c1e..8b4a2dd36e6c 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1005,7 +1005,6 @@ public class WindowManagerService extends IWindowManager.Stub mAppTransition.registerListenerLocked(mActivityManagerAppTransitionNotifier); final AnimationHandler animationHandler = new AnimationHandler(); - animationHandler.setProvider(new SfVsyncFrameCallbackProvider()); mBoundsAnimationController = new BoundsAnimationController(context, mAppTransition, AnimationThread.getHandler(), animationHandler); @@ -6221,6 +6220,17 @@ public class WindowManagerService extends IWindowManager.Stub } /** + * Returns true if the callingUid has any window currently visible to the user. + */ + public boolean isAnyWindowVisibleForUid(int callingUid) { + synchronized (mWindowMap) { + return mRoot.forAllWindows(w -> { + return w.getOwningUid() == callingUid && w.isVisible(); + }, true /* traverseTopToBottom */); + } + } + + /** * Called when a task has been removed from the recent tasks list. * <p> * Note: This doesn't go through {@link TaskWindowContainerController} yet as the window diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 009f3930d02e..1ae680f793ca 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -681,6 +681,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP void forceSeamlesslyRotateIfAllowed(int oldRotation, int rotation) { if (mForceSeamlesslyRotate) { + if (mPendingForcedSeamlessRotate != null) { + oldRotation = mPendingForcedSeamlessRotate.getOldRotation(); + } + mPendingForcedSeamlessRotate = new ForcedSeamlessRotator( oldRotation, rotation, getDisplayInfo()); mPendingForcedSeamlessRotate.unrotate(this.mToken); diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java index 66c8cca8f0e0..4548cec88e7e 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 @@ class WindowSurfaceController { 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/core/java/com/android/server/wm/utils/InsetUtils.java b/services/core/java/com/android/server/wm/utils/InsetUtils.java index b4a998add374..c8600dd151d2 100644 --- a/services/core/java/com/android/server/wm/utils/InsetUtils.java +++ b/services/core/java/com/android/server/wm/utils/InsetUtils.java @@ -17,6 +17,7 @@ package com.android.server.wm.utils; import android.graphics.Rect; +import android.view.Surface; /** * Utility methods to handle insets represented as rects. @@ -27,6 +28,32 @@ public class InsetUtils { } /** + * Transforms insets given in one rotation into insets in a different rotation. + * + * @param inOutInsets the insets to transform, is set to the transformed insets + * @param rotationDelta the delta between the new and old rotation. + * Must be one of Surface.ROTATION_0/90/180/270. + */ + public static void rotateInsets(Rect inOutInsets, int rotationDelta) { + final Rect r = inOutInsets; + switch (rotationDelta) { + case Surface.ROTATION_0: + return; + case Surface.ROTATION_90: + r.set(r.top, r.right, r.bottom, r.left); + break; + case Surface.ROTATION_180: + r.set(r.right, r.bottom, r.left, r.top); + break; + case Surface.ROTATION_270: + r.set(r.bottom, r.left, r.top, r.right); + break; + default: + throw new IllegalArgumentException("Unknown rotation: " + rotationDelta); + } + } + + /** * Adds {@code insetsToAdd} to {@code inOutInsets}. */ public static void addInsets(Rect inOutInsets, Rect insetsToAdd) { diff --git a/services/core/jni/com_android_server_net_NetworkStatsService.cpp b/services/core/jni/com_android_server_net_NetworkStatsService.cpp index 649f1a56f011..4d4a7b41643c 100644 --- a/services/core/jni/com_android_server_net_NetworkStatsService.cpp +++ b/services/core/jni/com_android_server_net_NetworkStatsService.cpp @@ -34,7 +34,6 @@ #include "netdbpf/BpfNetworkStats.h" using android::bpf::Stats; -using android::bpf::hasBpfSupport; using android::bpf::bpfGetUidStats; using android::bpf::bpfGetIfaceStats; diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 123d6159d940..8f5d36abcf2c 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -4572,10 +4572,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { enforceFullCrossUsersPermission(userHandle); synchronized (getLockObject()) { if (!isCallerWithSystemUid()) { - // This API can only be called by an active device admin, - // so try to retrieve it to check that the caller is one. - getActiveAdminForCallerLocked( - null, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent); + // This API can be called by an active device admin or by keyguard code. + if (mContext.checkCallingPermission(permission.ACCESS_KEYGUARD_SECURE_STORAGE) + != PackageManager.PERMISSION_GRANTED) { + getActiveAdminForCallerLocked( + null, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent); + } } DevicePolicyData policy = getUserDataUnchecked(getCredentialOwner(userHandle, parent)); diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 80b0e6f4fca7..2d07fd6c6442 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -29,6 +29,7 @@ import android.content.res.Configuration; import android.content.res.Resources.Theme; import android.database.sqlite.SQLiteCompatibilityWalFlags; import android.database.sqlite.SQLiteGlobal; +import android.hardware.display.DisplayManagerInternal; import android.os.BaseBundle; import android.os.Binder; import android.os.Build; @@ -48,6 +49,7 @@ import android.os.SystemProperties; import android.os.Trace; import android.os.UserHandle; import android.os.storage.IStorageManager; +import android.sysprop.VoldProperties; import android.util.DisplayMetrics; import android.util.EventLog; import android.util.Slog; @@ -625,7 +627,7 @@ public final class SystemServer { traceEnd(); // Only run "core" apps if we're encrypting the device. - String cryptState = SystemProperties.get("vold.decrypt"); + String cryptState = VoldProperties.decrypt().orElse(""); if (ENCRYPTING_STATE.equals(cryptState)) { Slog.w(TAG, "Detected encryption in progress - only parsing core apps"); mOnlyCore = true; @@ -687,9 +689,17 @@ public final class SystemServer { // Manages Overlay packages traceBeginAndSlog("StartOverlayManagerService"); - mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer)); + OverlayManagerService overlayManagerService = new OverlayManagerService( + mSystemContext, installer); + mSystemServiceManager.startService(overlayManagerService); traceEnd(); + if (SystemProperties.getInt("persist.sys.displayinset.top", 0) > 0) { + // DisplayManager needs the overlay immediately. + overlayManagerService.updateSystemUiContext(); + LocalServices.getService(DisplayManagerInternal.class).onOverlayChanged(); + } + // The sensor service needs access to package manager service, app ops // service, and permissions service, therefore we start it after them. // Start sensor service in a separate thread. Completion should be checked @@ -1194,6 +1204,16 @@ public final class SystemServer { } 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 a7209a076461..f0379059a5f7 100644 --- a/services/net/java/android/net/apf/ApfFilter.java +++ b/services/net/java/android/net/apf/ApfFilter.java @@ -111,7 +111,7 @@ public class ApfFilter { * the last writable 32bit word. */ @VisibleForTesting - private static enum Counter { + public static enum Counter { RESERVED_OOB, // Points to offset 0 from the end of the buffer (out-of-bounds) TOTAL_PACKETS, PASSED_ARP, @@ -139,7 +139,8 @@ public class ApfFilter { 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 @@ public class ApfFilter { /** * 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 @@ public class ApfFilter { 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 @@ public class ApfFilter { 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 @@ public class ApfFilter { // 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 @@ public class ApfFilter { // 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 @@ public class ApfFilter { 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 @@ public class ApfFilter { // 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 @@ public class ApfFilter { // 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 @@ public class ApfFilter { // 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 @@ public class ApfFilter { 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 @@ public class ApfFilter { 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 @@ public class ApfFilter { 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 @@ public class ApfFilter { 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 @@ public class ApfFilter { // 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 @@ public class ApfFilter { // 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 cee6fa96bbc5..35d29e75c0e4 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.annotation.Nullable; 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 @@ public class DhcpServer { @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 class DhcpServer { } } - 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 @@ public class DhcpServer { 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 @@ public class DhcpServer { // 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 823c0a1ac7b0..493350d776f3 100644 --- a/services/net/java/android/net/ip/IpServer.java +++ b/services/net/java/android/net/ip/IpServer.java @@ -138,9 +138,9 @@ public class IpServer extends StateMachine { 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 @@ public class IpServer extends StateMachine { 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 @@ public class IpServer extends StateMachine { 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/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp index af8596de451a..d2d6e32fb1b0 100644 --- a/services/tests/servicestests/Android.bp +++ b/services/tests/servicestests/Android.bp @@ -67,7 +67,7 @@ android_test { "liblzma", "libnativehelper", "libui", - "libunwind", + "libunwindstack", "libutils", "netd_aidl_interface-cpp", ], diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java index 1520859d4aac..8d056fc4a8c0 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityStarterTests.java @@ -53,6 +53,7 @@ import android.view.Gravity; import org.junit.runner.RunWith; import org.junit.Test; +import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; import static android.content.Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED; import static com.android.server.am.ActivityManagerService.ANIMATE; @@ -62,11 +63,13 @@ import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyObject; +import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.times; @@ -91,6 +94,7 @@ public class ActivityStarterTests extends ActivityTestsBase { private ActivityManagerService mService; private ActivityStarter mStarter; private ActivityStartController mController; + private ActivityMetricsLogger mActivityMetricsLogger; private static final int PRECONDITION_NO_CALLER_APP = 1; private static final int PRECONDITION_NO_INTENT_COMPONENT = 1 << 1; @@ -104,11 +108,17 @@ public class ActivityStarterTests extends ActivityTestsBase { private static final int PRECONDITION_CANNOT_START_ANY_ACTIVITY = 1 << 9; private static final int PRECONDITION_DISALLOW_APP_SWITCHING = 1 << 10; + private static final int FAKE_CALLING_UID = 666; + private static final int FAKE_REAL_CALLING_UID = 667; + private static final String FAKE_CALLING_PACKAGE = "com.whatever.dude"; + @Override public void setUp() throws Exception { super.setUp(); mService = createActivityManagerService(); mController = mock(ActivityStartController.class); + mActivityMetricsLogger = mock(ActivityMetricsLogger.class); + clearInvocations(mActivityMetricsLogger); mStarter = new ActivityStarter(mController, mService, mService.mStackSupervisor, mock(ActivityStartInterceptor.class)); } @@ -471,4 +481,46 @@ public class ActivityStarterTests extends ActivityTestsBase { assertTrue(stack.getAllTasks().isEmpty()); } } + + /** + * This test ensures that activity starts are not being logged when the logging is disabled. + */ + @Test + public void testActivityStartsLogging_noLoggingWhenDisabled() { + doReturn(false).when(mService).isActivityStartsLoggingEnabled(); + doReturn(mActivityMetricsLogger).when(mService.mStackSupervisor).getActivityMetricsLogger(); + + ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK); + starter.setReason("testActivityStartsLogging_noLoggingWhenDisabled").execute(); + + // verify logging wasn't done + verify(mActivityMetricsLogger, never()).logActivityStart(any(), any(), any(), anyInt(), + any(), anyInt(), anyBoolean(), anyInt(), anyInt(), anyBoolean(), anyInt(), any(), + anyInt(), anyBoolean(), any(), anyBoolean()); + } + + /** + * This test ensures that activity starts are being logged when the logging is enabled. + */ + @Test + public void testActivityStartsLogging_logsWhenEnabled() { + // note: conveniently this package doesn't have any activity visible + doReturn(true).when(mService).isActivityStartsLoggingEnabled(); + doReturn(mActivityMetricsLogger).when(mService.mStackSupervisor).getActivityMetricsLogger(); + + ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK) + .setCallingUid(FAKE_CALLING_UID) + .setRealCallingUid(FAKE_REAL_CALLING_UID) + .setCallingPackage(FAKE_CALLING_PACKAGE) + .setOriginatingPendingIntent(null); + + starter.setReason("testActivityStartsLogging_logsWhenEnabled").execute(); + + // verify the above activity start was logged + verify(mActivityMetricsLogger, times(1)).logActivityStart(any(), any(), any(), + eq(FAKE_CALLING_UID), eq(FAKE_CALLING_PACKAGE), anyInt(), anyBoolean(), + eq(FAKE_REAL_CALLING_UID), anyInt(), anyBoolean(), anyInt(), + eq(ActivityBuilder.getDefaultComponent().getPackageName()), anyInt(), anyBoolean(), + any(), eq(false)); + } } diff --git a/services/tests/servicestests/src/com/android/server/wm/utils/InsetUtilsTest.java b/services/tests/servicestests/src/com/android/server/wm/utils/InsetUtilsTest.java index d0f0fe315bcf..08bcc3d751f2 100644 --- a/services/tests/servicestests/src/com/android/server/wm/utils/InsetUtilsTest.java +++ b/services/tests/servicestests/src/com/android/server/wm/utils/InsetUtilsTest.java @@ -16,6 +16,11 @@ package com.android.server.wm.utils; +import static android.hardware.camera2.params.OutputConfiguration.ROTATION_90; +import static android.view.Surface.ROTATION_0; +import static android.view.Surface.ROTATION_180; +import static android.view.Surface.ROTATION_270; + import static junit.framework.Assert.assertEquals; import android.graphics.Rect; @@ -39,5 +44,29 @@ public class InsetUtilsTest { InsetUtils.addInsets(rect1, rect2); assertEquals(new Rect(60, 80, 100, 120), rect1); } + + @Test + public void rotate() { + final Rect original = new Rect(1, 2, 3, 4); + + assertEquals("rot0", original, rotateCopy(original, ROTATION_0)); + + final Rect rot90 = rotateCopy(original, ROTATION_90); + assertEquals("rot90", new Rect(2, 3, 4, 1), rot90); + + final Rect rot180 = rotateCopy(original, ROTATION_180); + assertEquals("rot180", new Rect(3, 4, 1, 2), rot180); + assertEquals("rot90(rot90)=rot180", rotateCopy(rot90, ROTATION_90), rot180); + + final Rect rot270 = rotateCopy(original, ROTATION_270); + assertEquals("rot270", new Rect(4, 1, 2, 3), rot270); + assertEquals("rot90(rot180)=rot270", rotateCopy(rot180, ROTATION_90), rot270); + } + + private static Rect rotateCopy(Rect insets, int rotationDelta) { + final Rect copy = new Rect(insets); + InsetUtils.rotateInsets(copy, rotationDelta); + return copy; + } } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java index afc12636007f..8222c386c0d9 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -38,6 +38,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.AppGlobals; import android.app.AppOpsManager; import android.app.NotificationManager; import android.content.ComponentName; @@ -49,8 +50,10 @@ import android.media.AudioManager; import android.media.AudioManagerInternal; import android.media.VolumePolicy; import android.media.AudioSystem; +import android.net.Uri; import android.provider.Settings; import android.provider.Settings.Global; +import android.service.notification.Condition; import android.service.notification.ZenModeConfig; import android.service.notification.ZenModeConfig.ScheduleInfo; import android.test.suitebuilder.annotation.SmallTest; @@ -61,6 +64,7 @@ import android.util.Xml; import com.android.internal.R; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; +import com.android.server.notification.ManagedServices.UserProfiles; import com.android.internal.util.FastXmlSerializer; import com.android.server.UiServiceTestCase; import android.util.Slog; @@ -83,7 +87,7 @@ import java.io.ByteArrayOutputStream; @TestableLooper.RunWithLooper public class ZenModeHelperTest extends UiServiceTestCase { - @Mock ConditionProviders mConditionProviders; + ConditionProviders mConditionProviders; @Mock NotificationManager mNotificationManager; @Mock private Resources mResources; private TestableLooper mTestableLooper; @@ -103,6 +107,9 @@ public class ZenModeHelperTest extends UiServiceTestCase { when(mResources.getString(R.string.zen_mode_default_events_name)).thenReturn("events"); when(mContext.getSystemService(NotificationManager.class)).thenReturn(mNotificationManager); + mConditionProviders = new ConditionProviders(mContext, new UserProfiles(), + AppGlobals.getPackageManager()); + mConditionProviders.addSystemProvider(new CountdownConditionProvider()); mZenModeHelperSpy = spy(new ZenModeHelper(mContext, mTestableLooper.getLooper(), mConditionProviders)); } @@ -116,7 +123,7 @@ public class ZenModeHelperTest extends UiServiceTestCase { mZenModeHelperSpy.writeXml(serializer, forBackup, version); serializer.endDocument(); serializer.flush(); - mZenModeHelperSpy.setConfig(new ZenModeConfig(), "writing xml"); + mZenModeHelperSpy.setConfig(new ZenModeConfig(), null, "writing xml"); return baos; } @@ -813,6 +820,30 @@ public class ZenModeHelperTest extends UiServiceTestCase { setupZenConfigMaintained(); } + @Test + public void testCountdownConditionSubscription() throws Exception { + ZenModeConfig config = new ZenModeConfig(); + mZenModeHelperSpy.mConfig = config; + mZenModeHelperSpy.mConditions.evaluateConfig(mZenModeHelperSpy.mConfig, null, true); + assertEquals(0, mZenModeHelperSpy.mConditions.mSubscriptions.size()); + + mZenModeHelperSpy.mConfig.manualRule = new ZenModeConfig.ZenRule(); + Uri conditionId = ZenModeConfig.toCountdownConditionId(9000000, false); + mZenModeHelperSpy.mConfig.manualRule.conditionId = conditionId; + mZenModeHelperSpy.mConfig.manualRule.component = new ComponentName("android", + CountdownConditionProvider.class.getName()); + mZenModeHelperSpy.mConfig.manualRule.condition = new Condition(conditionId, "", "", "", 0, + Condition.STATE_TRUE, Condition.FLAG_RELEVANT_NOW); + mZenModeHelperSpy.mConfig.manualRule.enabled = true; + ZenModeConfig originalConfig = mZenModeHelperSpy.mConfig.copy(); + + mZenModeHelperSpy.mConditions.evaluateConfig(mZenModeHelperSpy.mConfig, null, true); + + assertEquals(true, ZenModeConfig.isValidCountdownConditionId(conditionId)); + assertEquals(originalConfig, mZenModeHelperSpy.mConfig); + assertEquals(1, mZenModeHelperSpy.mConditions.mSubscriptions.size()); + } + private void setupZenConfig() { mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS; mZenModeHelperSpy.mConfig.allowAlarms = false; diff --git a/services/usb/java/com/android/server/usb/UsbDebuggingManager.java b/services/usb/java/com/android/server/usb/UsbDebuggingManager.java index 3b0850533ad3..423909921e21 100644 --- a/services/usb/java/com/android/server/usb/UsbDebuggingManager.java +++ b/services/usb/java/com/android/server/usb/UsbDebuggingManager.java @@ -34,10 +34,10 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.SystemClock; -import android.os.SystemProperties; import android.os.UserHandle; import android.os.UserManager; import android.service.usb.UsbDebuggingManagerProto; +import android.sysprop.VoldProperties; import android.util.Base64; import android.util.Slog; @@ -263,7 +263,7 @@ public class UsbDebuggingManager { case MESSAGE_ADB_CONFIRM: { if ("trigger_restart_min_framework".equals( - SystemProperties.get("vold.decrypt"))) { + VoldProperties.decrypt().orElse(""))) { Slog.d(TAG, "Deferring adb confirmation until after vold decrypt"); if (mThread != null) { mThread.sendResponse("NO"); diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java index 4da7285bcf2d..aa93c6b9cb89 100644 --- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java @@ -69,6 +69,7 @@ import android.os.storage.StorageVolume; import android.provider.Settings; import android.service.usb.UsbDeviceManagerProto; import android.service.usb.UsbHandlerProto; +import android.sysprop.VoldProperties; import android.util.Pair; import android.util.Slog; @@ -285,7 +286,7 @@ public class UsbDeviceManager implements ActivityManagerInternal.ScreenObserver mControlFds.put(UsbManager.FUNCTION_PTP, ptpFd); boolean secureAdbEnabled = SystemProperties.getBoolean("ro.adb.secure", false); - boolean dataEncrypted = "1".equals(SystemProperties.get("vold.decrypt")); + boolean dataEncrypted = "1".equals(VoldProperties.decrypt().orElse("")); if (secureAdbEnabled && !dataEncrypted) { mDebuggingManager = new UsbDebuggingManager(context); } diff --git a/startop/view_compiler/Android.bp b/startop/view_compiler/Android.bp index de40e0df48e7..91cec554d7cd 100644 --- a/startop/view_compiler/Android.bp +++ b/startop/view_compiler/Android.bp @@ -24,6 +24,9 @@ cc_defaults { "libdexfile", "slicer", ], + static_libs: [ + "libtinyxml2", + ], } cc_library_host_static { @@ -32,7 +35,9 @@ cc_library_host_static { srcs: [ "dex_builder.cc", "java_lang_builder.cc", + "tinyxml_layout_parser.cc", "util.cc", + "layout_validation.cc", ], } @@ -43,7 +48,6 @@ cc_binary_host { "main.cc", ], static_libs: [ - "libtinyxml2", "libgflags", "libviewcompiler", ], @@ -54,6 +58,7 @@ cc_test_host { defaults: ["viewcompiler_defaults"], srcs: [ "dex_builder_test.cc", + "layout_validation_test.cc", "util_test.cc", ], static_libs: [ diff --git a/startop/view_compiler/config.xml b/startop/view_compiler/config.xml new file mode 100644 index 000000000000..84e779d240d1 --- /dev/null +++ b/startop/view_compiler/config.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 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. +*/ +--> + +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Whether safe headphone volume warning dialog is disabled on Vol+ (operator specific). --> + <bool name="config_safe_media_disable_on_volume_up">false</bool> + +</resources> diff --git a/startop/view_compiler/dex_builder.cc b/startop/view_compiler/dex_builder.cc index 906d64c1f619..a78f7d53d135 100644 --- a/startop/view_compiler/dex_builder.cc +++ b/startop/view_compiler/dex_builder.cc @@ -61,16 +61,47 @@ std::ostream& operator<<(std::ostream& out, const Instruction::Op& opcode) { 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) { @@ -289,12 +320,20 @@ void MethodBuilder::EncodeInstruction(const Instruction& instruction) { 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 @@ void MethodBuilder::EncodeInvoke(const Instruction& instruction, ::art::Instruct // 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 @@ void MethodBuilder::EncodeNew(const Instruction& instruction) { 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 @@ const MethodDeclData& DexBuilder::GetOrDeclareMethod(TypeDescriptor type, const 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 adf82bf9a01a..757d863461f0 100644 --- a/startop/view_compiler/dex_builder.h +++ b/startop/view_compiler/dex_builder.h @@ -73,7 +73,7 @@ class TypeDescriptor { 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 TypeDescriptor { 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 @@ class Instruction { // 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 @@ class Instruction { // 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 @@ class Instruction { 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 @@ class MethodBuilder { // TODO: add builders for more instructions + DexBuilder* dex_file() const { return dex_; } + private: void EncodeInstructions(); void EncodeInstruction(const Instruction& instruction); @@ -257,6 +310,7 @@ class MethodBuilder { 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 e20f3a9406c0..42d4161ee81e 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 com.google.common.io.ByteStreams; 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 @@ public class DexBuilderTest { } @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 @@ public class DexBuilderTest { 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 e2bf43bc1d0c..f62ec5dde85e 100644 --- a/startop/view_compiler/dex_testcase_generator.cc +++ b/startop/view_compiler/dex_testcase_generator.cc @@ -108,6 +108,27 @@ void GenerateSimpleTestCases(const string& outdir) { } 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 @@ void GenerateSimpleTestCases(const string& outdir) { 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 000000000000..8c7737749124 --- /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 000000000000..bed34bb38e5e --- /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 000000000000..b74cdae8d725 --- /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 7d791c229a98..55bfdc78ec1b 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 @@ DEFINE_string(package, "", "The package name for the generated class (required)" 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 @@ int main(int argc, char** argv) { 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 000000000000..1b3a81f17976 --- /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 000000000000..8f714a2c5a3f --- /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 cef998651cfe..36d0188048c3 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -29,7 +29,6 @@ import android.os.ParcelFileDescriptor; 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; @@ -123,10 +122,21 @@ public final class Call { * The key to retrieve the optional {@code PhoneAccount}s Telecom can bundle with its Call * extras. Used to pass the phone accounts to display on the front end to the user in order to * select phone accounts to (for example) place a call. + * @deprecated Use the list from {@link #EXTRA_SUGGESTED_PHONE_ACCOUNTS} instead. */ + @Deprecated public static final String AVAILABLE_PHONE_ACCOUNTS = "selectPhoneAccountAccounts"; /** + * Key for extra used to pass along a list of {@link PhoneAccountSuggestion}s to the in-call + * UI when a call enters the {@link #STATE_SELECT_PHONE_ACCOUNT} state. The list included here + * will have the same length and be in the same order as the list passed with + * {@link #AVAILABLE_PHONE_ACCOUNTS}. + */ + public static final String EXTRA_SUGGESTED_PHONE_ACCOUNTS = + "android.telecom.extra.SUGGESTED_PHONE_ACCOUNTS"; + + /** * Extra key used to indicate the time (in milliseconds since midnight, January 1, 1970 UTC) * when the last outgoing emergency call was made. This is used to identify potential emergency * callbacks. @@ -908,10 +918,16 @@ public final class Call { @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 7db69407ad3d..662874316a7f 100644 --- a/telecomm/java/android/telecom/CallScreeningService.java +++ b/telecomm/java/android/telecom/CallScreeningService.java @@ -27,8 +27,8 @@ import android.os.Message; 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 @@ public abstract class CallScreeningService extends Service { private boolean mShouldSkipCallLog; private boolean mShouldSkipNotification; - /* + /** * Sets whether the incoming call should be blocked. */ public Builder setDisallowCall(boolean shouldDisallowCall) { @@ -155,7 +155,7 @@ public abstract class CallScreeningService extends Service { 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 @@ public abstract class CallScreeningService extends Service { 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 @@ public abstract class CallScreeningService extends Service { * 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 000000000000..e2fa7e4032c1 --- /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 new file mode 100644 index 000000000000..b401bcf0f876 --- /dev/null +++ b/telecomm/java/android/telecom/PhoneAccountSuggestion.java @@ -0,0 +1,151 @@ +/* + * 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.IntDef; +import android.annotation.SystemApi; +import android.annotation.TestApi; +import android.os.Parcel; +import android.os.Parcelable; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.Objects; + +public final class PhoneAccountSuggestion implements Parcelable { + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(value = {REASON_NONE, REASON_INTRA_CARRIER, REASON_FREQUENT, + REASON_USER_SET, REASON_OTHER}, prefix = { "REASON_" }) + public @interface SuggestionReason {} + + /** + * Indicates that this account is not suggested for use, but is still available. + */ + public static final int REASON_NONE = 0; + + /** + * Indicates that the {@link PhoneAccountHandle} is suggested because the number we're calling + * is on the same carrier, and therefore may have lower rates. + */ + public static final int REASON_INTRA_CARRIER = 1; + + /** + * Indicates that the {@link PhoneAccountHandle} is suggested because the user uses it + * frequently for the number that we are calling. + */ + public static final int REASON_FREQUENT = 2; + + /** + * Indicates that the {@link PhoneAccountHandle} is suggested because the user explicitly + * specified that it be used for the number we are calling. + */ + public static final int REASON_USER_SET = 3; + + /** + * Indicates that the {@link PhoneAccountHandle} is suggested for a reason not otherwise + * enumerated here. + */ + public static final int REASON_OTHER = 4; + + private PhoneAccountHandle mHandle; + private int mReason; + private boolean mShouldAutoSelect; + + /** + * @hide + */ + @SystemApi + @TestApi + public PhoneAccountSuggestion(PhoneAccountHandle handle, @SuggestionReason int reason, + boolean shouldAutoSelect) { + this.mHandle = handle; + this.mReason = reason; + this.mShouldAutoSelect = shouldAutoSelect; + } + + private PhoneAccountSuggestion(Parcel in) { + mHandle = in.readParcelable(PhoneAccountHandle.class.getClassLoader()); + mReason = in.readInt(); + mShouldAutoSelect = in.readByte() != 0; + } + + public static final Creator<PhoneAccountSuggestion> CREATOR = + new Creator<PhoneAccountSuggestion>() { + @Override + public PhoneAccountSuggestion createFromParcel(Parcel in) { + return new PhoneAccountSuggestion(in); + } + + @Override + public PhoneAccountSuggestion[] newArray(int size) { + return new PhoneAccountSuggestion[size]; + } + }; + + /** + * @return The {@link PhoneAccountHandle} for this suggestion. + */ + public PhoneAccountHandle getPhoneAccountHandle() { + return mHandle; + } + + /** + * @return The reason for this suggestion + */ + public @SuggestionReason int getReason() { + return mReason; + } + + /** + * Suggests whether the dialer should automatically place the call using this account without + * user interaction. This may be set on multiple {@link PhoneAccountSuggestion}s, and the dialer + * is free to choose which one to use. + * @return {@code true} if the hint is to auto-select, {@code false} otherwise. + */ + public boolean shouldAutoSelect() { + return mShouldAutoSelect; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelable(mHandle, flags); + 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 000000000000..ba3822cb9951 --- /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/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index 9f0bdd715359..e7ce78a7380c 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -1462,7 +1462,6 @@ public class TelecomManager { * otherwise. */ @RequiresPermission(Manifest.permission.ANSWER_PHONE_CALLS) - @SystemApi public boolean endCall() { try { if (isServiceConnected()) { @@ -1539,7 +1538,6 @@ public class TelecomManager { /** * Returns whether TTY is supported on this device. */ - @SystemApi @RequiresPermission(anyOf = { android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, android.Manifest.permission.READ_PHONE_STATE diff --git a/telecomm/java/android/telecom/VideoProfile.java b/telecomm/java/android/telecom/VideoProfile.java index bbac8eb88aec..7b2306128b7b 100644 --- a/telecomm/java/android/telecom/VideoProfile.java +++ b/telecomm/java/android/telecom/VideoProfile.java @@ -369,16 +369,13 @@ public class VideoProfile implements Parcelable { } /** - * 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 @@ public class VideoProfile implements Parcelable { } /** - * 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 000000000000..cb142417451c --- /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 000000000000..0ffab93d9f1b --- /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 143b323892f3..6f1b66a01725 100644 --- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl +++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl @@ -305,6 +305,10 @@ interface ITelecomService { */ void handleCallIntent(in Intent intent); + 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 0b5aa14eb427..3e4482e91d2b 100644 --- a/telephony/java/android/provider/Telephony.java +++ b/telephony/java/android/provider/Telephony.java @@ -2668,10 +2668,26 @@ public final class Telephony { /** * 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 @@ public final class Telephony { /** * 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 @@ public final class Telephony { "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 @@ public final class Telephony { /** * 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 @@ public final class Telephony { * 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 @@ public final class Telephony { * <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 @@ public final class Telephony { }) @Retention(RetentionPolicy.SOURCE) public @interface EditStatus {} - } /** @@ -3577,8 +3607,9 @@ public final class Telephony { /** * 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 @@ public final class Telephony { * * @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,22 +3641,20 @@ public final class Telephony { public static final String CARRIER_ID = "carrier_id"; /** - * A user facing carrier name for precise carrier id. - * @see TelephonyManager#getSimPreciseCarrierIdName() + * 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_NAME = "precise_carrier_id_name"; + public static final String PRECISE_CARRIER_ID = "precise_carrier_id"; /** - * A fine-grained carrier id. - * @see TelephonyManager#getSimPreciseCarrierId() + * 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)} - * @hide */ - public static final String PRECISE_CARRIER_ID = "precise_carrier_id"; + public static final String PRECISE_CARRIER_ID_NAME = "precise_carrier_id_name"; /** * A unique parent carrier id. The parent-child @@ -3640,18 +3668,6 @@ public final class Telephony { 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 e72d67b20160..4561ea33bb95 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -68,7 +68,13 @@ public class CarrierConfigManager { * 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"; @@ -81,7 +87,6 @@ public class CarrierConfigManager { * Specifies a value that identifies the version of the carrier configuration that is * currently in use. This string is displayed on the UI. * The format of the string is not specified. - * @hide */ public static final String KEY_CARRIER_CONFIG_VERSION_STRING = "carrier_config_version_string"; @@ -403,7 +408,6 @@ public class CarrierConfigManager { * @see SubscriptionManager#getSubscriptionPlans(int) * @see SubscriptionManager#setSubscriptionPlans(int, java.util.List) */ - @SystemApi public static final String KEY_CONFIG_PLANS_PACKAGE_OVERRIDE_STRING = "config_plans_package_override_string"; @@ -1394,9 +1398,9 @@ public class CarrierConfigManager { * 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} @@ -1996,6 +2000,8 @@ public class CarrierConfigManager { * 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"; @@ -2239,6 +2245,8 @@ public class CarrierConfigManager { * 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 598f56769ca3..fa198674c58a 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 @@ public final class CellIdentityCdma extends CellIdentity { * 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 @@ public final class CellIdentityCdma extends CellIdentity { } } + /** @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 04c28e5211c8..9a24e47288c3 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 @@ public final class CellIdentityGsm extends CellIdentity { // 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 @@ public final class CellIdentityGsm extends CellIdentity { 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 @@ public final class CellIdentityGsm extends CellIdentity { 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 @@ public final class CellIdentityGsm extends CellIdentity { /** * @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 04b6a6ca7fea..d957d077e016 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 @@ public final class CellIdentityLte extends CellIdentity { // 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 @@ public final class CellIdentityLte extends CellIdentity { /** * - * @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 @@ public final class CellIdentityLte extends CellIdentity { 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 @@ public final class CellIdentityLte extends CellIdentity { /** * @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 8b1c1b9f024c..38143335dbf1 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 @@ public final class CellIdentityTdscdma extends CellIdentity { } /** - * @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 @@ public final class CellIdentityTdscdma extends CellIdentity { 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 @@ public final class CellIdentityTdscdma extends CellIdentity { /** * @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 3416ffe0b8f4..6e0978434a57 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 @@ public final class CellIdentityWcdma extends CellIdentity { 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 @@ public final class CellIdentityWcdma extends CellIdentity { 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 @@ public final class CellIdentityWcdma extends CellIdentity { /** * @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 d0b268766314..b761bd7bf70c 100644 --- a/telephony/java/android/telephony/CellInfo.java +++ b/telephony/java/android/telephony/CellInfo.java @@ -132,7 +132,8 @@ public abstract class CellInfo implements Parcelable { /** 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 @@ public abstract class CellInfo implements Parcelable { protected CellInfo() { this.mRegistered = false; this.mTimeStamp = Long.MAX_VALUE; + mCellConnectionStatus = CONNECTION_NONE; } /** @hide */ @@ -300,4 +302,44 @@ public abstract class CellInfo implements Parcelable { 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 f67733d63ef2..8c76eae0b544 100644 --- a/telephony/java/android/telephony/CellInfoCdma.java +++ b/telephony/java/android/telephony/CellInfoCdma.java @@ -48,6 +48,24 @@ public final class CellInfoCdma extends CellInfo implements Parcelable { 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 7211de1798da..ad16dfae7295 100644 --- a/telephony/java/android/telephony/CellInfoGsm.java +++ b/telephony/java/android/telephony/CellInfoGsm.java @@ -43,8 +43,24 @@ public final class CellInfoGsm extends CellInfo implements Parcelable { /** @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 7d5388b7b7f4..8ca6a1a6815b 100644 --- a/telephony/java/android/telephony/CellInfoLte.java +++ b/telephony/java/android/telephony/CellInfoLte.java @@ -51,6 +51,24 @@ public final class CellInfoLte extends CellInfo implements Parcelable { 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 40cadde364dc..a8c49b7bf68e 100644 --- a/telephony/java/android/telephony/CellInfoTdscdma.java +++ b/telephony/java/android/telephony/CellInfoTdscdma.java @@ -48,8 +48,23 @@ public final class CellInfoTdscdma extends CellInfo implements Parcelable { 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 4f9dcb1a0637..a427e80fd65c 100644 --- a/telephony/java/android/telephony/CellInfoWcdma.java +++ b/telephony/java/android/telephony/CellInfoWcdma.java @@ -47,6 +47,22 @@ public final class CellInfoWcdma extends CellInfo implements Parcelable { 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 afa492226f65..a18275f95f9d 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 class CellSignalStrength { */ 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 5123052cb78b..47faf1e96aac 100644 --- a/telephony/java/android/telephony/CellSignalStrengthCdma.java +++ b/telephony/java/android/telephony/CellSignalStrengthCdma.java @@ -18,6 +18,7 @@ package android.telephony; import android.os.Parcel; import android.os.Parcelable; +import android.os.PersistableBundle; import android.telephony.Rlog; import java.util.Objects; @@ -35,6 +36,7 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements 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 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements * 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 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements mEvdoDbm = s.mEvdoDbm; mEvdoEcio = s.mEvdoEcio; mEvdoSnr = s.mEvdoSnr; + mLevel = s.mLevel; } /** @hide */ @@ -102,6 +111,7 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements mEvdoDbm = CellInfo.UNAVAILABLE; mEvdoEcio = CellInfo.UNAVAILABLE; mEvdoSnr = CellInfo.UNAVAILABLE; + mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; } /** @@ -112,26 +122,54 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements */ @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 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements } /** + * 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 final class CellSignalStrengthCdma extends CellSignalStrength implements public int getCdmaDbm() { return mCdmaDbm; } + /** @hide */ public void setCdmaDbm(int cdmaDbm) { mCdmaDbm = cdmaDbm; @@ -248,6 +344,7 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements public int getCdmaEcio() { return mCdmaEcio; } + /** @hide */ public void setCdmaEcio(int cdmaEcio) { mCdmaEcio = cdmaEcio; @@ -259,6 +356,7 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements public int getEvdoDbm() { return mEvdoDbm; } + /** @hide */ public void setEvdoDbm(int evdoDbm) { mEvdoDbm = evdoDbm; @@ -270,6 +368,7 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements public int getEvdoEcio() { return mEvdoEcio; } + /** @hide */ public void setEvdoEcio(int evdoEcio) { mEvdoEcio = evdoEcio; @@ -281,6 +380,7 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements public int getEvdoSnr() { return mEvdoSnr; } + /** @hide */ public void setEvdoSnr(int evdoSnr) { mEvdoSnr = evdoSnr; @@ -288,28 +388,29 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements @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 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements + " cdmaEcio=" + mCdmaEcio + " evdoDbm=" + mEvdoDbm + " evdoEcio=" + mEvdoEcio - + " evdoSnr=" + mEvdoSnr; + + " evdoSnr=" + mEvdoSnr + + " level=" + mLevel; } /** Implement the Parcelable interface */ @@ -334,6 +436,7 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements dest.writeInt(mEvdoDbm); dest.writeInt(mEvdoEcio); dest.writeInt(mEvdoSnr); + dest.writeInt(mLevel); } /** @@ -349,6 +452,7 @@ public final class CellSignalStrengthCdma extends CellSignalStrength implements 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 e906f460024a..7b29f69da6da 100644 --- a/telephony/java/android/telephony/CellSignalStrengthGsm.java +++ b/telephony/java/android/telephony/CellSignalStrengthGsm.java @@ -19,6 +19,7 @@ package android.telephony; 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 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P 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 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P } /** @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 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P /** @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 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P /** @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 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P */ @Override public int getLevel() { - 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 = 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; + return mLevel; + } + + /** @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 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P */ @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); } - @Override - public boolean equals (Object o) { - CellSignalStrengthGsm s; + private static final CellSignalStrengthGsm sInvalid = new CellSignalStrengthGsm(); - try { - s = (CellSignalStrengthGsm) o; - } catch (ClassCastException ex) { - return false; - } + /** @hide */ + @Override + public boolean isValid() { + return !this.equals(sInvalid); + } - if (o == null) { - return false; - } + @Override + public boolean equals(Object o) { + if (!(o instanceof CellSignalStrengthGsm)) return false; + CellSignalStrengthGsm s = (CellSignalStrengthGsm) o; - 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 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P @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 @@ public final class CellSignalStrengthGsm extends CellSignalStrength implements P * 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 d07539431348..893dbe31ce0b 100644 --- a/telephony/java/android/telephony/CellSignalStrengthLte.java +++ b/telephony/java/android/telephony/CellSignalStrengthLte.java @@ -19,7 +19,9 @@ package android.telephony; 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 @@ import java.util.Objects; 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 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P */ 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 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P 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 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P /** @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 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P @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 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P */ @Override public int getLevel() { - int levelRsrp = 0; - int levelRssnr = 0; - - 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; - - // 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; + return mLevel; + } + + // 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; + + /** @hide */ + @Override + public void updateLevel(PersistableBundle cc, ServiceState ss) { + int[] thresholds; + boolean rsrpOnly; + if (cc == null) { + thresholds = sThresholds; + rsrpOnly = false; + } else { + 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)); + } + + + 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 { - level = (levelRssnr < levelRsrp) ? levelRssnr : levelRsrp; + 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; + } } - if (DBG) log("Lte rsrp level: " + levelRsrp - + " snr level: " + levelRssnr + " level: " + level); - return level; + /* + * 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 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P * @return the RSSI if available or {@link CellInfo#UNAVAILABLE} if unavailable. */ public int getRssi() { - return convertRssiAsuToDBm(mSignalStrength); + return mRssi; } /** @@ -212,13 +318,16 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P } /** - * 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 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P @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 == null) { - return false; - } + if (!(o instanceof CellSignalStrengthLte)) return false; + s = (CellSignalStrengthLte) o; - 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 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P @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 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P * 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 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P } 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 807924222a26..061cd4b33950 100644 --- a/telephony/java/android/telephony/CellSignalStrengthNr.java +++ b/telephony/java/android/telephony/CellSignalStrengthNr.java @@ -18,6 +18,7 @@ package android.telephony; import android.os.Parcel; import android.os.Parcelable; +import android.os.PersistableBundle; import java.util.Objects; @@ -48,6 +49,12 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa 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 final class CellSignalStrengthNr extends CellSignalStrength implements Pa */ 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 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa dest.writeInt(mSsRsrp); dest.writeInt(mSsRsrq); dest.writeInt(mSsSinr); + dest.writeInt(mLevel); } private CellSignalStrengthNr(Parcel in) { @@ -151,6 +160,7 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa mSsRsrp = in.readInt(); mSsRsrq = in.readInt(); mSsSinr = in.readInt(); + mLevel = in.readInt(); } /** @hide */ @@ -162,27 +172,36 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa 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 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa } /** @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 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa 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 @@ public final class CellSignalStrengthNr extends CellSignalStrength implements Pa .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 4d040cca5fff..6f52b853d23b 100644 --- a/telephony/java/android/telephony/CellSignalStrengthTdscdma.java +++ b/telephony/java/android/telephony/CellSignalStrengthTdscdma.java @@ -18,6 +18,7 @@ package android.telephony; import android.os.Parcel; import android.os.Parcelable; +import android.os.PersistableBundle; import java.util.Objects; @@ -31,27 +32,53 @@ public final class CellSignalStrengthTdscdma extends CellSignalStrength implemen 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 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 mSignalStrength; // in ASU; Valid values are (0-31, 99) as defined in TS 27.007 8.5 - // 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; // 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 @@ public final class CellSignalStrengthTdscdma extends CellSignalStrength implemen /** @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 @@ public final class CellSignalStrengthTdscdma extends CellSignalStrength implemen /** @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 @@ public final class CellSignalStrengthTdscdma extends CellSignalStrength implemen */ @Override public int getLevel() { - 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 = 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; + return mLevel; + } + + /** @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 @@ public final class CellSignalStrengthTdscdma extends CellSignalStrength implemen */ @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); } - @Override - public boolean equals(Object o) { - CellSignalStrengthTdscdma s; + private static final CellSignalStrengthTdscdma sInvalid = new CellSignalStrengthTdscdma(); - try { - s = (CellSignalStrengthTdscdma) o; - } catch (ClassCastException ex) { - return false; - } + /** @hide */ + @Override + public boolean isValid() { + return !this.equals(sInvalid); + } - if (o == null) { - return false; - } + @Override + public boolean equals(Object o) { + if (!(o instanceof CellSignalStrengthTdscdma)) return false; + CellSignalStrengthTdscdma s = (CellSignalStrengthTdscdma) o; - return mSignalStrength == s.mSignalStrength + return mRssi == s.mRssi && mBitErrorRate == s.mBitErrorRate - && mRscp == s.mRscp; + && mRscp == s.mRscp + && mLevel == s.mLevel; } /** @@ -173,18 +193,20 @@ public final class CellSignalStrengthTdscdma extends CellSignalStrength implemen @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 @@ public final class CellSignalStrengthTdscdma extends CellSignalStrength implemen * 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 0048cbdea8f6..88f6fbc4464d 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 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements 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 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements } /** @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 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements /** @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 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements /** @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 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements */ @Override public int getLevel() { - 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 = 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; + return mLevel; + } + + /** @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 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements */ @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); } - @Override - public boolean equals (Object o) { - CellSignalStrengthWcdma s; + private static final CellSignalStrengthWcdma sInvalid = new CellSignalStrengthWcdma(); - try { - s = (CellSignalStrengthWcdma) o; - } catch (ClassCastException ex) { - return false; - } + /** @hide */ + @Override + public boolean isValid() { + return !this.equals(sInvalid); + } - if (o == null) { - return false; - } + @Override + public boolean equals(Object o) { + if (!(o instanceof CellSignalStrengthWcdma)) return false; + CellSignalStrengthWcdma s = (CellSignalStrengthWcdma) o; - 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 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements @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 @@ public final class CellSignalStrengthWcdma extends CellSignalStrength implements * 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 000000000000..c53b37d8ae6a --- /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/DataSpecificRegistrationStates.java b/telephony/java/android/telephony/DataSpecificRegistrationStates.java index b6e6cbae8c26..5d809d0b7c36 100644 --- a/telephony/java/android/telephony/DataSpecificRegistrationStates.java +++ b/telephony/java/android/telephony/DataSpecificRegistrationStates.java @@ -33,17 +33,31 @@ public class DataSpecificRegistrationStates implements Parcelable{ */ public final boolean isNrAvailable; + /** + * Indicates that if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the primary serving + * cell. + * + * True the primary serving cell is LTE cell and the plmn-InfoList-r15 is present in SIB2 and + * at least one bit in this list is true, otherwise this value should be false. + * + * Reference: 3GPP TS 36.331 v15.2.2 6.3.1 System information blocks. + */ + public final boolean isEnDcAvailable; + DataSpecificRegistrationStates( - int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable) { + int maxDataCalls, boolean isDcNrRestricted, boolean isNrAvailable, + boolean isEnDcAvailable) { this.maxDataCalls = maxDataCalls; this.isDcNrRestricted = isDcNrRestricted; this.isNrAvailable = isNrAvailable; + this.isEnDcAvailable = isEnDcAvailable; } private DataSpecificRegistrationStates(Parcel source) { maxDataCalls = source.readInt(); isDcNrRestricted = source.readBoolean(); isNrAvailable = source.readBoolean(); + isEnDcAvailable = source.readBoolean(); } @Override @@ -51,6 +65,7 @@ public class DataSpecificRegistrationStates implements Parcelable{ dest.writeInt(maxDataCalls); dest.writeBoolean(isDcNrRestricted); dest.writeBoolean(isNrAvailable); + dest.writeBoolean(isEnDcAvailable); } @Override @@ -65,13 +80,14 @@ public class DataSpecificRegistrationStates implements Parcelable{ .append(" maxDataCalls = " + maxDataCalls) .append(" isDcNrRestricted = " + isDcNrRestricted) .append(" isNrAvailable = " + isNrAvailable) + .append(" isEnDcAvailable = " + isEnDcAvailable) .append(" }") .toString(); } @Override public int hashCode() { - return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable); + return Objects.hash(maxDataCalls, isDcNrRestricted, isNrAvailable, isEnDcAvailable); } @Override @@ -83,7 +99,8 @@ public class DataSpecificRegistrationStates implements Parcelable{ DataSpecificRegistrationStates other = (DataSpecificRegistrationStates) o; return this.maxDataCalls == other.maxDataCalls && this.isDcNrRestricted == other.isDcNrRestricted - && this.isNrAvailable == other.isNrAvailable; + && this.isNrAvailable == other.isNrAvailable + && this.isEnDcAvailable == other.isEnDcAvailable; } public static final Parcelable.Creator<DataSpecificRegistrationStates> CREATOR = diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java index c6887ab93109..f53cb8224706 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 @@ public class DisconnectCause { /** 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 class DisconnectCause { */ 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 @@ public class DisconnectCause { * 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 @@ public class DisconnectCause { /** * 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 @@ public class DisconnectCause { /** * 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 @@ public class DisconnectCause { /** * The call has failed because of access class barring. - * {@hide} */ public static final int IMS_ACCESS_BLOCKED = 60; @@ -265,51 +258,43 @@ public class DisconnectCause { /** * 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 @@ public class DisconnectCause { // 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/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java index aee744fac20c..b00665e26ff2 100644 --- a/telephony/java/android/telephony/NetworkRegistrationState.java +++ b/telephony/java/android/telephony/NetworkRegistrationState.java @@ -219,12 +219,13 @@ public class NetworkRegistrationState implements Parcelable { public NetworkRegistrationState(int domain, int transportType, int regState, int accessNetworkTechnology, int rejectCause, boolean emergencyOnly, int[] availableServices, @Nullable CellIdentity cellIdentity, int maxDataCalls, - boolean isDcNrRestricted, boolean isNrAvailable) { + boolean isDcNrRestricted, boolean isNrAvailable, boolean isEndcAvailable) { this(domain, transportType, regState, accessNetworkTechnology, rejectCause, emergencyOnly, availableServices, cellIdentity); mDataSpecificStates = new DataSpecificRegistrationStates( - maxDataCalls, isDcNrRestricted, isNrAvailable); + maxDataCalls, isDcNrRestricted, isNrAvailable, isEndcAvailable); + updateNrStatus(mDataSpecificStates); } protected NetworkRegistrationState(Parcel source) { @@ -448,6 +449,34 @@ public class NetworkRegistrationState implements Parcelable { dest.writeInt(mNrStatus); } + /** + * Use the 5G NR Non-Standalone indicators from the network registration state to update the + * NR status. There are 3 indicators in the network registration state: + * + * 1. if E-UTRA-NR Dual Connectivity (EN-DC) is supported by the primary serving cell. + * 2. if NR is supported by the selected PLMN. + * 3. if the use of dual connectivity with NR is restricted. + * + * The network has 5G NR capability if E-UTRA-NR Dual Connectivity is supported by the primary + * serving cell. + * + * The use of NR 5G is not restricted If the network has 5G NR capability and both the use of + * DCNR is not restricted and NR is supported by the selected PLMN. Otherwise the use of 5G + * NR is restricted. + * + * @param state data specific registration state contains the 5G NR indicators. + */ + private void updateNrStatus(DataSpecificRegistrationStates state) { + mNrStatus = NR_STATUS_NONE; + if (state.isEnDcAvailable) { + if (!state.isDcNrRestricted && state.isNrAvailable) { + mNrStatus = NR_STATUS_NOT_RESTRICTED; + } else { + mNrStatus = NR_STATUS_RESTRICTED; + } + } + } + public static final Parcelable.Creator<NetworkRegistrationState> CREATOR = new Parcelable.Creator<NetworkRegistrationState>() { @Override diff --git a/telephony/java/android/telephony/NetworkService.java b/telephony/java/android/telephony/NetworkService.java index 4354314dac29..4bca404d9444 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 @@ public abstract class NetworkService extends Service { 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 @@ public abstract class NetworkService extends Service { * 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 @@ public abstract class NetworkService extends Service { } /** - * 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 @@ public abstract class NetworkService extends Service { 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 @@ public abstract class NetworkService extends Service { 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 e8a28cac3140..2b1628ce3f27 100644 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ b/telephony/java/android/telephony/PhoneStateListener.java @@ -171,14 +171,14 @@ public class PhoneStateListener { 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 class PhoneStateListener { */ 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,15 +538,27 @@ public class PhoneStateListener { /** * Callback invoked when precise device call state changes. - * + * @param callState {@link PreciseCallState} * @hide */ - @UnsupportedAppUsage + @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 + */ + @SystemApi + public void onCallDisconnectCauseChanged(int disconnectCause, int preciseDisconnectCause) { + // default implementation empty + } + + /** * Callback invoked when data connection state changes with precise information. * * @hide @@ -780,6 +804,15 @@ public class PhoneStateListener { () -> 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 ed5c26ac5cf2..59f3e1f0e7f7 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 @@ public class PreciseCallState implements Parcelable { /** 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 @@ public class PreciseCallState implements Parcelable { * @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 @@ public class PreciseCallState implements Parcelable { /** * Construct a PreciseCallState object from the given parcel. + * + * @hide */ private PreciseCallState(Parcel in) { mRingingCallState = in.readInt(); @@ -102,59 +127,23 @@ public class PreciseCallState implements Parcelable { } /** - * 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 @@ public class PreciseCallState implements Parcelable { * @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 @@ public class PreciseCallState implements Parcelable { * @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 @@ public class PreciseCallState implements Parcelable { @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 2acaf34dbb30..af88748af9e6 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 @@ public class PreciseDisconnectCause { * 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 @@ public class PreciseDisconnectCause { * 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 @@ public class PreciseDisconnectCause { * 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 class PreciseDisconnectCause { 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 13fbeaaa02b7..ca0c854a1a75 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -118,6 +118,13 @@ public class ServiceState implements Parcelable { */ 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 @@ public class ServiceState implements Parcelable { 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 240b8a981e70..ef185c5eeaf1 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 @@ public class SignalStrength implements Parcelable { /** @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 class SignalStrength implements Parcelable { 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 @@ public class SignalStrength implements Parcelable { } /** - * 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 @@ public class SignalStrength implements Parcelable { * @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 @@ public class SignalStrength implements Parcelable { */ @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 class SignalStrength implements Parcelable { 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 @@ public class SignalStrength implements Parcelable { }; /** - * 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 - * - * @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. + * Get the GSM RSSI in ASU. * - * @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. + * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 * - * @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 @@ public class SignalStrength implements Parcelable { * @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 @@ public class SignalStrength implements Parcelable { * @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 @@ public class SignalStrength implements Parcelable { * 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 @@ public class SignalStrength implements Parcelable { */ @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 @@ public class SignalStrength implements Parcelable { */ @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 @@ public class SignalStrength implements Parcelable { */ @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 @@ public class SignalStrength implements Parcelable { */ @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 @@ public class SignalStrength implements Parcelable { */ @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 @@ public class SignalStrength implements Parcelable { */ @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 @@ public class SignalStrength implements Parcelable { */ @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 @@ public class SignalStrength implements Parcelable { */ @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 @@ public class SignalStrength implements Parcelable { */ @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 @@ public class SignalStrength implements Parcelable { */ @UnsupportedAppUsage public int getLteDbm() { - return mLteRsrp; + return mLte.getRsrp(); } /** @@ -896,83 +482,7 @@ public class SignalStrength implements Parcelable { */ @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 @@ public class SignalStrength implements Parcelable { */ @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 @@ public class SignalStrength implements Parcelable { */ @UnsupportedAppUsage public int getTdScdmaDbm() { - return this.mTdScdmaRscp; + return mTdscdma.getRscp(); } /** @@ -1040,19 +523,7 @@ public class SignalStrength implements Parcelable { */ @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 @@ public class SignalStrength implements Parcelable { */ @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 @@ public class SignalStrength implements Parcelable { * @hide */ public int getWcdmaRscp() { - return mWcdmaRscp; + return mWcdma.getRscp(); } /** @@ -1094,14 +559,7 @@ public class SignalStrength implements Parcelable { * 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 @@ public class SignalStrength implements Parcelable { * @hide */ public int getWcdmaDbm() { - return mWcdmaRscp; + return mWcdma.getDbm(); } /** @@ -1119,55 +577,7 @@ public class SignalStrength implements Parcelable { * @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 @@ public class SignalStrength implements Parcelable { */ @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 @@ public class SignalStrength implements Parcelable { */ @Override public boolean equals (Object o) { - SignalStrength s; + if (!(o instanceof SignalStrength)) return false; - try { - s = (SignalStrength) o; - } catch (ClassCastException ex) { - return false; - } - - if (o == null) { - return false; - } + SignalStrength s = (SignalStrength) o; - 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 @@ public class SignalStrength implements Parcelable { */ @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 @@ public class SignalStrength implements Parcelable { */ @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 @@ public class SignalStrength implements Parcelable { */ @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.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); - } + m.putParcelable("Cdma", mCdma); + m.putParcelable("Gsm", mGsm); + m.putParcelable("Wcdma", mWcdma); + m.putParcelable("Tdscdma", mTdscdma); + m.putParcelable("Lte", mLte); - /** - * 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); + m.putInt("LteRsrpBoost", mLteRsrpBoost); } /** diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java index ea408bf8ff59..1b37bad65d57 100644 --- a/telephony/java/android/telephony/SmsManager.java +++ b/telephony/java/android/telephony/SmsManager.java @@ -365,7 +365,6 @@ public final class SmsManager { * * @see #sendTextMessage(String, String, String, PendingIntent, PendingIntent) */ - @SystemApi @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges @RequiresPermission(allOf = { android.Manifest.permission.MODIFY_PHONE_STATE, diff --git a/telephony/java/android/telephony/SubscriptionInfo.java b/telephony/java/android/telephony/SubscriptionInfo.java index bacfe61a1a10..0a58fa08f32e 100644 --- a/telephony/java/android/telephony/SubscriptionInfo.java +++ b/telephony/java/android/telephony/SubscriptionInfo.java @@ -80,6 +80,12 @@ public class SubscriptionInfo implements Parcelable { 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 @@ public class SubscriptionInfo implements Parcelable { 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 mCardString; + + /** + * The card ID of the SIM card. This maps uniquely to the card string. */ - private String mCardId; + private int mCardId; /** * Whether the subscription is opportunistic. @@ -155,15 +166,36 @@ public class SubscriptionInfo implements Parcelable { private boolean mIsMetered; /** + * Whether group of the subscription is disabled. + * This is only useful if it's a grouped opportunistic subscription. In this case, if all + * primary (non-opportunistic) subscriptions in the group are deactivated (unplugged pSIM + * or deactivated eSIM profile), we should disable this opportunistic subscription. + */ + private boolean mIsGroupDisabled = false; + + /** + * @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 cardString) { + this(id, iccId, simSlotIndex, displayName, carrierName, nameSource, iconTint, number, + roaming, icon, mcc, mnc, countryIso, isEmbedded, accessRules, cardString, + false, null, true, TelephonyManager.UNKNOWN_CARRIER_ID); + } + + /** * @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) { + @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, - false, null, true); + roaming, icon, mcc, mnc, countryIso, isEmbedded, accessRules, cardString, -1, + isOpportunistic, groupUUID, isMetered, false, carrierId); } /** @@ -172,8 +204,9 @@ public class SubscriptionInfo implements Parcelable { 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, int cardId, + boolean isOpportunistic, @Nullable String groupUUID, boolean isMetered, + boolean isGroupDisabled, int carrierid) { this.mId = id; this.mIccId = iccId; this.mSimSlotIndex = simSlotIndex; @@ -189,10 +222,13 @@ public class SubscriptionInfo implements Parcelable { 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; } @@ -218,6 +254,14 @@ public class SubscriptionInfo implements Parcelable { } /** + * @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() { @@ -487,13 +531,39 @@ public class SubscriptionInfo implements Parcelable { } /** - * @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 getCardString() { + return this.mCardString; + } + + /** + * @return the cardId of the SIM card which contains the subscription. * @hide */ - public String getCardId() { + @SystemApi + public int getCardId() { return this.mCardId; } + /** + * Set whether the subscription's group is disabled. + * @hide + */ + public void setGroupDisabled(boolean isGroupDisabled) { + this.mIsGroupDisabled = isGroupDisabled; + } + + /** + * Return whether the subscription's group is disabled. + * @hide + */ + public boolean isGroupDisabled() { + return mIsGroupDisabled; + } + public static final Parcelable.Creator<SubscriptionInfo> CREATOR = new Parcelable.Creator<SubscriptionInfo>() { @Override public SubscriptionInfo createFromParcel(Parcel source) { @@ -512,14 +582,18 @@ public class SubscriptionInfo implements Parcelable { 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); + isEmbedded, accessRules, cardString, cardId, isOpportunistic, groupUUID, + isMetered, isGroupDisabled, carrierid); } @Override @@ -545,10 +619,13 @@ public class SubscriptionInfo implements Parcelable { 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 @@ -574,22 +651,25 @@ public class SubscriptionInfo implements Parcelable { @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 + "}"; + + " 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); + mCountryIso, mCardString, mCardId, mDisplayName, mCarrierName, mAccessRules, + mIsGroupDisabled, mCarrierId); } @Override @@ -611,16 +691,19 @@ public class SubscriptionInfo implements Parcelable { && mDataRoaming == toCompare.mDataRoaming && mIsEmbedded == toCompare.mIsEmbedded && mIsOpportunistic == toCompare.mIsOpportunistic - && Objects.equals(mGroupUUID, toCompare.mGroupUUID) + && mIsGroupDisabled == toCompare.mIsGroupDisabled + && 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) && Arrays.equals(mAccessRules, toCompare.mAccessRules); } -}
\ No newline at end of file +} diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index ff20fd23b0c1..3235507d76cd 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -19,6 +19,7 @@ package android.telephony; 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.RemoteException; 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.List; 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 class SubscriptionManager { 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 @@ -635,7 +646,6 @@ public class SubscriptionManager { * the user is interested in. */ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) - @SystemApi public static final String ACTION_MANAGE_SUBSCRIPTION_PLANS = "android.telephony.action.MANAGE_SUBSCRIPTION_PLANS"; @@ -655,7 +665,6 @@ public class SubscriptionManager { * {@code android.permission.MANAGE_SUBSCRIPTION_PLANS} permission. */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) - @SystemApi public static final String ACTION_REFRESH_SUBSCRIPTION_PLANS = "android.telephony.action.REFRESH_SUBSCRIPTION_PLANS"; @@ -1592,14 +1601,23 @@ public class SubscriptionManager { return subId; } - /** @hide */ - @UnsupportedAppUsage - public void setDefaultSmsSubId(int subId) { - if (VDBG) logd("setDefaultSmsSubId sub id = " + subId); + /** + * Set the subscription which will be used by default for SMS, with the subscription which + * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied + * subscription ID is not usable (check with {@link #isUsableSubscriptionId(int)}). + * + * @param subscriptionId the supplied subscription ID + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void setDefaultSmsSubId(int subscriptionId) { + if (VDBG) logd("setDefaultSmsSubId sub id = " + subscriptionId); try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { - iSub.setDefaultSmsSubId(subId); + iSub.setDefaultSmsSubId(subscriptionId); } } catch (RemoteException ex) { // ignore it @@ -1647,14 +1665,23 @@ public class SubscriptionManager { return subId; } - /** @hide */ - @UnsupportedAppUsage - public void setDefaultDataSubId(int subId) { - if (VDBG) logd("setDataSubscription sub id = " + subId); + /** + * Set the subscription which will be used by default for data, with the subscription which + * the supplied subscription ID corresponds to; or throw a RuntimeException if the supplied + * subscription ID is not usable (check with {@link #isUsableSubscriptionId(int)}). + * + * @param subscriptionId the supplied subscription ID + * + * @hide + */ + @SystemApi + @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) + public void setDefaultDataSubId(int subscriptionId) { + if (VDBG) logd("setDataSubscription sub id = " + subscriptionId); try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); if (iSub != null) { - iSub.setDefaultDataSubId(subId); + iSub.setDefaultDataSubId(subscriptionId); } } catch (RemoteException ex) { // ignore it @@ -2043,7 +2070,6 @@ public class SubscriptionManager { * @throws SecurityException if the caller doesn't meet the requirements * outlined above. */ - @SystemApi public @NonNull List<SubscriptionPlan> getSubscriptionPlans(int subId) { try { SubscriptionPlan[] subscriptionPlans = @@ -2075,7 +2101,6 @@ public class SubscriptionManager { * @throws SecurityException if the caller doesn't meet the requirements * outlined above. */ - @SystemApi public void setSubscriptionPlans(int subId, @NonNull List<SubscriptionPlan> plans) { try { getNetworkPolicy().setSubscriptionPlans(subId, @@ -2117,7 +2142,6 @@ public class SubscriptionManager { * @throws SecurityException if the caller doesn't meet the requirements * outlined above. */ - @SystemApi public void setSubscriptionOverrideUnmetered(int subId, boolean overrideUnmetered, @DurationMillisLong long timeoutMillis) { try { @@ -2153,7 +2177,6 @@ public class SubscriptionManager { * @throws SecurityException if the caller doesn't meet the requirements * outlined above. */ - @SystemApi public void setSubscriptionOverrideCongested(int subId, boolean overrideCongested, @DurationMillisLong long timeoutMillis) { try { @@ -2389,16 +2412,21 @@ public class SubscriptionManager { * 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)); @@ -2418,6 +2446,80 @@ public class SubscriptionManager { } /** + * 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. @@ -2432,6 +2534,42 @@ public class SubscriptionManager { (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/SubscriptionPlan.java b/telephony/java/android/telephony/SubscriptionPlan.java index e8bbe42e834e..d67169ccd284 100644 --- a/telephony/java/android/telephony/SubscriptionPlan.java +++ b/telephony/java/android/telephony/SubscriptionPlan.java @@ -45,7 +45,6 @@ import java.util.Objects; * @see SubscriptionManager#setSubscriptionPlans(int, java.util.List) * @see SubscriptionManager#getSubscriptionPlans(int) */ -@SystemApi public final class SubscriptionPlan implements Parcelable { /** {@hide} */ @IntDef(prefix = "LIMIT_BEHAVIOR_", value = { diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index a976fe6ef2fe..26d2459d2116 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -225,6 +225,13 @@ public class TelephonyManager { @SystemApi public static final int SRVCC_STATE_HANDOVER_CANCELED = 3; + /** + * An invalid card identifier. + * @hide + */ + @SystemApi + public static final int INVALID_CARD_ID = -1; + /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(prefix = {"SRVCC_STATE_"}, @@ -618,8 +625,6 @@ public class TelephonyManager { * 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. @@ -627,12 +632,10 @@ public class TelephonyManager { * @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) @@ -640,8 +643,28 @@ public class TelephonyManager { "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 @@ -663,8 +686,9 @@ public class TelephonyManager { 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 @@ -686,8 +710,9 @@ public class TelephonyManager { 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 @@ -709,8 +734,9 @@ public class TelephonyManager { 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 * @@ -723,8 +749,9 @@ public class TelephonyManager { 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 * @@ -1216,81 +1243,79 @@ public class TelephonyManager { "android.telephony.action.SUBSCRIPTION_CARRIER_IDENTITY_CHANGED"; /** + * An int extra used with {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} which indicates + * 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 string extra used with {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} which + * indicates the updated carrier name of the current subscription. + * @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. - * 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 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 carrier name of the current - * subscription. + * <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. - * @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. - * <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()} - * <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"; - - /** * 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 @@ -3094,6 +3119,57 @@ public class TelephonyManager { } /** + * Get the card ID of the default eUICC card. If there is no eUICC, returns + * {@link #INVALID_CARD_ID}. + * + * <p>The card ID is a unique identifier associated with a UICC or eUICC card. Card IDs are + * unique to a device, and always refer to the same UICC or eUICC card unless the device goes + * through a factory reset. + * + * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} + * + * @return card ID of the default eUICC card. + * @hide + */ + @SystemApi + @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges + @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE) + public int getCardIdForDefaultEuicc() { + try { + ITelephony telephony = getITelephony(); + if (telephony == null) { + return INVALID_CARD_ID; + } + return telephony.getCardIdForDefaultEuicc(mSubId, mContext.getOpPackageName()); + } catch (RemoteException e) { + return INVALID_CARD_ID; + } + } + + /** + * 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. * @@ -4828,7 +4904,7 @@ public class TelephonyManager { */ @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; @@ -5569,7 +5645,7 @@ public class TelephonyManager { if (value == null) { value = ""; } - + value.replace(',', ' '); if (prop != null) { p = prop.split(","); } @@ -5595,7 +5671,13 @@ public class TelephonyManager { } } - if (propVal.length() > SystemProperties.PROP_VALUE_MAX) { + int propValLen = propVal.length(); + try { + propValLen = propVal.getBytes("utf-8").length; + } catch (java.io.UnsupportedEncodingException e) { + Rlog.d(TAG, "setTelephonyProperty: utf-8 not supported"); + } + if (propValLen > SystemProperties.PROP_VALUE_MAX) { Rlog.d(TAG, "setTelephonyProperty: property too long phoneId=" + phoneId + " property=" + property + " value: " + value + " propVal=" + propVal); return; @@ -6606,7 +6688,7 @@ public class TelephonyManager { try { ITelephony telephony = getITelephony(); if (telephony != null) { - return telephony.getCarrierPrivilegeStatus(mSubId) == + return telephony.getCarrierPrivilegeStatus(subId) == CARRIER_PRIVILEGE_STATUS_HAS_ACCESS; } } catch (RemoteException ex) { @@ -8492,7 +8574,7 @@ public class TelephonyManager { /** * 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, @@ -8502,7 +8584,7 @@ public class TelephonyManager { * @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) { @@ -8519,10 +8601,10 @@ public class TelephonyManager { * * <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 @@ -8532,8 +8614,6 @@ public class TelephonyManager { * @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 { @@ -8549,16 +8629,14 @@ public class TelephonyManager { /** * 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) { @@ -8571,43 +8649,54 @@ public class TelephonyManager { } /** - * Return a list of certs in hex string from loaded carrier privileges access rules. + * 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. * - * @return a list of certificate in hex string. return {@code null} if there is no certs - * or privilege rules are not loaded yet. + * 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. * - * <p>Requires Permission: - * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} - * @hide + * @return matching carrier id from sim MCCMNC. Return {@link #UNKNOWN_CARRIER_ID} if the + * subscription is unavailable or the carrier cannot be identified. */ - @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) - public List<String> getCertsFromCarrierPrivilegeAccessRules() { + public int getCarrierIdFromSimMccMnc() { try { ITelephony service = getITelephony(); if (service != null) { - return service.getCertsFromCarrierPrivilegeAccessRules(getSubId()); + return service.getCarrierIdFromMccMnc(getSlotIndex(), getSimOperator(), true); } } catch (RemoteException ex) { // This could happen if binder process crashes. } - return null; + return UNKNOWN_CARRIER_ID; } - /** - * 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() { + /** + * 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.getSubscriptionMNOCarrierId(getSubId()); + return service.getCarrierIdFromMccMnc(getSlotIndex(), mccmnc, false); } } catch (RemoteException ex) { // This could happen if binder process crashes. @@ -8615,24 +8704,27 @@ public class TelephonyManager { 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) { + /** + * 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 + * or privilege rules are not loaded yet. + * + * <p>Requires Permission: + * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} + * @hide + */ + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public List<String> getCertsFromCarrierPrivilegeAccessRules() { try { ITelephony service = getITelephony(); if (service != null) { - return service.getCarrierIdFromMccMnc(getSlotIndex(), mccmnc); + return service.getCertsFromCarrierPrivilegeAccessRules(getSubId()); } } catch (RemoteException ex) { // This could happen if binder process crashes. } - return UNKNOWN_CARRIER_ID; + return null; } /** diff --git a/telephony/java/android/telephony/UiccCardInfo.aidl b/telephony/java/android/telephony/UiccCardInfo.aidl new file mode 100644 index 000000000000..882c2333909f --- /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 000000000000..45e4704e8894 --- /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 b5a87585b567..200b5403eea9 100644 --- a/telephony/java/android/telephony/data/ApnSetting.java +++ b/telephony/java/android/telephony/data/ApnSetting.java @@ -969,7 +969,7 @@ public class ApnSetting implements Parcelable { */ 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 @@ public class ApnSetting implements Parcelable { 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 1db58506bb1c..74d1e838f186 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 @@ public abstract class DataService extends Service { 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 @@ public abstract class DataService extends Service { * 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 @@ public abstract class DataService extends Service { } /** - * 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 @@ public abstract class DataService extends Service { break; case DATA_SERVICE_REMOVE_DATA_SERVICE_PROVIDER: if (serviceProvider != null) { - serviceProvider.onDestroy(); + serviceProvider.close(); mServiceMap.remove(slotId); } break; @@ -353,7 +351,7 @@ public abstract class DataService extends Service { 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/DataServiceCallback.java b/telephony/java/android/telephony/data/DataServiceCallback.java index 4af31b5e5346..bef11425b470 100644 --- a/telephony/java/android/telephony/data/DataServiceCallback.java +++ b/telephony/java/android/telephony/data/DataServiceCallback.java @@ -125,7 +125,6 @@ public class DataServiceCallback { * * @param result The result code. Must be one of the {@link ResultCode}. */ - @SystemApi public void onSetDataProfileComplete(@ResultCode int result) { IDataServiceCallback callback = mCallback.get(); if (callback != null) { diff --git a/telephony/java/android/telephony/data/QualifiedNetworksService.java b/telephony/java/android/telephony/data/QualifiedNetworksService.java index 57d9cced53b1..45b4849990c2 100644 --- a/telephony/java/android/telephony/data/QualifiedNetworksService.java +++ b/telephony/java/android/telephony/data/QualifiedNetworksService.java @@ -151,7 +151,7 @@ public abstract class QualifiedNetworksService extends Service { /** * 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 8fcdb6e90569..4d95e552c1da 100644 --- a/telephony/java/android/telephony/ims/ImsReasonInfo.java +++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java @@ -16,11 +16,15 @@ package android.telephony.ims; +import android.annotation.IntDef; import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * This class enables an application to get details on why a method call failed. * @@ -30,158 +34,292 @@ import android.os.Parcelable; public final class ImsReasonInfo implements Parcelable { /** - * Specific code of each types + * The Reason is unspecified. */ public static final int CODE_UNSPECIFIED = 0; + + // LOCAL + + // IMS -> Telephony /** - * LOCAL + * The passed argument is invalid. */ - // IMS -> Telephony - // The passed argument is an invalid public static final int CODE_LOCAL_ILLEGAL_ARGUMENT = 101; - // The operation is invoked in invalid call state + /** + * The operation was invoked while in an invalid call state. + */ public static final int CODE_LOCAL_ILLEGAL_STATE = 102; - // IMS service internal error + /** + * IMS service internal error + */ public static final int CODE_LOCAL_INTERNAL_ERROR = 103; - // IMS service goes down (service connection is lost) + /** + * ImsService has crashed (service connection is lost). + */ public static final int CODE_LOCAL_IMS_SERVICE_DOWN = 106; - // No pending incoming call exists + /** + * No pending incoming call exists + */ public static final int CODE_LOCAL_NO_PENDING_CALL = 107; - // IMS Call ended during conference merge process + /** + * IMS Call ended during conference merge process + */ public static final int CODE_LOCAL_ENDED_BY_CONFERENCE_MERGE = 108; // IMS -> Telephony - // Service unavailable; by power off + /** + * Service unavailable; radio power off + */ public static final int CODE_LOCAL_POWER_OFF = 111; - // Service unavailable; by low battery + /** + * Service unavailable; low battery + */ public static final int CODE_LOCAL_LOW_BATTERY = 112; - // Service unavailable; by out of service (data service state) + /** + * Service unavailable; out of service (data service state) + */ public static final int CODE_LOCAL_NETWORK_NO_SERVICE = 121; - // Service unavailable; by no LTE coverage - // (VoLTE is not supported even though IMS is registered) + /** + * Service unavailable; no LTE coverage + * (VoLTE is not supported even though IMS is registered) + */ public static final int CODE_LOCAL_NETWORK_NO_LTE_COVERAGE = 122; - // Service unavailable; by located in roaming area + /** + * Service unavailable; located in roaming area + */ public static final int CODE_LOCAL_NETWORK_ROAMING = 123; - // Service unavailable; by IP changed + /** + * Service unavailable; IP changed + */ public static final int CODE_LOCAL_NETWORK_IP_CHANGED = 124; - // Service unavailable; other + /** + * Service unavailable; for an unspecified reason + */ public static final int CODE_LOCAL_SERVICE_UNAVAILABLE = 131; - // Service unavailable; IMS connection is lost (IMS is not registered) + /** + * Service unavailable; IMS is not registered + */ public static final int CODE_LOCAL_NOT_REGISTERED = 132; // IMS <-> Telephony - // Max call exceeded + /** + * Maximum number of simultaneous calls exceeded + */ public static final int CODE_LOCAL_CALL_EXCEEDED = 141; // IMS <- Telephony - // Call busy + /** + * The call is busy. + */ public static final int CODE_LOCAL_CALL_BUSY = 142; - // Call decline + /** + * The Call has been declined locally on this device. + */ public static final int CODE_LOCAL_CALL_DECLINE = 143; // IMS -> Telephony - // SRVCC is in progress + /** + * Can not complete call; an SRVCC is in progress. + */ public static final int CODE_LOCAL_CALL_VCC_ON_PROGRESSING = 144; - // Resource reservation is failed (QoS precondition) + /** + * Can not complete call; resource reservation is failed (QoS precondition) + */ public static final int CODE_LOCAL_CALL_RESOURCE_RESERVATION_FAILED = 145; - // 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 + /** + * VoLTE service can't be provided by the network or remote end, retry the call. + * Resolve the extra code provided in (EXTRA_CODE_CALL_RETRY_*) if the below code is set + */ public static final int CODE_LOCAL_CALL_CS_RETRY_REQUIRED = 146; - // Retry VoLTE call; VoLTE service can't be provided by the network temporarily + /** + * VoLTE service can't be provided by the network temporarily, retry the call. + */ public static final int CODE_LOCAL_CALL_VOLTE_RETRY_REQUIRED = 147; - // IMS call is already terminated (in TERMINATED state) + /** + * IMS call is already terminated (in TERMINATED state). + */ public static final int CODE_LOCAL_CALL_TERMINATED = 148; - // Handover not feasible + /** + * Call was disconnected because a handover is not feasible due to network conditions. + */ public static final int CODE_LOCAL_HO_NOT_FEASIBLE = 149; - /** + /* * TIMEOUT (IMS -> Telephony) */ - // 1xx waiting timer is expired after sending INVITE request (MO only) + /** + * 1xx waiting timer is expired after sending INVITE request (MO calls only) + */ public static final int CODE_TIMEOUT_1XX_WAITING = 201; - // 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 + /** + * User didn't 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 + */ public static final int CODE_TIMEOUT_NO_ANSWER = 202; - // 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 + /** + * 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 + */ public static final int CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE = 203; - //Call was blocked by call barring + /** + * The call was blocked by call barring configuration. + */ public static final int CODE_CALL_BARRED = 240; - //Call failures for FDN + /** + * The operation is restricted to fixed dialing numbers only. + */ public static final int CODE_FDN_BLOCKED = 241; - // Network does not accept the emergency call request because IMEI was used as identification - // and this capability is not supported by the network. + /** + * Network rejected the emergency call request because IMEI was used as identification + * and this capability is not supported by the network. + */ public static final int CODE_IMEI_NOT_ACCEPTED = 243; //STK CC errors + /** + * Stk Call Control modified DIAL request to USSD request. + */ public static final int CODE_DIAL_MODIFIED_TO_USSD = 244; + /** + * Stk Call Control modified DIAL request to SS request. + */ public static final int CODE_DIAL_MODIFIED_TO_SS = 245; + /** + * Stk Call Control modified DIAL request to DIAL with modified data. + */ public static final int CODE_DIAL_MODIFIED_TO_DIAL = 246; + /** + * Stk Call Control modified DIAL request to Video DIAL request. + */ public static final int CODE_DIAL_MODIFIED_TO_DIAL_VIDEO = 247; + /** + * Stk Call Control modified Video DIAL request to DIAL request. + */ public static final int CODE_DIAL_VIDEO_MODIFIED_TO_DIAL = 248; + /** + * Stk Call Control modified Video DIAL request to Video DIAL request. + */ public static final int CODE_DIAL_VIDEO_MODIFIED_TO_DIAL_VIDEO = 249; + /** + * Stk Call Control modified Video DIAL request to SS request. + */ public static final int CODE_DIAL_VIDEO_MODIFIED_TO_SS = 250; + /** + * Stk Call Control modified Video DIAL request to USSD request. + */ public static final int CODE_DIAL_VIDEO_MODIFIED_TO_USSD = 251; - /** + /* * STATUSCODE (SIP response code) (IMS -> Telephony) */ // 3xx responses - // SIP request is redirected + /** + * SIP 3xx response: SIP request is redirected + */ public static final int CODE_SIP_REDIRECTED = 321; // 4xx responses - // 400 : Bad Request + /** + * Sip 400 response : Bad Request + */ public static final int CODE_SIP_BAD_REQUEST = 331; - // 403 : Forbidden + /** + * Sip 403 response : Forbidden + */ public static final int CODE_SIP_FORBIDDEN = 332; - // 404 : Not Found + /** + * Sip 404 response : Not Found + */ public static final int CODE_SIP_NOT_FOUND = 333; - // 415 : Unsupported Media Type - // 416 : Unsupported URI Scheme - // 420 : Bad Extension + /** + * Not supported, because of one of the following: + * SIP response 415 : Unsupported Media Type, + * SIP response 416 : Unsupported URI Scheme, + * SIP response 420 : Bad Extension + */ public static final int CODE_SIP_NOT_SUPPORTED = 334; - // 408 : Request Timeout + /** + * SIP response 408 : Request Timeout. + */ public static final int CODE_SIP_REQUEST_TIMEOUT = 335; - // 480 : Temporarily Unavailable + /** + * SIP response 480 : Temporarily Unavailable + */ public static final int CODE_SIP_TEMPRARILY_UNAVAILABLE = 336; - // 484 : Address Incomplete + /** + * SIP response 484 : Address Incomplete + */ public static final int CODE_SIP_BAD_ADDRESS = 337; - // 486 : Busy Here - // 600 : Busy Everywhere + /** + * Returned a busy response, may be one of the following: + * SIP response 486 : Busy Here, + * SIP response 600 : Busy Everywhere + */ public static final int CODE_SIP_BUSY = 338; - // 487 : Request Terminated + /** + * SIP response 487 : Request Terminated + */ public static final int CODE_SIP_REQUEST_CANCELLED = 339; - // 406 : Not Acceptable - // 488 : Not Acceptable Here - // 606 : Not Acceptable + /** + * Received a not acceptable response, will be one of the following: + * SIP response 406 : Not Acceptable + * SIP response 488 : Not Acceptable Here + * SIP response 606 : Not Acceptable + */ public static final int CODE_SIP_NOT_ACCEPTABLE = 340; - // 410 : Gone - // 604 : Does Not Exist Anywhere + /** + * Received a not acceptable response, will be one of the following: + * SIP response 410 : Gone + * SIP response 604 : Does Not Exist Anywhere + */ public static final int CODE_SIP_NOT_REACHABLE = 341; - // Others + /** + * Received another unspecified error SIP response from the client. + */ public static final int CODE_SIP_CLIENT_ERROR = 342; - // 481 Transaction Does Not Exist + /** + * SIP response 481: Transaction Does Not Exist + */ public static final int CODE_SIP_TRANSACTION_DOES_NOT_EXIST = 343; // 5xx responses - // 501 : Server Internal Error + /** + * SIP response 501 : Server Internal Error + */ public static final int CODE_SIP_SERVER_INTERNAL_ERROR = 351; - // 503 : Service Unavailable + /** + * SIP response 503 : Service Unavailable + */ public static final int CODE_SIP_SERVICE_UNAVAILABLE = 352; - // 504 : Server Time-out + /** + * SIP response 504 : Server Time-out + */ public static final int CODE_SIP_SERVER_TIMEOUT = 353; - // Others + /** + * Received an unspecified SIP server error response. + */ public static final int CODE_SIP_SERVER_ERROR = 354; // 6xx responses - // 603 : Decline + /** + * 603 : Decline + */ public static final int CODE_SIP_USER_REJECTED = 361; - // Others + /** + * Unspecified 6xx error. + */ public static final int CODE_SIP_GLOBAL_ERROR = 362; - // Emergency failure + + /** + * Emergency call failed in the modem with a temporary fail cause and should be redialed on this + * slot. + */ public static final int CODE_EMERGENCY_TEMP_FAILURE = 363; + /** + * Emergency call failed in the modem with a permanent fail cause and should not be redialed on + * this slot. If there are any other slots available for emergency calling, try those. + */ public static final int CODE_EMERGENCY_PERM_FAILURE = 364; /** @@ -194,81 +332,239 @@ public final class ImsReasonInfo implements Parcelable { 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) */ - // Media resource initialization failed + /** + * Media resource initialization failed + */ public static final int CODE_MEDIA_INIT_FAILED = 401; - // RTP timeout (no audio / video traffic in the session) + /** + * RTP timeout (no audio / video traffic in the session) + */ public static final int CODE_MEDIA_NO_DATA = 402; - // Media is not supported; so dropped the call + /** + * Media is not supported; so dropped the call + */ public static final int CODE_MEDIA_NOT_ACCEPTABLE = 403; - // Unknown media related errors + /** + * Unspecified media related error. + */ public static final int CODE_MEDIA_UNSPECIFIED = 404; - /** + /* * USER */ // Telephony -> IMS - // User triggers the call end + /** + * User triggers the call to be terminated. + */ public static final int CODE_USER_TERMINATED = 501; - // No action while an incoming call is ringing + /** + * No action was taken while an incoming call was ringing. + */ public static final int CODE_USER_NOANSWER = 502; - // User ignores an incoming call + /** + * User ignored an incoming call. + */ public static final int CODE_USER_IGNORE = 503; - // User declines an incoming call + /** + * User declined an incoming call. + */ public static final int CODE_USER_DECLINE = 504; - // Device declines/ends a call due to low battery + /** + * Device declined/ended a call due to a low battery condition. + */ public static final int CODE_LOW_BATTERY = 505; - // Device declines call due to blacklisted call ID + /** + * Device declined a call due to a blacklisted caller ID. + */ public static final int CODE_BLACKLISTED_CALL_ID = 506; // IMS -> Telephony - // The call is terminated by the network or remote user + /** + * 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; /** - * Extra codes for the specific code value - * This value can be referred when the code is CODE_LOCAL_CALL_CS_RETRY_REQUIRED. - */ - // Try to connect CS call; normal - public static final int EXTRA_CODE_CALL_RETRY_NORMAL = 1; - // Try to connect CS call without the notification to user - public static final int EXTRA_CODE_CALL_RETRY_SILENT_REDIAL = 2; - // Try to connect CS call by the settings of the menu - public static final int EXTRA_CODE_CALL_RETRY_BY_SETTINGS = 3; + * 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 */ + /** + * UT is currently not supported on this device. + */ public static final int CODE_UT_NOT_SUPPORTED = 801; + /** + * UT services are currently not available on this device. + */ public static final int CODE_UT_SERVICE_UNAVAILABLE = 802; + /** + * The requested UT operation is not allowed. + */ public static final int CODE_UT_OPERATION_NOT_ALLOWED = 803; + /** + * The UT request resulted in a network error. + */ public static final int CODE_UT_NETWORK_ERROR = 804; + /** + * The password entered for UT operations does not match the stored password. + */ public static final int CODE_UT_CB_PASSWORD_MISMATCH = 821; //STK CC errors + /** + * Sim Toolkit Call Control modified the UT operation to a dial command. + */ public static final int CODE_UT_SS_MODIFIED_TO_DIAL = 822; + /** + * Sim Toolkit Call Control modified the UT operation to a USSD command. + */ public static final int CODE_UT_SS_MODIFIED_TO_USSD = 823; + /** + * Sim Toolkit Call Control modified the UT operation to another supplementary service command. + */ public static final int CODE_UT_SS_MODIFIED_TO_SS = 824; + /** + * Sim Toolkit Call Control modified the UT operation to a video call dial command. + */ public static final int CODE_UT_SS_MODIFIED_TO_DIAL_VIDEO = 825; + /**@hide*/ + @IntDef(value = { + CODE_UT_NOT_SUPPORTED, + CODE_UT_SERVICE_UNAVAILABLE, + CODE_UT_OPERATION_NOT_ALLOWED, + CODE_UT_NETWORK_ERROR, + CODE_UT_CB_PASSWORD_MISMATCH, + CODE_UT_SS_MODIFIED_TO_DIAL, + CODE_UT_SS_MODIFIED_TO_USSD, + CODE_UT_SS_MODIFIED_TO_SS, + CODE_UT_SS_MODIFIED_TO_DIAL_VIDEO + }, prefix = "CODE_UT_") + @Retention(RetentionPolicy.SOURCE) + public @interface UtReason {} + /** - * ECBM + * Emergency callback mode is not supported. */ public static final int CODE_ECBM_NOT_SUPPORTED = 901; /** - * Fail code used to indicate that Multi-endpoint is not supported by the Ims framework. + * Fail code used to indicate that Multi-endpoint is not supported by the IMS framework. */ public static final int CODE_MULTIENDPOINT_NOT_SUPPORTED = 902; /** - * Ims Registration error code + * IMS Registration error code */ public static final int CODE_REGISTRATION_ERROR = 1000; - /** + /* * CALL DROP error codes (Call could drop because of many reasons like Network not available, * handover, failed, etc) */ + /** + * MT call has ended due to a release from the network because the call was answered elsewhere. + */ + public static final int CODE_ANSWERED_ELSEWHERE = 1014; + + /** + * For MultiEndpoint - Call Pull request has failed. + */ + public static final int CODE_CALL_PULL_OUT_OF_SYNC = 1015; + + /** + * For MultiEndpoint - Call has been pulled from primary to secondary. + */ + public static final int CODE_CALL_END_CAUSE_CALL_PULL = 1016; /** * CALL DROP error code for the case when a device is ePDG capable and when the user is on an @@ -279,46 +575,45 @@ public final class ImsReasonInfo implements Parcelable { public static final int CODE_CALL_DROP_IWLAN_TO_LTE_UNAVAILABLE = 1100; /** - * MT call has ended due to a release from the network - * because the call was answered elsewhere + * For MultiEndPoint - Call was rejected elsewhere */ - public static final int CODE_ANSWERED_ELSEWHERE = 1014; + public static final int CODE_REJECTED_ELSEWHERE = 1017; /** - * For MultiEndpoint - Call Pull request has failed + * Supplementary services (HOLD/RESUME) failure error codes. + * Values for Supplemetary services failure - Failed, Cancelled and Re-Invite collision. */ - public static final int CODE_CALL_PULL_OUT_OF_SYNC = 1015; /** - * For MultiEndpoint - Call has been pulled from primary to secondary + * Supplementary Services (HOLD/RESUME) - the command failed. */ - public static final int CODE_CALL_END_CAUSE_CALL_PULL = 1016; - + public static final int CODE_SUPP_SVC_FAILED = 1201; /** - * Supplementary services (HOLD/RESUME) failure error codes. - * Values for Supplemetary services failure - Failed, Cancelled and Re-Invite collision. + * Supplementary Services (HOLD/RESUME) - the command was cancelled. */ - public static final int CODE_SUPP_SVC_FAILED = 1201; public static final int CODE_SUPP_SVC_CANCELLED = 1202; + /** + * Supplementary Services (HOLD/RESUME) - the command resulted in a re-invite collision. + */ public static final int CODE_SUPP_SVC_REINVITE_COLLISION = 1203; /** - * DPD Procedure received no response or send failed + * DPD Procedure received no response or send failed. */ public static final int CODE_IWLAN_DPD_FAILURE = 1300; /** - * Establishment of the ePDG Tunnel Failed + * Establishment of the ePDG Tunnel Failed. */ public static final int CODE_EPDG_TUNNEL_ESTABLISH_FAILURE = 1400; /** - * Re-keying of the ePDG Tunnel Failed; may not always result in teardown + * Re-keying of the ePDG Tunnel Failed; may not always result in teardown. */ public static final int CODE_EPDG_TUNNEL_REKEY_FAILURE = 1401; /** - * Connection to the packet gateway is lost + * Connection to the packet gateway is lost. */ public static final int CODE_EPDG_TUNNEL_LOST_CONNECTION = 1402; @@ -571,8 +866,10 @@ public final class ImsReasonInfo implements Parcelable { */ public static final int CODE_REJECT_ONGOING_CS_CALL = 1621; - /* OEM specific error codes. To be used by OEMs when they don't want to - reveal error code which would be replaced by ERROR_UNSPECIFIED */ + /* + * OEM specific 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 CODE_OEM_CAUSE_1 = 0xf001; public static final int CODE_OEM_CAUSE_2 = 0xf002; public static final int CODE_OEM_CAUSE_3 = 0xf003; @@ -597,6 +894,33 @@ public final class ImsReasonInfo implements Parcelable { = "Forbidden. Not Authorized for Service"; + /* + * Extra codes for the specific code value + * This value can be referred when the code is CODE_LOCAL_CALL_CS_RETRY_REQUIRED. + */ + /** + * An extra that may be populated when the {@link CODE_LOCAL_CALL_CS_RETRY_REQUIRED} result has + * been returned. + * <p> + * Try to connect the call using CS + */ + public static final int EXTRA_CODE_CALL_RETRY_NORMAL = 1; + /** + * An extra that may be populated when the {@link CODE_LOCAL_CALL_CS_RETRY_REQUIRED} result has + * been returned. + * <p> + * Try to connect the call using CS and do not notify the user. + */ + public static final int EXTRA_CODE_CALL_RETRY_SILENT_REDIAL = 2; + /** + * An extra that may be populated when the {@link CODE_LOCAL_CALL_CS_RETRY_REQUIRED} result has + * been returned. + * <p> + * Try to connect the call using CS by using the settings. + */ + public static final int EXTRA_CODE_CALL_RETRY_BY_SETTINGS = 3; + + // For main reason code /** @hide */ @UnsupportedAppUsage @@ -638,29 +962,28 @@ public final class ImsReasonInfo implements Parcelable { } /** - * + * @return an integer representing more information about the completion of an operation. */ public int getCode() { return mCode; } /** - * + * @return an optional OEM specified code that provides extra information. */ public int getExtraCode() { return mExtraCode; } /** - * + * @return an optional OEM specified string that provides extra information about the operation + * result. */ public String getExtraMessage() { return mExtraMessage; } /** - * Returns the string format of {@link ImsReasonInfo} - * * @return the string format of {@link ImsReasonInfo} */ public String toString() { diff --git a/telephony/java/android/telephony/ims/ImsSsData.java b/telephony/java/android/telephony/ims/ImsSsData.java index db5ba4784621..3a82517955ce 100644 --- a/telephony/java/android/telephony/ims/ImsSsData.java +++ b/telephony/java/android/telephony/ims/ImsSsData.java @@ -65,6 +65,17 @@ public final class ImsSsData implements Parcelable { public static final int SS_INCOMING_BARRING_DN = 21; public static final int SS_INCOMING_BARRING_ANONYMOUS = 22; + + /**@hide*/ + @IntDef(flag = true, prefix = {"SS_"}, value = { + SS_ACTIVATION, + SS_DEACTIVATION, + SS_INTERROGATION, + SS_REGISTRATION, + SS_ERASURE}) + @Retention(RetentionPolicy.SOURCE) + public @interface RequestType{} + //Supplementary Service Request Types public static final int SS_ACTIVATION = 0; public static final int SS_DEACTIVATION = 1; @@ -72,6 +83,17 @@ public final class ImsSsData implements Parcelable { public static final int SS_REGISTRATION = 3; public static final int SS_ERASURE = 4; + /**@hide*/ + @IntDef(flag = true, prefix = {"SS_"}, value = { + SS_ALL_TELE_AND_BEARER_SERVICES, + SS_ALL_TELESEVICES, + SS_TELEPHONY, + SS_ALL_DATA_TELESERVICES, + SS_SMS_SERVICES, + SS_ALL_TELESERVICES_EXCEPT_SMS}) + @Retention(RetentionPolicy.SOURCE) + public @interface TeleserviceType{} + // Supplementary Service Teleservice Type public static final int SS_ALL_TELE_AND_BEARER_SERVICES = 0; public static final int SS_ALL_TELESEVICES = 1; @@ -191,21 +213,6 @@ public final class ImsSsData implements Parcelable { @Retention(RetentionPolicy.SOURCE) public @interface ServiceType{} - /** @hide */ - @IntDef(flag = true, prefix = { "SERVICE_CLASS" }, value = { - SERVICE_CLASS_NONE, - SERVICE_CLASS_VOICE, - SERVICE_CLASS_DATA, - SERVICE_CLASS_FAX, - SERVICE_CLASS_SMS, - SERVICE_CLASS_DATA_CIRCUIT_SYNC, - SERVICE_CLASS_DATA_CIRCUIT_ASYNC, - SERVICE_CLASS_DATA_PACKET_ACCESS, - SERVICE_CLASS_DATA_PAD - }) - @Retention(RetentionPolicy.SOURCE) - public @interface ServiceClass{} - /** * The Service type of this Supplementary service. * @hide @@ -221,7 +228,7 @@ public final class ImsSsData implements Parcelable { * {@link #SS_ERASURE} * @hide */ - public final int requestType; + public final @RequestType int requestType; /** * Supplementary Service teleservice type: @@ -234,14 +241,14 @@ public final class ImsSsData implements Parcelable { * * @hide */ - public final int teleserviceType; + public final @TeleserviceType int teleserviceType; /** * Supplementary Service service class. * * @hide */ - public final @ServiceClass int serviceClass; + public final @ServiceClassFlags int serviceClass; /** * Result of Supplementary Service operation. Valid values are: @@ -285,7 +292,7 @@ public final class ImsSsData implements Parcelable { * @see #build() */ public Builder(@ServiceType int serviceType, int requestType, int teleserviceType, - @ServiceClass int serviceClass, int result) { + @ServiceClassFlags int serviceClass, int result) { mImsSsData = new ImsSsData(serviceType, requestType, teleserviceType, serviceClass, result); } @@ -294,7 +301,7 @@ public final class ImsSsData implements Parcelable { * Set the array of {@link ImsSsInfo}s that are associated with this supplementary service * data. */ - public Builder setSuppServiceInfo(@NonNull ImsSsInfo[] imsSsInfos) { + public @NonNull Builder setSuppServiceInfo(@NonNull ImsSsInfo[] imsSsInfos) { mImsSsData.mImsSsInfo = imsSsInfos; return this; } @@ -303,7 +310,8 @@ public final class ImsSsData implements Parcelable { * Set the array of {@link ImsCallForwardInfo}s that are associated with this supplementary * service data. */ - public Builder setCallForwardingInfo(@NonNull ImsCallForwardInfo[] imsCallForwardInfos) { + public @NonNull Builder setCallForwardingInfo( + @NonNull ImsCallForwardInfo[] imsCallForwardInfos) { mImsSsData.mCfInfo = imsCallForwardInfos; return this; } @@ -311,7 +319,7 @@ public final class ImsSsData implements Parcelable { /** * @return an {@link ImsSsData} containing optional parameters. */ - public ImsSsData build() { + public @NonNull ImsSsData build() { return mImsSsData; } } @@ -337,7 +345,7 @@ public final class ImsSsData implements Parcelable { * success, or ImsReasonInfo code if the result is a failure. */ public ImsSsData(@ServiceType int serviceType, int requestType, int teleserviceType, - @ServiceClass int serviceClass, int result) { + @ServiceClassFlags int serviceClass, int result) { this.serviceType = serviceType; this.requestType = requestType; this.teleserviceType = teleserviceType; @@ -449,14 +457,9 @@ public final class ImsSsData implements Parcelable { } /** - * Supplementary Service request Type: - * {@link #SS_ACTIVATION), - * {@link #SS_DEACTIVATION}, - * {@link #SS_INTERROGATION}, - * {@link #SS_REGISTRATION}, - * {@link #SS_ERASURE} + * Supplementary Service request Type. */ - public int getRequestType() { + public @RequestType int getRequestType() { return requestType; } @@ -468,31 +471,25 @@ public final class ImsSsData implements Parcelable { } /** - * Supplementary Service teleservice type: - * {@link #SS_ALL_TELE_AND_BEARER_SERVICES}, - * {@link #SS_ALL_TELESEVICES}, - * {@link #SS_TELEPHONY}, - * {@link #SS_ALL_DATA_TELESERVICES}, - * {@link #SS_SMS_SERVICES}, - * {@link #SS_ALL_TELESERVICES_EXCEPT_SMS} + * Supplementary Service teleservice type. */ - public int getTeleserviceType() { + public @TeleserviceType int getTeleserviceType() { return teleserviceType; } /** * Supplementary Service service class. */ - public @ServiceClass int getServiceClass() { + public @ServiceClassFlags int getServiceClass() { return serviceClass; } /** * Result of Supplementary Service operation. Valid values are: * {@link #RESULT_SUCCESS} if the result is success, or - * {@link ImsReasonInfo} CODE_* code if the result is a failure. + * {@link ImsReasonInfo.UtReason} code if the result is a failure. */ - public int getResult() { + public @ImsReasonInfo.UtReason int getResult() { return result; } diff --git a/telephony/java/android/telephony/ims/ImsSsInfo.java b/telephony/java/android/telephony/ims/ImsSsInfo.java index 0af6e6298c87..031f9e10175b 100644 --- a/telephony/java/android/telephony/ims/ImsSsInfo.java +++ b/telephony/java/android/telephony/ims/ImsSsInfo.java @@ -82,6 +82,7 @@ public final class ImsSsInfo implements Parcelable { */ public static final int SERVICE_PROVISIONED = 1; + /**@hide*/ @IntDef(value = { CLIR_OUTGOING_DEFAULT, CLIR_OUTGOING_INVOCATION, @@ -141,6 +142,7 @@ public final class ImsSsInfo implements Parcelable { */ public static final int CLIR_STATUS_TEMPORARILY_ALLOWED = 4; + /**@hide*/ @IntDef(value = { CLIR_STATUS_NOT_PROVISIONED, CLIR_STATUS_PROVISIONED_PERMANENT, @@ -184,7 +186,7 @@ public final class ImsSsInfo implements Parcelable { * Set the ICB number for IMS call barring. * @param number The number in E.164 international format. */ - public Builder setIncomingCommunicationBarringNumber(@NonNull String number) { + public @NonNull Builder setIncomingCommunicationBarringNumber(@NonNull String number) { mImsSsInfo.mIcbNum = number; return this; } @@ -192,7 +194,7 @@ public final class ImsSsInfo implements Parcelable { /** * Set the provisioning status for a Supplementary Service interrogation response. */ - public Builder setProvisionStatus(@ServiceProvisionStatus int provisionStatus) { + public @NonNull Builder setProvisionStatus(@ServiceProvisionStatus int provisionStatus) { mImsSsInfo.mProvisionStatus = provisionStatus; return this; } @@ -201,7 +203,7 @@ public final class ImsSsInfo implements Parcelable { * Set the Calling Line Identification Restriction (CLIR) status for a supplementary service * interrogation response. */ - public Builder setClirInterrogationStatus(@ClirInterrogationStatus int status) { + public @NonNull Builder setClirInterrogationStatus(@ClirInterrogationStatus int status) { mImsSsInfo.mClirInterrogationStatus = status; return this; } @@ -209,7 +211,7 @@ public final class ImsSsInfo implements Parcelable { /** * Set the Calling line identification Restriction (CLIR) state for outgoing calls. */ - public Builder setClirOutgoingState(@ClirOutgoingState int state) { + public @NonNull Builder setClirOutgoingState(@ClirOutgoingState int state) { mImsSsInfo.mClirOutgoingState = state; return this; } @@ -217,7 +219,7 @@ public final class ImsSsInfo implements Parcelable { /** * @return a built {@link ImsSsInfo} containing optional the parameters that were set. */ - public ImsSsInfo build() { + public @NonNull ImsSsInfo build() { return mImsSsInfo; } } diff --git a/telephony/java/android/telephony/ims/RcsManager.java b/telephony/java/android/telephony/ims/RcsManager.java new file mode 100644 index 000000000000..d50b516b8754 --- /dev/null +++ b/telephony/java/android/telephony/ims/RcsManager.java @@ -0,0 +1,36 @@ +/* + * 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.ims; + +import android.annotation.SystemService; +import android.content.Context; + +/** + * The manager class for RCS related utilities. + * @hide + */ +@SystemService(Context.TELEPHONY_RCS_SERVICE) +public class RcsManager { + + private static final RcsMessageStore sRcsMessageStoreInstance = new RcsMessageStore(); + + /** + * Returns an instance of RcsMessageStore. + */ + public RcsMessageStore getRcsMessageStore() { + return sRcsMessageStoreInstance; + } +} diff --git a/telephony/java/android/telephony/rcs/RcsManager.java b/telephony/java/android/telephony/ims/RcsMessageStore.java index 0ef4e1552085..c89c0bebb1a1 100644 --- a/telephony/java/android/telephony/rcs/RcsManager.java +++ b/telephony/java/android/telephony/ims/RcsMessageStore.java @@ -14,24 +14,20 @@ * limitations under the License. */ -package android.telephony.rcs; +package android.telephony.ims; -import android.annotation.SystemService; -import android.content.Context; import android.os.RemoteException; import android.os.ServiceManager; import android.telephony.Rlog; - -import com.android.internal.telephony.rcs.IRcs; +import android.telephony.ims.aidl.IRcs; /** - * RcsManager is the application interface to RcsProvider and provides access methods to + * RcsMessageStore is the application interface to RcsProvider and provides access methods to * RCS related database tables. * @hide - TODO make this public */ -@SystemService(Context.TELEPHONY_RCS_SERVICE) -public class RcsManager { - private static final String TAG = "RcsManager"; +public class RcsMessageStore { + private static final String TAG = "RcsMessageStore"; private static final boolean VDBG = false; /** diff --git a/telephony/java/android/telephony/ims/RcsThread.aidl b/telephony/java/android/telephony/ims/RcsThread.aidl new file mode 100644 index 000000000000..79d473266272 --- /dev/null +++ b/telephony/java/android/telephony/ims/RcsThread.aidl @@ -0,0 +1,20 @@ +/* + * + * Copyright 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 RcsThread;
\ No newline at end of file diff --git a/telephony/java/android/telephony/rcs/RcsThread.java b/telephony/java/android/telephony/ims/RcsThread.java index 83eb973ec12b..b7f440d94583 100644 --- a/telephony/java/android/telephony/rcs/RcsThread.java +++ b/telephony/java/android/telephony/ims/RcsThread.java @@ -14,14 +14,13 @@ * limitations under the License. */ -package android.telephony.rcs; +package android.telephony.ims; import android.os.Parcel; import android.os.Parcelable; import android.os.RemoteException; import android.os.ServiceManager; - -import com.android.internal.telephony.rcs.IRcs; +import android.telephony.ims.aidl.IRcs; /** * RcsThread represents a single RCS conversation thread. It holds messages that were sent and diff --git a/telephony/java/com/android/internal/telephony/rcs/IRcs.aidl b/telephony/java/android/telephony/ims/aidl/IRcs.aidl index 4c289acd15ef..b2e2fadca138 100644 --- a/telephony/java/com/android/internal/telephony/rcs/IRcs.aidl +++ b/telephony/java/android/telephony/ims/aidl/IRcs.aidl @@ -14,10 +14,14 @@ * limitations under the License. */ -package com.android.internal.telephony.rcs; +package android.telephony.ims.aidl; +/** + * RPC definition between RCS storage APIs and phone process. + * {@hide} + */ interface IRcs { - // RcsManager APIs + // RcsMessageStore APIs void deleteThread(int threadId); // RcsThread APIs diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java index 0abe45ce448c..13539b855de2 100644 --- a/telephony/java/com/android/internal/telephony/CallerInfo.java +++ b/telephony/java/com/android/internal/telephony/CallerInfo.java @@ -17,6 +17,7 @@ package com.android.internal.telephony; import android.annotation.UnsupportedAppUsage; +import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.database.Cursor; @@ -32,15 +33,15 @@ import android.provider.ContactsContract.PhoneLookup; import android.provider.ContactsContract.RawContacts; import android.telephony.PhoneNumberUtils; import android.telephony.Rlog; +import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; import android.text.TextUtils; import android.util.Log; -import com.android.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder; import com.android.i18n.phonenumbers.NumberParseException; import com.android.i18n.phonenumbers.PhoneNumberUtil; import com.android.i18n.phonenumbers.Phonenumber.PhoneNumber; -import android.telephony.SubscriptionManager; +import com.android.i18n.phonenumbers.geocoding.PhoneNumberOfflineGeocoder; import java.util.Locale; @@ -112,6 +113,9 @@ public class CallerInfo { public Uri contactRefUri; public String lookupKey; + public ComponentName preferredPhoneAccountComponent; + public String preferredPhoneAccountId; + public long userType; /** @@ -264,6 +268,17 @@ public class CallerInfo { info.contactDisplayPhotoUri = null; } + columnIndex = cursor.getColumnIndex(Data.PREFERRED_PHONE_ACCOUNT_COMPONENT_NAME); + if ((columnIndex != -1) && (cursor.getString(columnIndex) != null)) { + info.preferredPhoneAccountComponent = + ComponentName.unflattenFromString(cursor.getString(columnIndex)); + } + + columnIndex = cursor.getColumnIndex(Data.PREFERRED_PHONE_ACCOUNT_ID); + if ((columnIndex != -1) && (cursor.getString(columnIndex) != null)) { + info.preferredPhoneAccountId = cursor.getString(columnIndex); + } + // look for the custom ringtone, create from the string stored // in the database. // An empty string ("") in the database indicates a silent ringtone, diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java index b0c875e0c6f2..0fdca5d24a20 100644 --- a/telephony/java/com/android/internal/telephony/DctConstants.java +++ b/telephony/java/com/android/internal/telephony/DctConstants.java @@ -79,10 +79,7 @@ public class DctConstants { 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 class DctConstants { 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 442fc34d4b71..40c7a9ae1f7b 100644 --- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -53,5 +53,6 @@ oneway interface IPhoneStateListener { 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 f9db4b0afd12..65d1a920a324 100755 --- a/telephony/java/com/android/internal/telephony/ISub.aidl +++ b/telephony/java/com/android/internal/telephony/ISub.aidl @@ -210,6 +210,10 @@ interface ISub { */ 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 8a1fb7bc8ff0..99d362a84924 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -56,6 +56,7 @@ import com.android.internal.telephony.OperatorInfo; import java.util.List; import java.util.Map; +import android.telephony.UiccCardInfo; import android.telephony.UiccSlotInfo; /** @@ -1337,18 +1338,6 @@ interface ITelephony { 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 @@ interface ITelephony { * 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 @@ -1482,6 +1474,30 @@ interface ITelephony { SignalStrength getSignalStrength(int subId); /** + * Get the card ID of the default eUICC card. If there is no eUICC, returns + * {@link #INVALID_CARD_ID}. + * + * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} + * + * @param subId subscription ID used for authentication + * @param callingPackage package making the call + * @return card ID of the default eUICC card. + * @hide + */ + 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/test-base/Android.bp b/test-base/Android.bp index 4d765d3e5f3f..157609cec09c 100644 --- a/test-base/Android.bp +++ b/test-base/Android.bp @@ -37,8 +37,6 @@ java_sdk_library { "junit.framework", ], - droiddoc_options: ["-stubsourceonly"], - metalava_enabled: false, compile_dex: true, } diff --git a/test-runner/Android.bp b/test-runner/Android.bp index 0a0d50cc330c..db5053eeb903 100644 --- a/test-runner/Android.bp +++ b/test-runner/Android.bp @@ -40,8 +40,6 @@ java_sdk_library { "junit.textui", ], - droiddoc_options: ["-stubsourceonly"], - metalava_enabled: false, compile_dex: true } diff --git a/test-runner/api/current.txt b/test-runner/api/current.txt index 1170eb53ab7f..4ba1b8f2fdc1 100644 --- a/test-runner/api/current.txt +++ b/test-runner/api/current.txt @@ -125,8 +125,8 @@ package android.test { method public static void assertEquals(double[], double[]); method public static void assertEquals(java.lang.String, java.lang.Object[], java.lang.Object[]); method public static void assertEquals(java.lang.Object[], java.lang.Object[]); - method public static void assertEquals(java.lang.String, java.util.Set<? extends java.lang.Object>, java.util.Set<? extends java.lang.Object>); - method public static void assertEquals(java.util.Set<? extends java.lang.Object>, java.util.Set<? extends java.lang.Object>); + method public static void assertEquals(java.lang.String, java.util.Set<?>, java.util.Set<?>); + method public static void assertEquals(java.util.Set<?>, java.util.Set<?>); method public static java.util.regex.MatchResult assertMatchesRegex(java.lang.String, java.lang.String, java.lang.String); method public static java.util.regex.MatchResult assertMatchesRegex(java.lang.String, java.lang.String); method public static void assertNotContainsRegex(java.lang.String, java.lang.String, java.lang.String); diff --git a/tests/RcsTests/src/com/android/tests/rcs/RcsManagerTest.java b/tests/RcsTests/src/com/android/tests/rcs/RcsMessageStoreTest.java index 7f5f03e0d5a4..290e04ce8abb 100644 --- a/tests/RcsTests/src/com/android/tests/rcs/RcsManagerTest.java +++ b/tests/RcsTests/src/com/android/tests/rcs/RcsMessageStoreTest.java @@ -16,17 +16,17 @@ package com.android.tests.rcs; import android.support.test.runner.AndroidJUnit4; -import android.telephony.rcs.RcsManager; +import android.telephony.ims.RcsMessageStore; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) -public class RcsManagerTest { +public class RcsMessageStoreTest { //TODO(sahinc): Add meaningful tests once we have more of the implementation in place @Test public void testDeleteThreadDoesntCrash() { - RcsManager mRcsManager = new RcsManager(); - mRcsManager.deleteThread(0); + RcsMessageStore mRcsMessageStore = new RcsMessageStore(); + mRcsMessageStore.deleteThread(0); } } diff --git a/tests/net/java/android/net/NetworkCapabilitiesTest.java b/tests/net/java/android/net/NetworkCapabilitiesTest.java index 50aef1d24faf..84f735985b0d 100644 --- a/tests/net/java/android/net/NetworkCapabilitiesTest.java +++ b/tests/net/java/android/net/NetworkCapabilitiesTest.java @@ -474,7 +474,7 @@ public class NetworkCapabilitiesTest { new StringNetworkSpecifier("specs")); try { nc2.addTransportType(TRANSPORT_WIFI); - fail("Cannot set NetworkSpecifier on a NetworkCapability with multiple transports!"); + fail("Cannot set a second TransportType of a network which has a NetworkSpecifier!"); } catch (IllegalStateException expected) { // empty } @@ -500,16 +500,23 @@ public class NetworkCapabilitiesTest { // empty }); NetworkCapabilities nc2 = new NetworkCapabilities(); + // new TransportInfo so that object is not #equals to nc1's TransportInfo (that's where + // combine fails) nc2.setTransportInfo(new TransportInfo() { // empty }); try { nc1.combineCapabilities(nc2); - fail("Should not be able to combine NetworkCaabilities which contain TransportInfos"); + fail("Should not be able to combine NetworkCabilities which contain TransportInfos"); } catch (IllegalStateException expected) { // empty } + + // verify that can combine with identical TransportInfo objects + NetworkCapabilities nc3 = new NetworkCapabilities(); + nc3.setTransportInfo(nc1.getTransportInfo()); + nc1.combineCapabilities(nc3); } private void assertEqualsThroughMarshalling(NetworkCapabilities netCap) { diff --git a/tests/net/java/android/net/apf/ApfTest.java b/tests/net/java/android/net/apf/ApfTest.java index 983802035bfb..151b5594216a 100644 --- a/tests/net/java/android/net/apf/ApfTest.java +++ b/tests/net/java/android/net/apf/ApfTest.java @@ -46,6 +46,7 @@ import android.support.test.runner.AndroidJUnit4; import android.system.ErrnoException; import android.system.Os; import android.text.format.DateUtils; +import android.util.Log; import com.android.frameworks.tests.net.R; import com.android.internal.util.HexDump; import java.io.File; @@ -89,6 +90,7 @@ public class ApfTest { System.loadLibrary("frameworksnettestsjni"); } + private static final String TAG = "ApfTest"; // Expected return codes from APF interpreter. private static final int PASS = 1; private static final int DROP = 0; @@ -869,6 +871,37 @@ public class ApfTest { } } + /** + * Generate APF program, run pcap file though APF filter, then check all the packets in the file + * should be dropped. + */ + @Test + public void testApfFilterPcapFile() throws Exception { + final byte[] MOCK_PCAP_IPV4_ADDR = {(byte) 172, 16, 7, (byte) 151}; + String pcapFilename = stageFile(R.raw.apfPcap); + MockIpClientCallback ipClientCallback = new MockIpClientCallback(); + LinkAddress link = new LinkAddress(InetAddress.getByAddress(MOCK_PCAP_IPV4_ADDR), 16); + LinkProperties lp = new LinkProperties(); + lp.addLinkAddress(link); + + ApfConfiguration config = getDefaultConfig(); + ApfCapabilities MOCK_APF_PCAP_CAPABILITIES = new ApfCapabilities(4, 1700, ARPHRD_ETHER); + config.apfCapabilities = MOCK_APF_PCAP_CAPABILITIES; + config.multicastFilter = DROP_MULTICAST; + config.ieee802_3Filter = DROP_802_3_FRAMES; + TestApfFilter apfFilter = new TestApfFilter(mContext, config, ipClientCallback, mLog); + apfFilter.setLinkProperties(lp); + byte[] program = ipClientCallback.getApfProgram(); + byte[] data = new byte[ApfFilter.Counter.totalSize()]; + final boolean result; + + result = dropsAllPackets(program, data, pcapFilename); + Log.i(TAG, "testApfFilterPcapFile(): Data counters: " + HexDump.toHexString(data, false)); + + assertTrue("Failed to drop all packets by filter. \nAPF counters:" + + HexDump.toHexString(data, false), result); + } + private class MockIpClientCallback extends IpClient.Callback { private final ConditionVariable mGotApfProgram = new ConditionVariable(); private byte[] mLastApfProgram; @@ -1015,12 +1048,17 @@ public class ApfTest { 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. @@ -1366,10 +1404,16 @@ public class ApfTest { 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()); @@ -1398,19 +1442,20 @@ public class ApfTest { 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(); } @@ -1706,6 +1751,14 @@ public class ApfTest { private native static boolean compareBpfApf(String filter, String pcap_filename, byte[] apf_program); + + /** + * Open packet capture file {@code pcapFilename} and run it through APF filter. Then + * checks whether all the packets are dropped and populates data[] {@code data} with + * the APF counters. + */ + private native static boolean dropsAllPackets(byte[] program, byte[] data, String pcapFilename); + @Test public void testBroadcastAddress() throws Exception { assertEqualsIp("255.255.255.255", ApfFilter.ipv4BroadcastAddress(IPV4_ANY_HOST_ADDR, 0)); diff --git a/tests/net/java/android/net/dhcp/DhcpServerTest.java b/tests/net/java/android/net/dhcp/DhcpServerTest.java index df34c7310b63..ab9bd84b05cb 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 android.net.dhcp.DhcpPacket.INADDR_BROADCAST; 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.InvalidAddressException; 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 @@ import java.util.Set; 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 @@ public class DhcpServerTest { .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 cff0b5469d47..2c675c68a076 100644 --- a/tests/net/java/android/net/ip/IpServerTest.java +++ b/tests/net/java/android/net/ip/IpServerTest.java @@ -404,7 +404,7 @@ public class IpServerTest { 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 80818120fa3c..e6b43d286a3d 100644 --- a/tests/net/java/com/android/server/connectivity/TetheringTest.java +++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java @@ -71,7 +71,6 @@ import android.net.MacAddress; import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkInfo; -import android.net.NetworkRequest; import android.net.NetworkState; import android.net.NetworkUtils; import android.net.RouteInfo; @@ -130,10 +129,6 @@ public class TetheringTest { private static final String TEST_USB_IFNAME = "test_rndis0"; private static final String TEST_WLAN_IFNAME = "test_wlan0"; - // Actual contents of the request don't matter for this test. The lack of - // any specific TRANSPORT_* is sufficient to identify this request. - private static final NetworkRequest mDefaultRequest = new NetworkRequest.Builder().build(); - @Mock private ApplicationInfo mApplicationInfo; @Mock private Context mContext; @Mock private INetworkManagementService mNMService; @@ -245,7 +240,7 @@ public class TetheringTest { } @Override - public DhcpServer makeDhcpServer(Looper looper, InterfaceParams iface, + public DhcpServer makeDhcpServer(Looper looper, String ifName, DhcpServingParams params, SharedLog log) { return mDhcpServer; } @@ -257,11 +252,6 @@ public class TetheringTest { isTetheringSupportedCalls++; return true; } - - @Override - public NetworkRequest getDefaultNetworkRequest() { - return mDefaultRequest; - } } private static NetworkState buildMobileUpstreamState(boolean withIPv4, boolean withIPv6, @@ -496,7 +486,7 @@ public class TetheringTest { TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_LOCAL_ONLY); verifyNoMoreInteractions(mWifiManager); verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_LOCAL_ONLY); - verify(mUpstreamNetworkMonitor, times(1)).start(any(NetworkRequest.class)); + verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks(); // TODO: Figure out why this isn't exactly once, for sendTetherStateChangedBroadcast(). assertTrue(1 <= mTetheringDependencies.isTetheringSupportedCalls); @@ -730,7 +720,7 @@ public class TetheringTest { TEST_WLAN_IFNAME, WifiManager.IFACE_IP_MODE_TETHERED); verifyNoMoreInteractions(mWifiManager); verifyTetheringBroadcast(TEST_WLAN_IFNAME, EXTRA_ACTIVE_TETHER); - verify(mUpstreamNetworkMonitor, times(1)).start(any(NetworkRequest.class)); + verify(mUpstreamNetworkMonitor, times(1)).startObserveAllNetworks(); // In tethering mode, in the default configuration, an explicit request // for a mobile network is also made. verify(mUpstreamNetworkMonitor, times(1)).registerMobileNetworkRequest(); diff --git a/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java b/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java index a22cbd4c95d8..0afd607d1457 100644 --- a/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java +++ b/tests/net/java/com/android/server/connectivity/tethering/UpstreamNetworkMonitorTest.java @@ -24,6 +24,7 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN; import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; import static android.net.NetworkCapabilities.TRANSPORT_WIFI; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -53,7 +54,6 @@ import android.net.NetworkCapabilities; import android.net.NetworkRequest; import android.net.NetworkState; import android.net.util.SharedLog; - import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; @@ -65,7 +65,6 @@ import org.junit.Before; import org.junit.runner.RunWith; import org.junit.Test; import org.mockito.Mock; -import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import java.util.ArrayList; @@ -126,7 +125,7 @@ public class UpstreamNetworkMonitorTest { } @Test - public void testDoesNothingBeforeStarted() { + public void testDoesNothingBeforeTrackDefaultAndStarted() throws Exception { assertTrue(mCM.hasNoCallbacks()); assertFalse(mUNM.mobileNetworkRequested()); @@ -138,37 +137,40 @@ public class UpstreamNetworkMonitorTest { @Test public void testDefaultNetworkIsTracked() throws Exception { - assertEquals(0, mCM.trackingDefault.size()); + assertTrue(mCM.hasNoCallbacks()); + mUNM.startTrackDefaultNetwork(mDefaultRequest); - mUNM.start(mDefaultRequest); + mUNM.startObserveAllNetworks(); assertEquals(1, mCM.trackingDefault.size()); mUNM.stop(); - assertTrue(mCM.hasNoCallbacks()); + assertTrue(mCM.onlyHasDefaultCallbacks()); } @Test public void testListensForAllNetworks() throws Exception { assertTrue(mCM.listening.isEmpty()); - mUNM.start(mDefaultRequest); + mUNM.startTrackDefaultNetwork(mDefaultRequest); + mUNM.startObserveAllNetworks(); assertFalse(mCM.listening.isEmpty()); assertTrue(mCM.isListeningForAll()); mUNM.stop(); - assertTrue(mCM.hasNoCallbacks()); + assertTrue(mCM.onlyHasDefaultCallbacks()); } @Test public void testCallbacksRegistered() { - mUNM.start(mDefaultRequest); - verify(mCM, times(1)).registerNetworkCallback( - any(NetworkRequest.class), any(NetworkCallback.class), any(Handler.class)); + mUNM.startTrackDefaultNetwork(mDefaultRequest); verify(mCM, times(1)).requestNetwork( eq(mDefaultRequest), any(NetworkCallback.class), any(Handler.class)); + mUNM.startObserveAllNetworks(); + verify(mCM, times(1)).registerNetworkCallback( + any(NetworkRequest.class), any(NetworkCallback.class), any(Handler.class)); mUNM.stop(); - verify(mCM, times(2)).unregisterNetworkCallback(any(NetworkCallback.class)); + verify(mCM, times(1)).unregisterNetworkCallback(any(NetworkCallback.class)); } @Test @@ -176,7 +178,7 @@ public class UpstreamNetworkMonitorTest { assertFalse(mUNM.mobileNetworkRequested()); assertEquals(0, mCM.requested.size()); - mUNM.start(mDefaultRequest); + mUNM.startObserveAllNetworks(); assertFalse(mUNM.mobileNetworkRequested()); assertEquals(0, mCM.requested.size()); @@ -199,11 +201,9 @@ public class UpstreamNetworkMonitorTest { assertFalse(mUNM.mobileNetworkRequested()); assertEquals(0, mCM.requested.size()); - mUNM.start(mDefaultRequest); + mUNM.startObserveAllNetworks(); verify(mCM, times(1)).registerNetworkCallback( any(NetworkRequest.class), any(NetworkCallback.class), any(Handler.class)); - verify(mCM, times(1)).requestNetwork( - eq(mDefaultRequest), any(NetworkCallback.class), any(Handler.class)); assertFalse(mUNM.mobileNetworkRequested()); assertEquals(0, mCM.requested.size()); @@ -227,7 +227,7 @@ public class UpstreamNetworkMonitorTest { assertTrue(mCM.isDunRequested()); mUNM.stop(); - verify(mCM, times(3)).unregisterNetworkCallback(any(NetworkCallback.class)); + verify(mCM, times(2)).unregisterNetworkCallback(any(NetworkCallback.class)); verifyNoMoreInteractions(mCM); } @@ -237,7 +237,7 @@ public class UpstreamNetworkMonitorTest { assertFalse(mUNM.mobileNetworkRequested()); assertEquals(0, mCM.requested.size()); - mUNM.start(mDefaultRequest); + mUNM.startObserveAllNetworks(); assertFalse(mUNM.mobileNetworkRequested()); assertEquals(0, mCM.requested.size()); @@ -257,7 +257,7 @@ public class UpstreamNetworkMonitorTest { @Test public void testUpdateMobileRequiresDun() throws Exception { - mUNM.start(mDefaultRequest); + mUNM.startObserveAllNetworks(); // Test going from no-DUN to DUN correctly re-registers callbacks. mUNM.updateMobileRequiresDun(false); @@ -285,7 +285,8 @@ public class UpstreamNetworkMonitorTest { final Collection<Integer> preferredTypes = new ArrayList<>(); preferredTypes.add(TYPE_WIFI); - mUNM.start(mDefaultRequest); + mUNM.startTrackDefaultNetwork(mDefaultRequest); + mUNM.startObserveAllNetworks(); // There are no networks, so there is nothing to select. assertSatisfiesLegacyType(TYPE_NONE, mUNM.selectPreferredUpstreamType(preferredTypes)); @@ -350,7 +351,8 @@ public class UpstreamNetworkMonitorTest { @Test public void testGetCurrentPreferredUpstream() throws Exception { - mUNM.start(mDefaultRequest); + mUNM.startTrackDefaultNetwork(mDefaultRequest); + mUNM.startObserveAllNetworks(); mUNM.updateMobileRequiresDun(false); // [0] Mobile connects, DUN not required -> mobile selected. @@ -389,7 +391,8 @@ public class UpstreamNetworkMonitorTest { @Test public void testLocalPrefixes() throws Exception { - mUNM.start(mDefaultRequest); + mUNM.startTrackDefaultNetwork(mDefaultRequest); + mUNM.startObserveAllNetworks(); // [0] Test minimum set of local prefixes. Set<IpPrefix> local = mUNM.getLocalPrefixes(); @@ -521,11 +524,19 @@ public class UpstreamNetworkMonitorTest { } boolean hasNoCallbacks() { - return allCallbacks.isEmpty() && - trackingDefault.isEmpty() && - listening.isEmpty() && - requested.isEmpty() && - legacyTypeMap.isEmpty(); + return allCallbacks.isEmpty() + && trackingDefault.isEmpty() + && listening.isEmpty() + && requested.isEmpty() + && legacyTypeMap.isEmpty(); + } + + boolean onlyHasDefaultCallbacks() { + return (allCallbacks.size() == 1) + && (trackingDefault.size() == 1) + && listening.isEmpty() + && requested.isEmpty() + && legacyTypeMap.isEmpty(); } boolean isListeningForAll() { diff --git a/tests/net/jni/apf_jni.cpp b/tests/net/jni/apf_jni.cpp index 1ea9e274ab9e..4222adf9e06b 100644 --- a/tests/net/jni/apf_jni.cpp +++ b/tests/net/jni/apf_jni.cpp @@ -21,37 +21,40 @@ #include <stdlib.h> #include <string> #include <utils/Log.h> +#include <vector> #include "apf_interpreter.h" +#include "nativehelper/scoped_primitive_array.h" #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) // JNI function acting as simply call-through to native APF interpreter. static jint com_android_server_ApfTest_apfSimulate( - JNIEnv* env, jclass, jbyteArray program, jbyteArray packet, - jbyteArray data, jint filter_age) { - uint8_t* program_raw = (uint8_t*)env->GetByteArrayElements(program, nullptr); - uint8_t* packet_raw = (uint8_t*)env->GetByteArrayElements(packet, nullptr); - uint8_t* data_raw = (uint8_t*)(data ? env->GetByteArrayElements(data, nullptr) : nullptr); - uint32_t program_len = env->GetArrayLength(program); - uint32_t packet_len = env->GetArrayLength(packet); - uint32_t data_len = data ? env->GetArrayLength(data) : 0; - - // Merge program and data into a single buffer. - uint8_t* program_and_data = (uint8_t*)malloc(program_len + data_len); - memcpy(program_and_data, program_raw, program_len); - memcpy(program_and_data + program_len, data_raw, data_len); + JNIEnv* env, jclass, jbyteArray jprogram, jbyteArray jpacket, + jbyteArray jdata, jint filter_age) { + + ScopedByteArrayRO packet(env, jpacket); + uint32_t packet_len = (uint32_t)packet.size(); + uint32_t program_len = env->GetArrayLength(jprogram); + uint32_t data_len = jdata ? env->GetArrayLength(jdata) : 0; + std::vector<uint8_t> buf(program_len + data_len, 0); + + env->GetByteArrayRegion(jprogram, 0, program_len, reinterpret_cast<jbyte*>(buf.data())); + if (jdata) { + // Merge program and data into a single buffer. + env->GetByteArrayRegion(jdata, 0, data_len, + reinterpret_cast<jbyte*>(buf.data() + program_len)); + } jint result = - accept_packet(program_and_data, program_len, program_len + data_len, - packet_raw, packet_len, filter_age); - if (data) { - memcpy(data_raw, program_and_data + program_len, data_len); - env->ReleaseByteArrayElements(data, (jbyte*)data_raw, 0 /* copy back */); - } - free(program_and_data); - env->ReleaseByteArrayElements(packet, (jbyte*)packet_raw, JNI_ABORT); - env->ReleaseByteArrayElements(program, (jbyte*)program_raw, JNI_ABORT); + accept_packet(buf.data(), program_len, program_len + data_len, + reinterpret_cast<const uint8_t*>(packet.get()), packet_len, filter_age); + + if (jdata) { + env->SetByteArrayRegion(jdata, 0, data_len, + reinterpret_cast<jbyte*>(buf.data() + program_len)); + } + return result; } @@ -118,8 +121,7 @@ static jboolean com_android_server_ApfTest_compareBpfApf(JNIEnv* env, jclass, js jstring jpcap_filename, jbyteArray japf_program) { ScopedUtfChars filter(env, jfilter); ScopedUtfChars pcap_filename(env, jpcap_filename); - uint8_t* apf_program = (uint8_t*)env->GetByteArrayElements(japf_program, NULL); - uint32_t apf_program_len = env->GetArrayLength(japf_program); + ScopedByteArrayRO apf_program(env, japf_program); // Open pcap file for BPF filtering ScopedFILE bpf_fp(fopen(pcap_filename.c_str(), "rb")); @@ -161,14 +163,15 @@ static jboolean com_android_server_ApfTest_compareBpfApf(JNIEnv* env, jclass, js do { apf_packet = pcap_next(apf_pcap.get(), &apf_header); } while (apf_packet != NULL && !accept_packet( - apf_program, apf_program_len, 0 /* data_len */, + reinterpret_cast<uint8_t*>(const_cast<int8_t*>(apf_program.get())), + apf_program.size(), 0 /* data_len */, apf_packet, apf_header.len, 0 /* filter_age */)); // Make sure both filters matched the same packet. if (apf_packet == NULL && bpf_packet == NULL) - break; + break; if (apf_packet == NULL || bpf_packet == NULL) - return false; + return false; if (apf_header.len != bpf_header.len || apf_header.ts.tv_sec != bpf_header.ts.tv_sec || apf_header.ts.tv_usec != bpf_header.ts.tv_usec || @@ -178,6 +181,48 @@ static jboolean com_android_server_ApfTest_compareBpfApf(JNIEnv* env, jclass, js return true; } +static jboolean com_android_server_ApfTest_dropsAllPackets(JNIEnv* env, jclass, jbyteArray jprogram, + jbyteArray jdata, jstring jpcap_filename) { + ScopedUtfChars pcap_filename(env, jpcap_filename); + ScopedByteArrayRO apf_program(env, jprogram); + uint32_t apf_program_len = (uint32_t)apf_program.size(); + uint32_t data_len = env->GetArrayLength(jdata); + pcap_pkthdr apf_header; + const uint8_t* apf_packet; + char pcap_error[PCAP_ERRBUF_SIZE]; + std::vector<uint8_t> buf(apf_program_len + data_len, 0); + + // Merge program and data into a single buffer. + env->GetByteArrayRegion(jprogram, 0, apf_program_len, reinterpret_cast<jbyte*>(buf.data())); + env->GetByteArrayRegion(jdata, 0, data_len, + reinterpret_cast<jbyte*>(buf.data() + apf_program_len)); + + // Open pcap file + ScopedFILE apf_fp(fopen(pcap_filename.c_str(), "rb")); + ScopedPcap apf_pcap(pcap_fopen_offline(apf_fp.get(), pcap_error)); + + if (apf_pcap.get() == NULL) { + throwException(env, "pcap_fopen_offline failed: " + std::string(pcap_error)); + return false; + } + + while ((apf_packet = pcap_next(apf_pcap.get(), &apf_header)) != NULL) { + int result = accept_packet(buf.data(), apf_program_len, + apf_program_len + data_len, apf_packet, apf_header.len, 0); + + // Return false once packet passes the filter + if (result) { + env->SetByteArrayRegion(jdata, 0, data_len, + reinterpret_cast<jbyte*>(buf.data() + apf_program_len)); + return false; + } + } + + env->SetByteArrayRegion(jdata, 0, data_len, + reinterpret_cast<jbyte*>(buf.data() + apf_program_len)); + return true; +} + extern "C" jint JNI_OnLoad(JavaVM* vm, void*) { JNIEnv *env; if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { @@ -192,6 +237,8 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void*) { (void*)com_android_server_ApfTest_compileToBpf }, { "compareBpfApf", "(Ljava/lang/String;Ljava/lang/String;[B)Z", (void*)com_android_server_ApfTest_compareBpfApf }, + { "dropsAllPackets", "([B[BLjava/lang/String;)Z", + (void*)com_android_server_ApfTest_dropsAllPackets }, }; jniRegisterNativeMethods(env, "android/net/apf/ApfTest", diff --git a/tests/net/res/raw/apfPcap.pcap b/tests/net/res/raw/apfPcap.pcap Binary files differnew file mode 100644 index 000000000000..6f69c4add0f8 --- /dev/null +++ b/tests/net/res/raw/apfPcap.pcap diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp index 39ca80bbcf51..968376b8229b 100644 --- a/tools/aapt2/ResourceParser.cpp +++ b/tools/aapt2/ResourceParser.cpp @@ -78,7 +78,7 @@ static uint32_t ParseFormatType(const StringPiece& piece) { 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 82d9e041b41a..99420de47fca 100644 --- a/tools/aapt2/ResourceUtils.cpp +++ b/tools/aapt2/ResourceUtils.cpp @@ -360,7 +360,7 @@ std::unique_ptr<BinaryPrimitive> TryParseFlagSymbol(const Attribute* flag_attr, 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 411ad747faa3..0b43c5d4a808 100644 --- a/tools/aapt2/cmd/Compile.cpp +++ b/tools/aapt2/cmd/Compile.cpp @@ -486,7 +486,7 @@ static bool CompileXml(IAaptContext* context, const CompileOptions& options, } 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/configuration/ConfigurationParser_test.cpp b/tools/aapt2/configuration/ConfigurationParser_test.cpp index 960880a8daa6..4c23bd3d6e3e 100644 --- a/tools/aapt2/configuration/ConfigurationParser_test.cpp +++ b/tools/aapt2/configuration/ConfigurationParser_test.cpp @@ -230,7 +230,7 @@ TEST_F(ConfigurationParserTest, ValidateFile) { test::ParseConfigOrDie("fr"), test::ParseConfigOrDie("de"))); ASSERT_TRUE(a1.android_sdk); ASSERT_TRUE(a1.android_sdk.value().min_sdk_version); - EXPECT_EQ(a1.android_sdk.value().min_sdk_version, 19l); + EXPECT_EQ(a1.android_sdk.value().min_sdk_version, 19L); EXPECT_THAT(a1.textures, SizeIs(1ul)); EXPECT_THAT(a1.features, SizeIs(1ul)); @@ -250,7 +250,7 @@ TEST_F(ConfigurationParserTest, ValidateFile) { test::ParseConfigOrDie("fr-rCA"))); ASSERT_TRUE(a2.android_sdk); ASSERT_TRUE(a2.android_sdk.value().min_sdk_version); - EXPECT_EQ(a2.android_sdk.value().min_sdk_version, 19l); + EXPECT_EQ(a2.android_sdk.value().min_sdk_version, 19L); EXPECT_THAT(a2.textures, SizeIs(1ul)); EXPECT_THAT(a2.features, SizeIs(1ul)); } diff --git a/tools/aapt2/java/AnnotationProcessor.cpp b/tools/aapt2/java/AnnotationProcessor.cpp index 8d91b0098c1f..a4610b2575b9 100644 --- a/tools/aapt2/java/AnnotationProcessor.cpp +++ b/tools/aapt2/java/AnnotationProcessor.cpp @@ -113,7 +113,7 @@ void AnnotationProcessor::AppendNewLine() { 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 5a8ff0926483..a407c228503a 100644 --- a/tools/aapt2/util/Files.cpp +++ b/tools/aapt2/util/Files.cpp @@ -165,7 +165,7 @@ void AppendPath(std::string* base, StringPiece part) { 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/hiddenapi/exclude.sh b/tools/hiddenapi/exclude.sh index 2291e5a92730..4ffcf6846947 100755 --- a/tools/hiddenapi/exclude.sh +++ b/tools/hiddenapi/exclude.sh @@ -11,6 +11,7 @@ LIBCORE_PACKAGES="\ android.system \ com.android.bouncycastle \ com.android.conscrypt \ + com.android.i18n.phonenumbers \ com.android.okhttp \ com.sun \ dalvik \ diff --git a/tools/incident_report/printer.h b/tools/incident_report/printer.h index ed93fa19542c..63e276b367ca 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/localedata/extract_icu_data.py b/tools/localedata/extract_icu_data.py index 9dceba2163eb..6b4c34677d96 100755 --- a/tools/localedata/extract_icu_data.py +++ b/tools/localedata/extract_icu_data.py @@ -155,7 +155,7 @@ def dump_representative_locales(representative_locales): print print 'std::unordered_set<uint64_t> REPRESENTATIVE_LOCALES({' for locale in sorted(representative_locales): - print ' 0x%08Xllu, // %s' % ( + print ' 0x%08XLLU, // %s' % ( pack_to_uint64(locale), locale) print '});' diff --git a/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessor.java b/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessor.java index 1d4c435939db..d368136c7081 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 com.sun.tools.javac.util.Position; 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.RoundEnvironment; 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 @@ public class UnsupportedAppUsageProcessor extends AbstractProcessor { "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 @@ public class UnsupportedAppUsageProcessor extends AbstractProcessor { 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 703a67b791be..5725f0cdae6e 100644 --- a/tools/stats_log_api_gen/Android.bp +++ b/tools/stats_log_api_gen/Android.bp @@ -96,6 +96,7 @@ genrule { cc_library_shared { name: "libstatslog", + host_supported: true, generated_sources: ["statslog.cpp"], generated_headers: ["statslog.h"], cflags: [ @@ -105,8 +106,19 @@ cc_library_shared { 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 ebdcdfdd6c50..61174d99198b 100644 --- a/tools/stats_log_api_gen/Collation.cpp +++ b/tools/stats_log_api_gen/Collation.cpp @@ -47,7 +47,8 @@ AtomDecl::AtomDecl(const AtomDecl& that) 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 @@ java_type(const FieldDescriptor* field) 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 @@ int collate_atom(const Descriptor *atom, AtomDecl *atomDecl, 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 @@ int collate_atom(const Descriptor *atom, AtomDecl *atomDecl, 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 @@ int collate_atom(const Descriptor *atom, AtomDecl *atomDecl, 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 @@ int collate_atom(const Descriptor *atom, AtomDecl *atomDecl, 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 5d2c30292c9c..a8b270caefaf 100644 --- a/tools/stats_log_api_gen/Collation.h +++ b/tools/stats_log_api_gen/Collation.h @@ -86,6 +86,8 @@ struct AtomDecl { 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 e519909aa026..2478b9154b10 100644 --- a/tools/stats_log_api_gen/main.cpp +++ b/tools/stats_log_api_gen/main.cpp @@ -68,6 +68,8 @@ cpp_type_name(java_type_t type) return "double"; case JAVA_TYPE_STRING: return "char const*"; + case JAVA_TYPE_BYTE_ARRAY: + return "char const*"; default: return "UNKNOWN"; } @@ -90,6 +92,8 @@ java_type_name(java_type_t type) return "double"; case JAVA_TYPE_STRING: return "java.lang.String"; + case JAVA_TYPE_BYTE_ARRAY: + return "byte[]"; default: return "UNKNOWN"; } @@ -104,7 +108,9 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, 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 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, 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 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, } 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 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, 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 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, 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 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, 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 @@ static int write_stats_log_cpp(FILE *out, const Atoms &atoms, 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 @@ static void write_cpp_usage( 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 @@ static void write_cpp_method_header( 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 @@ write_stats_log_header(FILE* out, const Atoms& atoms, const AtomDecl &attributio 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 @@ static void write_java_usage(FILE* out, const string& method_name, const string& 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 @@ jni_type_name(java_type_t type) return "jdouble"; case JAVA_TYPE_STRING: return "jstring"; + case JAVA_TYPE_BYTE_ARRAY: + return "jbyteArray"; default: return "UNKNOWN"; } @@ -868,6 +931,9 @@ jni_function_name(const string& method_name, const vector<java_type_t>& signatur case JAVA_TYPE_ATTRIBUTION_CHAIN: result += "_AttributionChain"; break; + case JAVA_TYPE_BYTE_ARRAY: + result += "_bytes"; + break; default: result += "_UNKNOWN"; break; @@ -893,6 +959,8 @@ java_type_signature(java_type_t type) return "D"; case JAVA_TYPE_STRING: return "Ljava/lang/String;"; + case JAVA_TYPE_BYTE_ARRAY: + return "[B"; default: return "UNKNOWN"; } @@ -960,6 +1028,32 @@ write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp 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 @@ write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp } } } 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 @@ write_stats_log_jni(FILE* out, const string& java_method_name, const string& cpp 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 264a865e3b39..188b765e241e 100644 --- a/tools/stats_log_api_gen/test.proto +++ b/tools/stats_log_api_gen/test.proto @@ -109,6 +109,28 @@ message BadAttributionNodePosition { 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 1936d9667948..ad3bffacd442 100644 --- a/tools/stats_log_api_gen/test_collation.cpp +++ b/tools/stats_log_api_gen/test_collation.cpp @@ -212,5 +212,19 @@ TEST(CollationTest, PassOnGoodStateAtomOptions) { 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 diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java index 66c1a3c0ffbc..17847eaa0ca5 100644 --- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java +++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java @@ -954,16 +954,15 @@ public class WifiEnterpriseConfig implements Parcelable { * for Hotspot 2.0 defined matching of AAA server certs per WFA HS2.0 spec, section 7.3.3.2, * second paragraph. * - * From wpa_supplicant documentation: - * Constraint for server domain name. If set, this FQDN is used as a suffix match requirement + * <p>From wpa_supplicant documentation: + * <p>Constraint for server domain name. If set, this FQDN is used as a suffix match requirement * for the AAAserver certificate in SubjectAltName dNSName element(s). If a matching dNSName is - * found, this constraint is met. If no dNSName values are present, this constraint is matched - * against SubjectName CN using same suffix match comparison. - * Suffix match here means that the host/domain name is compared one label at a time starting + * found, this constraint is met. + * <p>Suffix match here means that the host/domain name is compared one label at a time starting * from the top-level domain and all the labels in domain_suffix_match shall be included in the * certificate. The certificate may include additional sub-level labels in addition to the * required labels. - * For example, domain_suffix_match=example.com would match test.example.com but would not + * <p>For example, domain_suffix_match=example.com would match test.example.com but would not * match test-example.com. * @param domain The domain value */ diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 15e092bc8623..2aed2de064f2 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1550,7 +1550,6 @@ public class WifiManager { /** * @return true if this adapter supports Device-to-AP RTT */ - @SystemApi public boolean isDeviceToApRttSupported() { return isFeatureSupported(WIFI_FEATURE_D2AP_RTT); } |