diff options
86 files changed, 2895 insertions, 702 deletions
diff --git a/Android.bp b/Android.bp index 48391fc5e4aa..f49e4e5eb496 100644 --- a/Android.bp +++ b/Android.bp @@ -546,6 +546,7 @@ java_defaults { "telephony/java/com/android/internal/telephony/IOnSubscriptionsChangedListener.aidl", "telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl", "telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl", + "telephony/java/com/android/internal/telephony/IRcs.aidl", "telephony/java/com/android/internal/telephony/ISms.aidl", "telephony/java/com/android/internal/telephony/ISub.aidl", "telephony/java/com/android/internal/telephony/IAns.aidl", @@ -1154,6 +1155,7 @@ stubs_defaults { ":openjdk_javadoc_files", ":non_openjdk_javadoc_files", ":android_icu4j_src_files_for_docs", + ":conscrypt_public_api_files", "test-mock/src/**/*.java", "test-runner/src/**/*.java", ], @@ -1214,6 +1216,7 @@ stubs_defaults { ":openjdk_javadoc_files", ":non_openjdk_javadoc_files", ":android_icu4j_src_files_for_docs", + ":conscrypt_public_api_files", ], srcs_lib: "framework", srcs_lib_whitelist_dirs: frameworks_base_subdirs, diff --git a/api/current.txt b/api/current.txt index 6d0c5a69081d..ff4e00fa6f26 100755 --- a/api/current.txt +++ b/api/current.txt @@ -20276,6 +20276,51 @@ package android.icu.text { enum_constant public static final android.icu.text.TimeZoneNames.NameType SHORT_STANDARD; } + public abstract class Transliterator { + method public static final android.icu.text.Transliterator createFromRules(java.lang.String, java.lang.String, int); + method public void filteredTransliterate(android.icu.text.Replaceable, android.icu.text.Transliterator.Position, boolean); + method public final void finishTransliteration(android.icu.text.Replaceable, android.icu.text.Transliterator.Position); + method public static final java.util.Enumeration<java.lang.String> getAvailableIDs(); + method public static final java.util.Enumeration<java.lang.String> getAvailableSources(); + method public static final java.util.Enumeration<java.lang.String> getAvailableTargets(java.lang.String); + method public static final java.util.Enumeration<java.lang.String> getAvailableVariants(java.lang.String, java.lang.String); + method public static final java.lang.String getDisplayName(java.lang.String); + method public static java.lang.String getDisplayName(java.lang.String, java.util.Locale); + method public static java.lang.String getDisplayName(java.lang.String, android.icu.util.ULocale); + method public android.icu.text.Transliterator[] getElements(); + method public final android.icu.text.UnicodeFilter getFilter(); + method public final java.lang.String getID(); + method public static final android.icu.text.Transliterator getInstance(java.lang.String); + method public static android.icu.text.Transliterator getInstance(java.lang.String, int); + method public final android.icu.text.Transliterator getInverse(); + method public final int getMaximumContextLength(); + method public final android.icu.text.UnicodeSet getSourceSet(); + method public android.icu.text.UnicodeSet getTargetSet(); + method public void setFilter(android.icu.text.UnicodeFilter); + method public java.lang.String toRules(boolean); + method public final int transliterate(android.icu.text.Replaceable, int, int); + method public final void transliterate(android.icu.text.Replaceable); + method public final java.lang.String transliterate(java.lang.String); + method public final void transliterate(android.icu.text.Replaceable, android.icu.text.Transliterator.Position, java.lang.String); + method public final void transliterate(android.icu.text.Replaceable, android.icu.text.Transliterator.Position, int); + method public final void transliterate(android.icu.text.Replaceable, android.icu.text.Transliterator.Position); + field public static final int FORWARD = 0; // 0x0 + field public static final int REVERSE = 1; // 0x1 + } + + public static class Transliterator.Position { + ctor public Transliterator.Position(); + ctor public Transliterator.Position(int, int, int); + ctor public Transliterator.Position(int, int, int, int); + ctor public Transliterator.Position(android.icu.text.Transliterator.Position); + method public void set(android.icu.text.Transliterator.Position); + method public final void validate(int); + field public int contextLimit; + field public int contextStart; + field public int limit; + field public int start; + } + public abstract class UCharacterIterator implements java.lang.Cloneable { ctor protected UCharacterIterator(); method public java.lang.Object clone() throws java.lang.CloneNotSupportedException; @@ -28224,6 +28269,20 @@ package android.net.sip { } +package android.net.ssl { + + public class SSLEngines { + method public static boolean isSupportedEngine(javax.net.ssl.SSLEngine); + method public static void setUseSessionTickets(javax.net.ssl.SSLEngine, boolean); + } + + public class SSLSockets { + method public static boolean isSupportedSocket(javax.net.ssl.SSLSocket); + method public static void setUseSessionTickets(javax.net.ssl.SSLSocket, boolean); + } + +} + package android.net.wifi { public class ScanResult implements android.os.Parcelable { @@ -35081,6 +35140,15 @@ package android.provider { method public static java.lang.String getLastOutgoingCall(android.content.Context); field public static final int ANSWERED_EXTERNALLY_TYPE = 7; // 0x7 field public static final int BLOCKED_TYPE = 6; // 0x6 + field public static final java.lang.String BLOCK_REASON = "block_reason"; + field public static final int BLOCK_REASON_BLOCKED_NUMBER = 3; // 0x3 + field public static final int BLOCK_REASON_CALL_SCREENING_SERVICE = 1; // 0x1 + field public static final int BLOCK_REASON_DIRECT_TO_VOICEMAIL = 2; // 0x2 + field public static final int BLOCK_REASON_NOT_BLOCKED = 0; // 0x0 + field public static final int BLOCK_REASON_NOT_IN_CONTACTS = 7; // 0x7 + field public static final int BLOCK_REASON_PAY_PHONE = 6; // 0x6 + field public static final int BLOCK_REASON_RESTRICTED_NUMBER = 5; // 0x5 + field public static final int BLOCK_REASON_UNKNOWN_NUMBER = 4; // 0x4 field public static final java.lang.String CACHED_FORMATTED_NUMBER = "formatted_number"; field public static final java.lang.String CACHED_LOOKUP_URI = "lookup_uri"; field public static final java.lang.String CACHED_MATCHED_NUMBER = "matched_number"; @@ -35090,6 +35158,8 @@ package android.provider { field public static final java.lang.String CACHED_NUMBER_TYPE = "numbertype"; field public static final java.lang.String CACHED_PHOTO_ID = "photo_id"; field public static final java.lang.String CACHED_PHOTO_URI = "photo_uri"; + field public static final java.lang.String CALL_SCREENING_APP_NAME = "call_screening_app_name"; + field public static final java.lang.String CALL_SCREENING_COMPONENT_NAME = "call_screening_component_name"; field public static final android.net.Uri CONTENT_FILTER_URI; field public static final java.lang.String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/calls"; field public static final java.lang.String CONTENT_TYPE = "vnd.android.cursor.dir/calls"; @@ -37259,6 +37329,7 @@ package android.provider { field public static final java.lang.String AUTH_TYPE = "authtype"; field public static final deprecated java.lang.String BEARER = "bearer"; field public static final java.lang.String CARRIER_ENABLED = "carrier_enabled"; + field public static final java.lang.String CARRIER_ID = "carrier_id"; 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"; @@ -41327,7 +41398,7 @@ package android.telecom { field public static final int CAPABILITY_CAN_PAUSE_VIDEO = 1048576; // 0x100000 field public static final int CAPABILITY_CAN_PULL_CALL = 16777216; // 0x1000000 field public static final int CAPABILITY_CAN_SEND_RESPONSE_VIA_CONNECTION = 4194304; // 0x400000 - field public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 524288; // 0x80000 + field public static final deprecated int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 524288; // 0x80000 field public static final int CAPABILITY_DISCONNECT_FROM_CONFERENCE = 8192; // 0x2000 field public static final int CAPABILITY_HOLD = 1; // 0x1 field public static final int CAPABILITY_MANAGE_CONFERENCE = 128; // 0x80 @@ -41747,6 +41818,7 @@ package android.telecom { method public android.telecom.PhoneAccount getPhoneAccount(android.telecom.PhoneAccountHandle); method public java.util.List<android.telecom.PhoneAccountHandle> getSelfManagedPhoneAccounts(); method public android.telecom.PhoneAccountHandle getSimCallManager(); + method public java.lang.String getSystemDialerPackage(); method public java.lang.String getVoiceMailNumber(android.telecom.PhoneAccountHandle); method public boolean handleMmi(java.lang.String); method public boolean handleMmi(java.lang.String, android.telecom.PhoneAccountHandle); @@ -42162,6 +42234,16 @@ package android.telephony { field public static final android.os.Parcelable.Creator<android.telephony.CellIdentityLte> CREATOR; } + public final class CellIdentityNr extends android.telephony.CellIdentity { + method public int getChannelNumber(); + method public java.lang.String getMccString(); + method public java.lang.String getMncString(); + method public int getPci(); + method public int getTac(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.CellIdentityNr> CREATOR; + } + public final class CellIdentityTdscdma extends android.telephony.CellIdentity { method public int getCid(); method public int getCpid(); @@ -42221,6 +42303,13 @@ package android.telephony { field public static final android.os.Parcelable.Creator<android.telephony.CellInfoLte> CREATOR; } + public final class CellInfoNr extends android.telephony.CellInfo { + method public android.telephony.CellIdentity getCellIdentity(); + method public android.telephony.CellSignalStrength getCellSignalStrength(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.CellInfoNr> CREATOR; + } + public final class CellInfoWcdma extends android.telephony.CellInfo implements android.os.Parcelable { method public android.telephony.CellIdentityWcdma getCellIdentity(); method public android.telephony.CellSignalStrengthWcdma getCellSignalStrength(); @@ -42281,12 +42370,28 @@ package android.telephony { method public int getLevel(); method public int getRsrp(); method public int getRsrq(); + method public int getRssi(); method public int getRssnr(); method public int getTimingAdvance(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.telephony.CellSignalStrengthLte> CREATOR; } + public final class CellSignalStrengthNr extends android.telephony.CellSignalStrength implements android.os.Parcelable { + method public int describeContents(); + method public int getAsuLevel(); + method public int getCsiRsrp(); + method public int getCsiRsrq(); + method public int getCsiSinr(); + method public int getDbm(); + method public int getLevel(); + method public int getSsRsrp(); + method public int getSsRsrq(); + method public int getSsSinr(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.telephony.CellSignalStrengthNr> CREATOR; + } + public final class CellSignalStrengthWcdma extends android.telephony.CellSignalStrength implements android.os.Parcelable { method public int describeContents(); method public int getAsuLevel(); @@ -42476,6 +42581,7 @@ package android.telephony { public class PhoneStateListener { ctor public PhoneStateListener(); + ctor public PhoneStateListener(java.util.concurrent.Executor); method public void onCallForwardingIndicatorChanged(boolean); method public void onCallStateChanged(int, java.lang.String); method public void onCellInfoChanged(java.util.List<android.telephony.CellInfo>); @@ -72744,10 +72850,13 @@ package javax.net.ssl { method public abstract void beginHandshake() throws javax.net.ssl.SSLException; method public abstract void closeInbound() throws javax.net.ssl.SSLException; method public abstract void closeOutbound(); + method public java.lang.String getApplicationProtocol(); method public abstract java.lang.Runnable getDelegatedTask(); method public abstract boolean getEnableSessionCreation(); method public abstract java.lang.String[] getEnabledCipherSuites(); method public abstract java.lang.String[] getEnabledProtocols(); + method public java.lang.String getHandshakeApplicationProtocol(); + method public java.util.function.BiFunction<javax.net.ssl.SSLEngine, java.util.List<java.lang.String>, java.lang.String> getHandshakeApplicationProtocolSelector(); method public javax.net.ssl.SSLSession getHandshakeSession(); method public abstract javax.net.ssl.SSLEngineResult.HandshakeStatus getHandshakeStatus(); method public abstract boolean getNeedClientAuth(); @@ -72764,6 +72873,7 @@ package javax.net.ssl { method public abstract void setEnableSessionCreation(boolean); method public abstract void setEnabledCipherSuites(java.lang.String[]); method public abstract void setEnabledProtocols(java.lang.String[]); + method public void setHandshakeApplicationProtocolSelector(java.util.function.BiFunction<javax.net.ssl.SSLEngine, java.util.List<java.lang.String>, java.lang.String>); method public abstract void setNeedClientAuth(boolean); method public void setSSLParameters(javax.net.ssl.SSLParameters); method public abstract void setUseClientMode(boolean); @@ -72822,6 +72932,7 @@ package javax.net.ssl { ctor public SSLParameters(java.lang.String[]); ctor public SSLParameters(java.lang.String[], java.lang.String[]); method public java.security.AlgorithmConstraints getAlgorithmConstraints(); + method public java.lang.String[] getApplicationProtocols(); method public java.lang.String[] getCipherSuites(); method public java.lang.String getEndpointIdentificationAlgorithm(); method public boolean getNeedClientAuth(); @@ -72831,6 +72942,7 @@ package javax.net.ssl { method public final boolean getUseCipherSuitesOrder(); method public boolean getWantClientAuth(); method public void setAlgorithmConstraints(java.security.AlgorithmConstraints); + method public void setApplicationProtocols(java.lang.String[]); method public void setCipherSuites(java.lang.String[]); method public void setEndpointIdentificationAlgorithm(java.lang.String); method public void setNeedClientAuth(boolean); @@ -72935,9 +73047,12 @@ package javax.net.ssl { ctor protected SSLSocket(java.lang.String, int, java.net.InetAddress, int) throws java.io.IOException, java.net.UnknownHostException; ctor protected SSLSocket(java.net.InetAddress, int, java.net.InetAddress, int) throws java.io.IOException; method public abstract void addHandshakeCompletedListener(javax.net.ssl.HandshakeCompletedListener); + method public java.lang.String getApplicationProtocol(); method public abstract boolean getEnableSessionCreation(); method public abstract java.lang.String[] getEnabledCipherSuites(); method public abstract java.lang.String[] getEnabledProtocols(); + method public java.lang.String getHandshakeApplicationProtocol(); + method public java.util.function.BiFunction<javax.net.ssl.SSLSocket, java.util.List<java.lang.String>, java.lang.String> getHandshakeApplicationProtocolSelector(); method public javax.net.ssl.SSLSession getHandshakeSession(); method public abstract boolean getNeedClientAuth(); method public javax.net.ssl.SSLParameters getSSLParameters(); @@ -72950,6 +73065,7 @@ package javax.net.ssl { method public abstract void setEnableSessionCreation(boolean); method public abstract void setEnabledCipherSuites(java.lang.String[]); method public abstract void setEnabledProtocols(java.lang.String[]); + method public void setHandshakeApplicationProtocolSelector(java.util.function.BiFunction<javax.net.ssl.SSLSocket, java.util.List<java.lang.String>, java.lang.String>); method public abstract void setNeedClientAuth(boolean); method public void setSSLParameters(javax.net.ssl.SSLParameters); method public abstract void setUseClientMode(boolean); diff --git a/api/system-current.txt b/api/system-current.txt index 77112363c9b8..f9d6701ffe1d 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -5064,15 +5064,21 @@ package android.telecom { method public int getAllPhoneAccountsCount(); method public int getCallState(); method public android.telecom.PhoneAccountHandle getConnectionManager(); + method public int getCurrentTtyMode(); method public deprecated android.content.ComponentName getDefaultPhoneApp(); method public java.util.List<android.telecom.PhoneAccountHandle> getPhoneAccountsForPackage(); 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"; field public static final java.lang.String EXTRA_CONNECTION_SERVICE = "android.telecom.extra.CONNECTION_SERVICE"; + field public static final int TTY_MODE_FULL = 1; // 0x1 + field public static final int TTY_MODE_HCO = 2; // 0x2 + field public static final int TTY_MODE_OFF = 0; // 0x0 + field public static final int TTY_MODE_VCO = 3; // 0x3 } } @@ -5113,6 +5119,7 @@ package android.telephony { method public int getDomain(); method public int getRegState(); method public int getRejectCause(); + method public int getRoamingType(); method public int getTransportType(); method public boolean isEmergencyEnabled(); method public boolean isRoaming(); @@ -5160,7 +5167,9 @@ package android.telephony { public class PhoneStateListener { method public void onRadioPowerStateChanged(int); + method public void onSrvccStateChanged(int); field public static final int LISTEN_RADIO_POWER_STATE_CHANGED = 8388608; // 0x800000 + field public static final int LISTEN_SRVCC_STATE_CHANGED = 16384; // 0x4000 } public class ServiceState implements android.os.Parcelable { @@ -5170,6 +5179,10 @@ package android.telephony { method public deprecated android.telephony.NetworkRegistrationState getNetworkRegistrationStates(int, int); method public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStatesForDomain(int); method public java.util.List<android.telephony.NetworkRegistrationState> getNetworkRegistrationStatesForTransportType(int); + field public static final int ROAMING_TYPE_DOMESTIC = 2; // 0x2 + field public static final int ROAMING_TYPE_INTERNATIONAL = 3; // 0x3 + field public static final int ROAMING_TYPE_NOT_ROAMING = 0; // 0x0 + field public static final int ROAMING_TYPE_UNKNOWN = 1; // 0x1 } public final class SmsManager { @@ -5208,8 +5221,12 @@ package android.telephony { 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"; - field public static final android.net.Uri ENHANCED_4G_ENABLED_CONTENT_URI; + 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; + field public static final android.net.Uri WFC_MODE_CONTENT_URI; + field public static final android.net.Uri WFC_ROAMING_ENABLED_CONTENT_URI; + field public static final android.net.Uri WFC_ROAMING_MODE_CONTENT_URI; } public final class SubscriptionPlan implements android.os.Parcelable { @@ -5389,6 +5406,11 @@ package android.telephony { field public static final int SIM_ACTIVATION_STATE_UNKNOWN = 0; // 0x0 field public static final int SIM_STATE_LOADED = 10; // 0xa field public static final int SIM_STATE_PRESENT = 11; // 0xb + field public static final int SRVCC_STATE_HANDOVER_CANCELED = 3; // 0x3 + field public static final int SRVCC_STATE_HANDOVER_COMPLETED = 1; // 0x1 + field public static final int SRVCC_STATE_HANDOVER_FAILED = 2; // 0x2 + field public static final int SRVCC_STATE_HANDOVER_NONE = -1; // 0xffffffff + field public static final int SRVCC_STATE_HANDOVER_STARTED = 0; // 0x0 } public final class UiccAccessRule implements android.os.Parcelable { @@ -5954,6 +5976,7 @@ package android.telephony.ims { 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_TRANSACTION_DOES_NOT_EXIST = 343; // 0x157 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 diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java index 09343f174587..70e81dfe7404 100644 --- a/cmds/sm/src/com/android/commands/sm/Sm.java +++ b/cmds/sm/src/com/android/commands/sm/Sm.java @@ -125,6 +125,8 @@ public final class Sm { filterType = VolumeInfo.TYPE_PRIVATE; } else if ("emulated".equals(filter)) { filterType = VolumeInfo.TYPE_EMULATED; + } else if ("stub".equals(filter)) { + filterType = VolumeInfo.TYPE_STUB; } else { filterType = -1; } @@ -298,7 +300,7 @@ public final class Sm { private static int showUsage() { System.err.println("usage: sm list-disks [adoptable]"); - System.err.println(" sm list-volumes [public|private|emulated|all]"); + System.err.println(" sm list-volumes [public|private|emulated|stub|all]"); System.err.println(" sm has-adoptable"); System.err.println(" sm get-primary-storage-uuid"); System.err.println(" sm set-force-adoptable [on|off|default]"); diff --git a/config/boot-image-profile.txt b/config/boot-image-profile.txt index 9857cd072068..dacbd674837b 100644 --- a/config/boot-image-profile.txt +++ b/config/boot-image-profile.txt @@ -24141,7 +24141,90 @@ HSPLandroid/icu/util/CharsTrie;->jumpByDelta(Ljava/lang/CharSequence;I)I HSPLandroid/icu/util/CharsTrie;->next(I)Landroid/icu/util/BytesTrie$Result; HSPLandroid/icu/util/CharsTrie;->nextImpl(II)Landroid/icu/util/BytesTrie$Result; HSPLandroid/icu/util/CharsTrie;->readValue(Ljava/lang/CharSequence;II)I -HSPLandroid/icu/util/Currency$1;-><init>()V +HSPLandroid/icu/util/CodePointTrie$Small8;->fromBinary(Ljava/nio/ByteBuffer;)Landroid/icu/util/CodePointTrie$Small8; +HSPLandroid/icu/util/CodePointTrie$Small32;->fromBinary(Ljava/nio/ByteBuffer;)Landroid/icu/util/CodePointTrie$Small32; +HSPLandroid/icu/util/CodePointTrie$Small16;->fromBinary(Ljava/nio/ByteBuffer;)Landroid/icu/util/CodePointTrie$Small16; +HSPLandroid/icu/util/CodePointTrie$Fast8;->fromBinary(Ljava/nio/ByteBuffer;)Landroid/icu/util/CodePointTrie$Fast8; +HSPLandroid/icu/util/CodePointTrie$Fast8;->bmpGet(I)I +HSPLandroid/icu/util/CodePointTrie$Fast8;->get(I)I +HSPLandroid/icu/util/CodePointTrie$Fast8;->suppGet(I)I +HSPLandroid/icu/util/CodePointTrie$Fast32;->fromBinary(Ljava/nio/ByteBuffer;)Landroid/icu/util/CodePointTrie$Fast32; +HSPLandroid/icu/util/CodePointTrie$Fast32;->bmpGet(I)I +HSPLandroid/icu/util/CodePointTrie$Fast32;->get(I)I +HSPLandroid/icu/util/CodePointTrie$Fast32;->suppGet(I)I +HSPLandroid/icu/util/CodePointTrie$Fast16;->fromBinary(Ljava/nio/ByteBuffer;)Landroid/icu/util/CodePointTrie$Fast16; +HSPLandroid/icu/util/CodePointTrie$Fast16;->bmpGet(I)I +HSPLandroid/icu/util/CodePointTrie$Fast16;->get(I)I +HSPLandroid/icu/util/CodePointTrie$Fast16;->suppGet(I)I +HSPLandroid/icu/util/CodePointTrie$Small;->fromBinary(Landroid/icu/util/CodePointTrie$ValueWidth;Ljava/nio/ByteBuffer;)Landroid/icu/util/CodePointTrie$Small; +HSPLandroid/icu/util/CodePointTrie$Small;->cpIndex(I)I +HSPLandroid/icu/util/CodePointTrie$Small;->getType()Landroid/icu/util/CodePointTrie$Type; +HSPLandroid/icu/util/CodePointTrie$Small;->stringIterator(Ljava/lang/CharSequence;I)Landroid/icu/util/CodePointMap$StringIterator; +HSPLandroid/icu/util/CodePointTrie$Fast;->fromBinary(Landroid/icu/util/CodePointTrie$ValueWidth;Ljava/nio/ByteBuffer;)Landroid/icu/util/CodePointTrie$Fast; +HSPLandroid/icu/util/CodePointTrie$Fast;->bmpGet(I)I +HSPLandroid/icu/util/CodePointTrie$Fast;->cpIndex(I)I +HSPLandroid/icu/util/CodePointTrie$Fast;->getType()Landroid/icu/util/CodePointTrie$Type; +HSPLandroid/icu/util/CodePointTrie$Fast;->stringIterator(Ljava/lang/CharSequence;I)Landroid/icu/util/CodePointMap$StringIterator; +HSPLandroid/icu/util/CodePointTrie$Fast;->suppGet(I)I +HSPLandroid/icu/util/CodePointTrie$Data8;->getDataLength()I +HSPLandroid/icu/util/CodePointTrie$Data8;->getFromIndex(I)I +HSPLandroid/icu/util/CodePointTrie$Data8;->getValueWidth()Landroid/icu/util/CodePointTrie$ValueWidth; +HSPLandroid/icu/util/CodePointTrie$Data8;->write(Ljava/io/DataOutputStream;)I +HSPLandroid/icu/util/CodePointTrie$Data32;->getDataLength()I +HSPLandroid/icu/util/CodePointTrie$Data32;->getFromIndex(I)I +HSPLandroid/icu/util/CodePointTrie$Data32;->getValueWidth()Landroid/icu/util/CodePointTrie$ValueWidth; +HSPLandroid/icu/util/CodePointTrie$Data32;->write(Ljava/io/DataOutputStream;)I +HSPLandroid/icu/util/CodePointTrie$Data16;->getDataLength()I +HSPLandroid/icu/util/CodePointTrie$Data16;->getFromIndex(I)I +HSPLandroid/icu/util/CodePointTrie$Data16;->getValueWidth()Landroid/icu/util/CodePointTrie$ValueWidth; +HSPLandroid/icu/util/CodePointTrie$Data16;->write(Ljava/io/DataOutputStream;)I +HSPLandroid/icu/util/CodePointTrie$Data;->getDataLength()I +HSPLandroid/icu/util/CodePointTrie$Data;->getFromIndex(I)I +HSPLandroid/icu/util/CodePointTrie$Data;->getValueWidth()Landroid/icu/util/CodePointTrie$ValueWidth; +HSPLandroid/icu/util/CodePointTrie$Data;->write(Ljava/io/DataOutputStream;)I +HSPLandroid/icu/util/CodePointTrie$ValueWidth;->valueOf(Ljava/lang/String;)Landroid/icu/util/CodePointTrie$ValueWidth; +HSPLandroid/icu/util/CodePointTrie$ValueWidth;->values()[Landroid/icu/util/CodePointTrie$ValueWidth; +HSPLandroid/icu/util/CodePointTrie$Type;->valueOf(Ljava/lang/String;)Landroid/icu/util/CodePointTrie$Type; +HSPLandroid/icu/util/CodePointTrie$Type;->values()[Landroid/icu/util/CodePointTrie$Type; +HSPLandroid/icu/util/CodePointTrie;->fromBinary(Landroid/icu/util/CodePointTrie$Type;Landroid/icu/util/CodePointTrie$ValueWidth;Ljava/nio/ByteBuffer;)Landroid/icu/util/CodePointTrie; +HSPLandroid/icu/util/CodePointTrie;->internalSmallIndex(Landroid/icu/util/CodePointTrie$Type;I)I +HSPLandroid/icu/util/CodePointTrie;->maybeFilterValue(IIILandroid/icu/util/CodePointMap$ValueFilter;)I +HSPLandroid/icu/util/CodePointTrie;->asciiGet(I)I +HSPLandroid/icu/util/CodePointTrie;->cpIndex(I)I +HSPLandroid/icu/util/CodePointTrie;->fastIndex(I)I +HSPLandroid/icu/util/CodePointTrie;->get(I)I +HSPLandroid/icu/util/CodePointTrie;->getRange(ILandroid/icu/util/CodePointMap$ValueFilter;Landroid/icu/util/CodePointMap$Range;)Z +HSPLandroid/icu/util/CodePointTrie;->getType()Landroid/icu/util/CodePointTrie$Type; +HSPLandroid/icu/util/CodePointTrie;->getValueWidth()Landroid/icu/util/CodePointTrie$ValueWidth; +HSPLandroid/icu/util/CodePointTrie;->smallIndex(Landroid/icu/util/CodePointTrie$Type;I)I +HSPLandroid/icu/util/CodePointTrie;->toBinary(Ljava/io/OutputStream;)I +HSPLandroid/icu/util/CodePointMap$StringIterator;->getCodePoint()I +HSPLandroid/icu/util/CodePointMap$StringIterator;->getIndex()I +HSPLandroid/icu/util/CodePointMap$StringIterator;->getValue()I +HSPLandroid/icu/util/CodePointMap$StringIterator;->next()Z +HSPLandroid/icu/util/CodePointMap$StringIterator;->previous()Z +HSPLandroid/icu/util/CodePointMap$StringIterator;->reset(Ljava/lang/CharSequence;I)V +HSPLandroid/icu/util/CodePointMap$RangeIterator;->hasNext()Z +HSPLandroid/icu/util/CodePointMap$RangeIterator;->next()Landroid/icu/util/CodePointMap$Range; +HSPLandroid/icu/util/CodePointMap$RangeIterator;->next()Ljava/lang/Object; +HSPLandroid/icu/util/CodePointMap$RangeIterator;->remove()V +HSPLandroid/icu/util/CodePointMap$Range;->access$000(Landroid/icu/util/CodePointMap$Range;)I +HSPLandroid/icu/util/CodePointMap$Range;->access$002(Landroid/icu/util/CodePointMap$Range;I)I +HSPLandroid/icu/util/CodePointMap$Range;->access$100(Landroid/icu/util/CodePointMap$Range;)I +HSPLandroid/icu/util/CodePointMap$Range;->access$102(Landroid/icu/util/CodePointMap$Range;I)I +HSPLandroid/icu/util/CodePointMap$Range;->access$202(Landroid/icu/util/CodePointMap$Range;I)I +HSPLandroid/icu/util/CodePointMap$Range;->getEnd()I +HSPLandroid/icu/util/CodePointMap$Range;->getStart()I +HSPLandroid/icu/util/CodePointMap$Range;->getValue()I +HSPLandroid/icu/util/CodePointMap$Range;->set(III)V +HSPLandroid/icu/util/CodePointMap$ValueFilter;->apply(I)I +HSPLandroid/icu/util/CodePointMap$RangeOption;->valueOf(Ljava/lang/String;)Landroid/icu/util/CodePointMap$RangeOption; +HSPLandroid/icu/util/CodePointMap$RangeOption;->values()[Landroid/icu/util/CodePointMap$RangeOption; +HSPLandroid/icu/util/CodePointMap;->get(I)I +HSPLandroid/icu/util/CodePointMap;->getRange(ILandroid/icu/util/CodePointMap$RangeOption;ILandroid/icu/util/CodePointMap$ValueFilter;Landroid/icu/util/CodePointMap$Range;)Z +HSPLandroid/icu/util/CodePointMap;->getRange(ILandroid/icu/util/CodePointMap$ValueFilter;Landroid/icu/util/CodePointMap$Range;)Z +HSPLandroid/icu/util/CodePointMap;->iterator()Ljava/util/Iterator; +HSPLandroid/icu/util/CodePointMap;->stringIterator(Ljava/lang/CharSequence;I)Landroid/icu/util/CodePointMap$StringIterator;HSPLandroid/icu/util/Currency$1;-><init>()V HSPLandroid/icu/util/Currency$1;->createInstance(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; HSPLandroid/icu/util/Currency$1;->createInstance(Ljava/lang/String;Ljava/lang/Void;)Landroid/icu/util/Currency; HSPLandroid/icu/util/Currency$CurrencyUsage;-><init>(Ljava/lang/String;I)V @@ -24187,6 +24270,61 @@ HSPLandroid/icu/util/MeasureUnit;->addUnit(Ljava/lang/String;Ljava/lang/String;L HSPLandroid/icu/util/MeasureUnit;->equals(Ljava/lang/Object;)Z HSPLandroid/icu/util/MeasureUnit;->hashCode()I HSPLandroid/icu/util/MeasureUnit;->internalGetInstance(Ljava/lang/String;Ljava/lang/String;)Landroid/icu/util/MeasureUnit; +HSPLandroid/icu/util/MutableCodePointTrie$MixedBlocks;->addEntry([I[CIII)V +HSPLandroid/icu/util/MutableCodePointTrie$MixedBlocks;->findEntry([III)I +HSPLandroid/icu/util/MutableCodePointTrie$MixedBlocks;->findEntry([I[C[I[CII)I +HSPLandroid/icu/util/MutableCodePointTrie$MixedBlocks;->makeHashCode(I)I +HSPLandroid/icu/util/MutableCodePointTrie$MixedBlocks;->makeHashCode([CI)I +HSPLandroid/icu/util/MutableCodePointTrie$MixedBlocks;->makeHashCode([II)I +HSPLandroid/icu/util/MutableCodePointTrie$MixedBlocks;->modulo(II)I +HSPLandroid/icu/util/MutableCodePointTrie$MixedBlocks;->nextIndex(II)I +HSPLandroid/icu/util/MutableCodePointTrie$MixedBlocks;->extend([CIII)V +HSPLandroid/icu/util/MutableCodePointTrie$MixedBlocks;->extend([IIII)V +HSPLandroid/icu/util/MutableCodePointTrie$MixedBlocks;->findAllSameBlock([II)I +HSPLandroid/icu/util/MutableCodePointTrie$MixedBlocks;->findBlock([C[CI)I +HSPLandroid/icu/util/MutableCodePointTrie$MixedBlocks;->findBlock([C[II)I +HSPLandroid/icu/util/MutableCodePointTrie$MixedBlocks;->findBlock([I[II)I +HSPLandroid/icu/util/MutableCodePointTrie$MixedBlocks;->init(II)V +HSPLandroid/icu/util/MutableCodePointTrie$AllSameBlocks;->add(III)V +HSPLandroid/icu/util/MutableCodePointTrie$AllSameBlocks;->findMostUsed()I +HSPLandroid/icu/util/MutableCodePointTrie$AllSameBlocks;->findOrAdd(III)I +HSPLandroid/icu/util/MutableCodePointTrie;->access$000([II[III)Z +HSPLandroid/icu/util/MutableCodePointTrie;->access$100([CI[III)Z +HSPLandroid/icu/util/MutableCodePointTrie;->access$200([CI[CII)Z +HSPLandroid/icu/util/MutableCodePointTrie;->access$300([IIII)Z +HSPLandroid/icu/util/MutableCodePointTrie;->allValuesSameAs([IIII)Z +HSPLandroid/icu/util/MutableCodePointTrie;->allocDataBlock(I)I +HSPLandroid/icu/util/MutableCodePointTrie;->build(Landroid/icu/util/CodePointTrie$Type;Landroid/icu/util/CodePointTrie$ValueWidth;)Landroid/icu/util/CodePointTrie; +HSPLandroid/icu/util/MutableCodePointTrie;->clear()V +HSPLandroid/icu/util/MutableCodePointTrie;->compactData(I[IILandroid/icu/util/MutableCodePointTrie$MixedBlocks;)I +HSPLandroid/icu/util/MutableCodePointTrie;->compactIndex(ILandroid/icu/util/MutableCodePointTrie$MixedBlocks;)I +HSPLandroid/icu/util/MutableCodePointTrie;->compactTrie(I)I +HSPLandroid/icu/util/MutableCodePointTrie;->compactWholeDataBlocks(ILandroid/icu/util/MutableCodePointTrie$AllSameBlocks;)I +HSPLandroid/icu/util/MutableCodePointTrie;->ensureHighStart(I)V +HSPLandroid/icu/util/MutableCodePointTrie;->equalBlocks([CI[CII)Z +HSPLandroid/icu/util/MutableCodePointTrie;->equalBlocks([CI[III)Z +HSPLandroid/icu/util/MutableCodePointTrie;->equalBlocks([II[III)Z +HSPLandroid/icu/util/MutableCodePointTrie;->fillBlock(IIII)V +HSPLandroid/icu/util/MutableCodePointTrie;->findAllSameBlock([IIIII)I +HSPLandroid/icu/util/MutableCodePointTrie;->findHighStart()I +HSPLandroid/icu/util/MutableCodePointTrie;->findSameBlock([CII[CII)I +HSPLandroid/icu/util/MutableCodePointTrie;->fromCodePointMap(Landroid/icu/util/CodePointMap;)Landroid/icu/util/MutableCodePointTrie; +HSPLandroid/icu/util/MutableCodePointTrie;->getAllSameOverlap([IIII)I +HSPLandroid/icu/util/MutableCodePointTrie;->getDataBlock(I)I +HSPLandroid/icu/util/MutableCodePointTrie;->getOverlap([CI[CII)I +HSPLandroid/icu/util/MutableCodePointTrie;->getOverlap([CI[III)I +HSPLandroid/icu/util/MutableCodePointTrie;->getOverlap([II[III)I +HSPLandroid/icu/util/MutableCodePointTrie;->isStartOfSomeFastBlock(I[II)Z +HSPLandroid/icu/util/MutableCodePointTrie;->maskValues(I)V +HSPLandroid/icu/util/MutableCodePointTrie;->maybeFilterValue(IIILandroid/icu/util/CodePointMap$ValueFilter;)I +HSPLandroid/icu/util/MutableCodePointTrie;->writeBlock(II)V +HSPLandroid/icu/util/MutableCodePointTrie;->buildImmutable(Landroid/icu/util/CodePointTrie$Type;Landroid/icu/util/CodePointTrie$ValueWidth;)Landroid/icu/util/CodePointTrie; +HSPLandroid/icu/util/MutableCodePointTrie;->clone()Landroid/icu/util/MutableCodePointTrie; +HSPLandroid/icu/util/MutableCodePointTrie;->clone()Ljava/lang/Object; +HSPLandroid/icu/util/MutableCodePointTrie;->get(I)I +HSPLandroid/icu/util/MutableCodePointTrie;->getRange(ILandroid/icu/util/CodePointMap$ValueFilter;Landroid/icu/util/CodePointMap$Range;)Z +HSPLandroid/icu/util/MutableCodePointTrie;->set(II)V +HSPLandroid/icu/util/MutableCodePointTrie;->setRange(III)V HSPLandroid/icu/util/SimpleTimeZone;-><init>(ILjava/lang/String;IIIIIIIIIII)V HSPLandroid/icu/util/SimpleTimeZone;->clone()Ljava/lang/Object; HSPLandroid/icu/util/SimpleTimeZone;->cloneAsThawed()Landroid/icu/util/TimeZone; diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt index bb9a7c541bf5..ce0f9450030a 100644 --- a/config/hiddenapi-light-greylist.txt +++ b/config/hiddenapi-light-greylist.txt @@ -494,40 +494,6 @@ Landroid/hardware/location/IActivityRecognitionHardwareClient$Stub;-><init>()V Landroid/hardware/location/IContextHubService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/location/IContextHubService; Landroid/hardware/usb/IUsbManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V Landroid/hardware/usb/IUsbManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/usb/IUsbManager; -Landroid/icu/impl/CurrencyData;-><init>()V -Landroid/icu/impl/ICUResourceBundle;->getULocale()Landroid/icu/util/ULocale; -Landroid/icu/impl/ICUResourceBundle;->getWithFallback(Ljava/lang/String;)Landroid/icu/impl/ICUResourceBundle; -Landroid/icu/impl/IllegalIcuArgumentException;-><init>(Ljava/lang/String;)V -Landroid/icu/text/ArabicShaping;-><init>(I)V -Landroid/icu/text/ArabicShaping;->isAlefMaksouraChar(C)Z -Landroid/icu/text/ArabicShaping;->isSeenTailFamilyChar(C)I -Landroid/icu/text/ArabicShaping;->isTailChar(C)Z -Landroid/icu/text/ArabicShaping;->isYehHamzaChar(C)Z -Landroid/icu/text/ArabicShaping;->shape(Ljava/lang/String;)Ljava/lang/String; -Landroid/icu/text/DateFormatSymbols;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale; -Landroid/icu/text/DateIntervalFormat;-><init>()V -Landroid/icu/text/DateTimePatternGenerator$DistanceInfo;-><init>()V -Landroid/icu/text/DecimalFormatSymbols;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale; -Landroid/icu/text/RuleBasedCollator;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale; -Landroid/icu/text/SpoofChecker$ScriptSet;-><init>()V -Landroid/icu/text/SpoofChecker$ScriptSet;->and(I)V -Landroid/icu/text/SpoofChecker$ScriptSet;->isFull()Z -Landroid/icu/text/SpoofChecker$ScriptSet;->setAll()V -Landroid/icu/text/TimeZoneNames$DefaultTimeZoneNames$FactoryImpl;-><init>()V -Landroid/icu/text/Transliterator;->createFromRules(Ljava/lang/String;Ljava/lang/String;I)Landroid/icu/text/Transliterator; -Landroid/icu/text/Transliterator;->getInstance(Ljava/lang/String;)Landroid/icu/text/Transliterator; -Landroid/icu/text/Transliterator;->getInstance(Ljava/lang/String;I)Landroid/icu/text/Transliterator; -Landroid/icu/text/Transliterator;->transliterate(Landroid/icu/text/Replaceable;Landroid/icu/text/Transliterator$Position;Ljava/lang/String;)V -Landroid/icu/text/Transliterator;->transliterate(Ljava/lang/String;)Ljava/lang/String; -Landroid/icu/text/UFormat;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale; -Landroid/icu/util/Calendar;->getLocale(Landroid/icu/util/ULocale$Type;)Landroid/icu/util/ULocale; -Landroid/icu/util/PersianCalendar;-><init>(Ljava/util/Locale;)V -Landroid/icu/util/UResourceBundle;->getBundleInstance(Ljava/lang/String;Landroid/icu/util/ULocale;)Landroid/icu/util/UResourceBundle; -Landroid/icu/util/UResourceBundle;->getKey()Ljava/lang/String; -Landroid/icu/util/UResourceBundle;->getString()Ljava/lang/String; -Landroid/icu/util/UResourceBundle;->getType()I -Landroid/icu/util/UResourceBundleIterator;->hasNext()Z -Landroid/icu/util/UResourceBundleIterator;->next()Landroid/icu/util/UResourceBundle; Landroid/inputmethodservice/IInputMethodSessionWrapper;->mCaller:Lcom/android/internal/os/HandlerCaller; Landroid/inputmethodservice/IInputMethodWrapper;->mCaller:Lcom/android/internal/os/HandlerCaller; Landroid/location/ICountryDetector$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ICountryDetector; @@ -1433,15 +1399,11 @@ Landroid/security/IKeystoreService;->exist(Ljava/lang/String;I)I Landroid/security/IKeystoreService;->generateKey(Ljava/lang/String;Landroid/security/keymaster/KeymasterArguments;[BIILandroid/security/keymaster/KeyCharacteristics;)I Landroid/security/IKeystoreService;->get(Ljava/lang/String;I)[B Landroid/security/IKeystoreService;->getState(I)I -Landroid/security/IKeystoreService;->get_pubkey(Ljava/lang/String;)[B -Landroid/security/IKeystoreService;->import_key(Ljava/lang/String;[BII)I Landroid/security/IKeystoreService;->insert(Ljava/lang/String;[BII)I Landroid/security/IKeystoreService;->is_hardware_backed(Ljava/lang/String;)I Landroid/security/IKeystoreService;->list(Ljava/lang/String;I)[Ljava/lang/String; Landroid/security/IKeystoreService;->reset()I -Landroid/security/IKeystoreService;->sign(Ljava/lang/String;[B)[B Landroid/security/IKeystoreService;->ungrant(Ljava/lang/String;I)I -Landroid/security/IKeystoreService;->verify(Ljava/lang/String;[B[B)I Landroid/security/keymaster/KeymasterBlobArgument;-><init>(ILandroid/os/Parcel;)V Landroid/security/keymaster/KeymasterBlobArgument;-><init>(I[B)V Landroid/security/keymaster/KeymasterBlobArgument;->blob:[B @@ -4327,172 +4289,6 @@ Lcom/android/okhttp/Response;->headers:Lcom/android/okhttp/Headers; Lcom/android/okhttp/Response;->message:Ljava/lang/String; Lcom/android/okhttp/Response;->networkResponse:Lcom/android/okhttp/Response; Lcom/android/okhttp/Response;->protocol:Lcom/android/okhttp/Protocol; -Lcom/android/org/bouncycastle/asn1/ASN1EncodableVector;-><init>()V -Lcom/android/org/bouncycastle/asn1/ASN1EncodableVector;->add(Lcom/android/org/bouncycastle/asn1/ASN1Encodable;)V -Lcom/android/org/bouncycastle/asn1/ASN1InputStream;-><init>(Ljava/io/InputStream;)V -Lcom/android/org/bouncycastle/asn1/ASN1InputStream;-><init>([B)V -Lcom/android/org/bouncycastle/asn1/ASN1InputStream;->readObject()Lcom/android/org/bouncycastle/asn1/ASN1Primitive; -Lcom/android/org/bouncycastle/asn1/ASN1Integer;-><init>(Ljava/math/BigInteger;)V -Lcom/android/org/bouncycastle/asn1/DERBitString;-><init>([B)V -Lcom/android/org/bouncycastle/asn1/DEREncodableVector;-><init>()V -Lcom/android/org/bouncycastle/asn1/DERInteger;-><init>(J)V -Lcom/android/org/bouncycastle/asn1/DERInteger;-><init>(Ljava/math/BigInteger;)V -Lcom/android/org/bouncycastle/asn1/DERNull;->INSTANCE:Lcom/android/org/bouncycastle/asn1/DERNull; -Lcom/android/org/bouncycastle/asn1/DERObjectIdentifier;-><init>(Ljava/lang/String;)V -Lcom/android/org/bouncycastle/asn1/DEROctetString;-><init>([B)V -Lcom/android/org/bouncycastle/asn1/DEROutputStream;-><init>(Ljava/io/OutputStream;)V -Lcom/android/org/bouncycastle/asn1/DERSequence;-><init>()V -Lcom/android/org/bouncycastle/asn1/DERSequence;-><init>(Lcom/android/org/bouncycastle/asn1/ASN1EncodableVector;)V -Lcom/android/org/bouncycastle/asn1/DERSet;-><init>(Lcom/android/org/bouncycastle/asn1/ASN1EncodableVector;)V -Lcom/android/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers;->sha256WithRSAEncryption:Lcom/android/org/bouncycastle/asn1/ASN1ObjectIdentifier; -Lcom/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier;-><init>(Lcom/android/org/bouncycastle/asn1/ASN1ObjectIdentifier;)V -Lcom/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier;-><init>(Lcom/android/org/bouncycastle/asn1/ASN1ObjectIdentifier;Lcom/android/org/bouncycastle/asn1/ASN1Encodable;)V -Lcom/android/org/bouncycastle/asn1/x509/Certificate;->getInstance(Ljava/lang/Object;)Lcom/android/org/bouncycastle/asn1/x509/Certificate; -Lcom/android/org/bouncycastle/asn1/x509/DigestInfo;-><init>(Lcom/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier;[B)V -Lcom/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo;->getInstance(Ljava/lang/Object;)Lcom/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo; -Lcom/android/org/bouncycastle/asn1/x509/Time;-><init>(Ljava/util/Date;)V -Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;-><init>()V -Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->generateTBSCertificate()Lcom/android/org/bouncycastle/asn1/x509/TBSCertificate; -Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setEndDate(Lcom/android/org/bouncycastle/asn1/x509/Time;)V -Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setIssuer(Lcom/android/org/bouncycastle/asn1/x509/X509Name;)V -Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setSerialNumber(Lcom/android/org/bouncycastle/asn1/ASN1Integer;)V -Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setSignature(Lcom/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier;)V -Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setStartDate(Lcom/android/org/bouncycastle/asn1/x509/Time;)V -Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setSubject(Lcom/android/org/bouncycastle/asn1/x509/X509Name;)V -Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setSubjectPublicKeyInfo(Lcom/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo;)V -Lcom/android/org/bouncycastle/asn1/x509/X509Name;-><init>(Lcom/android/org/bouncycastle/asn1/ASN1Sequence;)V -Lcom/android/org/bouncycastle/asn1/x509/X509Name;-><init>(Ljava/lang/String;)V -Lcom/android/org/bouncycastle/asn1/x509/X509Name;->CN:Lcom/android/org/bouncycastle/asn1/ASN1ObjectIdentifier; -Lcom/android/org/bouncycastle/asn1/x509/X509Name;->getOIDs()Ljava/util/Vector; -Lcom/android/org/bouncycastle/asn1/x509/X509Name;->getValues()Ljava/util/Vector; -Lcom/android/org/bouncycastle/asn1/x9/X9ObjectIdentifiers;->ecdsa_with_SHA256:Lcom/android/org/bouncycastle/asn1/ASN1ObjectIdentifier; -Lcom/android/org/bouncycastle/jce/provider/BouncyCastleProvider;-><init>()V -Lcom/android/org/bouncycastle/jce/provider/X509CertificateObject;-><init>(Lcom/android/org/bouncycastle/asn1/x509/Certificate;)V -Lcom/android/org/bouncycastle/jce/X509Principal;-><init>([B)V -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;-><init>()V -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->generate(Ljava/security/PrivateKey;)Ljava/security/cert/X509Certificate; -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setIssuerDN(Lcom/android/org/bouncycastle/asn1/x509/X509Name;)V -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setIssuerDN(Ljavax/security/auth/x500/X500Principal;)V -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setNotAfter(Ljava/util/Date;)V -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setNotBefore(Ljava/util/Date;)V -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setPublicKey(Ljava/security/PublicKey;)V -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setSerialNumber(Ljava/math/BigInteger;)V -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setSignatureAlgorithm(Ljava/lang/String;)V -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setSubjectDN(Lcom/android/org/bouncycastle/asn1/x509/X509Name;)V -Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setSubjectDN(Ljavax/security/auth/x500/X500Principal;)V -Lcom/android/org/conscrypt/AbstractConscryptSocket;->getAlpnSelectedProtocol()[B -Lcom/android/org/conscrypt/AbstractConscryptSocket;->getApplicationProtocol()Ljava/lang/String; -Lcom/android/org/conscrypt/AbstractConscryptSocket;->getApplicationProtocols()[Ljava/lang/String; -Lcom/android/org/conscrypt/AbstractConscryptSocket;->getChannelId()[B -Lcom/android/org/conscrypt/AbstractConscryptSocket;->getHandshakeApplicationProtocol()Ljava/lang/String; -Lcom/android/org/conscrypt/AbstractConscryptSocket;->getHostname()Ljava/lang/String; -Lcom/android/org/conscrypt/AbstractConscryptSocket;->getHostnameOrIP()Ljava/lang/String; -Lcom/android/org/conscrypt/AbstractConscryptSocket;->getNpnSelectedProtocol()[B -Lcom/android/org/conscrypt/AbstractConscryptSocket;->getSoWriteTimeout()I -Lcom/android/org/conscrypt/AbstractConscryptSocket;->setAlpnProtocols([B)V -Lcom/android/org/conscrypt/AbstractConscryptSocket;->setAlpnProtocols([Ljava/lang/String;)V -Lcom/android/org/conscrypt/AbstractConscryptSocket;->setApplicationProtocols([Ljava/lang/String;)V -Lcom/android/org/conscrypt/AbstractConscryptSocket;->setChannelIdEnabled(Z)V -Lcom/android/org/conscrypt/AbstractConscryptSocket;->setChannelIdPrivateKey(Ljava/security/PrivateKey;)V -Lcom/android/org/conscrypt/AbstractConscryptSocket;->setHandshakeTimeout(I)V -Lcom/android/org/conscrypt/AbstractConscryptSocket;->setHostname(Ljava/lang/String;)V -Lcom/android/org/conscrypt/AbstractConscryptSocket;->setNpnProtocols([B)V -Lcom/android/org/conscrypt/AbstractConscryptSocket;->setSoWriteTimeout(I)V -Lcom/android/org/conscrypt/AbstractConscryptSocket;->setUseSessionTickets(Z)V -Lcom/android/org/conscrypt/ClientSessionContext;->getSession(Ljava/lang/String;I)Lcom/android/org/conscrypt/NativeSslSession; -Lcom/android/org/conscrypt/ClientSessionContext;->setPersistentCache(Lcom/android/org/conscrypt/SSLClientSessionCache;)V -Lcom/android/org/conscrypt/ConscryptFileDescriptorSocket;->setHostname(Ljava/lang/String;)V -Lcom/android/org/conscrypt/ConscryptFileDescriptorSocket;->setUseSessionTickets(Z)V -Lcom/android/org/conscrypt/FileClientSessionCache$Impl;->getSessionData(Ljava/lang/String;I)[B -Lcom/android/org/conscrypt/FileClientSessionCache;->usingDirectory(Ljava/io/File;)Lcom/android/org/conscrypt/SSLClientSessionCache; -Lcom/android/org/conscrypt/NativeCrypto;->ASN1_seq_pack_X509([J)[B -Lcom/android/org/conscrypt/NativeCrypto;->ASN1_seq_unpack_X509_bio(J)[J -Lcom/android/org/conscrypt/NativeCrypto;->ASN1_TIME_to_Calendar(JLjava/util/Calendar;)V -Lcom/android/org/conscrypt/NativeCrypto;->BIO_free_all(J)V -Lcom/android/org/conscrypt/NativeCrypto;->create_BIO_InputStream(Lcom/android/org/conscrypt/OpenSSLBIOInputStream;Z)J -Lcom/android/org/conscrypt/NativeCrypto;->create_BIO_OutputStream(Ljava/io/OutputStream;)J -Lcom/android/org/conscrypt/NativeCrypto;->d2i_PKCS7_bio(JI)[J -Lcom/android/org/conscrypt/NativeCrypto;->d2i_SSL_SESSION([B)J -Lcom/android/org/conscrypt/NativeCrypto;->d2i_X509([B)J -Lcom/android/org/conscrypt/NativeCrypto;->d2i_X509_bio(J)J -Lcom/android/org/conscrypt/NativeCrypto;->d2i_X509_CRL_bio(J)J -Lcom/android/org/conscrypt/NativeCrypto;->EC_GROUP_clear_free(J)V -Lcom/android/org/conscrypt/NativeCrypto;->EC_GROUP_new_by_curve_name(Ljava/lang/String;)J -Lcom/android/org/conscrypt/NativeCrypto;->EC_POINT_clear_free(J)V -Lcom/android/org/conscrypt/NativeCrypto;->EVP_CIPHER_CTX_new()J -Lcom/android/org/conscrypt/NativeCrypto;->EVP_CIPHER_iv_length(J)I -Lcom/android/org/conscrypt/NativeCrypto;->EVP_get_cipherbyname(Ljava/lang/String;)J -Lcom/android/org/conscrypt/NativeCrypto;->EVP_get_digestbyname(Ljava/lang/String;)J -Lcom/android/org/conscrypt/NativeCrypto;->EVP_MD_CTX_create()J -Lcom/android/org/conscrypt/NativeCrypto;->EVP_MD_CTX_destroy(J)V -Lcom/android/org/conscrypt/NativeCrypto;->EVP_MD_size(J)I -Lcom/android/org/conscrypt/NativeCrypto;->EVP_PKEY_free(J)V -Lcom/android/org/conscrypt/NativeCrypto;->EVP_PKEY_new_RSA([B[B[B[B[B[B[B[B)J -Lcom/android/org/conscrypt/NativeCrypto;->get_X509_REVOKED_ext_oids(JI)[Ljava/lang/String; -Lcom/android/org/conscrypt/NativeCrypto;->get_X509_REVOKED_revocationDate(J)J -Lcom/android/org/conscrypt/NativeCrypto;->i2d_PKCS7([J)[B -Lcom/android/org/conscrypt/NativeCrypto;->i2d_SSL_SESSION(J)[B -Lcom/android/org/conscrypt/NativeCrypto;->i2d_X509_REVOKED(J)[B -Lcom/android/org/conscrypt/NativeCrypto;->PEM_read_bio_PKCS7(JI)[J -Lcom/android/org/conscrypt/NativeCrypto;->PEM_read_bio_X509(J)J -Lcom/android/org/conscrypt/NativeCrypto;->PEM_read_bio_X509_CRL(J)J -Lcom/android/org/conscrypt/NativeCrypto;->RAND_bytes([B)V -Lcom/android/org/conscrypt/NativeCrypto;->RSA_generate_key_ex(I[B)J -Lcom/android/org/conscrypt/NativeCrypto;->SSL_CTX_new()J -Lcom/android/org/conscrypt/NativeCrypto;->SSL_SESSION_cipher(J)Ljava/lang/String; -Lcom/android/org/conscrypt/NativeCrypto;->SSL_SESSION_free(J)V -Lcom/android/org/conscrypt/NativeCrypto;->SSL_SESSION_get_time(J)J -Lcom/android/org/conscrypt/NativeCrypto;->SSL_SESSION_get_version(J)Ljava/lang/String; -Lcom/android/org/conscrypt/NativeCrypto;->SSL_SESSION_session_id(J)[B -Lcom/android/org/conscrypt/NativeCrypto;->X509_REVOKED_dup(J)J -Lcom/android/org/conscrypt/NativeCrypto;->X509_REVOKED_get_ext(JLjava/lang/String;)J -Lcom/android/org/conscrypt/NativeCrypto;->X509_REVOKED_get_ext_oid(JLjava/lang/String;)[B -Lcom/android/org/conscrypt/NativeCrypto;->X509_REVOKED_get_serialNumber(J)[B -Lcom/android/org/conscrypt/NativeCrypto;->X509_REVOKED_print(JJ)V -Lcom/android/org/conscrypt/NativeCrypto;->X509_supported_extension(J)I -Lcom/android/org/conscrypt/OpenSSLBIOInputStream;-><init>(Ljava/io/InputStream;Z)V -Lcom/android/org/conscrypt/OpenSSLBIOInputStream;->getBioContext()J -Lcom/android/org/conscrypt/OpenSSLBIOInputStream;->release()V -Lcom/android/org/conscrypt/OpenSSLContextImpl$TLSv12;-><init>()V -Lcom/android/org/conscrypt/OpenSSLContextImpl;-><init>()V -Lcom/android/org/conscrypt/OpenSSLContextImpl;->engineGetClientSessionContext()Lcom/android/org/conscrypt/ClientSessionContext; -Lcom/android/org/conscrypt/OpenSSLContextImpl;->getPreferred()Lcom/android/org/conscrypt/OpenSSLContextImpl; -Lcom/android/org/conscrypt/OpenSSLKey;-><init>(J)V -Lcom/android/org/conscrypt/OpenSSLKey;->fromPrivateKey(Ljava/security/PrivateKey;)Lcom/android/org/conscrypt/OpenSSLKey; -Lcom/android/org/conscrypt/OpenSSLKey;->getNativeRef()Lcom/android/org/conscrypt/NativeRef$EVP_PKEY; -Lcom/android/org/conscrypt/OpenSSLKey;->getPublicKey()Ljava/security/PublicKey; -Lcom/android/org/conscrypt/OpenSSLKeyHolder;->getOpenSSLKey()Lcom/android/org/conscrypt/OpenSSLKey; -Lcom/android/org/conscrypt/OpenSSLProvider;-><init>()V -Lcom/android/org/conscrypt/OpenSSLRandom;-><init>()V -Lcom/android/org/conscrypt/OpenSSLSocketFactoryImpl;-><init>()V -Lcom/android/org/conscrypt/OpenSSLSocketFactoryImpl;->sslParameters:Lcom/android/org/conscrypt/SSLParametersImpl; -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getAlpnSelectedProtocol()[B -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getChannelId()[B -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getHostname()Ljava/lang/String; -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getHostnameOrIP()Ljava/lang/String; -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getNpnSelectedProtocol()[B -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getSoWriteTimeout()I -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setAlpnProtocols([B)V -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setAlpnProtocols([Ljava/lang/String;)V -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setChannelIdEnabled(Z)V -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setChannelIdPrivateKey(Ljava/security/PrivateKey;)V -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setHandshakeTimeout(I)V -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setHostname(Ljava/lang/String;)V -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setNpnProtocols([B)V -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setSoWriteTimeout(I)V -Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setUseSessionTickets(Z)V -Lcom/android/org/conscrypt/OpenSSLX509Certificate;->fromX509PemInputStream(Ljava/io/InputStream;)Lcom/android/org/conscrypt/OpenSSLX509Certificate; -Lcom/android/org/conscrypt/OpenSSLX509Certificate;->mContext:J -Lcom/android/org/conscrypt/SSLParametersImpl;->getDefault()Lcom/android/org/conscrypt/SSLParametersImpl; -Lcom/android/org/conscrypt/SSLParametersImpl;->getDefaultX509TrustManager()Ljavax/net/ssl/X509TrustManager; -Lcom/android/org/conscrypt/SSLParametersImpl;->getX509TrustManager()Ljavax/net/ssl/X509TrustManager; -Lcom/android/org/conscrypt/SSLParametersImpl;->setEnabledProtocols([Ljava/lang/String;)V -Lcom/android/org/conscrypt/SSLParametersImpl;->x509TrustManager:Ljavax/net/ssl/X509TrustManager; -Lcom/android/org/conscrypt/TrustedCertificateStore;-><init>()V -Lcom/android/org/conscrypt/TrustedCertificateStore;->getCertificateChain(Ljava/security/cert/X509Certificate;)Ljava/util/List; -Lcom/android/org/conscrypt/TrustManagerImpl;-><init>(Ljava/security/KeyStore;)V -Lcom/android/org/conscrypt/TrustManagerImpl;->checkServerTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;Ljava/lang/String;)Ljava/util/List; -Lcom/android/org/conscrypt/X509PublicKey;-><init>(Ljava/lang/String;[B)V Lcom/android/server/net/BaseNetworkObserver;-><init>()V Lcom/android/server/net/NetlinkTracker;-><init>(Ljava/lang/String;Lcom/android/server/net/NetlinkTracker$Callback;)V Lcom/android/server/net/NetlinkTracker;->clearLinkProperties()V diff --git a/core/java/android/app/DexLoadReporter.java b/core/java/android/app/DexLoadReporter.java index 0643414727cf..229bee55e911 100644 --- a/core/java/android/app/DexLoadReporter.java +++ b/core/java/android/app/DexLoadReporter.java @@ -87,7 +87,7 @@ import java.util.Set; } @Override - public void report(List<BaseDexClassLoader> classLoadersChain, List<String> classPaths) { + public void report(List<ClassLoader> classLoadersChain, List<String> classPaths) { if (classLoadersChain.size() != classPaths.size()) { Slog.wtf(TAG, "Bad call to DexLoadReporter: argument size mismatch"); return; @@ -113,12 +113,12 @@ import java.util.Set; registerSecondaryDexForProfiling(dexPathsForRegistration); } - private void notifyPackageManager(List<BaseDexClassLoader> classLoadersChain, + private void notifyPackageManager(List<ClassLoader> classLoadersChain, List<String> classPaths) { // Get the class loader names for the binder call. List<String> classLoadersNames = new ArrayList<>(classPaths.size()); - for (BaseDexClassLoader bdc : classLoadersChain) { - classLoadersNames.add(bdc.getClass().getName()); + for (ClassLoader classLoader : classLoadersChain) { + classLoadersNames.add(classLoader.getClass().getName()); } String packageName = ActivityThread.currentPackageName(); try { diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl index bc5b32c69b59..da7d6643c3fb 100644 --- a/core/java/android/content/pm/IPackageManager.aidl +++ b/core/java/android/content/pm/IPackageManager.aidl @@ -475,7 +475,7 @@ interface IPackageManager { * @param classPaths the class paths corresponding to the class loaders names from * {@param classLoadersNames}. The the first element corresponds to the first class loader * and so on. A classpath is represented as a list of dex files separated by - * {@code File.pathSeparator}. + * {@code File.pathSeparator}, or null if the class loader's classpath is not known. * The dex files found in the first class path will be recorded in the usage file. * @param loaderIsa the ISA of the loader process */ diff --git a/core/java/android/os/BinderProxy.java b/core/java/android/os/BinderProxy.java index e492f88d4329..591370ff728b 100644 --- a/core/java/android/os/BinderProxy.java +++ b/core/java/android/os/BinderProxy.java @@ -225,10 +225,11 @@ public final class BinderProxy implements IBinder { } } - /** - * Dump a histogram to the logcat. Used to diagnose abnormally large proxy maps. - */ - private void dumpProxyInterfaceCounts() { + private InterfaceCount[] getSortedInterfaceCounts(int maxToReturn) { + if (maxToReturn < 0) { + throw new IllegalArgumentException("negative interface count"); + } + Map<String, Integer> counts = new HashMap<>(); for (ArrayList<WeakReference<BinderProxy>> a : mMainIndexValues) { if (a != null) { @@ -258,13 +259,30 @@ public final class BinderProxy implements IBinder { } Map.Entry<String, Integer>[] sorted = counts.entrySet().toArray( new Map.Entry[counts.size()]); + Arrays.sort(sorted, (Map.Entry<String, Integer> a, Map.Entry<String, Integer> b) -> b.getValue().compareTo(a.getValue())); - Log.v(Binder.TAG, "BinderProxy descriptor histogram (top ten):"); - int printLength = Math.min(10, sorted.length); - for (int i = 0; i < printLength; i++) { - Log.v(Binder.TAG, " #" + (i + 1) + ": " + sorted[i].getKey() + " x" - + sorted[i].getValue()); + + int returnCount = Math.min(maxToReturn, sorted.length); + InterfaceCount[] ifaceCounts = new InterfaceCount[returnCount]; + for (int i = 0; i < returnCount; i++) { + ifaceCounts[i] = new InterfaceCount(sorted[i].getKey(), sorted[i].getValue()); + } + return ifaceCounts; + } + + static final int MAX_NUM_INTERFACES_TO_DUMP = 10; + + /** + * Dump a histogram to the logcat. Used to diagnose abnormally large proxy maps. + */ + private void dumpProxyInterfaceCounts() { + final InterfaceCount[] sorted = getSortedInterfaceCounts(MAX_NUM_INTERFACES_TO_DUMP); + + Log.v(Binder.TAG, "BinderProxy descriptor histogram " + + "(top " + Integer.toString(MAX_NUM_INTERFACES_TO_DUMP) + "):"); + for (int i = 0; i < sorted.length; i++) { + Log.v(Binder.TAG, " #" + (i + 1) + ": " + sorted[i]); } } @@ -296,30 +314,57 @@ public final class BinderProxy implements IBinder { new ArrayList[MAIN_INDEX_SIZE]; } - private static ProxyMap sProxyMap = new ProxyMap(); + @GuardedBy("sProxyMap") + private static final ProxyMap sProxyMap = new ProxyMap(); /** - * Dump proxy debug information. - * - * Note: this method is not thread-safe; callers must serialize with other - * accesses to sProxyMap, in particular {@link #getInstance(long, long)}. - * - * @hide - */ - private static void dumpProxyDebugInfo() { + * Simple pair-value class to store number of binder proxy interfaces live in this process. + */ + public static final class InterfaceCount { + private final String mInterfaceName; + private final int mCount; + + InterfaceCount(String interfaceName, int count) { + mInterfaceName = interfaceName; + mCount = count; + } + + @Override + public String toString() { + return mInterfaceName + " x" + Integer.toString(mCount); + } + } + + /** + * Get a sorted array with entries mapping proxy interface names to the number + * of live proxies with those names. + * + * @param num maximum number of proxy interface counts to return. Use + * Integer.MAX_VALUE to retrieve all + * @hide + */ + public static InterfaceCount[] getSortedInterfaceCounts(int num) { + synchronized (sProxyMap) { + return sProxyMap.getSortedInterfaceCounts(num); + } + } + + /** + * Dump proxy debug information. + * + * @hide + */ + public static void dumpProxyDebugInfo() { if (Build.IS_DEBUGGABLE) { - sProxyMap.dumpProxyInterfaceCounts(); - // Note that we don't call dumpPerUidProxyCounts(); this is because this - // method may be called as part of the uid limit being hit, and calling - // back into the UID tracking code would cause us to try to acquire a mutex - // that is held during that callback. + synchronized (sProxyMap) { + sProxyMap.dumpProxyInterfaceCounts(); + sProxyMap.dumpPerUidProxyCounts(); + } } } /** * Return a BinderProxy for IBinder. - * This method is thread-hostile! The (native) caller serializes getInstance() calls using - * gProxyLock. * If we previously returned a BinderProxy bp for the same iBinder, and bp is still * in use, then we return the same bp. * @@ -331,21 +376,23 @@ public final class BinderProxy implements IBinder { */ private static BinderProxy getInstance(long nativeData, long iBinder) { BinderProxy result; - try { - result = sProxyMap.get(iBinder); - if (result != null) { - return result; + synchronized (sProxyMap) { + try { + result = sProxyMap.get(iBinder); + if (result != null) { + return result; + } + result = new BinderProxy(nativeData); + } catch (Throwable e) { + // We're throwing an exception (probably OOME); don't drop nativeData. + NativeAllocationRegistry.applyFreeFunction(NoImagePreloadHolder.sNativeFinalizer, + nativeData); + throw e; } - result = new BinderProxy(nativeData); - } catch (Throwable e) { - // We're throwing an exception (probably OOME); don't drop nativeData. - NativeAllocationRegistry.applyFreeFunction(NoImagePreloadHolder.sNativeFinalizer, - nativeData); - throw e; + NoImagePreloadHolder.sRegistry.registerNativeAllocation(result, nativeData); + // The registry now owns nativeData, even if registration threw an exception. + sProxyMap.set(iBinder, result); } - NoImagePreloadHolder.sRegistry.registerNativeAllocation(result, nativeData); - // The registry now owns nativeData, even if registration threw an exception. - sProxyMap.set(iBinder, result); return result; } @@ -526,12 +573,11 @@ public final class BinderProxy implements IBinder { } } - private static final void sendDeathNotice(DeathRecipient recipient) { + private static void sendDeathNotice(DeathRecipient recipient) { if (false) Log.v("JavaBinder", "sendDeathNotice to " + recipient); try { recipient.binderDied(); - } - catch (RuntimeException exc) { + } catch (RuntimeException exc) { Log.w("BinderNative", "Uncaught exception from death notification", exc); } diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java index 88d6e847b644..ddeb8380c331 100644 --- a/core/java/android/os/FileUtils.java +++ b/core/java/android/os/FileUtils.java @@ -16,6 +16,18 @@ package android.os; +import static android.os.ParcelFileDescriptor.MODE_APPEND; +import static android.os.ParcelFileDescriptor.MODE_CREATE; +import static android.os.ParcelFileDescriptor.MODE_READ_ONLY; +import static android.os.ParcelFileDescriptor.MODE_READ_WRITE; +import static android.os.ParcelFileDescriptor.MODE_TRUNCATE; +import static android.os.ParcelFileDescriptor.MODE_WRITE_ONLY; +import static android.system.OsConstants.O_APPEND; +import static android.system.OsConstants.O_CREAT; +import static android.system.OsConstants.O_RDONLY; +import static android.system.OsConstants.O_RDWR; +import static android.system.OsConstants.O_TRUNC; +import static android.system.OsConstants.O_WRONLY; import static android.system.OsConstants.SPLICE_F_MORE; import static android.system.OsConstants.SPLICE_F_MOVE; import static android.system.OsConstants.S_ISFIFO; @@ -1050,6 +1062,30 @@ public class FileUtils { return val * pow; } + /** {@hide} */ + public static int translateModePfdToPosix(int mode) { + int res = 0; + if ((mode & MODE_READ_WRITE) == MODE_READ_WRITE) { + res |= O_RDWR; + } else if ((mode & MODE_WRITE_ONLY) == MODE_WRITE_ONLY) { + res |= O_WRONLY; + } else if ((mode & MODE_READ_ONLY) == MODE_READ_ONLY) { + res |= O_RDONLY; + } else { + throw new IllegalArgumentException("Bad mode: " + mode); + } + if ((mode & MODE_CREATE) == MODE_CREATE) { + res |= O_CREAT; + } + if ((mode & MODE_TRUNCATE) == MODE_TRUNCATE) { + res |= O_TRUNC; + } + if ((mode & MODE_APPEND) == MODE_APPEND) { + res |= O_APPEND; + } + return res; + } + @VisibleForTesting public static class MemoryPipe extends Thread implements AutoCloseable { private final FileDescriptor[] pipe; @@ -1115,3 +1151,4 @@ public class FileUtils { } } } + diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java index c9edc531d134..81fc5c0303d5 100644 --- a/core/java/android/os/ParcelFileDescriptor.java +++ b/core/java/android/os/ParcelFileDescriptor.java @@ -917,9 +917,9 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { @Override public void close() throws IOException { try { - mPfd.close(); - } finally { super.close(); + } finally { + mPfd.close(); } } @@ -968,9 +968,9 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { @Override public void close() throws IOException { try { - mPfd.close(); - } finally { super.close(); + } finally { + mPfd.close(); } } } @@ -1092,6 +1092,9 @@ public class ParcelFileDescriptor implements Parcelable, Closeable { /** * Internal class representing a remote status read by * {@link ParcelFileDescriptor#readCommStatus(FileDescriptor, byte[])}. + * + * Warning: this must be kept in sync with ParcelFileDescriptorStatus at + * frameworks/native/libs/binder/Parcel.cpp */ private static class Status { /** Special value indicating remote side died. */ diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index d9eb7754ef7b..d072d02741ed 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -774,7 +774,7 @@ public class StorageManager { try { for (VolumeInfo vol : mStorageManager.getVolumes(0)) { if (vol.path != null && FileUtils.contains(vol.path, pathString) - && vol.type != VolumeInfo.TYPE_PUBLIC) { + && vol.type != VolumeInfo.TYPE_PUBLIC && vol.type != VolumeInfo.TYPE_STUB) { // TODO: verify that emulated adopted devices have UUID of // underlying volume try { diff --git a/core/java/android/os/storage/VolumeInfo.java b/core/java/android/os/storage/VolumeInfo.java index afd383691300..a0c7f753f394 100644 --- a/core/java/android/os/storage/VolumeInfo.java +++ b/core/java/android/os/storage/VolumeInfo.java @@ -84,6 +84,7 @@ public class VolumeInfo implements Parcelable { public static final int TYPE_EMULATED = IVold.VOLUME_TYPE_EMULATED; public static final int TYPE_ASEC = IVold.VOLUME_TYPE_ASEC; public static final int TYPE_OBB = IVold.VOLUME_TYPE_OBB; + public static final int TYPE_STUB = IVold.VOLUME_TYPE_STUB; public static final int STATE_UNMOUNTED = IVold.VOLUME_STATE_UNMOUNTED; public static final int STATE_CHECKING = IVold.VOLUME_STATE_CHECKING; @@ -295,7 +296,7 @@ public class VolumeInfo implements Parcelable { } public boolean isVisibleForUser(int userId) { - if (type == TYPE_PUBLIC && mountUserId == userId) { + if ((type == TYPE_PUBLIC || type == TYPE_STUB) && mountUserId == userId) { return isVisible(); } else if (type == TYPE_EMULATED) { return isVisible(); @@ -327,7 +328,7 @@ public class VolumeInfo implements Parcelable { public File getPathForUser(int userId) { if (path == null) { return null; - } else if (type == TYPE_PUBLIC) { + } else if (type == TYPE_PUBLIC || type == TYPE_STUB) { return new File(path); } else if (type == TYPE_EMULATED) { return new File(path, Integer.toString(userId)); @@ -344,7 +345,7 @@ public class VolumeInfo implements Parcelable { public File getInternalPathForUser(int userId) { if (path == null) { return null; - } else if (type == TYPE_PUBLIC) { + } else if (type == TYPE_PUBLIC || type == TYPE_STUB) { // TODO: plumb through cleaner path from vold return new File(path.replace("/storage/", "/mnt/media_rw/")); } else { @@ -390,7 +391,7 @@ public class VolumeInfo implements Parcelable { removable = true; } - } else if (type == TYPE_PUBLIC) { + } else if (type == TYPE_PUBLIC || type == TYPE_STUB) { emulated = false; removable = true; @@ -447,7 +448,8 @@ public class VolumeInfo implements Parcelable { public @Nullable Intent buildBrowseIntentForUser(int userId) { final Uri uri; - if (type == VolumeInfo.TYPE_PUBLIC && mountUserId == userId) { + if ((type == VolumeInfo.TYPE_PUBLIC || type == VolumeInfo.TYPE_STUB) + && mountUserId == userId) { uri = DocumentsContract.buildRootUri(DOCUMENT_AUTHORITY, fsUuid); } else if (type == VolumeInfo.TYPE_EMULATED && isPrimary()) { uri = DocumentsContract.buildRootUri(DOCUMENT_AUTHORITY, diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java index c0fa1de6feeb..3d93afdd1423 100644 --- a/core/java/android/provider/CallLog.java +++ b/core/java/android/provider/CallLog.java @@ -509,6 +509,100 @@ public class CallLog { private static final int MIN_DURATION_FOR_NORMALIZED_NUMBER_UPDATE_MS = 1000 * 10; /** + * Value for {@link CallLog.Calls#BLOCK_REASON}, set as the default value when a call was + * not blocked by a CallScreeningService or any other system call blocking method. + */ + public static final int BLOCK_REASON_NOT_BLOCKED = 0; + + /** + * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is + * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked by a + * CallScreeningService. The {@link CallLog.Calls#CALL_SCREENING_COMPONENT_NAME} and + * {@link CallLog.Calls#CALL_SCREENING_APP_NAME} columns will indicate which call screening + * service was responsible for blocking the call. + */ + public static final int BLOCK_REASON_CALL_SCREENING_SERVICE = 1; + + /** + * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is + * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked because the user + * configured a contact to be sent directly to voicemail. + */ + public static final int BLOCK_REASON_DIRECT_TO_VOICEMAIL = 2; + + /** + * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is + * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked because it is + * in the BlockedNumbers provider. + */ + public static final int BLOCK_REASON_BLOCKED_NUMBER = 3; + + /** + * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is + * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked because the user + * has chosen to block all calls from unknown numbers. + */ + public static final int BLOCK_REASON_UNKNOWN_NUMBER = 4; + + /** + * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is + * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked because the user + * has chosen to block all calls from restricted numbers. + */ + public static final int BLOCK_REASON_RESTRICTED_NUMBER = 5; + + /** + * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is + * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked because the user + * has chosen to block all calls from pay phones. + */ + public static final int BLOCK_REASON_PAY_PHONE = 6; + + /** + * Value for {@link CallLog.Calls#BLOCK_REASON}, set when {@link CallLog.Calls#TYPE} is + * {@link CallLog.Calls#BLOCKED_TYPE} to indicate that a call was blocked because the user + * has chosen to block all calls from numbers not in their contacts. + */ + public static final int BLOCK_REASON_NOT_IN_CONTACTS = 7; + + /** + * The ComponentName of the CallScreeningService which blocked this call. Will be + * populated when the {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#BLOCKED_TYPE}. + * <P>Type: TEXT</P> + */ + public static final String CALL_SCREENING_COMPONENT_NAME = "call_screening_component_name"; + + /** + * The name of the app which blocked a call. Will be populated when the + * {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#BLOCKED_TYPE}. Provided as a + * convenience so that the call log can still indicate which app blocked a call, even if + * that app is no longer installed. + * <P>Type: TEXT</P> + */ + public static final String CALL_SCREENING_APP_NAME = "call_screening_app_name"; + + /** + * Where the {@link CallLog.Calls#TYPE} is {@link CallLog.Calls#BLOCKED_TYPE}, + * indicates the reason why a call is blocked. + * <P>Type: INTEGER</P> + * + * <p> + * Allowed values: + * <ul> + * <li>{@link CallLog.Calls#BLOCK_REASON_NOT_BLOCKED}</li> + * <li>{@link CallLog.Calls#BLOCK_REASON_CALL_SCREENING_SERVICE}</li> + * <li>{@link CallLog.Calls#BLOCK_REASON_DIRECT_TO_VOICEMAIL}</li> + * <li>{@link CallLog.Calls#BLOCK_REASON_BLOCKED_NUMBER}</li> + * <li>{@link CallLog.Calls#BLOCK_REASON_UNKNOWN_NUMBER}</li> + * <li>{@link CallLog.Calls#BLOCK_REASON_RESTRICTED_NUMBER}</li> + * <li>{@link CallLog.Calls#BLOCK_REASON_PAY_PHONE}</li> + * <li>{@link CallLog.Calls#BLOCK_REASON_NOT_IN_CONTACTS}</li> + * </ul> + * </p> + */ + public static final String BLOCK_REASON = "block_reason"; + + /** * Adds a call to the call log. * * @param ci the CallerInfo object to get the target contact from. Can be null @@ -530,12 +624,14 @@ public class CallLog { * {@hide} */ public static Uri addCall(CallerInfo ci, Context context, String number, - int presentation, int callType, int features, PhoneAccountHandle accountHandle, + int presentation, int callType, int features, + PhoneAccountHandle accountHandle, long start, int duration, Long dataUsage) { - return addCall(ci, context, number, /* postDialDigits =*/ "", /* viaNumber =*/ "", - presentation, callType, features, accountHandle, start, duration, - dataUsage, /* addForAllUsers =*/ false, /* userToBeInsertedTo =*/ null, - /* is_read =*/ false); + return addCall(ci, context, number, "" /* postDialDigits */, "" /* viaNumber */, + presentation, callType, features, accountHandle, start, duration, + dataUsage, false /* addForAllUsers */, null /* userToBeInsertedTo */, + false /* isRead */, Calls.BLOCK_REASON_NOT_BLOCKED /* callBlockReason */, + null /* callScreeningAppName */, null /* callScreeningComponentName */); } @@ -572,8 +668,10 @@ public class CallLog { int features, PhoneAccountHandle accountHandle, long start, int duration, Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo) { return addCall(ci, context, number, postDialDigits, viaNumber, presentation, callType, - features, accountHandle, start, duration, dataUsage, addForAllUsers, - userToBeInsertedTo, /* is_read =*/ false); + features, accountHandle, start, duration, dataUsage, addForAllUsers, + userToBeInsertedTo, false /* isRead */ , Calls.BLOCK_REASON_NOT_BLOCKED + /* callBlockReason */, null /* callScreeningAppName */, + null /* callScreeningComponentName */); } /** @@ -602,8 +700,11 @@ public class CallLog { * @param userToBeInsertedTo {@link UserHandle} of user that the call is going to be * inserted to. null if it is inserted to the current user. The * value is ignored if @{link addForAllUsers} is true. - * @param is_read Flag to show if the missed call log has been read by the user or not. + * @param isRead Flag to show if the missed call log has been read by the user or not. * Used for call log restore of missed calls. + * @param callBlockReason The reason why the call is blocked. + * @param callScreeningAppName The call screening application name which block the call. + * @param callScreeningComponentName The call screening component name which block the call. * * @result The URI of the call log entry belonging to the user that made or received this * call. This could be of the shadow provider. Do not return it to non-system apps, @@ -615,7 +716,8 @@ public class CallLog { String postDialDigits, String viaNumber, int presentation, int callType, int features, PhoneAccountHandle accountHandle, long start, int duration, Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo, - boolean is_read) { + boolean isRead, int callBlockReason, String callScreeningAppName, + String callScreeningComponentName) { if (VERBOSE_LOG) { Log.v(LOG_TAG, String.format("Add call: number=%s, user=%s, for all=%s", number, userToBeInsertedTo, addForAllUsers)); @@ -690,9 +792,13 @@ public class CallLog { values.put(ADD_FOR_ALL_USERS, addForAllUsers ? 1 : 0); if (callType == MISSED_TYPE) { - values.put(IS_READ, Integer.valueOf(is_read ? 1 : 0)); + values.put(IS_READ, Integer.valueOf(isRead ? 1 : 0)); } + values.put(BLOCK_REASON, callBlockReason); + values.put(CALL_SCREENING_APP_NAME, callScreeningAppName); + values.put(CALL_SCREENING_COMPONENT_NAME, callScreeningComponentName); + if ((ci != null) && (ci.contactIdOrZero > 0)) { // Update usage information for the number associated with the contact ID. // We need to use both the number and the ID for obtaining a data ID since other diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index ba72be637c15..325fcc64781a 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -24045,7 +24045,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @param outShadowSize A {@link android.graphics.Point} containing the width and height * of the shadow image. Your application must set {@link android.graphics.Point#x} to the * desired width and must set {@link android.graphics.Point#y} to the desired height of the - * image. + * image. Since Android P, the width and height must be positive values. * * @param outShadowTouchPoint A {@link android.graphics.Point} for the position within the * shadow image that should be underneath the touch point during the drag and drop diff --git a/core/jni/Android.bp b/core/jni/Android.bp index ed59dd4e60d1..3326d1219e77 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -233,7 +233,7 @@ cc_library_shared { ], shared_libs: [ - "libbpf", + "libbpf_android", "libnetdbpf", "libnetdutils", "libmemtrack", diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index 9341d9a48913..adff4d644c08 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -110,7 +110,6 @@ static struct binderproxy_offsets_t jclass mClass; jmethodID mGetInstance; jmethodID mSendDeathNotice; - jmethodID mDumpProxyDebugInfo; // Object state. jfieldID mNativeData; // Field holds native pointer to BinderProxyNativeData. @@ -1038,18 +1037,6 @@ static void android_os_BinderInternal_handleGc(JNIEnv* env, jobject clazz) static void android_os_BinderInternal_proxyLimitcallback(int uid) { JNIEnv *env = AndroidRuntime::getJNIEnv(); - { - // Calls into BinderProxy must be serialized - AutoMutex _l(gProxyLock); - env->CallStaticObjectMethod(gBinderProxyOffsets.mClass, - gBinderProxyOffsets.mDumpProxyDebugInfo); - } - if (env->ExceptionCheck()) { - ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred()); - report_exception(env, excep.get(), - "*** Uncaught exception in dumpProxyDebugInfo"); - } - env->CallStaticVoidMethod(gBinderInternalOffsets.mClass, gBinderInternalOffsets.mProxyLimitCallback, uid); @@ -1439,8 +1426,6 @@ static int int_register_android_os_BinderProxy(JNIEnv* env) "(JJ)Landroid/os/BinderProxy;"); gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;)V"); - gBinderProxyOffsets.mDumpProxyDebugInfo = GetStaticMethodIDOrDie(env, clazz, "dumpProxyDebugInfo", - "()V"); gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J"); clazz = FindClassOrDie(env, "java/lang/Class"); diff --git a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp index b3ff4dbf8bef..b708735616c4 100644 --- a/core/jni/com_android_internal_net_NetworkStatsFactory.cpp +++ b/core/jni/com_android_internal_net_NetworkStatsFactory.cpp @@ -175,7 +175,7 @@ static int legacyReadNetworkStatsDetail(std::vector<stats_line>* lines, } } s.tag = rawTag >> 32; - if (limitTag != -1 && s.tag != limitTag) { + if (limitTag != -1 && s.tag != static_cast<uint32_t>(limitTag)) { //ALOGI("skipping due to tag: %s", buffer); continue; } @@ -188,7 +188,7 @@ static int legacyReadNetworkStatsDetail(std::vector<stats_line>* lines, if (sscanf(pos, "%u %u %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64, &s.uid, &s.set, &s.rxBytes, &s.rxPackets, &s.txBytes, &s.txPackets) == 6) { - if (limitUid != -1 && limitUid != s.uid) { + if (limitUid != -1 && static_cast<uint32_t>(limitUid) != s.uid) { //ALOGI("skipping due to uid: %s", buffer); continue; } diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 1f3a8fce8ef1..9ce6044bcf3e 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -398,6 +398,8 @@ <protected-broadcast android:name="android.telecom.action.DEFAULT_DIALER_CHANGED" /> <protected-broadcast android:name="android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED" /> + <protected-broadcast android:name="android.provider.action.SMS_MMS_DB_CREATED" /> + <protected-broadcast android:name="android.provider.action.SMS_MMS_DB_LOST" /> <protected-broadcast android:name="android.intent.action.CONTENT_CHANGED" /> <protected-broadcast android:name="android.provider.Telephony.MMS_DOWNLOADED" /> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 0f31a8a7d00c..8518c7021ee7 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -248,6 +248,10 @@ <item>@string/wfcSpnFormat_spn_wifi</item> <item>@string/wfcSpnFormat_wifi_calling_bar_spn</item> <item>@string/wfcSpnFormat_spn_vowifi</item> + <item>@string/wfcSpnFormat_wifi_calling</item> + <item>@string/wfcSpnFormat_wifi</item> + <item>@string/wfcSpnFormat_wifi_calling_wo_hyphen</item> + <item>@string/wfcSpnFormat_vowifi</item> </string-array> <!-- Spn during Wi-Fi Calling: "<operator>" --> @@ -264,6 +268,14 @@ <string name="wfcSpnFormat_wifi_calling_bar_spn">WiFi Calling | <xliff:g id="spn" example="Operator">%s</xliff:g></string> <!-- Spn during Wi-Fi Calling: "<operator> VoWifi" --> <string name="wfcSpnFormat_spn_vowifi"><xliff:g id="spn" example="Operator">%s</xliff:g> VoWifi</string> + <!-- Spn during Wi-Fi Calling: "Wi-Fi Calling" --> + <string name="wfcSpnFormat_wifi_calling">Wi-Fi Calling</string> + <!-- Spn during Wi-Fi Calling: "Wi-Fi" --> + <string name="wfcSpnFormat_wifi">Wi-Fi</string> + <!-- Spn during Wi-Fi Calling: "WiFi Calling" (without hyphen) --> + <string name="wfcSpnFormat_wifi_calling_wo_hyphen">WiFi Calling</string> + <!-- Spn during Wi-Fi Calling: "VoWifi" --> + <string name="wfcSpnFormat_vowifi">VoWifi</string> <!-- WFC, summary for Disabled --> <string name="wifi_calling_off_summary">Off</string> diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index 799900f3bd6a..4e018833f1ff 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -30,6 +30,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; +import android.security.KeyStoreException; import android.security.keymaster.ExportResult; import android.security.keymaster.KeyCharacteristics; import android.security.keymaster.KeymasterArguments; @@ -40,14 +41,21 @@ import android.security.keymaster.OperationResult; import android.security.keystore.KeyExpiredException; import android.security.keystore.KeyNotYetValidException; import android.security.keystore.KeyPermanentlyInvalidatedException; +import android.security.keystore.KeyProperties; +import android.security.keystore.KeyProtection; import android.security.keystore.StrongBoxUnavailableException; import android.security.keystore.UserNotAuthenticatedException; import android.util.Log; - +import com.android.org.bouncycastle.asn1.ASN1InputStream; +import com.android.org.bouncycastle.asn1.pkcs.PrivateKeyInfo; import java.math.BigInteger; +import java.io.ByteArrayInputStream; +import java.io.IOException; import java.security.InvalidKeyException; import java.util.List; import java.util.Locale; +import sun.security.util.ObjectIdentifier; +import sun.security.x509.AlgorithmId; /** * @hide This should not be made public in its present form because it @@ -69,6 +77,7 @@ public class KeyStore { public static final int VALUE_CORRUPTED = 8; public static final int UNDEFINED_ACTION = 9; public static final int WRONG_PASSWORD = 10; + public static final int KEY_ALREADY_EXISTS = 16; public static final int CANNOT_ATTEST_IDS = -66; public static final int HARDWARE_TYPE_UNAVAILABLE = -68; @@ -228,7 +237,12 @@ public class KeyStore { if (value == null) { value = new byte[0]; } - return mBinder.insert(key, value, uid, flags); + int error = mBinder.insert(key, value, uid, flags); + if (error == KEY_ALREADY_EXISTS) { + mBinder.del(key, uid); + error = mBinder.insert(key, value, uid, flags); + } + return error; } catch (RemoteException e) { Log.w(TAG, "Cannot connect to keystore", e); return SYSTEM_ERROR; @@ -355,53 +369,6 @@ public class KeyStore { return isEmpty(UserHandle.myUserId()); } - public boolean generate(String key, int uid, int keyType, int keySize, int flags, - byte[][] args) { - try { - return mBinder.generate(key, uid, keyType, keySize, flags, - new KeystoreArguments(args)) == NO_ERROR; - } catch (RemoteException e) { - Log.w(TAG, "Cannot connect to keystore", e); - return false; - } - } - - public boolean importKey(String keyName, byte[] key, int uid, int flags) { - try { - return mBinder.import_key(keyName, key, uid, flags) == NO_ERROR; - } catch (RemoteException e) { - Log.w(TAG, "Cannot connect to keystore", e); - return false; - } - } - - public byte[] sign(String key, byte[] data) { - try { - return mBinder.sign(key, data); - } catch (RemoteException e) { - Log.w(TAG, "Cannot connect to keystore", e); - return null; - } catch (android.os.ServiceSpecificException e) { - Log.w(TAG, "KeyStore exception", e); - return null; - } - - } - - public boolean verify(String key, byte[] data, byte[] signature) { - try { - signature = signature != null ? signature : new byte[0]; - return mBinder.verify(key, data, signature) == NO_ERROR; - } catch (RemoteException e) { - Log.w(TAG, "Cannot connect to keystore", e); - return false; - } catch (android.os.ServiceSpecificException e) { - Log.w(TAG, "KeyStore exception", e); - return false; - } - - } - public String grant(String key, int uid) { try { String grantAlias = mBinder.grant(key, uid); @@ -485,7 +452,12 @@ public class KeyStore { try { entropy = entropy != null ? entropy : new byte[0]; args = args != null ? args : new KeymasterArguments(); - return mBinder.generateKey(alias, args, entropy, uid, flags, outCharacteristics); + int error = mBinder.generateKey(alias, args, entropy, uid, flags, outCharacteristics); + if (error == KEY_ALREADY_EXISTS) { + mBinder.del(alias, uid); + error = mBinder.generateKey(alias, args, entropy, uid, flags, outCharacteristics); + } + return error; } catch (RemoteException e) { Log.w(TAG, "Cannot connect to keystore", e); return SYSTEM_ERROR; @@ -517,8 +489,14 @@ public class KeyStore { public int importKey(String alias, KeymasterArguments args, int format, byte[] keyData, int uid, int flags, KeyCharacteristics outCharacteristics) { try { - return mBinder.importKey(alias, args, format, keyData, uid, flags, + int error = mBinder.importKey(alias, args, format, keyData, uid, flags, outCharacteristics); + if (error == KEY_ALREADY_EXISTS) { + mBinder.del(alias, uid); + error = mBinder.importKey(alias, args, format, keyData, uid, flags, + outCharacteristics); + } + return error; } catch (RemoteException e) { Log.w(TAG, "Cannot connect to keystore", e); return SYSTEM_ERROR; @@ -530,13 +508,78 @@ public class KeyStore { return importKey(alias, args, format, keyData, UID_SELF, flags, outCharacteristics); } + private String getAlgorithmFromPKCS8(byte[] keyData) { + try { + final ASN1InputStream bIn = new ASN1InputStream(new ByteArrayInputStream(keyData)); + final PrivateKeyInfo pki = PrivateKeyInfo.getInstance(bIn.readObject()); + final String algOid = pki.getPrivateKeyAlgorithm().getAlgorithm().getId(); + return new AlgorithmId(new ObjectIdentifier(algOid)).getName(); + } catch (IOException e) { + Log.e(TAG, "getAlgorithmFromPKCS8 Failed to parse key data"); + Log.e(TAG, Log.getStackTraceString(e)); + return null; + } + } + + private KeymasterArguments makeLegacyArguments(String algorithm) { + KeymasterArguments args = new KeymasterArguments(); + args.addEnum(KeymasterDefs.KM_TAG_ALGORITHM, + KeyProperties.KeyAlgorithm.toKeymasterAsymmetricKeyAlgorithm(algorithm)); + args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_SIGN); + args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_VERIFY); + args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_ENCRYPT); + args.addEnum(KeymasterDefs.KM_TAG_PURPOSE, KeymasterDefs.KM_PURPOSE_DECRYPT); + args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_NONE); + if (algorithm.equalsIgnoreCase(KeyProperties.KEY_ALGORITHM_RSA)) { + args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_RSA_OAEP); + args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT); + args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_SIGN); + args.addEnum(KeymasterDefs.KM_TAG_PADDING, KeymasterDefs.KM_PAD_RSA_PSS); + } + args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_NONE); + args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_MD5); + args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA1); + args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA_2_224); + args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA_2_256); + args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA_2_384); + args.addEnum(KeymasterDefs.KM_TAG_DIGEST, KeymasterDefs.KM_DIGEST_SHA_2_512); + args.addBoolean(KeymasterDefs.KM_TAG_NO_AUTH_REQUIRED); + args.addUnsignedLong(KeymasterDefs.KM_TAG_ORIGINATION_EXPIRE_DATETIME, + KeymasterArguments.UINT64_MAX_VALUE); + args.addUnsignedLong(KeymasterDefs.KM_TAG_USAGE_EXPIRE_DATETIME, + KeymasterArguments.UINT64_MAX_VALUE); + args.addUnsignedLong(KeymasterDefs.KM_TAG_ACTIVE_DATETIME, BigInteger.ZERO); + return args; + } + + public boolean importKey(String alias, byte[] keyData, int uid, int flags) { + String algorithm = getAlgorithmFromPKCS8(keyData); + if (algorithm == null) return false; + KeymasterArguments args = makeLegacyArguments(algorithm); + KeyCharacteristics out = new KeyCharacteristics(); + int result = importKey(alias, args, KeymasterDefs.KM_KEY_FORMAT_PKCS8, keyData, uid, + flags, out); + if (result != NO_ERROR) { + Log.e(TAG, Log.getStackTraceString( + new KeyStoreException(result, "legacy key import failed"))); + return false; + } + return true; + } + public int importWrappedKey(String wrappedKeyAlias, byte[] wrappedKey, String wrappingKeyAlias, byte[] maskingKey, KeymasterArguments args, long rootSid, long fingerprintSid, int uid, KeyCharacteristics outCharacteristics) { try { - return mBinder.importWrappedKey(wrappedKeyAlias, wrappedKey, wrappingKeyAlias, + int error = mBinder.importWrappedKey(wrappedKeyAlias, wrappedKey, wrappingKeyAlias, maskingKey, args, rootSid, fingerprintSid, outCharacteristics); + if (error == KEY_ALREADY_EXISTS) { + mBinder.del(wrappedKeyAlias, -1); + error = mBinder.importWrappedKey(wrappedKeyAlias, wrappedKey, wrappingKeyAlias, + maskingKey, args, rootSid, fingerprintSid, outCharacteristics); + } + return error; } catch (RemoteException e) { Log.w(TAG, "Cannot connect to keystore", e); return SYSTEM_ERROR; @@ -616,21 +659,6 @@ public class KeyStore { } /** - * Check if the operation referenced by {@code token} is currently authorized. - * - * @param token An operation token returned by a call to - * {@link #begin(String, int, boolean, KeymasterArguments, byte[], KeymasterArguments) begin}. - */ - public boolean isOperationAuthorized(IBinder token) { - try { - return mBinder.isOperationAuthorized(token); - } catch (RemoteException e) { - Log.w(TAG, "Cannot connect to keystore", e); - return false; - } - } - - /** * Add an authentication record to the keystore authorization table. * * @param authToken The packed bytes of a hw_auth_token_t to be provided to keymaster. diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java index 8207a5410519..091c659ee97f 100644 --- a/media/java/android/media/MediaScanner.java +++ b/media/java/android/media/MediaScanner.java @@ -1634,7 +1634,7 @@ public class MediaScanner implements AutoCloseable { selectionArgs = new String[] { path }; c = mMediaProvider.query(mFilesUriNoNotify, FILES_PRESCAN_PROJECTION, where, selectionArgs, null, null); - if (c.moveToFirst()) { + if (c != null && c.moveToFirst()) { long rowId = c.getLong(FILES_PRESCAN_ID_COLUMN_INDEX); int format = c.getInt(FILES_PRESCAN_FORMAT_COLUMN_INDEX); long lastModified = c.getLong(FILES_PRESCAN_DATE_MODIFIED_COLUMN_INDEX); diff --git a/native/android/Android.bp b/native/android/Android.bp index 4fb5e748aaac..c26d980aa2fc 100644 --- a/native/android/Android.bp +++ b/native/android/Android.bp @@ -76,6 +76,8 @@ cc_library_shared { export_static_lib_headers: ["libarect"], include_dirs: ["bionic/libc/dns/include"], + + version_script: "libandroid.map.txt", } // Network library. diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java index 0a720a5b234e..4a9c35615131 100644 --- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java +++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java @@ -184,7 +184,8 @@ public class ExternalStorageProvider extends FileSystemProvider { title = mStorageManager.getBestVolumeDescription(privateVol); storageUuid = StorageManager.convert(privateVol.fsUuid); } - } else if (volume.getType() == VolumeInfo.TYPE_PUBLIC + } else if ((volume.getType() == VolumeInfo.TYPE_PUBLIC + || volume.getType() == VolumeInfo.TYPE_STUB) && volume.getMountUserId() == userId) { rootId = volume.getFsUuid(); title = mStorageManager.getBestVolumeDescription(volume); diff --git a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java index 5a57e69ae131..8f9394fd3c5a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java +++ b/packages/SettingsLib/src/com/android/settingslib/deviceinfo/StorageMeasurement.java @@ -152,7 +152,8 @@ public class StorageMeasurement { final MeasurementDetails details = new MeasurementDetails(); if (mVolume == null) return details; - if (mVolume.getType() == VolumeInfo.TYPE_PUBLIC) { + if (mVolume.getType() == VolumeInfo.TYPE_PUBLIC + || mVolume.getType() == VolumeInfo.TYPE_STUB) { details.totalSize = mVolume.getPath().getTotalSpace(); details.availSize = mVolume.getPath().getUsableSpace(); return details; diff --git a/packages/Shell/OWNERS b/packages/Shell/OWNERS new file mode 100644 index 000000000000..75c0391e6840 --- /dev/null +++ b/packages/Shell/OWNERS @@ -0,0 +1,10 @@ +svetoslavganov@google.com +hackbod@google.com +yamasani@google.com +moltmann@google.com +toddke@google.com +jsharkey@google.com +cbrubaker@google.com +omakoto@google.com +nandana@google.com +felipeal@google.com diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java index cb8c119d08eb..f400f6039882 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPinBasedInputView.java @@ -68,12 +68,18 @@ public abstract class KeyguardPinBasedInputView extends KeyguardAbsKeyInputView protected void setPasswordEntryEnabled(boolean enabled) { mPasswordEntry.setEnabled(enabled); mOkButton.setEnabled(enabled); + if (enabled && !mPasswordEntry.hasFocus()) { + mPasswordEntry.requestFocus(); + } } @Override protected void setPasswordEntryInputEnabled(boolean enabled) { mPasswordEntry.setEnabled(enabled); mOkButton.setEnabled(enabled); + if (enabled && !mPasswordEntry.hasFocus()) { + mPasswordEntry.requestFocus(); + } } @Override diff --git a/services/core/java/com/android/server/StorageManagerService.java b/services/core/java/com/android/server/StorageManagerService.java index 3b71cd9f3fa1..a3e6ea2518a6 100644 --- a/services/core/java/com/android/server/StorageManagerService.java +++ b/services/core/java/com/android/server/StorageManagerService.java @@ -1190,6 +1190,9 @@ class StorageManagerService extends IStorageManager.Stub } else if (vol.type == VolumeInfo.TYPE_PRIVATE) { mHandler.obtainMessage(H_VOLUME_MOUNT, vol).sendToTarget(); + } else if (vol.type == VolumeInfo.TYPE_STUB) { + vol.mountUserId = mCurrentUserId; + mHandler.obtainMessage(H_VOLUME_MOUNT, vol).sendToTarget(); } else { Slog.d(TAG, "Skipping automatic mounting of " + vol); } @@ -1200,6 +1203,7 @@ class StorageManagerService extends IStorageManager.Stub case VolumeInfo.TYPE_PRIVATE: case VolumeInfo.TYPE_PUBLIC: case VolumeInfo.TYPE_EMULATED: + case VolumeInfo.TYPE_STUB: break; default: return false; @@ -1276,7 +1280,8 @@ class StorageManagerService extends IStorageManager.Stub } } - if (vol.type == VolumeInfo.TYPE_PUBLIC && vol.state == VolumeInfo.STATE_EJECTING) { + if ((vol.type == VolumeInfo.TYPE_PUBLIC || vol.type == VolumeInfo.TYPE_STUB) + && vol.state == VolumeInfo.STATE_EJECTING) { // TODO: this should eventually be handled by new ObbVolume state changes /* * Some OBBs might have been unmounted when this volume was @@ -1358,7 +1363,8 @@ class StorageManagerService extends IStorageManager.Stub } boolean isTypeRestricted = false; - if (vol.type == VolumeInfo.TYPE_PUBLIC || vol.type == VolumeInfo.TYPE_PRIVATE) { + if (vol.type == VolumeInfo.TYPE_PUBLIC || vol.type == VolumeInfo.TYPE_PRIVATE + || vol.type == VolumeInfo.TYPE_STUB) { isTypeRestricted = userManager .hasUserRestriction(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA, Binder.getCallingUserHandle()); @@ -2596,24 +2602,35 @@ class StorageManagerService extends IStorageManager.Stub class AppFuseMountScope extends AppFuseBridge.MountScope { boolean opened = false; - public AppFuseMountScope(int uid, int pid, int mountId) { - super(uid, pid, mountId); + public AppFuseMountScope(int uid, int mountId) { + super(uid, mountId); } @Override public ParcelFileDescriptor open() throws NativeDaemonConnectorException { try { return new ParcelFileDescriptor( - mVold.mountAppFuse(uid, Process.myPid(), mountId)); + mVold.mountAppFuse(uid, mountId)); } catch (Exception e) { throw new NativeDaemonConnectorException("Failed to mount", e); } } @Override + public ParcelFileDescriptor openFile(int mountId, int fileId, int flags) + throws NativeDaemonConnectorException { + try { + return new ParcelFileDescriptor( + mVold.openAppFuseFile(uid, mountId, fileId, flags)); + } catch (Exception e) { + throw new NativeDaemonConnectorException("Failed to open", e); + } + } + + @Override public void close() throws Exception { if (opened) { - mVold.unmountAppFuse(uid, Process.myPid(), mountId); + mVold.unmountAppFuse(uid, mountId); opened = false; } } @@ -2623,7 +2640,6 @@ class StorageManagerService extends IStorageManager.Stub public @Nullable AppFuseMount mountProxyFileDescriptorBridge() { Slog.v(TAG, "mountProxyFileDescriptorBridge"); final int uid = Binder.getCallingUid(); - final int pid = Binder.getCallingPid(); while (true) { synchronized (mAppFuseLock) { @@ -2637,7 +2653,7 @@ class StorageManagerService extends IStorageManager.Stub final int name = mNextAppFuseName++; try { return new AppFuseMount( - name, mAppFuseBridge.addBridge(new AppFuseMountScope(uid, pid, name))); + name, mAppFuseBridge.addBridge(new AppFuseMountScope(uid, name))); } catch (FuseUnavailableMountException e) { if (newlyCreated) { // If newly created bridge fails, it's a real error. @@ -2658,14 +2674,13 @@ class StorageManagerService extends IStorageManager.Stub public @Nullable ParcelFileDescriptor openProxyFileDescriptor( int mountId, int fileId, int mode) { Slog.v(TAG, "mountProxyFileDescriptor"); - final int pid = Binder.getCallingPid(); try { synchronized (mAppFuseLock) { if (mAppFuseBridge == null) { Slog.e(TAG, "FuseBridge has not been created"); return null; } - return mAppFuseBridge.openFile(pid, mountId, fileId, mode); + return mAppFuseBridge.openFile(mountId, fileId, mode); } } catch (FuseUnavailableMountException | InterruptedException error) { Slog.v(TAG, "The mount point has already been invalid", error); @@ -2749,6 +2764,7 @@ class StorageManagerService extends IStorageManager.Stub final VolumeInfo vol = mVolumes.valueAt(i); switch (vol.getType()) { case VolumeInfo.TYPE_PUBLIC: + case VolumeInfo.TYPE_STUB: case VolumeInfo.TYPE_EMULATED: break; default: diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index e410302457a8..4bfcd25c56db 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -47,7 +47,6 @@ import android.telephony.ServiceState; import android.telephony.SignalStrength; import android.telephony.SubscriptionManager; import android.telephony.TelephonyManager; -import android.telephony.VoLteServiceState; import android.util.LocalLog; import android.util.StatsLog; @@ -196,7 +195,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { private ArrayList<List<PhysicalChannelConfig>> mPhysicalChannelConfigs; - private VoLteServiceState mVoLteServiceState = new VoLteServiceState(); + private int[] mSrvccState; private int mDefaultSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; @@ -230,8 +229,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { static final int ENFORCE_PHONE_STATE_PERMISSION_MASK = PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR | - PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR | - PhoneStateListener.LISTEN_VOLTE_STATE; + PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR; static final int PRECISE_PHONE_STATE_PERMISSION_MASK = PhoneStateListener.LISTEN_PRECISE_CALL_STATE | @@ -356,6 +354,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mCallForwarding = new boolean[numPhones]; mCellLocation = new Bundle[numPhones]; mCellInfo = new ArrayList<List<CellInfo>>(); + mSrvccState = new int[numPhones]; mPhysicalChannelConfigs = new ArrayList<List<PhysicalChannelConfig>>(); for (int i = 0; i < numPhones; i++) { mCallState[i] = TelephonyManager.CALL_STATE_IDLE; @@ -371,6 +370,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { mCallForwarding[i] = false; mCellLocation[i] = new Bundle(); mCellInfo.add(i, null); + mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE; mPhysicalChannelConfigs.add(i, new ArrayList<PhysicalChannelConfig>()); } @@ -772,6 +772,13 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { remove(r.binder); } } + if ((events & PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) != 0) { + try { + r.callback.onSrvccStateChanged(mSrvccState[phoneId]); + } catch (RemoteException ex) { + remove(r.binder); + } + } } } } else { @@ -1522,19 +1529,30 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { TelephonyManager.NETWORK_TYPE_UNKNOWN, apnType, apn, reason, null, failCause); } - public void notifyVoLteServiceStateChanged(VoLteServiceState lteState) { - if (!checkNotifyPermission("notifyVoLteServiceStateChanged()")) { + @Override + public void notifySrvccStateChanged(int subId, @TelephonyManager.SrvccState int state) { + if (!checkNotifyPermission("notifySrvccStateChanged()")) { return; } + if (VDBG) { + log("notifySrvccStateChanged: subId=" + subId + " srvccState=" + state); + } + int phoneId = SubscriptionManager.getPhoneId(subId); synchronized (mRecords) { - mVoLteServiceState = lteState; - for (Record r : mRecords) { - if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_VOLTE_STATE)) { - try { - r.callback.onVoLteServiceStateChanged( - new VoLteServiceState(mVoLteServiceState)); - } catch (RemoteException ex) { - mRemoveList.add(r.binder); + if (validatePhoneId(phoneId)) { + mSrvccState[phoneId] = state; + for (Record r : mRecords) { + if (r.matchPhoneStateListenerEvent( + PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) && + idMatch(r.subId, subId, phoneId)) { + try { + if (DBG_LOC) { + log("notifySrvccStateChanged: mSrvccState=" + state + " r=" + r); + } + r.callback.onSrvccStateChanged(state); + } catch (RemoteException ex) { + mRemoveList.add(r.binder); + } } } } @@ -1680,7 +1698,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println("mRingingCallState=" + mRingingCallState); pw.println("mForegroundCallState=" + mForegroundCallState); pw.println("mBackgroundCallState=" + mBackgroundCallState); - pw.println("mVoLteServiceState=" + mVoLteServiceState); + pw.println("mSrvccState=" + mSrvccState); pw.println("mPhoneCapability=" + mPhoneCapability); pw.println("mPreferredDataSubId=" + mPreferredDataSubId); pw.println("mRadioPowerState=" + mRadioPowerState); @@ -1931,6 +1949,12 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub { android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null); } + if ((events & PhoneStateListener.LISTEN_SRVCC_STATE_CHANGED) != 0) { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE, null); + } + + return true; } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 7aadcd400f0e..fa9c58e1955c 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -318,6 +318,7 @@ import android.net.ProxyInfo; import android.net.Uri; import android.os.BatteryStats; import android.os.Binder; +import android.os.BinderProxy; import android.os.Build; import android.os.Bundle; import android.os.Debug; @@ -15210,6 +15211,7 @@ public class ActivityManagerService extends IActivityManager.Stub public void onLimitReached(int uid) { Slog.wtf(TAG, "Uid " + uid + " sent too many Binders to uid " + Process.myUid()); + BinderProxy.dumpProxyDebugInfo(); if (uid == Process.SYSTEM_UID) { Slog.i(TAG, "Skipping kill (uid is SYSTEM)"); } else { @@ -16061,8 +16063,10 @@ public class ActivityManagerService extends IActivityManager.Stub } } else if ("binder-proxies".equals(cmd)) { if (opti >= args.length) { + dumpBinderProxyInterfaceCounts(pw, + "Top proxy interface names held by SYSTEM"); dumpBinderProxiesCounts(pw, BinderInternal.nGetBinderProxyPerUidCounts(), - "Counts of Binder Proxies held by SYSTEM"); + "Number of proxies per uid held by SYSTEM"); } else { String uid = args[opti]; opti++; @@ -16565,6 +16569,15 @@ public class ActivityManagerService extends IActivityManager.Stub return printed; } + void dumpBinderProxyInterfaceCounts(PrintWriter pw, String header) { + final BinderProxy.InterfaceCount[] proxyCounts = BinderProxy.getSortedInterfaceCounts(50); + + pw.println(header); + for (int i = 0; i < proxyCounts.length; i++) { + pw.println(" #" + (i + 1) + ": " + proxyCounts[i]); + } + } + boolean dumpBinderProxiesCounts(PrintWriter pw, SparseIntArray counts, String header) { if(counts != null) { pw.println(header); diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java index dc9a5adb5a0c..7fb161c8c4ae 100644 --- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java +++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java @@ -2069,8 +2069,13 @@ final class ActivityManagerShellCommand extends ShellCommand { } FeatureInfo[] features = pm.getSystemAvailableFeatures(); - Arrays.sort(features, (o1, o2) -> - (o1.name == o2.name ? 0 : (o1.name == null ? -1 : o1.name.compareTo(o2.name)))); + Arrays.sort(features, (o1, o2) -> { + if (o1.name == o2.name) return 0; + if (o1.name == null) return -1; + if (o2.name == null) return 1; + return o1.name.compareTo(o2.name); + }); + for (int i = 0; i < features.length; i++) { if (features[i].name != null) { if (protoOutputStream != null) { diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index d3ac7cb15824..766cee3278ad 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -1839,7 +1839,9 @@ class TaskRecord extends ConfigurationContainer implements TaskWindowContainerLi final int compatScreenHeightDp = (int) (mTmpNonDecorBounds.height() / density); // We're only overriding LONG, SIZE and COMPAT parts of screenLayout, so we start override // calculation with partial default. - final int sl = Configuration.SCREENLAYOUT_LONG_YES | Configuration.SCREENLAYOUT_SIZE_XLARGE; + // Reducing the screen layout starting from its parent config. + final int sl = parentConfig.screenLayout & + (Configuration.SCREENLAYOUT_LONG_MASK | Configuration.SCREENLAYOUT_SIZE_MASK); final int longSize = Math.max(compatScreenHeightDp, compatScreenWidthDp); final int shortSize = Math.min(compatScreenHeightDp, compatScreenWidthDp); config.screenLayout = Configuration.reduceScreenLayout(sl, longSize, shortSize); diff --git a/services/core/java/com/android/server/connectivity/LingerMonitor.java b/services/core/java/com/android/server/connectivity/LingerMonitor.java index 635db19521d6..0e727c5e0b5f 100644 --- a/services/core/java/com/android/server/connectivity/LingerMonitor.java +++ b/services/core/java/com/android/server/connectivity/LingerMonitor.java @@ -90,6 +90,8 @@ public class LingerMonitor { mNotifier = notifier; mDailyLimit = dailyLimit; mRateLimitMillis = rateLimitMillis; + // Ensure that (now - mFirstNotificationMillis) >= rateLimitMillis at first + mFirstNotificationMillis = -rateLimitMillis; } private static HashMap<String, Integer> makeTransportToNameMap() { diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java index f96f6e87a9e3..6596d27d021e 100644 --- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java +++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java @@ -94,7 +94,7 @@ public class Nat464Xlat extends BaseNetworkObserver { final boolean hasIPv4Address = (nai.linkProperties != null) && nai.linkProperties.hasIPv4Address(); final boolean skip464xlat = - (nai.networkMisc != null) && nai.networkMisc.skip464xlat; + (nai.netMisc() != null) && nai.netMisc().skip464xlat; return supported && connected && !hasIPv4Address && !skip464xlat; } diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java index 505480ea537e..262184b0b12d 100644 --- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java +++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java @@ -266,6 +266,10 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> { return mConnService; } + public NetworkMisc netMisc() { + return networkMisc; + } + public Handler handler() { return mHandler; } diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java index de4f2d88aa19..c3e38424e90b 100644 --- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java +++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java @@ -313,6 +313,7 @@ public class NetworkMonitor extends StateMachine { private int mReevaluateDelayMs = INITIAL_REEVALUATE_DELAY_MS; private int mEvaluateAttempts = 0; + private volatile int mProbeToken = 0; public NetworkMonitor(Context context, Handler handler, NetworkAgentInfo networkAgentInfo, NetworkRequest defaultRequest) { @@ -838,7 +839,8 @@ public class NetworkMonitor extends StateMachine { @Override public void enter() { - mThread = new Thread(() -> sendMessage(obtainMessage(CMD_PROBE_COMPLETE, + final int token = ++mProbeToken; + mThread = new Thread(() -> sendMessage(obtainMessage(CMD_PROBE_COMPLETE, token, 0, isCaptivePortal()))); mThread.start(); } @@ -847,16 +849,13 @@ public class NetworkMonitor extends StateMachine { public boolean processMessage(Message message) { switch (message.what) { case CMD_PROBE_COMPLETE: - // Currently, it's not possible to exit this state without mThread having - // terminated. Therefore, this state can never get CMD_PROBE_COMPLETE from a - // stale thread that is not mThread. - // TODO: As soon as it's possible to exit this state without mThread having - // terminated, ensure that CMD_PROBE_COMPLETE from stale threads are ignored. - // This could be done via a sequence number, or by changing mThread to a class - // that has a stopped volatile boolean or AtomicBoolean. + // Ensure that CMD_PROBE_COMPLETE from stale threads are ignored. + if (message.arg1 != mProbeToken) { + return HANDLED; + } + final CaptivePortalProbeResult probeResult = (CaptivePortalProbeResult) message.obj; - if (probeResult.isSuccessful()) { // Transit EvaluatingPrivateDnsState to get to Validated // state (even if no Private DNS validation required). @@ -883,6 +882,7 @@ public class NetworkMonitor extends StateMachine { case CMD_REEVALUATE: // Leave the event to EvaluatingState. Defer this message will result in reset // of mReevaluateDelayMs and mEvaluateAttempts. + case CMD_NETWORK_DISCONNECTED: return NOT_HANDLED; default: // TODO: Some events may able to handle in this state, instead of deferring to @@ -894,11 +894,9 @@ public class NetworkMonitor extends StateMachine { @Override public void exit() { - // If StateMachine get here, the probe started in enter() is guaranteed to have - // completed, because in this state, all messages except CMD_PROBE_COMPLETE and - // CMD_REEVALUATE are deferred. CMD_REEVALUATE cannot be in the queue, because it is - // only ever sent in EvaluatingState#enter, and the StateMachine reach this state by - // processing it. Therefore, there is no need to stop the thread. + if (mThread.isAlive()) { + mThread.interrupt(); + } mThread = null; } } diff --git a/services/core/java/com/android/server/connectivity/PermissionMonitor.java b/services/core/java/com/android/server/connectivity/PermissionMonitor.java index deaa33485170..94c94a514dec 100644 --- a/services/core/java/com/android/server/connectivity/PermissionMonitor.java +++ b/services/core/java/com/android/server/connectivity/PermissionMonitor.java @@ -165,7 +165,7 @@ public class PermissionMonitor { } @VisibleForTesting - int getDeviceFirstSdkInt() { + protected int getDeviceFirstSdkInt() { return Build.VERSION.FIRST_SDK_INT; } diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java index 753c2833b056..580e4f481a27 100644 --- a/services/core/java/com/android/server/pm/dex/DexManager.java +++ b/services/core/java/com/android/server/pm/dex/DexManager.java @@ -35,6 +35,7 @@ import android.util.Slog; import android.util.jar.StrictJarFile; import com.android.internal.annotations.GuardedBy; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.ArrayUtils; import com.android.server.pm.Installer; import com.android.server.pm.Installer.InstallerException; @@ -153,7 +154,7 @@ public class DexManager { * @param classPaths the class paths corresponding to the class loaders names from * {@param classLoadersNames}. The the first element corresponds to the first class loader * and so on. A classpath is represented as a list of dex files separated by - * {@code File.pathSeparator}. + * {@code File.pathSeparator}, or null if the class loader's classpath is not known. * The dex files found in the first class path will be recorded in the usage file. * @param loaderIsa the ISA of the app loading the dex files * @param loaderUserId the user id which runs the code loading the dex files @@ -169,7 +170,8 @@ public class DexManager { } } - private void notifyDexLoadInternal(ApplicationInfo loadingAppInfo, + @VisibleForTesting + /*package*/ void notifyDexLoadInternal(ApplicationInfo loadingAppInfo, List<String> classLoaderNames, List<String> classPaths, String loaderIsa, int loaderUserId) { if (classLoaderNames.size() != classPaths.size()) { @@ -186,8 +188,14 @@ public class DexManager { return; } + // The first classpath should never be null because the first classloader + // should always be an instance of BaseDexClassLoader. + String firstClassPath = classPaths.get(0); + if (firstClassPath == null) { + return; + } // The classpath is represented as a list of dex files separated by File.pathSeparator. - String[] dexPathsToRegister = classPaths.get(0).split(File.pathSeparator); + String[] dexPathsToRegister = firstClassPath.split(File.pathSeparator); // Encode the class loader contexts for the dexPathsToRegister. String[] classLoaderContexts = DexoptUtils.processContextForDexLoad( diff --git a/services/core/java/com/android/server/pm/dex/DexoptUtils.java b/services/core/java/com/android/server/pm/dex/DexoptUtils.java index e1310a2f1ab3..d2600b5060b5 100644 --- a/services/core/java/com/android/server/pm/dex/DexoptUtils.java +++ b/services/core/java/com/android/server/pm/dex/DexoptUtils.java @@ -318,7 +318,8 @@ public final class DexoptUtils { // is fine (they come over binder). Even if something changes we expect the sizes to be // very small and it shouldn't matter much. for (int i = 1; i < classLoadersNames.size(); i++) { - if (!ClassLoaderFactory.isValidClassLoaderName(classLoadersNames.get(i))) { + if (!ClassLoaderFactory.isValidClassLoaderName(classLoadersNames.get(i)) + || classPaths.get(i) == null) { return null; } String classpath = encodeClasspath(classPaths.get(i).split(File.pathSeparator)); diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index 8cccbb1a5fb4..cc11b771f608 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -140,13 +140,14 @@ public class StatusBarManagerService extends IStatusBarService.Stub { switch (which) { case 1: what1 = what; - return; + break; case 2: what2 = what; - return; + break; default: Slog.w(TAG, "Can't set unsupported disable flag " + which + ": 0x" + Integer.toHexString(what)); + break; } this.pkg = pkg; } diff --git a/services/core/java/com/android/server/storage/AppFuseBridge.java b/services/core/java/com/android/server/storage/AppFuseBridge.java index 6a0b6489f470..9d6a64701e85 100644 --- a/services/core/java/com/android/server/storage/AppFuseBridge.java +++ b/services/core/java/com/android/server/storage/AppFuseBridge.java @@ -16,6 +16,7 @@ package com.android.server.storage; +import android.os.FileUtils; import android.os.ParcelFileDescriptor; import android.system.ErrnoException; import android.system.Os; @@ -25,8 +26,6 @@ import com.android.internal.os.FuseUnavailableMountException; import com.android.internal.util.Preconditions; import com.android.server.NativeDaemonConnectorException; import libcore.io.IoUtils; -import java.io.File; -import java.io.FileNotFoundException; import java.util.concurrent.CountDownLatch; /** @@ -87,7 +86,7 @@ public class AppFuseBridge implements Runnable { } } - public ParcelFileDescriptor openFile(int pid, int mountId, int fileId, int mode) + public ParcelFileDescriptor openFile(int mountId, int fileId, int mode) throws FuseUnavailableMountException, InterruptedException { final MountScope scope; synchronized (this) { @@ -96,17 +95,14 @@ public class AppFuseBridge implements Runnable { throw new FuseUnavailableMountException(mountId); } } - if (scope.pid != pid) { - throw new SecurityException("PID does not match"); - } final boolean result = scope.waitForMount(); if (result == false) { throw new FuseUnavailableMountException(mountId); } try { - return ParcelFileDescriptor.open( - new File(scope.mountPoint, String.valueOf(fileId)), mode); - } catch (FileNotFoundException error) { + int flags = FileUtils.translateModePfdToPosix(mode); + return scope.openFile(mountId, fileId, flags); + } catch (NativeDaemonConnectorException error) { throw new FuseUnavailableMountException(mountId); } } @@ -131,17 +127,13 @@ public class AppFuseBridge implements Runnable { public static abstract class MountScope implements AutoCloseable { public final int uid; - public final int pid; public final int mountId; - public final File mountPoint; private final CountDownLatch mMounted = new CountDownLatch(1); private boolean mMountResult = false; - public MountScope(int uid, int pid, int mountId) { + public MountScope(int uid, int mountId) { this.uid = uid; - this.pid = pid; this.mountId = mountId; - this.mountPoint = new File(String.format(APPFUSE_MOUNT_NAME_TEMPLATE, uid, mountId)); } @GuardedBy("AppFuseBridge.this") @@ -159,6 +151,8 @@ public class AppFuseBridge implements Runnable { } public abstract ParcelFileDescriptor open() throws NativeDaemonConnectorException; + public abstract ParcelFileDescriptor openFile(int mountId, int fileId, int flags) + throws NativeDaemonConnectorException; } private native long native_new(); diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp index 902bafb8cfd5..5f2a0e8ba9d8 100644 --- a/services/core/jni/Android.bp +++ b/services/core/jni/Android.bp @@ -96,7 +96,7 @@ cc_defaults { "libhwbinder", "libutils", "libhwui", - "libbpf", + "libbpf_android", "libnetdbpf", "libnetdutils", "android.hardware.audio.common@2.0", diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java index 030f9cca265e..b30c04309955 100644 --- a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java +++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java @@ -69,6 +69,7 @@ public class DexManagerTests { private static final String PATH_CLASS_LOADER_NAME = PathClassLoader.class.getName(); private static final String DELEGATE_LAST_CLASS_LOADER_NAME = DelegateLastClassLoader.class.getName(); + private static final String UNSUPPORTED_CLASS_LOADER_NAME = "unsupported.class_loader"; @Rule public MockitoRule mockito = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS); @Mock Installer mInstaller; @@ -106,7 +107,7 @@ public class DexManagerTests { mDoesNotExist = new TestData("DOES.NOT.EXIST", isa, mUser1); mBarUser0UnsupportedClassLoader = new TestData(bar, isa, mUser0, - "unsupported.class_loader"); + UNSUPPORTED_CLASS_LOADER_NAME); mBarUser0DelegateLastClassLoader = new TestData(bar, isa, mUser0, DELEGATE_LAST_CLASS_LOADER_NAME); @@ -406,6 +407,24 @@ public class DexManagerTests { } @Test + public void testNotifySupportedAndUnsupportedClassLoader() { + String classPath = String.join(File.pathSeparator, mBarUser0.getSecondaryDexPaths()); + List<String> classLoaders = + Arrays.asList(PATH_CLASS_LOADER_NAME, UNSUPPORTED_CLASS_LOADER_NAME); + List<String> classPaths = Arrays.asList(classPath, classPath); + notifyDexLoad(mBarUser0, classLoaders, classPaths, mUser0); + + assertNoUseInfo(mBarUser0); + } + + @Test + public void testNotifyNullClassPath() { + notifyDexLoad(mBarUser0, null, mUser0); + + assertNoUseInfo(mBarUser0); + } + + @Test public void testNotifyVariableClassLoader() { // Record bar secondaries with the default PathClassLoader. List<String> secondaries = mBarUser0.getSecondaryDexPaths(); @@ -500,14 +519,17 @@ public class DexManagerTests { // By default, assume a single class loader in the chain. // This makes writing tests much easier. List<String> classLoaders = Arrays.asList(testData.mClassLoader); - List<String> classPaths = Arrays.asList(String.join(File.pathSeparator, dexPaths)); + List<String> classPaths = (dexPaths == null) + ? Arrays.asList((String) null) + : Arrays.asList(String.join(File.pathSeparator, dexPaths)); notifyDexLoad(testData, classLoaders, classPaths, loaderUserId); } - private void notifyDexLoad(TestData testData, List<String> classLoader, List<String> classPaths, - int loaderUserId) { - mDexManager.notifyDexLoad(testData.mPackageInfo.applicationInfo, classLoader, classPaths, - testData.mLoaderIsa, loaderUserId); + private void notifyDexLoad(TestData testData, List<String> classLoaders, + List<String> classPaths, int loaderUserId) { + // We call the internal function so any exceptions thrown cause test failures. + mDexManager.notifyDexLoadInternal(testData.mPackageInfo.applicationInfo, classLoaders, + classPaths, testData.mLoaderIsa, loaderUserId); } private PackageUseInfo getPackageUseInfo(TestData testData) { diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java index 150f7f0c948c..6e0f56c8e7c8 100644 --- a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java @@ -353,6 +353,18 @@ public class DexoptUtilsTest { } @Test + public void testProcessContextForDexLoadNoClassPath() { + List<String> classLoaders = Arrays.asList( + DELEGATE_LAST_CLASS_LOADER_NAME, + PATH_CLASS_LOADER_NAME); + List<String> classPaths = Arrays.asList( + String.join(File.pathSeparator, "foo.dex", "bar.dex"), + null); + String[] context = DexoptUtils.processContextForDexLoad(classLoaders, classPaths); + assertNull(context); + } + + @Test public void testProcessContextForDexLoadIllegalCallEmptyList() { boolean gotException = false; try { diff --git a/startop/view_compiler/Android.bp b/startop/view_compiler/Android.bp index c39688cb8f2d..0c40a6b5fa84 100644 --- a/startop/view_compiler/Android.bp +++ b/startop/view_compiler/Android.bp @@ -62,3 +62,22 @@ cc_test_host { ], test_suites: ["general-tests"], } + +cc_binary_host { + name: "dex_testcase_generator", + defaults: ["viewcompiler_defaults"], + srcs: ["dex_testcase_generator.cc"], + static_libs: [ + "libviewcompiler", + ], +} + +genrule { + name: "generate_dex_testcases", + tools: [":dex_testcase_generator"], + cmd: "$(location :dex_testcase_generator) $(genDir)", + out: [ + "simple.dex", + "trivial.dex", + ], +} diff --git a/startop/view_compiler/README.md b/startop/view_compiler/README.md index 56595016cbb9..f8da02b53907 100644 --- a/startop/view_compiler/README.md +++ b/startop/view_compiler/README.md @@ -23,3 +23,31 @@ This tool is still in its early stages and has a number of limitations. application. * This only works for apps that do not use a custom layout inflater. * Other limitations yet to be discovered. + +## DexBuilder Tests + +The DexBuilder has several low-level end to end tests to verify generated DEX +code validates, runs, and has the correct behavior. There are, unfortunately, a +number of pieces that must be added to generate new tests. Here are the +components: + +* `dex_testcase_generator` - Written in C++ using `DexBuilder`. This runs as a + build step produce the DEX files that will be tested on device. See the + `genrule` named `generate_dex_testcases` in `Android.bp`. These files are then + copied over to the device by TradeFed when running tests. +* `DexBuilderTest` - This is a Java Language test harness that loads the + generated DEX files and exercises methods in the file. + +To add a new DEX file test, follow these steps: +1. Modify `dex_testcase_generator` to produce the DEX file. +2. Add the filename to the `out` list of the `generate_dex_testcases` rule in + `Android.bp`. +3. Add a new `push` option to `AndroidTest.xml` to copy the DEX file to the + device. +4. Modify `DexBuilderTest.java` to load and exercise the new test. + +In each case, you should be able to cargo-cult the existing test cases. + +In general, you can probably get by without adding a new generated DEX file, and +instead add more methods to the files that are already generated. In this case, +you can skip all of steps 2 and 3 above, and simplify steps 1 and 4. diff --git a/startop/view_compiler/TEST_MAPPING b/startop/view_compiler/TEST_MAPPING new file mode 100644 index 000000000000..5d675b76b395 --- /dev/null +++ b/startop/view_compiler/TEST_MAPPING @@ -0,0 +1,7 @@ +{ + "presubmit": [ + { + "name": "dex-builder-test" + } + ] +} diff --git a/startop/view_compiler/dex_builder.cc b/startop/view_compiler/dex_builder.cc index 13e7f73e6713..85357bb79bc0 100644 --- a/startop/view_compiler/dex_builder.cc +++ b/startop/view_compiler/dex_builder.cc @@ -17,7 +17,6 @@ #include "dex_builder.h" #include "dex/descriptors_names.h" -#include "dex/dex_instruction.h" #include <fstream> #include <memory> @@ -50,12 +49,21 @@ std::ostream& operator<<(std::ostream& out, const Instruction::Op& opcode) { case Instruction::Op::kReturn: out << "kReturn"; return out; + case Instruction::Op::kReturnObject: + out << "kReturnObject"; + return out; case Instruction::Op::kMove: out << "kMove"; return out; case Instruction::Op::kInvokeVirtual: out << "kInvokeVirtual"; return out; + case Instruction::Op::kBindLabel: + out << "kBindLabel"; + return out; + case Instruction::Op::kBranchEqz: + out << "kBranchEqz"; + return out; } } @@ -132,6 +140,9 @@ ir::String* DexBuilder::GetOrAddString(const std::string& string) { entry = Alloc<ir::String>(); // +1 for null terminator entry->data = slicer::MemView{buffer.get(), header_length + string.size() + 1}; + ::dex::u4 const new_index = dex_file_->strings_indexes.AllocateIndex(); + dex_file_->strings_map[new_index] = entry; + entry->orig_index = new_index; string_data_.push_back(std::move(buffer)); } return entry; @@ -224,14 +235,20 @@ ir::EncodedMethod* MethodBuilder::Encode() { Value MethodBuilder::MakeRegister() { return Value::Local(num_registers_++); } +Value MethodBuilder::MakeLabel() { + labels_.push_back({}); + return Value::Label(labels_.size() - 1); +} + void MethodBuilder::AddInstruction(Instruction instruction) { instructions_.push_back(instruction); } void MethodBuilder::BuildReturn() { AddInstruction(Instruction::OpNoArgs(Op::kReturn)); } -void MethodBuilder::BuildReturn(Value src) { - AddInstruction(Instruction::OpWithArgs(Op::kReturn, /*destination=*/{}, src)); +void MethodBuilder::BuildReturn(Value src, bool is_object) { + AddInstruction(Instruction::OpWithArgs( + is_object ? Op::kReturnObject : Op::kReturn, /*destination=*/{}, src)); } void MethodBuilder::BuildConst4(Value target, int value) { @@ -239,6 +256,11 @@ void MethodBuilder::BuildConst4(Value target, int value) { AddInstruction(Instruction::OpWithArgs(Op::kMove, target, Value::Immediate(value))); } +void MethodBuilder::BuildConstString(Value target, const std::string& value) { + const ir::String* const dex_string = dex_->GetOrAddString(value); + AddInstruction(Instruction::OpWithArgs(Op::kMove, target, Value::String(dex_string->orig_index))); +} + void MethodBuilder::EncodeInstructions() { buffer_.clear(); for (const auto& instruction : instructions_) { @@ -249,23 +271,28 @@ void MethodBuilder::EncodeInstructions() { void MethodBuilder::EncodeInstruction(const Instruction& instruction) { switch (instruction.opcode()) { case Instruction::Op::kReturn: - return EncodeReturn(instruction); + return EncodeReturn(instruction, ::art::Instruction::RETURN); + case Instruction::Op::kReturnObject: + return EncodeReturn(instruction, ::art::Instruction::RETURN_OBJECT); case Instruction::Op::kMove: return EncodeMove(instruction); case Instruction::Op::kInvokeVirtual: return EncodeInvokeVirtual(instruction); + case Instruction::Op::kBindLabel: + return BindLabel(instruction.args()[0]); + case Instruction::Op::kBranchEqz: + return EncodeBranch(art::Instruction::IF_EQZ, instruction); } } -void MethodBuilder::EncodeReturn(const Instruction& instruction) { - DCHECK_EQ(Instruction::Op::kReturn, instruction.opcode()); +void MethodBuilder::EncodeReturn(const Instruction& instruction, ::art::Instruction::Code opcode) { DCHECK(!instruction.dest().has_value()); if (instruction.args().size() == 0) { buffer_.push_back(art::Instruction::RETURN_VOID); } else { - DCHECK(instruction.args().size() == 1); + DCHECK_EQ(1, instruction.args().size()); size_t source = RegisterValue(instruction.args()[0]); - buffer_.push_back(art::Instruction::RETURN | source << 8); + buffer_.push_back(opcode | source << 8); } } @@ -283,6 +310,12 @@ void MethodBuilder::EncodeMove(const Instruction& instruction) { DCHECK_LT(source.value(), 16); buffer_.push_back(art::Instruction::CONST_4 | (source.value() << 12) | (RegisterValue(*instruction.dest()) << 8)); + } else if (source.is_string()) { + constexpr size_t kMaxRegisters = 256; + DCHECK_LT(RegisterValue(*instruction.dest()), kMaxRegisters); + DCHECK_LT(source.value(), 65536); // make sure we don't need a jumbo string + buffer_.push_back(::art::Instruction::CONST_STRING | (RegisterValue(*instruction.dest()) << 8)); + buffer_.push_back(source.value()); } else { UNIMPLEMENTED(FATAL); } @@ -307,7 +340,22 @@ void MethodBuilder::EncodeInvokeVirtual(const Instruction& instruction) { } } -size_t MethodBuilder::RegisterValue(Value value) const { +// Encodes a conditional branch that tests a single argument. +void MethodBuilder::EncodeBranch(art::Instruction::Code op, const Instruction& instruction) { + const auto& args = instruction.args(); + const auto& test_value = args[0]; + const auto& branch_target = args[1]; + CHECK_EQ(2, args.size()); + CHECK(test_value.is_variable()); + CHECK(branch_target.is_label()); + + size_t instruction_offset = buffer_.size(); + buffer_.push_back(op | (RegisterValue(test_value) << 8)); + size_t field_offset = buffer_.size(); + buffer_.push_back(LabelValue(branch_target, instruction_offset, field_offset)); +} + +size_t MethodBuilder::RegisterValue(const Value& value) const { if (value.is_register()) { return value.value(); } else if (value.is_parameter()) { @@ -317,6 +365,37 @@ size_t MethodBuilder::RegisterValue(Value value) const { return 0; } +void MethodBuilder::BindLabel(const Value& label_id) { + CHECK(label_id.is_label()); + + LabelData& label = labels_[label_id.value()]; + CHECK(!label.bound_address.has_value()); + + label.bound_address = buffer_.size(); + + // patch any forward references to this label. + for (const auto& ref : label.references) { + buffer_[ref.field_offset] = *label.bound_address - ref.instruction_offset; + } + // No point keeping these around anymore. + label.references.clear(); +} + +::dex::u2 MethodBuilder::LabelValue(const Value& label_id, size_t instruction_offset, + size_t field_offset) { + CHECK(label_id.is_label()); + LabelData& label = labels_[label_id.value()]; + + // Short-circuit if the label is already bound. + if (label.bound_address.has_value()) { + return *label.bound_address - instruction_offset; + } + + // Otherwise, save a reference to where we need to back-patch later. + label.references.push_front(LabelReference{instruction_offset, field_offset}); + return 0; +} + const MethodDeclData& DexBuilder::GetOrDeclareMethod(TypeDescriptor type, const std::string& name, Prototype prototype) { MethodDeclData& entry = method_id_map_[{type, name, prototype}]; diff --git a/startop/view_compiler/dex_builder.h b/startop/view_compiler/dex_builder.h index e46655e0d429..31414c82e510 100644 --- a/startop/view_compiler/dex_builder.h +++ b/startop/view_compiler/dex_builder.h @@ -16,12 +16,14 @@ #ifndef DEX_BUILDER_H_ #define DEX_BUILDER_H_ +#include <forward_list> #include <map> #include <optional> #include <string> #include <unordered_map> #include <vector> +#include "dex/dex_instruction.h" #include "slicer/dex_ir.h" #include "slicer/writer.h" @@ -108,15 +110,20 @@ class Value { static constexpr Value Local(size_t id) { return Value{id, Kind::kLocalRegister}; } static constexpr Value Parameter(size_t id) { return Value{id, Kind::kParameter}; } static constexpr Value Immediate(size_t value) { return Value{value, Kind::kImmediate}; } + static constexpr Value String(size_t value) { return Value{value, Kind::kString}; } + static constexpr Value Label(size_t id) { return Value{id, Kind::kLabel}; } bool is_register() const { return kind_ == Kind::kLocalRegister; } bool is_parameter() const { return kind_ == Kind::kParameter; } + bool is_variable() const { return is_register() || is_parameter(); } bool is_immediate() const { return kind_ == Kind::kImmediate; } + bool is_string() const { return kind_ == Kind::kString; } + bool is_label() const { return kind_ == Kind::kLabel; } size_t value() const { return value_; } private: - enum class Kind { kLocalRegister, kParameter, kImmediate }; + enum class Kind { kLocalRegister, kParameter, kImmediate, kString, kLabel }; const size_t value_; const Kind kind_; @@ -132,7 +139,7 @@ class Instruction { public: // The operation performed by this instruction. These are virtual instructions that do not // correspond exactly to DEX instructions. - enum class Op { kReturn, kMove, kInvokeVirtual }; + enum class Op { kReturn, kReturnObject, kMove, kInvokeVirtual, kBindLabel, kBranchEqz }; //////////////////////// // Named Constructors // @@ -195,6 +202,8 @@ class MethodBuilder { // it's up to the caller to reuse registers as appropriate. Value MakeRegister(); + Value MakeLabel(); + ///////////////////////////////// // Instruction builder methods // ///////////////////////////////// @@ -203,21 +212,36 @@ class MethodBuilder { // return-void void BuildReturn(); - void BuildReturn(Value src); + void BuildReturn(Value src, bool is_object = false); // const/4 void BuildConst4(Value target, int value); + void BuildConstString(Value target, const std::string& value); // TODO: add builders for more instructions private: void EncodeInstructions(); void EncodeInstruction(const Instruction& instruction); - void EncodeReturn(const Instruction& instruction); + + // Encodes a return instruction. For instructions with no return value, the opcode field is + // ignored. Otherwise, this specifies which return instruction will be used (return, + // return-object, etc.) + void EncodeReturn(const Instruction& instruction, ::art::Instruction::Code opcode); + void EncodeMove(const Instruction& instruction); void EncodeInvokeVirtual(const Instruction& instruction); + void EncodeBranch(art::Instruction::Code op, const Instruction& instruction); // Converts a register or parameter to its DEX register number. - size_t RegisterValue(Value value) const; + size_t RegisterValue(const Value& value) const; + + // Sets a label's address to the current position in the instruction buffer. If there are any + // forward references to the label, this function will back-patch them. + void BindLabel(const Value& label); + + // Returns the offset of the label relative to the given instruction offset. If the label is not + // bound, a reference will be saved and it will automatically be patched when the label is bound. + ::dex::u2 LabelValue(const Value& label, size_t instruction_offset, size_t field_offset); DexBuilder* dex_; ir::Class* class_; @@ -231,6 +255,21 @@ class MethodBuilder { // How many registers we've allocated size_t num_registers_{0}; + + // Stores information needed to back-patch a label once it is bound. We need to know the start of + // the instruction that refers to the label, and the offset to where the actual label value should + // go. + struct LabelReference { + size_t instruction_offset; + size_t field_offset; + }; + + struct LabelData { + std::optional<size_t> bound_address; + std::forward_list<LabelReference> references; + }; + + std::vector<LabelData> labels_; }; // A helper to build class definitions. diff --git a/startop/view_compiler/dex_builder_test/Android.bp b/startop/view_compiler/dex_builder_test/Android.bp new file mode 100644 index 000000000000..4449ea0f707e --- /dev/null +++ b/startop/view_compiler/dex_builder_test/Android.bp @@ -0,0 +1,29 @@ +// +// 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. +// + +android_test { + name: "dex-builder-test", + srcs: ["src/android/startop/test/DexBuilderTest.java"], + sdk_version: "current", + data: [":generate_dex_testcases"], + static_libs: [ + "android-support-test", + "guava", + ], + manifest: "AndroidManifest.xml", + test_config: "AndroidTest.xml", + test_suites: ["general-tests"], +} diff --git a/startop/view_compiler/dex_builder_test/AndroidManifest.xml b/startop/view_compiler/dex_builder_test/AndroidManifest.xml new file mode 100644 index 000000000000..6ac5fc5db345 --- /dev/null +++ b/startop/view_compiler/dex_builder_test/AndroidManifest.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="android.startop.test" > + + <uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" /> + + <application> + <uses-library android:name="android.test.runner" /> + </application> + + <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner" + android:targetPackage="android.startop.test" + android:label="DexBuilder Tests"/> + +</manifest> diff --git a/startop/view_compiler/dex_builder_test/AndroidTest.xml b/startop/view_compiler/dex_builder_test/AndroidTest.xml new file mode 100644 index 000000000000..6f90cf3b81a7 --- /dev/null +++ b/startop/view_compiler/dex_builder_test/AndroidTest.xml @@ -0,0 +1,34 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> +<configuration description="Runs DexBuilder Tests."> + <option name="test-suite-tag" value="apct" /> + <option name="test-suite-tag" value="apct-instrumentation" /> + <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller"> + <option name="cleanup-apks" value="true" /> + <option name="test-file-name" value="dex-builder-test.apk" /> + </target_preparer> + + <target_preparer class="com.android.compatibility.common.tradefed.targetprep.FilePusher"> + <option name="cleanup" value="true" /> + <option name="push" value="trivial.dex->/data/local/tmp/dex-builder-test/trivial.dex" /> + <option name="push" value="simple.dex->/data/local/tmp/dex-builder-test/simple.dex" /> + </target_preparer> + + <test class="com.android.tradefed.testtype.AndroidJUnitTest" > + <option name="package" value="android.startop.test" /> + <option name="runner" value="android.support.test.runner.AndroidJUnitRunner" /> + </test> +</configuration> 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 new file mode 100644 index 000000000000..2ccdc6d5b4bf --- /dev/null +++ b/startop/view_compiler/dex_builder_test/src/android/startop/test/DexBuilderTest.java @@ -0,0 +1,119 @@ +/* + * 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.startop.test; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import com.google.common.io.ByteStreams; +import dalvik.system.InMemoryDexClassLoader; +import dalvik.system.PathClassLoader; +import java.io.InputStream; +import java.lang.reflect.Method; +import java.nio.ByteBuffer; +import org.junit.Assert; +import org.junit.Test; + +// Adding tests here requires changes in several other places. See README.md in +// the view_compiler directory for more information. +public class DexBuilderTest { + static ClassLoader loadDexFile(String filename) throws Exception { + return new PathClassLoader("/data/local/tmp/dex-builder-test/" + filename, + ClassLoader.getSystemClassLoader()); + } + + public void hello() {} + + @Test + public void loadTrivialDex() throws Exception { + ClassLoader loader = loadDexFile("trivial.dex"); + loader.loadClass("android.startop.test.testcases.Trivial"); + } + + @Test + public void return5() throws Exception { + ClassLoader loader = loadDexFile("simple.dex"); + Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests"); + Method method = clazz.getMethod("return5"); + Assert.assertEquals(5, method.invoke(null)); + } + + @Test + public void returnParam() throws Exception { + ClassLoader loader = loadDexFile("simple.dex"); + Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests"); + Method method = clazz.getMethod("returnParam", int.class); + Assert.assertEquals(5, method.invoke(null, 5)); + Assert.assertEquals(42, method.invoke(null, 42)); + } + + @Test + public void returnStringLength() throws Exception { + ClassLoader loader = loadDexFile("simple.dex"); + Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests"); + Method method = clazz.getMethod("returnStringLength", String.class); + Assert.assertEquals(13, method.invoke(null, "Hello, World!")); + } + + @Test + public void returnIfZero() throws Exception { + ClassLoader loader = loadDexFile("simple.dex"); + Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests"); + Method method = clazz.getMethod("returnIfZero", int.class); + Assert.assertEquals(5, method.invoke(null, 0)); + Assert.assertEquals(3, method.invoke(null, 17)); + } + + @Test + public void backwardsBranch() throws Exception { + ClassLoader loader = loadDexFile("simple.dex"); + Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests"); + Method method = clazz.getMethod("backwardsBranch"); + Assert.assertEquals(2, method.invoke(null)); + } + + @Test + public void returnNull() throws Exception { + ClassLoader loader = loadDexFile("simple.dex"); + Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests"); + Method method = clazz.getMethod("returnNull"); + Assert.assertEquals(null, method.invoke(null)); + } + + @Test + public void makeString() throws Exception { + ClassLoader loader = loadDexFile("simple.dex"); + Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests"); + Method method = clazz.getMethod("makeString"); + Assert.assertEquals("Hello, World!", method.invoke(null)); + } + + @Test + public void returnStringIfZeroAB() throws Exception { + ClassLoader loader = loadDexFile("simple.dex"); + Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests"); + Method method = clazz.getMethod("returnStringIfZeroAB", int.class); + Assert.assertEquals("a", method.invoke(null, 0)); + Assert.assertEquals("b", method.invoke(null, 1)); + } + + @Test + public void returnStringIfZeroBA() throws Exception { + ClassLoader loader = loadDexFile("simple.dex"); + Class clazz = loader.loadClass("android.startop.test.testcases.SimpleTests"); + Method method = clazz.getMethod("returnStringIfZeroBA", int.class); + Assert.assertEquals("b", method.invoke(null, 0)); + Assert.assertEquals("a", method.invoke(null, 1)); + } +} diff --git a/startop/view_compiler/dex_testcase_generator.cc b/startop/view_compiler/dex_testcase_generator.cc new file mode 100644 index 000000000000..063a0cf6df7e --- /dev/null +++ b/startop/view_compiler/dex_testcase_generator.cc @@ -0,0 +1,218 @@ +/* + * 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 "android-base/logging.h" +#include "dex_builder.h" + +#include <fstream> +#include <string> + +// Adding tests here requires changes in several other places. See README.md in +// the view_compiler directory for more information. + +using namespace startop::dex; +using namespace std; + +void GenerateTrivialDexFile(const string& outdir) { + DexBuilder dex_file; + + ClassBuilder cbuilder{dex_file.MakeClass("android.startop.test.testcases.Trivial")}; + cbuilder.set_source_file("dex_testcase_generator.cc#GenerateTrivialDexFile"); + + slicer::MemView image{dex_file.CreateImage()}; + std::ofstream out_file(outdir + "/trivial.dex"); + out_file.write(image.ptr<const char>(), image.size()); +} + +// Generates test cases that test around 1 instruction. +void GenerateSimpleTestCases(const string& outdir) { + DexBuilder dex_file; + + ClassBuilder cbuilder{dex_file.MakeClass("android.startop.test.testcases.SimpleTests")}; + cbuilder.set_source_file("dex_testcase_generator.cc#GenerateSimpleTestCases"); + + // int return5() { return 5; } + auto return5{cbuilder.CreateMethod("return5", Prototype{TypeDescriptor::Int()})}; + { + Value r{return5.MakeRegister()}; + return5.BuildConst4(r, 5); + return5.BuildReturn(r); + } + return5.Encode(); + + // // int returnParam(int x) { return x; } + auto returnParam{cbuilder.CreateMethod("returnParam", + Prototype{TypeDescriptor::Int(), TypeDescriptor::Int()})}; + returnParam.BuildReturn(Value::Parameter(0)); + returnParam.Encode(); + + // int returnStringLength(String x) { return x.length(); } + auto string_type{TypeDescriptor::FromClassname("java.lang.String")}; + MethodDeclData string_length{ + dex_file.GetOrDeclareMethod(string_type, "length", Prototype{TypeDescriptor::Int()})}; + + auto returnStringLength{ + cbuilder.CreateMethod("returnStringLength", Prototype{TypeDescriptor::Int(), string_type})}; + { + Value result = returnStringLength.MakeRegister(); + returnStringLength.AddInstruction( + Instruction::InvokeVirtual(string_length.id, result, Value::Parameter(0))); + returnStringLength.BuildReturn(result); + } + returnStringLength.Encode(); + + // int returnIfZero(int x) { if (x == 0) { return 5; } else { return 3; } } + MethodBuilder returnIfZero{cbuilder.CreateMethod( + "returnIfZero", Prototype{TypeDescriptor::Int(), TypeDescriptor::Int()})}; + { + Value resultIfZero{returnIfZero.MakeRegister()}; + Value else_target{returnIfZero.MakeLabel()}; + returnIfZero.AddInstruction(Instruction::OpWithArgs( + Instruction::Op::kBranchEqz, /*dest=*/{}, Value::Parameter(0), else_target)); + // else branch + returnIfZero.BuildConst4(resultIfZero, 3); + returnIfZero.AddInstruction( + Instruction::OpWithArgs(Instruction::Op::kReturn, /*dest=*/{}, resultIfZero)); + // then branch + returnIfZero.AddInstruction( + Instruction::OpWithArgs(Instruction::Op::kBindLabel, /*dest=*/{}, else_target)); + returnIfZero.BuildConst4(resultIfZero, 5); + returnIfZero.AddInstruction( + Instruction::OpWithArgs(Instruction::Op::kReturn, /*dest=*/{}, resultIfZero)); + } + returnIfZero.Encode(); + + // Make sure backwards branches work too. + // + // Pseudo code for test: + // { + // zero = 0; + // result = 1; + // if (zero == 0) goto B; + // A: + // return result; + // B: + // result = 2; + // if (zero == 0) goto A; + // result = 3; + // return result; + // } + // If it runs correctly, this test should return 2. + MethodBuilder backwardsBranch{ + cbuilder.CreateMethod("backwardsBranch", Prototype{TypeDescriptor::Int()})}; + [](MethodBuilder& method) { + Value zero = method.MakeRegister(); + Value result = method.MakeRegister(); + Value labelA = method.MakeLabel(); + Value labelB = method.MakeLabel(); + method.BuildConst4(zero, 0); + method.BuildConst4(result, 1); + method.AddInstruction( + Instruction::OpWithArgs(Instruction::Op::kBranchEqz, /*dest=*/{}, zero, labelB)); + + method.AddInstruction( + Instruction::OpWithArgs(Instruction::Op::kBindLabel, /*dest=*/{}, labelA)); + method.BuildReturn(result); + + method.AddInstruction( + Instruction::OpWithArgs(Instruction::Op::kBindLabel, /*dest=*/{}, labelB)); + method.BuildConst4(result, 2); + method.AddInstruction( + Instruction::OpWithArgs(Instruction::Op::kBranchEqz, /*dest=*/{}, zero, labelA)); + + method.BuildConst4(result, 3); + method.BuildReturn(result); + }(backwardsBranch); + backwardsBranch.Encode(); + + // Test that we can make a null value. Basically: + // + // public static String returnNull() { return null; } + MethodBuilder returnNull{cbuilder.CreateMethod("returnNull", Prototype{string_type})}; + [](MethodBuilder& method) { + Value zero = method.MakeRegister(); + method.BuildConst4(zero, 0); + method.BuildReturn(zero, /*is_object=*/true); + }(returnNull); + returnNull.Encode(); + + // Test that we can make String literals. Basically: + // + // public static String makeString() { return "Hello, World!"; } + MethodBuilder makeString{cbuilder.CreateMethod("makeString", Prototype{string_type})}; + [](MethodBuilder& method) { + Value string = method.MakeRegister(); + method.BuildConstString(string, "Hello, World!"); + method.BuildReturn(string, /*is_object=*/true); + }(makeString); + makeString.Encode(); + + // Make sure strings are sorted correctly. + // + // int returnStringIfZeroAB(int x) { if (x == 0) { return "a"; } else { return "b"; } } + MethodBuilder returnStringIfZeroAB{ + cbuilder.CreateMethod("returnStringIfZeroAB", Prototype{string_type, TypeDescriptor::Int()})}; + [&](MethodBuilder& method) { + Value resultIfZero{method.MakeRegister()}; + Value else_target{method.MakeLabel()}; + method.AddInstruction(Instruction::OpWithArgs( + Instruction::Op::kBranchEqz, /*dest=*/{}, Value::Parameter(0), else_target)); + // else branch + method.BuildConstString(resultIfZero, "b"); + method.AddInstruction( + Instruction::OpWithArgs(Instruction::Op::kReturnObject, /*dest=*/{}, resultIfZero)); + // then branch + method.AddInstruction( + Instruction::OpWithArgs(Instruction::Op::kBindLabel, /*dest=*/{}, else_target)); + method.BuildConstString(resultIfZero, "a"); + method.AddInstruction( + Instruction::OpWithArgs(Instruction::Op::kReturnObject, /*dest=*/{}, resultIfZero)); + method.Encode(); + }(returnStringIfZeroAB); + // int returnStringIfZeroAB(int x) { if (x == 0) { return "b"; } else { return "a"; } } + MethodBuilder returnStringIfZeroBA{ + cbuilder.CreateMethod("returnStringIfZeroBA", Prototype{string_type, TypeDescriptor::Int()})}; + [&](MethodBuilder& method) { + Value resultIfZero{method.MakeRegister()}; + Value else_target{method.MakeLabel()}; + method.AddInstruction(Instruction::OpWithArgs( + Instruction::Op::kBranchEqz, /*dest=*/{}, Value::Parameter(0), else_target)); + // else branch + method.BuildConstString(resultIfZero, "a"); + method.AddInstruction( + Instruction::OpWithArgs(Instruction::Op::kReturnObject, /*dest=*/{}, resultIfZero)); + // then branch + method.AddInstruction( + Instruction::OpWithArgs(Instruction::Op::kBindLabel, /*dest=*/{}, else_target)); + method.BuildConstString(resultIfZero, "b"); + method.AddInstruction( + Instruction::OpWithArgs(Instruction::Op::kReturnObject, /*dest=*/{}, resultIfZero)); + method.Encode(); + }(returnStringIfZeroBA); + + slicer::MemView image{dex_file.CreateImage()}; + std::ofstream out_file(outdir + "/simple.dex"); + out_file.write(image.ptr<const char>(), image.size()); +} + +int main(int argc, char** argv) { + CHECK_EQ(argc, 2); + + string outdir = argv[1]; + + GenerateTrivialDexFile(outdir); + GenerateSimpleTestCases(outdir); +} diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index b6ac91d45e78..cef998651cfe 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -21,6 +21,7 @@ import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.ParcelFileDescriptor; @@ -322,8 +323,11 @@ public final class Call { /** * Call can be upgraded to a video call. * @hide + * @deprecated Use {@link #CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL} and + * {@link #CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL} to indicate for a call + * whether or not video calling is supported. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 119305590) public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 0x00080000; /** diff --git a/telecomm/java/android/telecom/CallScreeningService.java b/telecomm/java/android/telecom/CallScreeningService.java index f62b170989ad..7db69407ad3d 100644 --- a/telecomm/java/android/telecom/CallScreeningService.java +++ b/telecomm/java/android/telecom/CallScreeningService.java @@ -18,6 +18,7 @@ package android.telecom; import android.annotation.SdkConstant; import android.app.Service; +import android.content.ComponentName; import android.content.Intent; import android.os.Handler; import android.os.IBinder; @@ -229,7 +230,8 @@ public abstract class CallScreeningService extends Service { callDetails.getTelecomCallId(), response.getRejectCall(), !response.getSkipCallLog(), - !response.getSkipNotification()); + !response.getSkipNotification(), + new ComponentName(getPackageName(), getClass().getName())); } else { mCallScreeningAdapter.allowCall(callDetails.getTelecomCallId()); } diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index 34603a3f056a..0589cd4a538e 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -272,6 +272,9 @@ public abstract class Connection extends Conferenceable { /** * Call can be upgraded to a video call. + * @deprecated Use {@link #CAPABILITY_SUPPORTS_VT_LOCAL_BIDIRECTIONAL} and + * {@link #CAPABILITY_SUPPORTS_VT_REMOTE_BIDIRECTIONAL} to indicate for a call whether or not + * video calling is supported. */ public static final int CAPABILITY_CAN_UPGRADE_TO_VIDEO = 0x00080000; diff --git a/telecomm/java/android/telecom/Logging/EventManager.java b/telecomm/java/android/telecom/Logging/EventManager.java index 2bda6480b99e..1342038c6477 100644 --- a/telecomm/java/android/telecom/Logging/EventManager.java +++ b/telecomm/java/android/telecom/Logging/EventManager.java @@ -180,7 +180,7 @@ public class EventManager { } } - private final List<Event> mEvents = new LinkedList<>(); + private final List<Event> mEvents = Collections.synchronizedList(new LinkedList<>()); private final Loggable mRecordEntry; public EventRecord(Loggable recordEntry) { @@ -197,7 +197,7 @@ public class EventManager { } public List<Event> getEvents() { - return mEvents; + return new LinkedList<>(mEvents); } public List<EventTiming> extractEventTimings() { @@ -207,21 +207,24 @@ public class EventManager { LinkedList<EventTiming> result = new LinkedList<>(); Map<String, PendingResponse> pendingResponses = new HashMap<>(); - for (Event event : mEvents) { - if (requestResponsePairs.containsKey(event.eventId)) { - // This event expects a response, so add that expected response to the maps - // of pending events. - for (EventManager.TimedEventPair p : requestResponsePairs.get(event.eventId)) { - pendingResponses.put(p.mResponse, new PendingResponse(event.eventId, - event.time, p.mTimeoutMillis, p.mName)); + synchronized (mEvents) { + for (Event event : mEvents) { + if (requestResponsePairs.containsKey(event.eventId)) { + // This event expects a response, so add that expected response to the maps + // of pending events. + for (EventManager.TimedEventPair p : requestResponsePairs.get( + event.eventId)) { + pendingResponses.put(p.mResponse, new PendingResponse(event.eventId, + event.time, p.mTimeoutMillis, p.mName)); + } } - } - PendingResponse pendingResponse = pendingResponses.remove(event.eventId); - if (pendingResponse != null) { - long elapsedTime = event.time - pendingResponse.requestEventTimeMillis; - if (elapsedTime < pendingResponse.timeoutMillis) { - result.add(new EventTiming(pendingResponse.name, elapsedTime)); + PendingResponse pendingResponse = pendingResponses.remove(event.eventId); + if (pendingResponse != null) { + long elapsedTime = event.time - pendingResponse.requestEventTimeMillis; + if (elapsedTime < pendingResponse.timeoutMillis) { + result.add(new EventTiming(pendingResponse.name, elapsedTime)); + } } } } @@ -233,7 +236,8 @@ public class EventManager { pw.print(mRecordEntry.getDescription()); pw.increaseIndent(); - for (Event event : mEvents) { + // Iterate over copy of events so that this doesn't hold the lock for too long. + for (Event event : getEvents()) { pw.print(event.timestampString); pw.print(" - "); pw.print(event.eventId); diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java index 9a4ea9e7f4bd..2ffad0345c64 100644 --- a/telecomm/java/android/telecom/PhoneAccount.java +++ b/telecomm/java/android/telecom/PhoneAccount.java @@ -985,10 +985,10 @@ public final class PhoneAccount implements Parcelable { /** * Generates a string representation of a capabilities bitmask. * - * @param capabilities The capabilities bitmask. * @return String representation of the capabilities bitmask. + * @hide */ - private String capabilitiesToString() { + public String capabilitiesToString() { StringBuilder sb = new StringBuilder(); if (hasCapabilities(CAPABILITY_SELF_MANAGED)) { sb.append("SelfManaged "); diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index fa16bfe8e795..9f0bdd715359 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -15,6 +15,7 @@ package android.telecom; import android.Manifest; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.RequiresPermission; import android.annotation.SuppressAutoDoc; @@ -36,6 +37,8 @@ import android.util.Log; import com.android.internal.telecom.ITelecomService; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -413,8 +416,10 @@ public class TelecomManager { * <p> * The phone number of the call used by Telecom to determine which call should be handed over. * @hide + * @deprecated Use the public handover APIs. See + * {@link Call#handoverTo(PhoneAccountHandle, int, Bundle)} for more information. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 119305590) public static final String EXTRA_IS_HANDOVER = "android.telecom.extra.IS_HANDOVER"; /** @@ -528,11 +533,19 @@ public class TelecomManager { public static final char DTMF_CHARACTER_WAIT = ';'; /** + * @hide + */ + @IntDef(prefix = { "TTY_MODE_" }, + value = {TTY_MODE_OFF, TTY_MODE_FULL, TTY_MODE_HCO, TTY_MODE_VCO}) + @Retention(RetentionPolicy.SOURCE) + public @interface TtyMode {} + + /** * TTY (teletypewriter) mode is off. * * @hide */ - @UnsupportedAppUsage + @SystemApi public static final int TTY_MODE_OFF = 0; /** @@ -541,6 +554,7 @@ public class TelecomManager { * * @hide */ + @SystemApi public static final int TTY_MODE_FULL = 1; /** @@ -550,6 +564,7 @@ public class TelecomManager { * * @hide */ + @SystemApi public static final int TTY_MODE_HCO = 2; /** @@ -559,6 +574,7 @@ public class TelecomManager { * * @hide */ + @SystemApi public static final int TTY_MODE_VCO = 3; /** @@ -827,8 +843,9 @@ public class TelecomManager { * @return The phone account handle of the current sim call manager. * * @hide + * @deprecated Use {@link #getSimCallManager()}. */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 119305590) public PhoneAccountHandle getSimCallManager(int userId) { try { if (isServiceConnected()) { @@ -929,10 +946,12 @@ public class TelecomManager { * Returns a list of {@link PhoneAccountHandle}s including those which have not been enabled * by the user. * + * @param includeDisabledAccounts When {@code true}, disabled phone accounts will be included, + * when {@code false}, only * @return A list of {@code PhoneAccountHandle} objects. * @hide */ - @UnsupportedAppUsage + @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 119305590) public List<PhoneAccountHandle> getCallCapablePhoneAccounts(boolean includeDisabledAccounts) { try { if (isServiceConnected()) { @@ -1155,7 +1174,7 @@ public class TelecomManager { /** * Used to set the default dialer package. * - * @param packageName to set the default dialer to.. + * @param packageName to set the default dialer to. * * @result {@code true} if the default dialer was successfully changed, {@code false} if * the specified package does not correspond to an installed dialer, or is already @@ -1166,7 +1185,10 @@ public class TelecomManager { * * @hide */ - @UnsupportedAppUsage + @SystemApi + @RequiresPermission(allOf = { + android.Manifest.permission.MODIFY_PHONE_STATE, + android.Manifest.permission.WRITE_SECURE_SETTINGS}) public boolean setDefaultDialer(String packageName) { try { if (isServiceConnected()) { @@ -1179,12 +1201,10 @@ public class TelecomManager { } /** - * Used to determine the dialer package that is preloaded on the system partition. + * Determines the package name of the system-provided default phone app. * * @return package name for the system dialer package or null if no system dialer is preloaded. - * @hide */ - @UnsupportedAppUsage public String getSystemDialerPackage() { try { if (isServiceConnected()) { @@ -1545,8 +1565,9 @@ public class TelecomManager { * - {@link TelecomManager#TTY_MODE_VCO} * @hide */ - @UnsupportedAppUsage - public int getCurrentTtyMode() { + @SystemApi + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public @TtyMode int getCurrentTtyMode() { try { if (isServiceConnected()) { return getTelecomService().getCurrentTtyMode(mContext.getOpPackageName()); diff --git a/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl b/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl index 2e0af27907b5..d255ed169c98 100644 --- a/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl +++ b/telecomm/java/com/android/internal/telecom/ICallScreeningAdapter.aidl @@ -16,6 +16,8 @@ package com.android.internal.telecom; +import android.content.ComponentName; + /** * Internal remote callback interface for call screening services. * @@ -30,5 +32,6 @@ oneway interface ICallScreeningAdapter { String callId, boolean shouldReject, boolean shouldAddToCallLog, - boolean shouldShowNotification); + boolean shouldShowNotification, + in ComponentName componentName); } diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java index 109ffe96571f..efea81763b9f 100644 --- a/telephony/java/android/provider/Telephony.java +++ b/telephony/java/android/provider/Telephony.java @@ -16,6 +16,7 @@ package android.provider; +import android.annotation.RequiresPermission; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; @@ -1181,6 +1182,58 @@ public final class Telephony { "android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL"; /** + * Broadcast action: When SMS-MMS db is being created. If file-based encryption is + * supported, this broadcast indicates creation of the db in credential-encrypted + * storage. A boolean is specified in {@link #EXTRA_IS_INITIAL_CREATE} to indicate if + * this is the initial create of the db. Requires + * {@link android.Manifest.permission#READ_SMS} to receive. + * + * @see #EXTRA_IS_INITIAL_CREATE + * + * @hide + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_SMS_MMS_DB_CREATED = + "android.provider.action.SMS_MMS_DB_CREATED"; + + /** + * Boolean flag passed as an extra with {@link #ACTION_SMS_MMS_DB_CREATED} to indicate + * whether the DB creation is the initial creation on the device, that is it is after a + * factory-data reset or a new device. Any subsequent creations of the DB (which + * happens only in error scenarios) will have this flag set to false. + * + * @see #ACTION_SMS_MMS_DB_CREATED + * + * @hide + */ + public static final String EXTRA_IS_INITIAL_CREATE = + "android.provider.extra.IS_INITIAL_CREATE"; + + /** + * Broadcast intent action indicating that the telephony provider SMS MMS database is + * corrupted. A boolean is specified in {@link #EXTRA_IS_CORRUPTED} to indicate if the + * database is corrupted. Requires the + * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE permission. + * + * @hide + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public static final String ACTION_SMS_MMS_DB_LOST = + "android.provider.action.SMS_MMS_DB_LOST"; + + /** + * Boolean flag passed as an extra with {@link #ACTION_SMS_MMS_DB_LOST} to indicate + * whether the DB got corrupted or not. + * + * @see #ACTION_SMS_MMS_DB_LOST + * + * @hide + */ + public static final String EXTRA_IS_CORRUPTED = + "android.provider.extra.IS_CORRUPTED"; + + /** * Read the PDUs out of an {@link #SMS_RECEIVED_ACTION} or a * {@link #DATA_SMS_RECEIVED_ACTION} intent. * @@ -2639,6 +2692,13 @@ 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 */ @@ -2995,6 +3055,13 @@ public final class Telephony { @SystemApi public static final int NO_SET_SET = 0; + /** + * A unique carrier id associated with this APN + * {@see TelephonyManager#getSimCarrierId()} + * <p>Type: STRING</p> + */ + public static final String CARRIER_ID = "carrier_id"; + } /** @@ -3483,6 +3550,27 @@ 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}. + * <p> + * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the + * precise carrier identity {@link TelephonyManager#getSimPreciseCarrierId()} + * while your app is running. You can also use a {@link JobService} to ensure your app + * is notified of changes to the {@link Uri} even when it is not running. + * Note, however, that using a {@link JobService} does not guarantee timely delivery of + * updates to the {@link Uri}. + * + * @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"), + String.valueOf(subscriptionId)); + } + + /** * A user facing carrier name. * @see TelephonyManager#getSimCarrierIdName() * <P>Type: TEXT </P> @@ -3497,6 +3585,35 @@ public final class Telephony { public static final String CARRIER_ID = "carrier_id"; /** + * A user facing carrier name for precise carrier id. + * @see TelephonyManager#getSimPreciseCarrierIdName() + * This is not a database column, only used to notify content observers for + * {@link #getPreciseCarrierIdUriForSubscriptionId(int)} + * @hide + */ + public static final String PRECISE_CARRIER_ID_NAME = "precise_carrier_id_name"; + + /** + * A fine-grained carrier id. + * @see TelephonyManager#getSimPreciseCarrierId() + * This is not a database column, only used to notify content observers for + * {@link #getPreciseCarrierIdUriForSubscriptionId(int)} + * @hide + */ + public static final String PRECISE_CARRIER_ID = "precise_carrier_id"; + + /** + * A unique parent carrier id. The parent-child + * relationship can be used to further differentiate a single carrier by different networks, + * by prepaid v.s. postpaid or even by 4G v.s. 3G plan. It's an optional field. + * A carrier id with a valid parent_carrier_id is considered fine-grained carrier id, will + * not be returned as {@link #CARRIER_ID} but {@link #PRECISE_CARRIER_ID}. + * <P>Type: INTEGER </P> + * @hide + */ + 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}. diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index c2958d35709b..5b739bab66a3 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -1079,24 +1079,44 @@ public class CarrierConfigManager { "wfc_operator_error_codes_string_array"; /** - * Indexes of SPN format strings in wfcSpnFormats and wfcDataSpnFormats. + * Indexes of SPN format strings in wfcSpnFormats. * * <p>Available options are: * <ul> - * <li> 0: %s</li> - * <li> 1: %s Wi-Fi Calling</li> - * <li> 2: WLAN Call</li> - * <li> 3: %s WLAN Call</li> - * <li> 4: %s Wi-Fi</li> - * <li> 5: WiFi Calling | %s</li> - * <li> 6: %s VoWifi</li> + * <li> 0: %s</li> + * <li> 1: %s Wi-Fi Calling</li> + * <li> 2: WLAN Call</li> + * <li> 3: %s WLAN Call</li> + * <li> 4: %s Wi-Fi</li> + * <li> 5: WiFi Calling | %s</li> + * <li> 6: %s VoWifi</li> + * <li> 7: Wi-Fi Calling</li> + * <li> 8: Wi-Fi</li> + * <li> 9: WiFi Calling</li> + * <li> 10: VoWifi</li> * @hide */ public static final String KEY_WFC_SPN_FORMAT_IDX_INT = "wfc_spn_format_idx_int"; - /** @hide */ + + /** + * Indexes of data SPN format strings in wfcSpnFormats. + * + * @see KEY_WFC_SPN_FORMAT_IDX_INT for available options. + * @hide + */ public static final String KEY_WFC_DATA_SPN_FORMAT_IDX_INT = "wfc_data_spn_format_idx_int"; /** + * Indexes of SPN format strings in wfcSpnFormats used during flight mode. + * + * Set to -1 to use the value from KEY_WFC_SPN_FORMAT_IDX_INT also in this case. + * @see KEY_WFC_SPN_FORMAT_IDX_INT for other available options. + * @hide + */ + public static final String KEY_WFC_FLIGHT_MODE_SPN_FORMAT_IDX_INT = + "wfc_flight_mode_spn_format_idx_int"; + + /** * Use root locale when reading wfcSpnFormats. * * If true, then the root locale will always be used when reading wfcSpnFormats. This means the @@ -1257,20 +1277,11 @@ public class CarrierConfigManager { public static final String KEY_WORLD_MODE_ENABLED_BOOL = "world_mode_enabled_bool"; /** - * Package name of the carrier settings activity. - * @see {@link #KEY_CARRIER_SETTINGS_ACTIVITY_CLASS_NAME_STRING}. - * @hide - */ - public static final String KEY_CARRIER_SETTINGS_ACTIVITY_PACKAGE_NAME_STRING = - "carrier_settings_activity_package_name_string"; - - /** - * Class name of the carrier settings activity. - * @see {@link #KEY_CARRIER_SETTINGS_ACTIVITY_PACKAGE_NAME_STRING}. + * Flatten {@link android.content.ComponentName} of the carrier's settings activity. * @hide */ - public static final String KEY_CARRIER_SETTINGS_ACTIVITY_CLASS_NAME_STRING = - "carrier_settings_activity_class_name_string"; + public static final String KEY_CARRIER_SETTINGS_ACTIVITY_COMPONENT_NAME_STRING = + "carrier_settings_activity_component_name_string"; // These variables are used by the MMS service and exposed through another API, // SmsManager. The variable names and string values are copied from there. @@ -2466,6 +2477,7 @@ public class CarrierConfigManager { sDefaults.putStringArray(KEY_WFC_OPERATOR_ERROR_CODES_STRING_ARRAY, null); sDefaults.putInt(KEY_WFC_SPN_FORMAT_IDX_INT, 0); sDefaults.putInt(KEY_WFC_DATA_SPN_FORMAT_IDX_INT, 0); + sDefaults.putInt(KEY_WFC_FLIGHT_MODE_SPN_FORMAT_IDX_INT, -1); sDefaults.putBoolean(KEY_WFC_SPN_USE_ROOT_LOCALE, false); sDefaults.putString(KEY_WFC_EMERGENCY_ADDRESS_CARRIER_APP_STRING, ""); sDefaults.putBoolean(KEY_CONFIG_WIFI_DISABLE_IN_ECBM, false); @@ -2616,8 +2628,7 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_SUPPORT_TDSCDMA_BOOL, false); sDefaults.putStringArray(KEY_SUPPORT_TDSCDMA_ROAMING_NETWORKS_STRING_ARRAY, null); sDefaults.putBoolean(KEY_WORLD_MODE_ENABLED_BOOL, false); - sDefaults.putString(KEY_CARRIER_SETTINGS_ACTIVITY_PACKAGE_NAME_STRING, ""); - sDefaults.putString(KEY_CARRIER_SETTINGS_ACTIVITY_CLASS_NAME_STRING, ""); + sDefaults.putString(KEY_CARRIER_SETTINGS_ACTIVITY_COMPONENT_NAME_STRING, ""); sDefaults.putBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL, false); sDefaults.putBoolean(KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL, false); sDefaults.putIntArray(KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY, diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java index 76a002681710..6958d22bf5cc 100644 --- a/telephony/java/android/telephony/CellIdentity.java +++ b/telephony/java/android/telephony/CellIdentity.java @@ -190,6 +190,7 @@ public abstract class CellIdentity implements Parcelable { case CellInfo.TYPE_LTE: return CellIdentityLte.createFromParcelBody(in); case CellInfo.TYPE_TDSCDMA: return CellIdentityTdscdma.createFromParcelBody(in); + case CellInfo.TYPE_NR: return CellIdentityNr.createFromParcelBody(in); default: throw new IllegalArgumentException("Bad Cell identity Parcel"); } } diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java new file mode 100644 index 000000000000..6b1b84cd3458 --- /dev/null +++ b/telephony/java/android/telephony/CellIdentityNr.java @@ -0,0 +1,167 @@ +/* + * 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.os.Parcel; +import android.telephony.gsm.GsmCellLocation; + +import java.util.Objects; + +/** + * Information to represent a unique 5G NR cell. + */ +public final class CellIdentityNr extends CellIdentity { + private static final String TAG = "CellIdentityNr"; + + private final int mNrArfcn; + private final int mPci; + private final int mTac; + + /** + * + * @param pci Physical Cell Id in range [0, 1007]. + * @param tac 16-bit Tracking Area Code. + * @param nrArfcn NR Absolute Radio Frequency Channel Number, in range [0, 3279165]. + * @param mccStr 3-digit Mobile Country Code in string format. + * @param mncStr 2 or 3-digit Mobile Network Code in string format. + * @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 CellIdentityNr(int pci, int tac, int nrArfcn, String mccStr, String mncStr, + String alphal, String alphas) { + super(TAG, CellInfo.TYPE_NR, mccStr, mncStr, alphal, alphas); + mPci = pci; + mTac = tac; + mNrArfcn = nrArfcn; + } + + /** + * @return a CellLocation object for this CellIdentity. + * @hide + */ + @Override + public CellLocation asCellLocation() { + return new GsmCellLocation(); + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), mPci, mTac, mNrArfcn); + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof CellIdentityNr)) { + return false; + } + + CellIdentityNr o = (CellIdentityNr) other; + return super.equals(o) && mPci == o.mPci && mTac == o.mTac && mNrArfcn == o.mNrArfcn; + } + + /** + * Get the Absolute Radio Frequency Channel Number. + * @return Integer value in range [0, 3279165] or {@link CellInfo#UNAVAILABLE} if unknown. + */ + @Override + public int getChannelNumber() { + return mNrArfcn; + } + + /** + * Get the physical cell id. + * @return Integer value in range [0, 1007] or {@link CellInfo#UNAVAILABLE} if unknown. + */ + public int getPci() { + return mPci; + } + + /** + * Get the tracking area code. + * @return a 16 bit integer or {@link CellInfo#UNAVAILABLE} if unknown. + */ + public int getTac() { + return mTac; + } + + /** + * @return Mobile Country Code in string format, or {@code null} if unknown. + */ + public String getMccString() { + return mMccStr; + } + + /** + * @return Mobile Network Code in string fomrat, or {@code null} if unknown. + */ + public String getMncString() { + return mMncStr; + } + + @Override + public String toString() { + return new StringBuilder(TAG + ":{") + .append(" mPci = ").append(mPci) + .append(" mTac = ").append(mTac) + .append(" mNrArfcn = ").append(mNrArfcn) + .append(" mMcc = ").append(mMccStr) + .append(" mMnc = ").append(mMncStr) + .append(" mAlphaLong = ").append(mAlphaLong) + .append(" mAlphaShort = ").append(mAlphaShort) + .append(" }") + .toString(); + } + + @Override + public void writeToParcel(Parcel dest, int type) { + super.writeToParcel(dest, CellInfo.TYPE_NR); + dest.writeInt(mPci); + dest.writeInt(mTac); + dest.writeInt(mNrArfcn); + } + + /** Construct from Parcel, type has already been processed */ + private CellIdentityNr(Parcel in) { + super(TAG, CellInfo.TYPE_NR, in); + mPci = in.readInt(); + mTac = in.readInt(); + mNrArfcn = in.readInt(); + } + + /** Implement the Parcelable interface */ + public static final Creator<CellIdentityNr> CREATOR = + new Creator<CellIdentityNr>() { + @Override + public CellIdentityNr createFromParcel(Parcel in) { + // Skip the type info. + in.readInt(); + return createFromParcelBody(in); + } + + @Override + public CellIdentityNr[] newArray(int size) { + return new CellIdentityNr[size]; + } + }; + + /** @hide */ + protected static CellIdentityNr createFromParcelBody(Parcel in) { + return new CellIdentityNr(in); + } +} diff --git a/telephony/java/android/telephony/CellInfo.java b/telephony/java/android/telephony/CellInfo.java index 1c63e8205454..d0b268766314 100644 --- a/telephony/java/android/telephony/CellInfo.java +++ b/telephony/java/android/telephony/CellInfo.java @@ -42,38 +42,51 @@ public abstract class CellInfo implements Parcelable { * @hide */ @Retention(RetentionPolicy.SOURCE) - @IntDef(prefix = "TYPE_", value = {TYPE_GSM, TYPE_CDMA, TYPE_LTE, TYPE_WCDMA, TYPE_TDSCDMA}) + @IntDef(prefix = "TYPE_", + value = {TYPE_GSM, TYPE_CDMA, TYPE_LTE, TYPE_WCDMA, TYPE_TDSCDMA, TYPE_NR}) public @interface Type {} + /** * Unknown cell identity type * @hide */ - public static final int TYPE_UNKNOWN = 0; + public static final int TYPE_UNKNOWN = 0; + /** * GSM cell identity type * @hide */ - public static final int TYPE_GSM = 1; + public static final int TYPE_GSM = 1; + /** * CDMA cell identity type * @hide */ - public static final int TYPE_CDMA = 2; + public static final int TYPE_CDMA = 2; + /** * LTE cell identity type * @hide */ - public static final int TYPE_LTE = 3; + public static final int TYPE_LTE = 3; + /** * WCDMA cell identity type * @hide */ - public static final int TYPE_WCDMA = 4; + public static final int TYPE_WCDMA = 4; + /** * TD-SCDMA cell identity type * @hide */ - public static final int TYPE_TDSCDMA = 5; + public static final int TYPE_TDSCDMA = 5; + + /** + * 5G cell identity type + * @hide + */ + public static final int TYPE_NR = 6; // Type to distinguish where time stamp gets recorded. @@ -277,6 +290,7 @@ public abstract class CellInfo implements Parcelable { case TYPE_LTE: return CellInfoLte.createFromParcelBody(in); case TYPE_WCDMA: return CellInfoWcdma.createFromParcelBody(in); case TYPE_TDSCDMA: return CellInfoTdscdma.createFromParcelBody(in); + case TYPE_NR: return CellInfoNr.createFromParcelBody(in); default: throw new RuntimeException("Bad CellInfo Parcel"); } } diff --git a/telephony/java/android/telephony/CellInfoNr.java b/telephony/java/android/telephony/CellInfoNr.java new file mode 100644 index 000000000000..11857a60783d --- /dev/null +++ b/telephony/java/android/telephony/CellInfoNr.java @@ -0,0 +1,100 @@ +/* + * 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.os.Parcel; + +import java.util.Objects; + +/** + * A {@link CellInfo} representing an 5G NR cell that provides identity and measurement info. + */ +public final class CellInfoNr extends CellInfo { + private static final String TAG = "CellInfoNr"; + + private final CellIdentityNr mCellIdentity; + private final CellSignalStrengthNr mCellSignalStrength; + + private CellInfoNr(Parcel in) { + super(in); + mCellIdentity = CellIdentityNr.CREATOR.createFromParcel(in); + mCellSignalStrength = CellSignalStrengthNr.CREATOR.createFromParcel(in); + } + + @Override + public CellIdentity getCellIdentity() { + return mCellIdentity; + } + + @Override + public CellSignalStrength getCellSignalStrength() { + return mCellSignalStrength; + } + + @Override + public int hashCode() { + return Objects.hash(super.hashCode(), mCellIdentity, mCellSignalStrength); + } + + @Override + public boolean equals(Object other) { + if (!(other instanceof CellInfoNr)) { + return false; + } + + CellInfoNr o = (CellInfoNr) other; + return super.equals(o) && mCellIdentity.equals(o.mCellIdentity) + && mCellSignalStrength.equals(o.mCellSignalStrength); + } + + @Override + public String toString() { + return new StringBuilder() + .append(TAG + ":{") + .append(" " + super.toString()) + .append(" " + mCellIdentity) + .append(" " + mCellSignalStrength) + .append(" }") + .toString(); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + super.writeToParcel(dest, flags, TYPE_NR); + mCellIdentity.writeToParcel(dest, flags); + mCellSignalStrength.writeToParcel(dest, flags); + } + + public static final Creator<CellInfoNr> CREATOR = new Creator<CellInfoNr>() { + @Override + public CellInfoNr createFromParcel(Parcel in) { + // Skip the type info. + in.readInt(); + return new CellInfoNr(in); + } + + @Override + public CellInfoNr[] newArray(int size) { + return new CellInfoNr[size]; + } + }; + + /** @hide */ + protected static CellInfoNr createFromParcelBody(Parcel in) { + return new CellInfoNr(in); + } +} diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java index d6856b397a00..d07539431348 100644 --- a/telephony/java/android/telephony/CellSignalStrengthLte.java +++ b/telephony/java/android/telephony/CellSignalStrengthLte.java @@ -19,7 +19,6 @@ package android.telephony; import android.annotation.UnsupportedAppUsage; import android.os.Parcel; import android.os.Parcelable; -import android.telephony.Rlog; import java.util.Objects; @@ -31,6 +30,25 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P private static final String LOG_TAG = "CellSignalStrengthLte"; private static final boolean DBG = false; + /** + * Indicates the unknown or undetectable RSSI value in ASU. + * + * Reference: TS 27.007 8.5 - Signal quality +CSQ + */ + private static final int SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN = 99; + /** + * Indicates the maximum valid RSSI value in ASU. + * + * Reference: TS 27.007 8.5 - Signal quality +CSQ + */ + private static final int SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MAX_VALUE = 31; + /** + * Indicates the minimum valid RSSI value in ASU. + * + * Reference: TS 27.007 8.5 - Signal quality +CSQ + */ + private static final int SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE = 0; + @UnsupportedAppUsage private int mSignalStrength; @UnsupportedAppUsage @@ -142,6 +160,19 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P } /** + * Get Received Signal Strength Indication (RSSI) in dBm + * + * The value range is [-113, -51] inclusively or {@link CellInfo#UNAVAILABLE} if unavailable. + * + * Reference: TS 27.007 8.5 Signal quality +CSQ + * + * @return the RSSI if available or {@link CellInfo#UNAVAILABLE} if unavailable. + */ + public int getRssi() { + return convertRssiAsuToDBm(mSignalStrength); + } + + /** * Get reference signal signal-to-noise ratio * * @return the RSSNR if available or @@ -309,4 +340,17 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P private static void log(String s) { Rlog.w(LOG_TAG, s); } + + 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); + return CellInfo.UNAVAILABLE; + } + if (rssiAsu == SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN) { + return CellInfo.UNAVAILABLE; + } + return -113 + (2 * rssiAsu); + } } diff --git a/telephony/java/android/telephony/CellSignalStrengthNr.java b/telephony/java/android/telephony/CellSignalStrengthNr.java new file mode 100644 index 000000000000..807924222a26 --- /dev/null +++ b/telephony/java/android/telephony/CellSignalStrengthNr.java @@ -0,0 +1,257 @@ +/* + * 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.os.Parcel; +import android.os.Parcelable; + +import java.util.Objects; + +/** + * 5G NR signal strength related information. + */ +public final class CellSignalStrengthNr extends CellSignalStrength implements Parcelable { + /** + * The value is used to indicate that the asu level is unknown. + * Reference: 3GPP TS 27.007 section 8.69. + * @hide + */ + public static final int UNKNOWN_ASU_LEVEL = 99; + + private static final String TAG = "CellSignalStrengthNr"; + + /** + * These threshold values are copied from LTE. + * TODO: make it configurable via CarrierConfig. + */ + private static final int SIGNAL_GREAT_THRESHOLD = -95; + private static final int SIGNAL_GOOD_THRESHOLD = -105; + private static final int SIGNAL_MODERATE_THRESHOLD = -115; + + private int mCsiRsrp; + private int mCsiRsrq; + private int mCsiSinr; + private int mSsRsrp; + private int mSsRsrq; + private int mSsSinr; + + /** + * @param csiRsrp CSI reference signal received power. + * @param csiRsrq CSI reference signal received quality. + * @param csiSinr CSI signal-to-noise and interference ratio. + * @param ssRsrp SS reference signal received power. + * @param ssRsrq SS reference signal received quality. + * @param ssSinr SS signal-to-noise and interference ratio. + * @hide + */ + 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; + } + + /** + * Reference: 3GPP TS 38.215. + * Range: -140 dBm to -44 dBm. + * @return SS reference signal received power, {@link CellInfo#UNAVAILABLE} means unreported + * value. + */ + public int getSsRsrp() { + return mSsRsrp; + } + + /** + * Reference: 3GPP TS 38.215. + * Range: -20 dB to -3 dB. + * @return SS reference signal received quality, {@link CellInfo#UNAVAILABLE} means unreported + * value. + */ + public int getSsRsrq() { + return mSsRsrq; + } + + /** + * Reference: 3GPP TS 38.215 Sec 5.1.*, 3GPP TS 38.133 10.1.16.1 + * Range: -23 dB to 40 dB + * @return SS signal-to-noise and interference ratio, {@link CellInfo#UNAVAILABLE} means + * unreported value. + */ + public int getSsSinr() { + return mSsSinr; + } + + /** + * Reference: 3GPP TS 38.215. + * Range: -140 dBm to -44 dBm. + * @return CSI reference signal received power, {@link CellInfo#UNAVAILABLE} means unreported + * value. + */ + public int getCsiRsrp() { + return mCsiRsrp; + } + + /** + * Reference: 3GPP TS 38.215. + * Range: -20 dB to -3 dB. + * @return CSI reference signal received quality, {@link CellInfo#UNAVAILABLE} means unreported + * value. + */ + public int getCsiRsrq() { + return mCsiRsrq; + } + + /** + * Reference: 3GPP TS 38.215 Sec 5.1.*, 3GPP TS 38.133 10.1.16.1 + * Range: -23 dB to 23 dB + * @return CSI signal-to-noise and interference ratio, {@link CellInfo#UNAVAILABLE} means + * unreported value. + */ + public int getCsiSinr() { + return mCsiSinr; + } + + @Override + public int describeContents() { + return 0; + } + + /** @hide */ + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(mCsiRsrp); + dest.writeInt(mCsiRsrq); + dest.writeInt(mCsiSinr); + dest.writeInt(mSsRsrp); + dest.writeInt(mSsRsrq); + dest.writeInt(mSsSinr); + } + + private CellSignalStrengthNr(Parcel in) { + mCsiRsrp = in.readInt(); + mCsiRsrq = in.readInt(); + mCsiSinr = in.readInt(); + mSsRsrp = in.readInt(); + mSsRsrq = in.readInt(); + mSsSinr = in.readInt(); + } + + /** @hide */ + @Override + public void setDefaultValues() { + mCsiRsrp = CellInfo.UNAVAILABLE; + mCsiRsrq = CellInfo.UNAVAILABLE; + mCsiSinr = CellInfo.UNAVAILABLE; + mSsRsrp = CellInfo.UNAVAILABLE; + mSsRsrq = CellInfo.UNAVAILABLE; + mSsSinr = CellInfo.UNAVAILABLE; + } + + @Override + public int getLevel() { + if (mCsiRsrp == CellInfo.UNAVAILABLE) { + return SIGNAL_STRENGTH_NONE_OR_UNKNOWN; + } else if (mCsiRsrp >= SIGNAL_GREAT_THRESHOLD) { + return SIGNAL_STRENGTH_GREAT; + } else if (mCsiRsrp >= SIGNAL_GOOD_THRESHOLD) { + return SIGNAL_STRENGTH_GOOD; + } else if (mCsiRsrp >= SIGNAL_MODERATE_THRESHOLD) { + return SIGNAL_STRENGTH_MODERATE; + } else { + return 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. + */ + @Override + public int getAsuLevel() { + int asuLevel; + int nrDbm = getDbm(); + if (nrDbm == CellInfo.UNAVAILABLE) { + asuLevel = UNKNOWN_ASU_LEVEL; + } else if (nrDbm <= -140) { + asuLevel = 0; + } else if (nrDbm >= -43) { + asuLevel = 97; + } else { + asuLevel = nrDbm + 140; + } + return asuLevel; + } + + @Override + public int getDbm() { + return mCsiRsrp; + } + + /** @hide */ + @Override + public CellSignalStrength copy() { + return new CellSignalStrengthNr( + mCsiRsrp, mCsiRsrq, mCsiSinr, mSsRsrp, mSsRsrq, mSsSinr); + } + + @Override + public int hashCode() { + return Objects.hash(mCsiRsrp, mCsiRsrq, mCsiSinr, mSsRsrp, mSsRsrq, mSsSinr); + } + + @Override + public boolean equals(Object obj) { + 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; + } + return false; + } + + @Override + public String toString() { + return new StringBuilder() + .append(TAG + ":{") + .append(" csiRsrp = " + mCsiRsrp) + .append(" csiRsrq = " + mCsiRsrq) + .append(" csiSinr = " + mCsiSinr) + .append(" ssRsrp = " + mSsRsrp) + .append(" ssRsrq = " + mSsRsrq) + .append(" ssSinr = " + mSsSinr) + .append(" }") + .toString(); + } + + /** Implement the Parcelable interface */ + public static final Parcelable.Creator<CellSignalStrengthNr> CREATOR = + new Parcelable.Creator<CellSignalStrengthNr>() { + @Override + public CellSignalStrengthNr createFromParcel(Parcel in) { + return new CellSignalStrengthNr(in); + } + + @Override + public CellSignalStrengthNr[] newArray(int size) { + return new CellSignalStrengthNr[size]; + } + }; +} diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java index c3d88989ae96..68e512eaff37 100644 --- a/telephony/java/android/telephony/NetworkRegistrationState.java +++ b/telephony/java/android/telephony/NetworkRegistrationState.java @@ -237,10 +237,9 @@ public class NetworkRegistrationState implements Parcelable { } /** - * @return {@link ServiceState.RoamingType roaming type}. This could return - * overridden roaming type based on resource overlay or carrier config. - * @hide + * @return the current network roaming type. */ + public @ServiceState.RoamingType int getRoamingType() { return mRoamingType; } diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java index 2abf98c73944..0c8d581302c8 100644 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ b/telephony/java/android/telephony/PhoneStateListener.java @@ -16,19 +16,23 @@ package android.telephony; +import android.Manifest; import android.annotation.NonNull; +import android.annotation.RequiresPermission; import android.annotation.SystemApi; import android.annotation.UnsupportedAppUsage; +import android.os.Binder; import android.os.Bundle; import android.os.Handler; +import android.os.HandlerExecutor; import android.os.Looper; -import android.os.Message; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.IPhoneStateListener; import java.lang.ref.WeakReference; import java.util.List; +import java.util.concurrent.Executor; /** * A listener class for monitoring changes in specific telephony states @@ -201,12 +205,13 @@ public class PhoneStateListener { public static final int LISTEN_DATA_CONNECTION_REAL_TIME_INFO = 0x00002000; /** - * Listen for changes to LTE network state - * - * @see #onLteNetworkStateChanged + * Listen for changes to the SRVCC state of the active call. + * @see #onServiceStateChanged(ServiceState) * @hide */ - public static final int LISTEN_VOLTE_STATE = 0x00004000; + @SystemApi + @RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE) + public static final int LISTEN_SRVCC_STATE_CHANGED = 0x00004000; /** * Listen for OEM hook raw event @@ -317,7 +322,12 @@ public class PhoneStateListener { @UnsupportedAppUsage protected Integer mSubId; - private final Handler mHandler; + /** + * @hide + */ + @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) + @UnsupportedAppUsage + public final IPhoneStateListener callback; /** * Create a PhoneStateListener for the Phone with the default subscription. @@ -355,95 +365,27 @@ public class PhoneStateListener { */ @UnsupportedAppUsage public PhoneStateListener(Integer subId, Looper looper) { - if (DBG) log("ctor: subId=" + subId + " looper=" + looper); + this(subId, new HandlerExecutor(new Handler(looper))); + } + + /** + * Create a PhoneStateListener for the Phone using the specified Executor + * + * <p>Create a PhoneStateListener with a specified Executor for handling necessary callbacks. + * The Executor must not be null. + * + * @param executor a non-null Executor that will execute callbacks for the PhoneStateListener. + */ + public PhoneStateListener(@NonNull Executor executor) { + this(null, executor); + } + + private PhoneStateListener(Integer subId, Executor e) { + if (e == null) { + throw new IllegalArgumentException("PhoneStateListener Executor must be non-null"); + } mSubId = subId; - mHandler = new Handler(looper) { - public void handleMessage(Message msg) { - if (DBG) { - log("mSubId=" + mSubId + " what=0x" + Integer.toHexString(msg.what) - + " msg=" + msg); - } - switch (msg.what) { - case LISTEN_SERVICE_STATE: - PhoneStateListener.this.onServiceStateChanged((ServiceState)msg.obj); - break; - case LISTEN_SIGNAL_STRENGTH: - PhoneStateListener.this.onSignalStrengthChanged(msg.arg1); - break; - case LISTEN_MESSAGE_WAITING_INDICATOR: - PhoneStateListener.this.onMessageWaitingIndicatorChanged(msg.arg1 != 0); - break; - case LISTEN_CALL_FORWARDING_INDICATOR: - PhoneStateListener.this.onCallForwardingIndicatorChanged(msg.arg1 != 0); - break; - case LISTEN_CELL_LOCATION: - PhoneStateListener.this.onCellLocationChanged((CellLocation)msg.obj); - break; - case LISTEN_CALL_STATE: - PhoneStateListener.this.onCallStateChanged(msg.arg1, (String)msg.obj); - break; - case LISTEN_DATA_CONNECTION_STATE: - PhoneStateListener.this.onDataConnectionStateChanged(msg.arg1, msg.arg2); - PhoneStateListener.this.onDataConnectionStateChanged(msg.arg1); - break; - case LISTEN_DATA_ACTIVITY: - PhoneStateListener.this.onDataActivity(msg.arg1); - break; - case LISTEN_SIGNAL_STRENGTHS: - PhoneStateListener.this.onSignalStrengthsChanged((SignalStrength)msg.obj); - break; - case LISTEN_OTASP_CHANGED: - PhoneStateListener.this.onOtaspChanged(msg.arg1); - break; - case LISTEN_CELL_INFO: - PhoneStateListener.this.onCellInfoChanged((List<CellInfo>)msg.obj); - break; - case LISTEN_PRECISE_CALL_STATE: - PhoneStateListener.this.onPreciseCallStateChanged((PreciseCallState)msg.obj); - break; - case LISTEN_PRECISE_DATA_CONNECTION_STATE: - PhoneStateListener.this.onPreciseDataConnectionStateChanged( - (PreciseDataConnectionState)msg.obj); - break; - case LISTEN_DATA_CONNECTION_REAL_TIME_INFO: - PhoneStateListener.this.onDataConnectionRealTimeInfoChanged( - (DataConnectionRealTimeInfo)msg.obj); - break; - case LISTEN_VOLTE_STATE: - PhoneStateListener.this.onVoLteServiceStateChanged((VoLteServiceState)msg.obj); - break; - case LISTEN_VOICE_ACTIVATION_STATE: - PhoneStateListener.this.onVoiceActivationStateChanged((int)msg.obj); - break; - case LISTEN_DATA_ACTIVATION_STATE: - PhoneStateListener.this.onDataActivationStateChanged((int)msg.obj); - break; - case LISTEN_USER_MOBILE_DATA_STATE: - PhoneStateListener.this.onUserMobileDataStateChanged((boolean)msg.obj); - break; - case LISTEN_OEM_HOOK_RAW_EVENT: - PhoneStateListener.this.onOemHookRawEvent((byte[])msg.obj); - break; - case LISTEN_CARRIER_NETWORK_CHANGE: - PhoneStateListener.this.onCarrierNetworkChange((boolean)msg.obj); - break; - case LISTEN_PHYSICAL_CHANNEL_CONFIGURATION: - PhoneStateListener.this.onPhysicalChannelConfigurationChanged( - (List<PhysicalChannelConfig>)msg.obj); - break; - case LISTEN_PHONE_CAPABILITY_CHANGE: - PhoneStateListener.this.onPhoneCapabilityChanged( - (PhoneCapability) msg.obj); - break; - case LISTEN_RADIO_POWER_STATE_CHANGED: - PhoneStateListener.this.onRadioPowerStateChanged((int) msg.obj); - break; - case LISTEN_PREFERRED_DATA_SUBID_CHANGE: - PhoneStateListener.this.onPreferredDataSubIdChanged((int) msg.obj); - break; - } - } - }; + callback = new IPhoneStateListenerStub(this, e); } /** @@ -613,13 +555,13 @@ public class PhoneStateListener { } /** - * Callback invoked when the service state of LTE network - * related to the VoLTE service has changed. - * @param stateInfo is the current LTE network information + * Callback invoked when there has been a change in the Single Radio Voice Call Continuity + * (SRVCC) state for the currently active call. * @hide */ - @UnsupportedAppUsage - public void onVoLteServiceStateChanged(VoLteServiceState stateInfo) { + @SystemApi + public void onSrvccStateChanged(@TelephonyManager.SrvccState int srvccState) { + } /** @@ -681,25 +623,25 @@ public class PhoneStateListener { } /** - * Callback invoked when modem radio power state changes. Requires + * Callback invoked when preferred data subId changes. Requires * the READ_PRIVILEGED_PHONE_STATE permission. - * @param state the modem radio power state + * @param subId the new preferred data subId. If it's INVALID_SUBSCRIPTION_ID, + * it means it's unset and defaultDataSub is used to determine which + * modem is preferred. * @hide */ - @SystemApi - public void onRadioPowerStateChanged(@TelephonyManager.RadioPowerState int state) { + public void onPreferredDataSubIdChanged(int subId) { // default implementation empty } /** - * Callback invoked when preferred data subId changes. Requires + * Callback invoked when modem radio power state changes. Requires * the READ_PRIVILEGED_PHONE_STATE permission. - * @param subId the new preferred data subId. If it's INVALID_SUBSCRIPTION_ID, - * it means it's unset and defaultDataSub is used to determine which - * modem is preferred. + * @param state the modem radio power state * @hide */ - public void onPreferredDataSubIdChanged(int subId) { + @SystemApi + public void onRadioPowerStateChanged(@TelephonyManager.RadioPowerState int state) { // default implementation empty } @@ -732,124 +674,215 @@ public class PhoneStateListener { */ private static class IPhoneStateListenerStub extends IPhoneStateListener.Stub { private WeakReference<PhoneStateListener> mPhoneStateListenerWeakRef; + private Executor mExecutor; - public IPhoneStateListenerStub(PhoneStateListener phoneStateListener) { + IPhoneStateListenerStub(PhoneStateListener phoneStateListener, Executor executor) { mPhoneStateListenerWeakRef = new WeakReference<PhoneStateListener>(phoneStateListener); - } - - private void send(int what, int arg1, int arg2, Object obj) { - PhoneStateListener listener = mPhoneStateListenerWeakRef.get(); - if (listener != null) { - Message.obtain(listener.mHandler, what, arg1, arg2, obj).sendToTarget(); - } + mExecutor = executor; } public void onServiceStateChanged(ServiceState serviceState) { - send(LISTEN_SERVICE_STATE, 0, 0, serviceState); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onServiceStateChanged(serviceState))); } public void onSignalStrengthChanged(int asu) { - send(LISTEN_SIGNAL_STRENGTH, asu, 0, null); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onSignalStrengthChanged(asu))); } public void onMessageWaitingIndicatorChanged(boolean mwi) { - send(LISTEN_MESSAGE_WAITING_INDICATOR, mwi ? 1 : 0, 0, null); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onMessageWaitingIndicatorChanged(mwi))); } public void onCallForwardingIndicatorChanged(boolean cfi) { - send(LISTEN_CALL_FORWARDING_INDICATOR, cfi ? 1 : 0, 0, null); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onCallForwardingIndicatorChanged(cfi))); } public void onCellLocationChanged(Bundle bundle) { CellLocation location = CellLocation.newFromBundle(bundle); - send(LISTEN_CELL_LOCATION, 0, 0, location); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onCellLocationChanged(location))); } public void onCallStateChanged(int state, String incomingNumber) { - send(LISTEN_CALL_STATE, state, 0, incomingNumber); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onCallStateChanged(state, incomingNumber))); } public void onDataConnectionStateChanged(int state, int networkType) { - send(LISTEN_DATA_CONNECTION_STATE, state, networkType, null); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> psl.onDataConnectionStateChanged(state, networkType))); } public void onDataActivity(int direction) { - send(LISTEN_DATA_ACTIVITY, direction, 0, null); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onDataActivity(direction))); } public void onSignalStrengthsChanged(SignalStrength signalStrength) { - send(LISTEN_SIGNAL_STRENGTHS, 0, 0, signalStrength); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onSignalStrengthsChanged(signalStrength))); } public void onOtaspChanged(int otaspMode) { - send(LISTEN_OTASP_CHANGED, otaspMode, 0, null); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onOtaspChanged(otaspMode))); } public void onCellInfoChanged(List<CellInfo> cellInfo) { - send(LISTEN_CELL_INFO, 0, 0, cellInfo); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onCellInfoChanged(cellInfo))); } public void onPreciseCallStateChanged(PreciseCallState callState) { - send(LISTEN_PRECISE_CALL_STATE, 0, 0, callState); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onPreciseCallStateChanged(callState))); } public void onPreciseDataConnectionStateChanged( PreciseDataConnectionState dataConnectionState) { - send(LISTEN_PRECISE_DATA_CONNECTION_STATE, 0, 0, dataConnectionState); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> psl.onPreciseDataConnectionStateChanged(dataConnectionState))); } - public void onDataConnectionRealTimeInfoChanged( - DataConnectionRealTimeInfo dcRtInfo) { - send(LISTEN_DATA_CONNECTION_REAL_TIME_INFO, 0, 0, dcRtInfo); + public void onDataConnectionRealTimeInfoChanged(DataConnectionRealTimeInfo dcRtInfo) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> psl.onDataConnectionRealTimeInfoChanged(dcRtInfo))); } - public void onVoLteServiceStateChanged(VoLteServiceState lteState) { - send(LISTEN_VOLTE_STATE, 0, 0, lteState); + public void onSrvccStateChanged(int state) { + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onSrvccStateChanged(state))); } public void onVoiceActivationStateChanged(int activationState) { - send(LISTEN_VOICE_ACTIVATION_STATE, 0, 0, activationState); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> psl.onVoiceActivationStateChanged(activationState))); } public void onDataActivationStateChanged(int activationState) { - send(LISTEN_DATA_ACTIVATION_STATE, 0, 0, activationState); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> psl.onDataActivationStateChanged(activationState))); } public void onUserMobileDataStateChanged(boolean enabled) { - send(LISTEN_USER_MOBILE_DATA_STATE, 0, 0, enabled); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> psl.onUserMobileDataStateChanged(enabled))); } public void onOemHookRawEvent(byte[] rawData) { - send(LISTEN_OEM_HOOK_RAW_EVENT, 0, 0, rawData); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onOemHookRawEvent(rawData))); } public void onCarrierNetworkChange(boolean active) { - send(LISTEN_CARRIER_NETWORK_CHANGE, 0, 0, active); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onCarrierNetworkChange(active))); } public void onPhysicalChannelConfigurationChanged(List<PhysicalChannelConfig> configs) { - send(LISTEN_PHYSICAL_CHANNEL_CONFIGURATION, 0, 0, configs); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute( + () -> psl.onPhysicalChannelConfigurationChanged(configs))); } public void onPhoneCapabilityChanged(PhoneCapability capability) { - send(LISTEN_PHONE_CAPABILITY_CHANGE, 0, 0, capability); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onPhoneCapabilityChanged(capability))); } public void onRadioPowerStateChanged(@TelephonyManager.RadioPowerState int state) { - send(LISTEN_RADIO_POWER_STATE_CHANGED, 0, 0, state); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onRadioPowerStateChanged(state))); } public void onPreferredDataSubIdChanged(int subId) { - send(LISTEN_PREFERRED_DATA_SUBID_CHANGE, 0, 0, subId); + PhoneStateListener psl = mPhoneStateListenerWeakRef.get(); + if (psl == null) return; + + Binder.withCleanCallingIdentity( + () -> mExecutor.execute(() -> psl.onPreferredDataSubIdChanged(subId))); } } - /** - * @hide - */ - @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE) - @UnsupportedAppUsage - public final IPhoneStateListener callback = new IPhoneStateListenerStub(this); private void log(String s) { Rlog.d(LOG_TAG, s); diff --git a/telephony/java/android/telephony/PreciseDisconnectCause.java b/telephony/java/android/telephony/PreciseDisconnectCause.java index 46e2adbcfa7f..2acaf34dbb30 100644 --- a/telephony/java/android/telephony/PreciseDisconnectCause.java +++ b/telephony/java/android/telephony/PreciseDisconnectCause.java @@ -332,6 +332,8 @@ public class PreciseDisconnectCause { public static final int SIP_NOT_REACHABLE = 1320; /** Others */ public static final int SIP_CLIENT_ERROR = 1321; + /** 481 : Transaction Does Not Exist */ + public static final int SIP_TRANSACTION_DOES_NOT_EXIST = 1322; /** 5xx responses * 501 : Server Internal Error */ diff --git a/telephony/java/android/telephony/RcsManager.java b/telephony/java/android/telephony/RcsManager.java new file mode 100644 index 000000000000..00ce03a1f668 --- /dev/null +++ b/telephony/java/android/telephony/RcsManager.java @@ -0,0 +1,52 @@ +/* + * 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.os.RemoteException; +import android.os.ServiceManager; + +import com.android.internal.telephony.IRcs; + +/** + * RcsManager is the application interface to RcsProvider and provides access methods to + * RCS related database tables. + * @hide - TODO make this public + */ +public class RcsManager { + private static final String TAG = "RcsManager"; + private static final boolean VDBG = false; + + /** + * Delete the RcsThread identified by the given threadId. + * @param threadId threadId of the thread to be deleted. + */ + public void deleteThread(int threadId) { + if (VDBG) logd("deleteThread: threadId: " + threadId); + try { + IRcs iRcs = IRcs.Stub.asInterface(ServiceManager.getService("ircs")); + if (iRcs != null) { + iRcs.deleteThread(threadId); + } + } catch (RemoteException re) { + + } + } + + private static void logd(String msg) { + Rlog.d(TAG, msg); + } +} diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index c4076810b95e..0937b1071e23 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -211,29 +211,30 @@ public class ServiceState implements Parcelable { ROAMING_TYPE_INTERNATIONAL }) public @interface RoamingType {} + /** - * Roaming type - * HOME : in home network + * Not roaming, registered in home network. * @hide */ + @SystemApi public static final int ROAMING_TYPE_NOT_ROAMING = 0; /** - * Roaming type - * UNKNOWN : in a roaming network, but we can not tell if it's domestic or international + * registered in a roaming network, but can not tell if it's domestic or international. * @hide */ + @SystemApi public static final int ROAMING_TYPE_UNKNOWN = 1; /** - * Roaming type - * DOMESTIC : in domestic roaming network + * registered in a domestic roaming network * @hide */ + @SystemApi public static final int ROAMING_TYPE_DOMESTIC = 2; /** - * Roaming type - * INTERNATIONAL : in international roaming network + * registered in an international roaming network * @hide */ + @SystemApi public static final int ROAMING_TYPE_INTERNATIONAL = 3; /** diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index 6813bdd8ec8f..80ee9b393f4d 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -50,6 +50,7 @@ import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; import android.telephony.euicc.EuiccManager; +import android.telephony.ims.ImsMmTelManager; import android.util.DisplayMetrics; import android.util.Log; @@ -133,7 +134,7 @@ public class SubscriptionManager { * A content {@link Uri} used to receive updates on wfc enabled user setting. * <p> * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the - * subscription wfc enabled {@link SubscriptionManager#WFC_IMS_ENABLED} + * subscription wfc enabled {@link ImsMmTelManager#isVoWiFiSettingEnabled()} * while your app is running. You can also use a {@link JobService} to ensure your app * is notified of changes to the {@link Uri} even when it is not running. * Note, however, that using a {@link JobService} does not guarantee timely delivery of @@ -146,10 +147,28 @@ public class SubscriptionManager { public static final Uri WFC_ENABLED_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc"); /** - * A content {@link Uri} used to receive updates on enhanced 4g user setting. + * A content {@link Uri} used to receive updates on advanced calling user setting. * <p> * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the - * subscription enhanced 4G enabled {@link SubscriptionManager#ENHANCED_4G_MODE_ENABLED} + * subscription advanced calling enabled + * {@link ImsMmTelManager#isAdvancedCallingSettingEnabled()} while your app is running. + * You can also use a {@link JobService} to ensure your app is notified of changes to the + * {@link Uri} even when it is not running. + * Note, however, that using a {@link JobService} does not guarantee timely delivery of + * updates to the {@link Uri}. + * To be notified of changes to a specific subId, append subId to the URI + * {@link Uri#withAppendedPath(Uri, String)}. + * @hide + */ + @SystemApi + public static final Uri ADVANCED_CALLING_ENABLED_CONTENT_URI = Uri.withAppendedPath( + CONTENT_URI, "advanced_calling"); + + /** + * A content {@link Uri} used to receive updates on wfc mode setting. + * <p> + * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the + * subscription wfc mode {@link ImsMmTelManager#getVoWiFiModeSetting()} * while your app is running. You can also use a {@link JobService} to ensure your app * is notified of changes to the {@link Uri} even when it is not running. * Note, however, that using a {@link JobService} does not guarantee timely delivery of @@ -159,9 +178,59 @@ public class SubscriptionManager { * @hide */ @SystemApi - public static final Uri ENHANCED_4G_ENABLED_CONTENT_URI = Uri.withAppendedPath( - CONTENT_URI, "enhanced_4g"); + public static final Uri WFC_MODE_CONTENT_URI = Uri.withAppendedPath(CONTENT_URI, "wfc_mode"); + /** + * A content {@link Uri} used to receive updates on wfc roaming mode setting. + * <p> + * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the + * subscription wfc roaming mode {@link ImsMmTelManager#getVoWiFiRoamingModeSetting()} + * while your app is running. You can also use a {@link JobService} to ensure your app + * is notified of changes to the {@link Uri} even when it is not running. + * Note, however, that using a {@link JobService} does not guarantee timely delivery of + * updates to the {@link Uri}. + * To be notified of changes to a specific subId, append subId to the URI + * {@link Uri#withAppendedPath(Uri, String)}. + * @hide + */ + @SystemApi + public static final Uri WFC_ROAMING_MODE_CONTENT_URI = Uri.withAppendedPath( + CONTENT_URI, "wfc_roaming_mode"); + + /** + * A content {@link Uri} used to receive updates on vt(video telephony over IMS) enabled + * setting. + * <p> + * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the + * subscription vt enabled {@link ImsMmTelManager#isVtSettingEnabled()} + * while your app is running. You can also use a {@link JobService} to ensure your app + * is notified of changes to the {@link Uri} even when it is not running. + * Note, however, that using a {@link JobService} does not guarantee timely delivery of + * updates to the {@link Uri}. + * To be notified of changes to a specific subId, append subId to the URI + * {@link Uri#withAppendedPath(Uri, String)}. + * @hide + */ + @SystemApi + public static final Uri VT_ENABLED_CONTENT_URI = Uri.withAppendedPath( + CONTENT_URI, "vt_enabled"); + + /** + * A content {@link Uri} used to receive updates on wfc roaming enabled setting. + * <p> + * Use this {@link Uri} with a {@link ContentObserver} to be notified of changes to the + * subscription wfc roaming enabled {@link ImsMmTelManager#isVoWiFiRoamingSettingEnabled()} + * while your app is running. You can also use a {@link JobService} to ensure your app + * is notified of changes to the {@link Uri} even when it is not running. + * Note, however, that using a {@link JobService} does not guarantee timely delivery of + * updates to the {@link Uri}. + * To be notified of changes to a specific subId, append subId to the URI + * {@link Uri#withAppendedPath(Uri, String)}. + * @hide + */ + @SystemApi + public static final Uri WFC_ROAMING_ENABLED_CONTENT_URI = Uri.withAppendedPath( + CONTENT_URI, "wfc_roaming_enabled"); /** * TelephonyProvider unique key column name is the subscription id. diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 9f697e9c6e93..016a77d2a741 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -181,6 +181,57 @@ public class TelephonyManager { /** @hide */ static public final int KEY_TYPE_WLAN = 2; + /** + * No Single Radio Voice Call Continuity (SRVCC) handover is active. + * See TS 23.216 for more information. + * @hide + */ + @SystemApi + public static final int SRVCC_STATE_HANDOVER_NONE = -1; + + /** + * Single Radio Voice Call Continuity (SRVCC) handover has been started on the network. + * See TS 23.216 for more information. + * @hide + */ + @SystemApi + public static final int SRVCC_STATE_HANDOVER_STARTED = 0; + + /** + * Ongoing Single Radio Voice Call Continuity (SRVCC) handover has successfully completed. + * See TS 23.216 for more information. + * @hide + */ + @SystemApi + public static final int SRVCC_STATE_HANDOVER_COMPLETED = 1; + + /** + * Ongoing Single Radio Voice Call Continuity (SRVCC) handover has failed. + * See TS 23.216 for more information. + * @hide + */ + @SystemApi + public static final int SRVCC_STATE_HANDOVER_FAILED = 2; + + /** + * Ongoing Single Radio Voice Call Continuity (SRVCC) handover has been canceled. + * See TS 23.216 for more information. + * @hide + */ + @SystemApi + public static final int SRVCC_STATE_HANDOVER_CANCELED = 3; + + /** @hide */ + @Retention(RetentionPolicy.SOURCE) + @IntDef(prefix = {"SRVCC_STATE_"}, + value = { + SRVCC_STATE_HANDOVER_NONE, + SRVCC_STATE_HANDOVER_STARTED, + SRVCC_STATE_HANDOVER_COMPLETED, + SRVCC_STATE_HANDOVER_FAILED, + SRVCC_STATE_HANDOVER_CANCELED}) + public @interface SrvccState {} + private final Context mContext; private final int mSubId; @UnsupportedAppUsage @@ -1161,6 +1212,33 @@ public class TelephonyManager { "android.telephony.action.SUBSCRIPTION_CARRIER_IDENTITY_CHANGED"; /** + * Broadcast Action: The subscription precise carrier identity has changed. + * Similar like {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED}, this intent will be sent + * on the event of {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED}. However, its possible + * that precise carrier identity changes while + * {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} remains the same e.g, the same + * subscription switches to different IMSI could potentially change its precise carrier id. + * + * The intent will have the following extra values: + * <ul> + * <li>{@link #EXTRA_PRECISE_CARRIER_ID} The up-to-date precise carrier id of the + * current subscription. + * </li> + * <li>{@link #EXTRA_PRECISE_CARRIER_NAME} The up-to-date carrier name of the current + * subscription. + * </li> + * <li>{@link #EXTRA_SUBSCRIPTION_ID} The subscription id associated with the changed carrier + * identity. + * </li> + * </ul> + * <p class="note">This is a protected intent that can only be sent by the system. + * @hide + */ + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String ACTION_SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED = + "android.telephony.action.SUBSCRIPTION_PRECISE_CARRIER_IDENTITY_CHANGED"; + + /** * An int extra used with {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} which indicates * the updated carrier id {@link TelephonyManager#getSimCarrierId()} of * the current subscription. @@ -1189,6 +1267,28 @@ public class TelephonyManager { 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. + * <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 + */ + public static final String EXTRA_PRECISE_CARRIER_NAME = "android.telephony.extra.CARRIER_NAME"; + + /** * An int extra used with {@link #ACTION_SUBSCRIPTION_CARRIER_IDENTITY_CHANGED} to indicate the * subscription which has changed. */ @@ -8248,6 +8348,62 @@ public class TelephonyManager { } /** + * Returns fine-grained carrier id of the current subscription. + * + * <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. + * + * <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 + * <a href="https://android.googlesource.com/platform/packages/providers/TelephonyProvider/+/master/assets/carrier_list.textpb">here</a> + * except each with a "parent" id linking to its top-level carrier id. + * + * @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 { + ITelephony service = getITelephony(); + if (service != null) { + return service.getSubscriptionPreciseCarrierId(getSubId()); + } + } catch (RemoteException ex) { + // This could happen if binder process crashes. + } + return UNKNOWN_CARRIER_ID; + } + + /** + * Similar like {@link #getSimCarrierIdName()}, returns user-facing name of the + * precise carrier id {@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() { + try { + ITelephony service = getITelephony(); + if (service != null) { + return service.getSubscriptionPreciseCarrierName(getSubId()); + } + } catch (RemoteException ex) { + // This could happen if binder process crashes. + } + return null; + } + + /** * 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 @@ -8271,6 +8427,28 @@ public class TelephonyManager { } /** + * Returns MNO carrier id of the current subscription’s MCCMNC. + * <p>MNO carrier id can be solely identified by subscription mccmnc. This is mainly used + * for MNO fallback when exact carrier id {@link #getSimCarrierId()} + * configurations are not found. + * + * @return MNO carrier id of the current subscription. Return the value same as carrier id + * {@link #getSimCarrierId()}, if MNO carrier id cannot be identified. + * @hide + */ + public int getSimMNOCarrierId() { + try { + ITelephony service = getITelephony(); + if (service != null) { + return service.getSubscriptionMNOCarrierId(getSubId()); + } + } catch (RemoteException ex) { + // This could happen if binder process crashes. + } + return UNKNOWN_CARRIER_ID; + } + + /** * Return the application ID for the uicc application type like {@link #APPTYPE_CSIM}. * All uicc applications are uniquely identified by application ID. See ETSI 102.221 and 101.220 * <p>Requires Permission: @@ -9025,7 +9203,7 @@ public class TelephonyManager { public static final int NETWORK_TYPE_BITMASK_LTE_CA = (1 << NETWORK_TYPE_LTE_CA); /** - * @return Modem supported radio access family bitmask {@link NetworkTypeBitMask} + * @return Modem supported radio access family bitmask * * <p>Requires permission: {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE} or * that the calling app has carrier privileges (see {@link #hasCarrierPrivileges}). diff --git a/telephony/java/android/telephony/VoLteServiceState.java b/telephony/java/android/telephony/VoLteServiceState.java index 25bb8b4a414e..cf961d0be10c 100644 --- a/telephony/java/android/telephony/VoLteServiceState.java +++ b/telephony/java/android/telephony/VoLteServiceState.java @@ -24,9 +24,11 @@ import android.telephony.Rlog; /** * Contains LTE network state related information. - * + * @deprecated Only contains SRVCC state, which isn't specific to LTE handovers. For SRVCC + * indications, use {@link PhoneStateListener#onSrvccStateChanged(int)}. * @hide */ +@Deprecated public final class VoLteServiceState implements Parcelable { private static final String LOG_TAG = "VoLteServiceState"; diff --git a/telephony/java/android/telephony/ims/ImsReasonInfo.java b/telephony/java/android/telephony/ims/ImsReasonInfo.java index c9766668ae84..8fcdb6e90569 100644 --- a/telephony/java/android/telephony/ims/ImsReasonInfo.java +++ b/telephony/java/android/telephony/ims/ImsReasonInfo.java @@ -164,6 +164,8 @@ public final class ImsReasonInfo implements Parcelable { public static final int CODE_SIP_NOT_REACHABLE = 341; // Others public static final int CODE_SIP_CLIENT_ERROR = 342; + // 481 Transaction Does Not Exist + public static final int CODE_SIP_TRANSACTION_DOES_NOT_EXIST = 343; // 5xx responses // 501 : Server Internal Error public static final int CODE_SIP_SERVER_INTERNAL_ERROR = 351; diff --git a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl index 64ea6083d63d..442fc34d4b71 100644 --- a/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl +++ b/telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl @@ -25,7 +25,6 @@ import android.telephony.PhoneCapability; import android.telephony.PhysicalChannelConfig; import android.telephony.PreciseCallState; import android.telephony.PreciseDataConnectionState; -import android.telephony.VoLteServiceState; oneway interface IPhoneStateListener { void onServiceStateChanged(in ServiceState serviceState); @@ -45,7 +44,7 @@ oneway interface IPhoneStateListener { void onPreciseCallStateChanged(in PreciseCallState callState); void onPreciseDataConnectionStateChanged(in PreciseDataConnectionState dataConnectionState); void onDataConnectionRealTimeInfoChanged(in DataConnectionRealTimeInfo dcRtInfo); - void onVoLteServiceStateChanged(in VoLteServiceState lteState); + void onSrvccStateChanged(in int state); void onVoiceActivationStateChanged(int activationState); void onDataActivationStateChanged(int activationState); void onOemHookRawEvent(in byte[] rawData); diff --git a/telephony/java/com/android/internal/telephony/IRcs.aidl b/telephony/java/com/android/internal/telephony/IRcs.aidl new file mode 100644 index 000000000000..ede8695ef08e --- /dev/null +++ b/telephony/java/com/android/internal/telephony/IRcs.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 permissions and + * limitations under the License. + */ + +package com.android.internal.telephony; + +interface IRcs { + void deleteThread(int threadId); +}
\ No newline at end of file diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index cad10f34db46..1f3746668aa6 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -1311,6 +1311,49 @@ 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 + * 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 underlying network. + * + * <p>For carriers without any fine-grained carrier ids, return {@link #getSimCarrierId()} + * + * @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 + */ + int getSubscriptionPreciseCarrierId(int subId); + + /** + * Similar like {@link #getSimCarrierIdName()}, returns user-facing name of the + * precise carrier id {@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 + */ + String getSubscriptionPreciseCarrierName(int subId); + + /** * Action set from carrier signalling broadcast receivers to enable/disable metered apns * Permissions android.Manifest.permission.MODIFY_PHONE_STATE is required * @param subId the subscription ID that this action applies to. diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 0bbfa9a83b8b..e50cdcdedcf3 100644 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -25,7 +25,6 @@ import android.telephony.PhoneCapability; import android.telephony.PhysicalChannelConfig; import android.telephony.ServiceState; import android.telephony.SignalStrength; -import android.telephony.VoLteServiceState; import com.android.internal.telephony.IPhoneStateListener; import com.android.internal.telephony.IOnSubscriptionsChangedListener; @@ -70,7 +69,7 @@ interface ITelephonyRegistry { void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn, String failCause); void notifyCellInfoForSubscriber(in int subId, in List<CellInfo> cellInfo); - void notifyVoLteServiceStateChanged(in VoLteServiceState lteState); + void notifySrvccStateChanged(in int subId, in int lteState); void notifySimActivationStateChangedForPhoneId(in int phoneId, in int subId, int activationState, int activationType); void notifyOemHookRawEventForSubscriber(in int subId, in byte[] rawData); diff --git a/telephony/java/com/android/internal/telephony/NetworkScanResult.java b/telephony/java/com/android/internal/telephony/NetworkScanResult.java index 95f39d7f878a..d07d77ca742a 100644 --- a/telephony/java/com/android/internal/telephony/NetworkScanResult.java +++ b/telephony/java/com/android/internal/telephony/NetworkScanResult.java @@ -19,6 +19,7 @@ package com.android.internal.telephony; import android.os.Parcel; import android.os.Parcelable; import android.telephony.CellInfo; + import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -106,6 +107,17 @@ public final class NetworkScanResult implements Parcelable { } @Override + public String toString() { + return new StringBuilder() + .append("{") + .append("scanStatus=" + scanStatus) + .append(", scanError=" + scanError) + .append(", networkInfos=" + networkInfos) + .append("}") + .toString(); + } + + @Override public int hashCode () { return ((scanStatus * 31) + (scanError * 23) diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java index 5ecb43ebf112..2a648bd8b252 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java +++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java @@ -480,9 +480,9 @@ public class TelephonyIntents { public static final String EXTRA_PCO_VALUE_KEY = "pcoValue"; public static final String EXTRA_DEFAULT_NETWORK_AVAILABLE_KEY = "defaultNetworkAvailable"; - /** + /** * Broadcast action to trigger CI OMA-DM Session. - */ + */ public static final String ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE = "com.android.omadm.service.CONFIGURATION_UPDATE"; @@ -491,4 +491,14 @@ public class TelephonyIntents { */ public static final String ACTION_CARRIER_CERTIFICATE_DOWNLOAD = "com.android.internal.telephony.ACTION_CARRIER_CERTIFICATE_DOWNLOAD"; + + /** + * Broadcast action to indicate an error related to Line1Number has been detected. + * + * Requires the READ_PRIVILEGED_PHONE_STATE permission. + * + * @hide + */ + public static final String ACTION_LINE1_NUMBER_ERROR_DETECTED = + "com.android.internal.telephony.ACTION_LINE1_NUMBER_ERROR_DETECTED"; } diff --git a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java index dfe31bde4ecf..bf42412d68d8 100644 --- a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java +++ b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java @@ -31,6 +31,7 @@ import android.net.InterfaceConfiguration; import android.net.LinkAddress; import android.net.LinkProperties; import android.net.NetworkInfo; +import android.net.NetworkMisc; import android.os.Handler; import android.os.INetworkManagementService; import android.os.test.TestLooper; @@ -55,6 +56,7 @@ public class Nat464XlatTest { static final LinkAddress ADDR = new LinkAddress("192.0.2.5/29"); @Mock ConnectivityService mConnectivity; + @Mock NetworkMisc mMisc; @Mock INetworkManagementService mNms; @Mock InterfaceConfiguration mConfig; @Mock NetworkAgentInfo mNai; @@ -78,6 +80,7 @@ public class Nat464XlatTest { mNai.networkInfo = new NetworkInfo(null); mNai.networkInfo.setType(ConnectivityManager.TYPE_WIFI); when(mNai.connService()).thenReturn(mConnectivity); + when(mNai.netMisc()).thenReturn(mMisc); when(mNai.handler()).thenReturn(mHandler); when(mNms.getInterfaceConfig(eq(STACKED_IFACE))).thenReturn(mConfig); @@ -103,9 +106,16 @@ public class Nat464XlatTest { mNai.networkInfo.setType(type); for (NetworkInfo.DetailedState state : supportedDetailedStates) { mNai.networkInfo.setDetailedState(state, "reason", "extraInfo"); - assertTrue( - String.format("requiresClat expected for type=%d state=%s", type, state), - Nat464Xlat.requiresClat(mNai)); + String msg = String.format("requiresClat expected for type=%d state=%s", + type, state); + + mMisc.skip464xlat = true; + String errorMsg = msg + String.format(" skip464xlat=%b", mMisc.skip464xlat); + assertFalse(errorMsg, Nat464Xlat.requiresClat(mNai)); + + mMisc.skip464xlat = false; + errorMsg = msg + String.format(" skip464xlat=%b", mMisc.skip464xlat); + assertTrue(errorMsg, Nat464Xlat.requiresClat(mNai)); } } } diff --git a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java index f12756a8062f..af7123b84842 100644 --- a/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java +++ b/tests/net/java/com/android/server/connectivity/PermissionMonitorTest.java @@ -30,7 +30,9 @@ import static android.os.Process.SYSTEM_UID; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.anyInt; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.eq; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; import android.content.Context; @@ -63,24 +65,13 @@ public class PermissionMonitorTest { @Mock private PackageManager mPackageManager; private PermissionMonitor mPermissionMonitor; - private int mMockFirstSdkInt; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); when(mContext.getPackageManager()).thenReturn(mPackageManager); when(mPackageManager.getPackagesForUid(anyInt())).thenReturn(MOCK_PACKAGE_NAMES); - // Try to use spy() here for stubbing getDeviceFirstSdkInt value but the spies are loaded - // by a custom class loader that's different from the loader used for loading the real - // thing. That means those two classes are not in the same package, so a package private - // method is not accessible. Hence, using override method to control FIRST_SDK_INT value - // instead of spy function for testing. - mPermissionMonitor = new PermissionMonitor(mContext, null) { - @Override - int getDeviceFirstSdkInt() { - return mMockFirstSdkInt; - } - }; + mPermissionMonitor = spy(new PermissionMonitor(mContext, null)); } private boolean hasBgPermission(String partition, int targetSdkVersion, int uid, @@ -166,13 +157,13 @@ public class PermissionMonitorTest { @Test public void testHasUseBackgroundNetworksPermissionSystemUid() throws Exception { - mMockFirstSdkInt = VERSION_P; + doReturn(VERSION_P).when(mPermissionMonitor).getDeviceFirstSdkInt(); assertTrue(hasBgPermission(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID)); assertTrue(hasBgPermission(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID, CHANGE_WIFI_STATE)); assertTrue(hasBgPermission(PARTITION_SYSTEM, VERSION_P, SYSTEM_UID, CONNECTIVITY_USE_RESTRICTED_NETWORKS)); - mMockFirstSdkInt = VERSION_Q; + doReturn(VERSION_Q).when(mPermissionMonitor).getDeviceFirstSdkInt(); assertFalse(hasBgPermission(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID)); assertFalse(hasBgPermission(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID, CHANGE_WIFI_STATE)); assertTrue(hasBgPermission(PARTITION_SYSTEM, VERSION_Q, SYSTEM_UID, |