Merge "Fix equality method implementation in BandConfig class."
diff --git a/Android.mk b/Android.mk
index a2d70ce..623ceba 100644
--- a/Android.mk
+++ b/Android.mk
@@ -130,7 +130,6 @@
core/java/android/bluetooth/IBluetoothGatt.aidl \
core/java/android/bluetooth/IBluetoothGattCallback.aidl \
core/java/android/bluetooth/IBluetoothGattServerCallback.aidl \
- core/java/android/bluetooth/le/IAdvertiserCallback.aidl \
core/java/android/bluetooth/le/IAdvertisingSetCallback.aidl \
core/java/android/bluetooth/le/IPeriodicAdvertisingCallback.aidl \
core/java/android/bluetooth/le/IScannerCallback.aidl \
diff --git a/api/current.txt b/api/current.txt
index b93ef30..b20fe8f 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -36,6 +36,7 @@
field public static final java.lang.String BIND_TELECOM_CONNECTION_SERVICE = "android.permission.BIND_TELECOM_CONNECTION_SERVICE";
field public static final java.lang.String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE";
field public static final java.lang.String BIND_TV_INPUT = "android.permission.BIND_TV_INPUT";
+ field public static final java.lang.String BIND_VISUAL_VOICEMAIL_SERVICE = "android.permission.BIND_VISUAL_VOICEMAIL_SERVICE";
field public static final java.lang.String BIND_VOICE_INTERACTION = "android.permission.BIND_VOICE_INTERACTION";
field public static final java.lang.String BIND_VPN_SERVICE = "android.permission.BIND_VPN_SERVICE";
field public static final java.lang.String BIND_VR_LISTENER_SERVICE = "android.permission.BIND_VR_LISTENER_SERVICE";
@@ -7077,6 +7078,7 @@
method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback);
method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int);
method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int);
+ method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int, android.os.Handler);
method public boolean createBond();
method public android.bluetooth.BluetoothSocket createInsecureRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
method public android.bluetooth.BluetoothSocket createRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
@@ -7671,8 +7673,10 @@
field public static final android.os.Parcelable.Creator<android.bluetooth.le.ScanResult> CREATOR;
field public static final int DATA_COMPLETE = 0; // 0x0
field public static final int DATA_TRUNCATED = 2; // 0x2
+ field public static final int PERIODIC_INTERVAL_NOT_PRESENT = 0; // 0x0
field public static final int PHY_UNUSED = 0; // 0x0
field public static final int SID_NOT_PRESENT = 255; // 0xff
+ field public static final int TX_POWER_NOT_PRESENT = 127; // 0x7f
}
public final class ScanSettings implements android.os.Parcelable {
@@ -8318,7 +8322,6 @@
field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
field public static final java.lang.String INPUT_SERVICE = "input";
- field public static final java.lang.String IPSEC_SERVICE = "ipsec";
field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";
field public static final java.lang.String LAUNCHER_APPS_SERVICE = "launcherapps";
@@ -23870,66 +23873,6 @@
field public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR;
}
- public final class IpSecAlgorithm implements android.os.Parcelable {
- ctor public IpSecAlgorithm(java.lang.String, byte[]);
- ctor public IpSecAlgorithm(java.lang.String, byte[], int);
- method public int describeContents();
- method public byte[] getKey();
- method public java.lang.String getName();
- method public int getTruncationLengthBits();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final java.lang.String AUTH_HMAC_MD5 = "hmac(md5)";
- field public static final java.lang.String AUTH_HMAC_SHA1 = "hmac(sha1)";
- field public static final java.lang.String AUTH_HMAC_SHA256 = "hmac(sha256)";
- field public static final java.lang.String AUTH_HMAC_SHA384 = "hmac(sha384)";
- field public static final java.lang.String AUTH_HMAC_SHA512 = "hmac(sha512)";
- field public static final android.os.Parcelable.Creator<android.net.IpSecAlgorithm> CREATOR;
- field public static final java.lang.String CRYPT_AES_CBC = "cbc(aes)";
- }
-
- public final class IpSecManager {
- method public void applyTransportModeTransform(java.io.FileDescriptor, android.net.IpSecTransform) throws java.io.IOException;
- method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket(int) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
- method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
- method public void removeTransportModeTransform(java.io.FileDescriptor, android.net.IpSecTransform) throws java.io.IOException;
- method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress) throws android.net.IpSecManager.ResourceUnavailableException;
- method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
- field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
- }
-
- public static final class IpSecManager.ResourceUnavailableException extends android.util.AndroidException {
- }
-
- public static final class IpSecManager.SecurityParameterIndex implements java.lang.AutoCloseable {
- method public void close();
- method public int getSpi();
- }
-
- public static final class IpSecManager.SpiUnavailableException extends android.util.AndroidException {
- method public int getSpi();
- }
-
- public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable {
- method public void close() throws java.io.IOException;
- method public int getPort();
- method public java.io.FileDescriptor getSocket();
- }
-
- public final class IpSecTransform implements java.lang.AutoCloseable {
- method public void close();
- field public static final int DIRECTION_IN = 0; // 0x0
- field public static final int DIRECTION_OUT = 1; // 0x1
- }
-
- public static class IpSecTransform.Builder {
- ctor public IpSecTransform.Builder(android.content.Context);
- method public android.net.IpSecTransform buildTransportModeTransform(java.net.InetAddress) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
- method public android.net.IpSecTransform.Builder setAuthentication(int, android.net.IpSecAlgorithm);
- method public android.net.IpSecTransform.Builder setEncryption(int, android.net.IpSecAlgorithm);
- method public android.net.IpSecTransform.Builder setIpv4Encapsulation(android.net.IpSecManager.UdpEncapsulationSocket, int);
- method public android.net.IpSecTransform.Builder setSpi(int, android.net.IpSecManager.SecurityParameterIndex);
- }
-
public class LinkAddress implements android.os.Parcelable {
method public int describeContents();
method public java.net.InetAddress getAddress();
@@ -33840,6 +33783,8 @@
public static final class VoicemailContract.Voicemails implements android.provider.BaseColumns android.provider.OpenableColumns {
method public static android.net.Uri buildSourceUri(java.lang.String);
+ field public static final java.lang.String ARCHIVED = "archived";
+ field public static final java.lang.String BACKED_UP = "backed_up";
field public static final android.net.Uri CONTENT_URI;
field public static final java.lang.String DATE = "date";
field public static final java.lang.String DELETED = "deleted";
@@ -33847,6 +33792,7 @@
field public static final java.lang.String DIR_TYPE = "vnd.android.cursor.dir/voicemails";
field public static final java.lang.String DURATION = "duration";
field public static final java.lang.String HAS_CONTENT = "has_content";
+ field public static final java.lang.String IS_OMTP_VOICEMAIL = "is_omtp_voicemail";
field public static final java.lang.String IS_READ = "is_read";
field public static final java.lang.String ITEM_TYPE = "vnd.android.cursor.item/voicemail";
field public static final java.lang.String LAST_MODIFIED = "last_modified";
@@ -33854,6 +33800,7 @@
field public static final java.lang.String NUMBER = "number";
field public static final java.lang.String PHONE_ACCOUNT_COMPONENT_NAME = "subscription_component_name";
field public static final java.lang.String PHONE_ACCOUNT_ID = "subscription_id";
+ field public static final java.lang.String RESTORED = "restored";
field public static final java.lang.String SOURCE_DATA = "source_data";
field public static final java.lang.String SOURCE_PACKAGE = "source_package";
field public static final java.lang.String TRANSCRIPTION = "transcription";
@@ -37587,7 +37534,8 @@
field public static final java.lang.String KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL = "carrier_volte_provisioning_required_bool";
field public static final java.lang.String KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL = "carrier_volte_tty_supported_bool";
field public static final java.lang.String KEY_CARRIER_VT_AVAILABLE_BOOL = "carrier_vt_available_bool";
- field public static final java.lang.String KEY_CARRIER_VVM_PACKAGE_NAME_STRING = "carrier_vvm_package_name_string";
+ field public static final deprecated java.lang.String KEY_CARRIER_VVM_PACKAGE_NAME_STRING = "carrier_vvm_package_name_string";
+ field public static final java.lang.String KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY = "carrier_vvm_package_name_string_array";
field public static final java.lang.String KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL = "carrier_wfc_ims_available_bool";
field public static final java.lang.String KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL = "carrier_wfc_supports_wifi_only_bool";
field public static final java.lang.String KEY_CDMA_DTMF_TONE_DELAY_INT = "cdma_dtmf_tone_delay_int";
@@ -37671,9 +37619,13 @@
field public static final java.lang.String KEY_VOICE_PRIVACY_DISABLE_UI_BOOL = "voice_privacy_disable_ui_bool";
field public static final java.lang.String KEY_VOLTE_REPLACEMENT_RAT_INT = "volte_replacement_rat_int";
field public static final java.lang.String KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL = "vvm_cellular_data_required_bool";
+ field public static final java.lang.String KEY_VVM_CLIENT_PREFIX_STRING = "vvm_client_prefix_string";
field public static final java.lang.String KEY_VVM_DESTINATION_NUMBER_STRING = "vvm_destination_number_string";
+ field public static final java.lang.String KEY_VVM_DISABLED_CAPABILITIES_STRING_ARRAY = "vvm_disabled_capabilities_string_array";
+ field public static final java.lang.String KEY_VVM_LEGACY_MODE_ENABLED_BOOL = "vvm_legacy_mode_enabled_bool";
field public static final java.lang.String KEY_VVM_PORT_NUMBER_INT = "vvm_port_number_int";
field public static final java.lang.String KEY_VVM_PREFETCH_BOOL = "vvm_prefetch_bool";
+ field public static final java.lang.String KEY_VVM_SSL_ENABLED_BOOL = "vvm_ssl_enabled_bool";
field public static final java.lang.String KEY_VVM_TYPE_STRING = "vvm_type_string";
field public static final java.lang.String KEY_WORLD_PHONE_BOOL = "world_phone_bool";
}
@@ -38173,7 +38125,6 @@
method public android.os.PersistableBundle getCarrierConfig();
method public deprecated android.telephony.CellLocation getCellLocation();
method public int getDataActivity();
- method public boolean getDataEnabled();
method public int getDataNetworkType();
method public int getDataState();
method public deprecated java.lang.String getDeviceId();
@@ -38205,6 +38156,7 @@
method public int getSimState();
method public int getSimState(int);
method public java.lang.String getSubscriberId();
+ method public java.lang.String getVisualVoicemailPackageName();
method public java.lang.String getVoiceMailAlphaTag();
method public java.lang.String getVoiceMailNumber();
method public int getVoiceNetworkType();
@@ -38217,6 +38169,8 @@
method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String, int);
method public java.lang.String iccTransmitApduBasicChannel(int, int, int, int, int, java.lang.String);
method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String);
+ method public boolean isConcurrentVoiceAndDataAllowed();
+ method public boolean isDataEnabled();
method public boolean isHearingAidCompatibilitySupported();
method public boolean isNetworkRoaming();
method public boolean isSmsCapable();
@@ -38226,6 +38180,7 @@
method public boolean isWorldPhone();
method public void listen(android.telephony.PhoneStateListener, int);
method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
+ method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.OnReceiveUssdResponseCallback, android.os.Handler);
method public void setDataEnabled(boolean);
method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String);
method public boolean setOperatorBrandOverride(java.lang.String);
@@ -38300,6 +38255,57 @@
field public static final java.lang.String VVM_TYPE_OMTP = "vvm_type_omtp";
}
+ public static abstract class TelephonyManager.OnReceiveUssdResponseCallback {
+ ctor public TelephonyManager.OnReceiveUssdResponseCallback();
+ method public void onReceiveUssdResponse(java.lang.String, java.lang.CharSequence);
+ method public void onReceiveUssdResponseFailed(java.lang.String, int);
+ }
+
+ public abstract class VisualVoicemailService extends android.app.Service {
+ ctor public VisualVoicemailService();
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public abstract void onCellServiceConnected(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telecom.PhoneAccountHandle);
+ method public abstract void onSimRemoved(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telecom.PhoneAccountHandle);
+ method public abstract void onSmsReceived(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telephony.VisualVoicemailSms);
+ method public abstract void onStopped(android.telephony.VisualVoicemailService.VisualVoicemailTask);
+ method public static final void sendVisualVoicemailSms(android.content.Context, android.telecom.PhoneAccountHandle, java.lang.String, short, java.lang.String, android.app.PendingIntent);
+ method public static final void setSmsFilterSettings(android.content.Context, android.telecom.PhoneAccountHandle, android.telephony.VisualVoicemailSmsFilterSettings);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.telephony.VisualVoicemailService";
+ }
+
+ public static class VisualVoicemailService.VisualVoicemailTask {
+ method public final void finish();
+ }
+
+ public final class VisualVoicemailSms implements android.os.Parcelable {
+ method public int describeContents();
+ method public android.os.Bundle getFields();
+ method public java.lang.String getMessageBody();
+ method public android.telecom.PhoneAccountHandle getPhoneAccountHandle();
+ method public java.lang.String getPrefix();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.VisualVoicemailSms> CREATOR;
+ }
+
+ public final class VisualVoicemailSmsFilterSettings implements android.os.Parcelable {
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.VisualVoicemailSmsFilterSettings> CREATOR;
+ field public static final int DESTINATION_PORT_ANY = -1; // 0xffffffff
+ field public static final int DESTINATION_PORT_DATA_SMS = -2; // 0xfffffffe
+ field public final java.lang.String clientPrefix;
+ field public final int destinationPort;
+ field public final java.util.List<java.lang.String> originatingNumbers;
+ }
+
+ public static class VisualVoicemailSmsFilterSettings.Builder {
+ ctor public VisualVoicemailSmsFilterSettings.Builder();
+ method public android.telephony.VisualVoicemailSmsFilterSettings build();
+ method public android.telephony.VisualVoicemailSmsFilterSettings.Builder setClientPrefix(java.lang.String);
+ method public android.telephony.VisualVoicemailSmsFilterSettings.Builder setDestinationPort(int);
+ method public android.telephony.VisualVoicemailSmsFilterSettings.Builder setOriginatingNumbers(java.util.List<java.lang.String>);
+ }
+
}
package android.telephony.cdma {
diff --git a/api/system-current.txt b/api/system-current.txt
index 1761966..6ee54ca 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -55,6 +55,7 @@
field public static final java.lang.String BIND_TRUST_AGENT = "android.permission.BIND_TRUST_AGENT";
field public static final java.lang.String BIND_TV_INPUT = "android.permission.BIND_TV_INPUT";
field public static final java.lang.String BIND_TV_REMOTE_SERVICE = "android.permission.BIND_TV_REMOTE_SERVICE";
+ field public static final java.lang.String BIND_VISUAL_VOICEMAIL_SERVICE = "android.permission.BIND_VISUAL_VOICEMAIL_SERVICE";
field public static final java.lang.String BIND_VOICE_INTERACTION = "android.permission.BIND_VOICE_INTERACTION";
field public static final java.lang.String BIND_VPN_SERVICE = "android.permission.BIND_VPN_SERVICE";
field public static final java.lang.String BIND_VR_LISTENER_SERVICE = "android.permission.BIND_VR_LISTENER_SERVICE";
@@ -7380,6 +7381,7 @@
method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback);
method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int);
method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int);
+ method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int, android.os.Handler);
method public boolean createBond();
method public android.bluetooth.BluetoothSocket createInsecureRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
method public android.bluetooth.BluetoothSocket createRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
@@ -7989,8 +7991,10 @@
field public static final android.os.Parcelable.Creator<android.bluetooth.le.ScanResult> CREATOR;
field public static final int DATA_COMPLETE = 0; // 0x0
field public static final int DATA_TRUNCATED = 2; // 0x2
+ field public static final int PERIODIC_INTERVAL_NOT_PRESENT = 0; // 0x0
field public static final int PHY_UNUSED = 0; // 0x0
field public static final int SID_NOT_PRESENT = 255; // 0xff
+ field public static final int TX_POWER_NOT_PRESENT = 127; // 0x7f
}
public final class ScanSettings implements android.os.Parcelable {
@@ -8653,7 +8657,6 @@
field public static final java.lang.String HDMI_CONTROL_SERVICE = "hdmi_control";
field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
field public static final java.lang.String INPUT_SERVICE = "input";
- field public static final java.lang.String IPSEC_SERVICE = "ipsec";
field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";
field public static final java.lang.String LAUNCHER_APPS_SERVICE = "launcherapps";
@@ -25708,68 +25711,6 @@
field public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR;
}
- public final class IpSecAlgorithm implements android.os.Parcelable {
- ctor public IpSecAlgorithm(java.lang.String, byte[]);
- ctor public IpSecAlgorithm(java.lang.String, byte[], int);
- method public int describeContents();
- method public byte[] getKey();
- method public java.lang.String getName();
- method public int getTruncationLengthBits();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final java.lang.String AUTH_HMAC_MD5 = "hmac(md5)";
- field public static final java.lang.String AUTH_HMAC_SHA1 = "hmac(sha1)";
- field public static final java.lang.String AUTH_HMAC_SHA256 = "hmac(sha256)";
- field public static final java.lang.String AUTH_HMAC_SHA384 = "hmac(sha384)";
- field public static final java.lang.String AUTH_HMAC_SHA512 = "hmac(sha512)";
- field public static final android.os.Parcelable.Creator<android.net.IpSecAlgorithm> CREATOR;
- field public static final java.lang.String CRYPT_AES_CBC = "cbc(aes)";
- }
-
- public final class IpSecManager {
- method public void applyTransportModeTransform(java.io.FileDescriptor, android.net.IpSecTransform) throws java.io.IOException;
- method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket(int) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
- method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
- method public void removeTransportModeTransform(java.io.FileDescriptor, android.net.IpSecTransform) throws java.io.IOException;
- method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress) throws android.net.IpSecManager.ResourceUnavailableException;
- method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
- field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
- }
-
- public static final class IpSecManager.ResourceUnavailableException extends android.util.AndroidException {
- }
-
- public static final class IpSecManager.SecurityParameterIndex implements java.lang.AutoCloseable {
- method public void close();
- method public int getSpi();
- }
-
- public static final class IpSecManager.SpiUnavailableException extends android.util.AndroidException {
- method public int getSpi();
- }
-
- public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable {
- method public void close() throws java.io.IOException;
- method public int getPort();
- method public java.io.FileDescriptor getSocket();
- }
-
- public final class IpSecTransform implements java.lang.AutoCloseable {
- method public void close();
- field public static final int DIRECTION_IN = 0; // 0x0
- field public static final int DIRECTION_OUT = 1; // 0x1
- }
-
- public static class IpSecTransform.Builder {
- ctor public IpSecTransform.Builder(android.content.Context);
- method public android.net.IpSecTransform buildTransportModeTransform(java.net.InetAddress) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
- method public android.net.IpSecTransform.Builder setAuthentication(int, android.net.IpSecAlgorithm);
- method public android.net.IpSecTransform.Builder setEncryption(int, android.net.IpSecAlgorithm);
- method public android.net.IpSecTransform.Builder setIpv4Encapsulation(android.net.IpSecManager.UdpEncapsulationSocket, int);
- method public android.net.IpSecTransform.Builder setNattKeepalive(int);
- method public android.net.IpSecTransform.Builder setSpi(int, android.net.IpSecManager.SecurityParameterIndex);
- method public android.net.IpSecTransform.Builder setUnderlyingNetwork(android.net.Network);
- }
-
public class LinkAddress implements android.os.Parcelable {
method public int describeContents();
method public java.net.InetAddress getAddress();
@@ -36684,6 +36625,8 @@
public static final class VoicemailContract.Voicemails implements android.provider.BaseColumns android.provider.OpenableColumns {
method public static android.net.Uri buildSourceUri(java.lang.String);
+ field public static final java.lang.String ARCHIVED = "archived";
+ field public static final java.lang.String BACKED_UP = "backed_up";
field public static final android.net.Uri CONTENT_URI;
field public static final java.lang.String DATE = "date";
field public static final java.lang.String DELETED = "deleted";
@@ -36691,6 +36634,7 @@
field public static final java.lang.String DIR_TYPE = "vnd.android.cursor.dir/voicemails";
field public static final java.lang.String DURATION = "duration";
field public static final java.lang.String HAS_CONTENT = "has_content";
+ field public static final java.lang.String IS_OMTP_VOICEMAIL = "is_omtp_voicemail";
field public static final java.lang.String IS_READ = "is_read";
field public static final java.lang.String ITEM_TYPE = "vnd.android.cursor.item/voicemail";
field public static final java.lang.String LAST_MODIFIED = "last_modified";
@@ -36698,6 +36642,7 @@
field public static final java.lang.String NUMBER = "number";
field public static final java.lang.String PHONE_ACCOUNT_COMPONENT_NAME = "subscription_component_name";
field public static final java.lang.String PHONE_ACCOUNT_ID = "subscription_id";
+ field public static final java.lang.String RESTORED = "restored";
field public static final java.lang.String SOURCE_DATA = "source_data";
field public static final java.lang.String SOURCE_PACKAGE = "source_package";
field public static final java.lang.String TRANSCRIPTION = "transcription";
@@ -40760,7 +40705,8 @@
field public static final java.lang.String KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL = "carrier_volte_provisioning_required_bool";
field public static final java.lang.String KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL = "carrier_volte_tty_supported_bool";
field public static final java.lang.String KEY_CARRIER_VT_AVAILABLE_BOOL = "carrier_vt_available_bool";
- field public static final java.lang.String KEY_CARRIER_VVM_PACKAGE_NAME_STRING = "carrier_vvm_package_name_string";
+ field public static final deprecated java.lang.String KEY_CARRIER_VVM_PACKAGE_NAME_STRING = "carrier_vvm_package_name_string";
+ field public static final java.lang.String KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY = "carrier_vvm_package_name_string_array";
field public static final java.lang.String KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL = "carrier_wfc_ims_available_bool";
field public static final java.lang.String KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL = "carrier_wfc_supports_wifi_only_bool";
field public static final java.lang.String KEY_CDMA_DTMF_TONE_DELAY_INT = "cdma_dtmf_tone_delay_int";
@@ -40844,9 +40790,13 @@
field public static final java.lang.String KEY_VOICE_PRIVACY_DISABLE_UI_BOOL = "voice_privacy_disable_ui_bool";
field public static final java.lang.String KEY_VOLTE_REPLACEMENT_RAT_INT = "volte_replacement_rat_int";
field public static final java.lang.String KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL = "vvm_cellular_data_required_bool";
+ field public static final java.lang.String KEY_VVM_CLIENT_PREFIX_STRING = "vvm_client_prefix_string";
field public static final java.lang.String KEY_VVM_DESTINATION_NUMBER_STRING = "vvm_destination_number_string";
+ field public static final java.lang.String KEY_VVM_DISABLED_CAPABILITIES_STRING_ARRAY = "vvm_disabled_capabilities_string_array";
+ field public static final java.lang.String KEY_VVM_LEGACY_MODE_ENABLED_BOOL = "vvm_legacy_mode_enabled_bool";
field public static final java.lang.String KEY_VVM_PORT_NUMBER_INT = "vvm_port_number_int";
field public static final java.lang.String KEY_VVM_PREFETCH_BOOL = "vvm_prefetch_bool";
+ field public static final java.lang.String KEY_VVM_SSL_ENABLED_BOOL = "vvm_ssl_enabled_bool";
field public static final java.lang.String KEY_VVM_TYPE_STRING = "vvm_type_string";
field public static final java.lang.String KEY_WORLD_PHONE_BOOL = "world_phone_bool";
}
@@ -41386,8 +41336,8 @@
method public int getCurrentPhoneType();
method public int getCurrentPhoneType(int);
method public int getDataActivity();
- method public boolean getDataEnabled();
- method public boolean getDataEnabled(int);
+ method public deprecated boolean getDataEnabled();
+ method public deprecated boolean getDataEnabled(int);
method public int getDataNetworkType();
method public int getDataState();
method public deprecated java.lang.String getDeviceId();
@@ -41420,6 +41370,7 @@
method public int getSimState(int);
method public java.lang.String getSubscriberId();
method public java.util.List<android.telephony.TelephonyHistogram> getTelephonyHistograms();
+ method public java.lang.String getVisualVoicemailPackageName();
method public java.lang.String getVoiceMailAlphaTag();
method public java.lang.String getVoiceMailNumber();
method public int getVoiceNetworkType();
@@ -41434,7 +41385,9 @@
method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String, int);
method public java.lang.String iccTransmitApduBasicChannel(int, int, int, int, int, java.lang.String);
method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String);
+ method public boolean isConcurrentVoiceAndDataAllowed();
method public boolean isDataConnectivityPossible();
+ method public boolean isDataEnabled();
method public boolean isHearingAidCompatibilitySupported();
method public boolean isIdle();
method public boolean isNetworkRoaming();
@@ -41451,6 +41404,7 @@
method public void listen(android.telephony.PhoneStateListener, int);
method public boolean needsOtaServiceProvisioning();
method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
+ method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.OnReceiveUssdResponseCallback, android.os.Handler);
method public int setAllowedCarriers(int, java.util.List<android.service.carrier.CarrierIdentifier>);
method public void setDataEnabled(boolean);
method public void setDataEnabled(int, boolean);
@@ -41546,6 +41500,57 @@
field public static final java.lang.String VVM_TYPE_OMTP = "vvm_type_omtp";
}
+ public static abstract class TelephonyManager.OnReceiveUssdResponseCallback {
+ ctor public TelephonyManager.OnReceiveUssdResponseCallback();
+ method public void onReceiveUssdResponse(java.lang.String, java.lang.CharSequence);
+ method public void onReceiveUssdResponseFailed(java.lang.String, int);
+ }
+
+ public abstract class VisualVoicemailService extends android.app.Service {
+ ctor public VisualVoicemailService();
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public abstract void onCellServiceConnected(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telecom.PhoneAccountHandle);
+ method public abstract void onSimRemoved(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telecom.PhoneAccountHandle);
+ method public abstract void onSmsReceived(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telephony.VisualVoicemailSms);
+ method public abstract void onStopped(android.telephony.VisualVoicemailService.VisualVoicemailTask);
+ method public static final void sendVisualVoicemailSms(android.content.Context, android.telecom.PhoneAccountHandle, java.lang.String, short, java.lang.String, android.app.PendingIntent);
+ method public static final void setSmsFilterSettings(android.content.Context, android.telecom.PhoneAccountHandle, android.telephony.VisualVoicemailSmsFilterSettings);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.telephony.VisualVoicemailService";
+ }
+
+ public static class VisualVoicemailService.VisualVoicemailTask {
+ method public final void finish();
+ }
+
+ public final class VisualVoicemailSms implements android.os.Parcelable {
+ method public int describeContents();
+ method public android.os.Bundle getFields();
+ method public java.lang.String getMessageBody();
+ method public android.telecom.PhoneAccountHandle getPhoneAccountHandle();
+ method public java.lang.String getPrefix();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.VisualVoicemailSms> CREATOR;
+ }
+
+ public final class VisualVoicemailSmsFilterSettings implements android.os.Parcelable {
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.VisualVoicemailSmsFilterSettings> CREATOR;
+ field public static final int DESTINATION_PORT_ANY = -1; // 0xffffffff
+ field public static final int DESTINATION_PORT_DATA_SMS = -2; // 0xfffffffe
+ field public final java.lang.String clientPrefix;
+ field public final int destinationPort;
+ field public final java.util.List<java.lang.String> originatingNumbers;
+ }
+
+ public static class VisualVoicemailSmsFilterSettings.Builder {
+ ctor public VisualVoicemailSmsFilterSettings.Builder();
+ method public android.telephony.VisualVoicemailSmsFilterSettings build();
+ method public android.telephony.VisualVoicemailSmsFilterSettings.Builder setClientPrefix(java.lang.String);
+ method public android.telephony.VisualVoicemailSmsFilterSettings.Builder setDestinationPort(int);
+ method public android.telephony.VisualVoicemailSmsFilterSettings.Builder setOriginatingNumbers(java.util.List<java.lang.String>);
+ }
+
}
package android.telephony.cdma {
diff --git a/api/test-current.txt b/api/test-current.txt
index d324db9..1c4db6c 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -36,6 +36,7 @@
field public static final java.lang.String BIND_TELECOM_CONNECTION_SERVICE = "android.permission.BIND_TELECOM_CONNECTION_SERVICE";
field public static final java.lang.String BIND_TEXT_SERVICE = "android.permission.BIND_TEXT_SERVICE";
field public static final java.lang.String BIND_TV_INPUT = "android.permission.BIND_TV_INPUT";
+ field public static final java.lang.String BIND_VISUAL_VOICEMAIL_SERVICE = "android.permission.BIND_VISUAL_VOICEMAIL_SERVICE";
field public static final java.lang.String BIND_VOICE_INTERACTION = "android.permission.BIND_VOICE_INTERACTION";
field public static final java.lang.String BIND_VPN_SERVICE = "android.permission.BIND_VPN_SERVICE";
field public static final java.lang.String BIND_VR_LISTENER_SERVICE = "android.permission.BIND_VR_LISTENER_SERVICE";
@@ -7086,6 +7087,7 @@
method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback);
method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int);
method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int);
+ method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int, android.os.Handler);
method public boolean createBond();
method public android.bluetooth.BluetoothSocket createInsecureRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
method public android.bluetooth.BluetoothSocket createRfcommSocketToServiceRecord(java.util.UUID) throws java.io.IOException;
@@ -7680,8 +7682,10 @@
field public static final android.os.Parcelable.Creator<android.bluetooth.le.ScanResult> CREATOR;
field public static final int DATA_COMPLETE = 0; // 0x0
field public static final int DATA_TRUNCATED = 2; // 0x2
+ field public static final int PERIODIC_INTERVAL_NOT_PRESENT = 0; // 0x0
field public static final int PHY_UNUSED = 0; // 0x0
field public static final int SID_NOT_PRESENT = 255; // 0xff
+ field public static final int TX_POWER_NOT_PRESENT = 127; // 0x7f
}
public final class ScanSettings implements android.os.Parcelable {
@@ -8329,7 +8333,6 @@
field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties";
field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
field public static final java.lang.String INPUT_SERVICE = "input";
- field public static final java.lang.String IPSEC_SERVICE = "ipsec";
field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler";
field public static final java.lang.String KEYGUARD_SERVICE = "keyguard";
field public static final java.lang.String LAUNCHER_APPS_SERVICE = "launcherapps";
@@ -23944,66 +23947,6 @@
field public static final android.os.Parcelable.Creator<android.net.IpPrefix> CREATOR;
}
- public final class IpSecAlgorithm implements android.os.Parcelable {
- ctor public IpSecAlgorithm(java.lang.String, byte[]);
- ctor public IpSecAlgorithm(java.lang.String, byte[], int);
- method public int describeContents();
- method public byte[] getKey();
- method public java.lang.String getName();
- method public int getTruncationLengthBits();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final java.lang.String AUTH_HMAC_MD5 = "hmac(md5)";
- field public static final java.lang.String AUTH_HMAC_SHA1 = "hmac(sha1)";
- field public static final java.lang.String AUTH_HMAC_SHA256 = "hmac(sha256)";
- field public static final java.lang.String AUTH_HMAC_SHA384 = "hmac(sha384)";
- field public static final java.lang.String AUTH_HMAC_SHA512 = "hmac(sha512)";
- field public static final android.os.Parcelable.Creator<android.net.IpSecAlgorithm> CREATOR;
- field public static final java.lang.String CRYPT_AES_CBC = "cbc(aes)";
- }
-
- public final class IpSecManager {
- method public void applyTransportModeTransform(java.io.FileDescriptor, android.net.IpSecTransform) throws java.io.IOException;
- method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket(int) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
- method public android.net.IpSecManager.UdpEncapsulationSocket openUdpEncapsulationSocket() throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException;
- method public void removeTransportModeTransform(java.io.FileDescriptor, android.net.IpSecTransform) throws java.io.IOException;
- method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress) throws android.net.IpSecManager.ResourceUnavailableException;
- method public android.net.IpSecManager.SecurityParameterIndex reserveSecurityParameterIndex(int, java.net.InetAddress, int) throws android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
- field public static final int INVALID_SECURITY_PARAMETER_INDEX = 0; // 0x0
- }
-
- public static final class IpSecManager.ResourceUnavailableException extends android.util.AndroidException {
- }
-
- public static final class IpSecManager.SecurityParameterIndex implements java.lang.AutoCloseable {
- method public void close();
- method public int getSpi();
- }
-
- public static final class IpSecManager.SpiUnavailableException extends android.util.AndroidException {
- method public int getSpi();
- }
-
- public static final class IpSecManager.UdpEncapsulationSocket implements java.lang.AutoCloseable {
- method public void close() throws java.io.IOException;
- method public int getPort();
- method public java.io.FileDescriptor getSocket();
- }
-
- public final class IpSecTransform implements java.lang.AutoCloseable {
- method public void close();
- field public static final int DIRECTION_IN = 0; // 0x0
- field public static final int DIRECTION_OUT = 1; // 0x1
- }
-
- public static class IpSecTransform.Builder {
- ctor public IpSecTransform.Builder(android.content.Context);
- method public android.net.IpSecTransform buildTransportModeTransform(java.net.InetAddress) throws java.io.IOException, android.net.IpSecManager.ResourceUnavailableException, android.net.IpSecManager.SpiUnavailableException;
- method public android.net.IpSecTransform.Builder setAuthentication(int, android.net.IpSecAlgorithm);
- method public android.net.IpSecTransform.Builder setEncryption(int, android.net.IpSecAlgorithm);
- method public android.net.IpSecTransform.Builder setIpv4Encapsulation(android.net.IpSecManager.UdpEncapsulationSocket, int);
- method public android.net.IpSecTransform.Builder setSpi(int, android.net.IpSecManager.SecurityParameterIndex);
- }
-
public class LinkAddress implements android.os.Parcelable {
method public int describeContents();
method public java.net.InetAddress getAddress();
@@ -33922,6 +33865,8 @@
public static final class VoicemailContract.Voicemails implements android.provider.BaseColumns android.provider.OpenableColumns {
method public static android.net.Uri buildSourceUri(java.lang.String);
+ field public static final java.lang.String ARCHIVED = "archived";
+ field public static final java.lang.String BACKED_UP = "backed_up";
field public static final android.net.Uri CONTENT_URI;
field public static final java.lang.String DATE = "date";
field public static final java.lang.String DELETED = "deleted";
@@ -33929,6 +33874,7 @@
field public static final java.lang.String DIR_TYPE = "vnd.android.cursor.dir/voicemails";
field public static final java.lang.String DURATION = "duration";
field public static final java.lang.String HAS_CONTENT = "has_content";
+ field public static final java.lang.String IS_OMTP_VOICEMAIL = "is_omtp_voicemail";
field public static final java.lang.String IS_READ = "is_read";
field public static final java.lang.String ITEM_TYPE = "vnd.android.cursor.item/voicemail";
field public static final java.lang.String LAST_MODIFIED = "last_modified";
@@ -33936,6 +33882,7 @@
field public static final java.lang.String NUMBER = "number";
field public static final java.lang.String PHONE_ACCOUNT_COMPONENT_NAME = "subscription_component_name";
field public static final java.lang.String PHONE_ACCOUNT_ID = "subscription_id";
+ field public static final java.lang.String RESTORED = "restored";
field public static final java.lang.String SOURCE_DATA = "source_data";
field public static final java.lang.String SOURCE_PACKAGE = "source_package";
field public static final java.lang.String TRANSCRIPTION = "transcription";
@@ -37686,7 +37633,8 @@
field public static final java.lang.String KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL = "carrier_volte_provisioning_required_bool";
field public static final java.lang.String KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL = "carrier_volte_tty_supported_bool";
field public static final java.lang.String KEY_CARRIER_VT_AVAILABLE_BOOL = "carrier_vt_available_bool";
- field public static final java.lang.String KEY_CARRIER_VVM_PACKAGE_NAME_STRING = "carrier_vvm_package_name_string";
+ field public static final deprecated java.lang.String KEY_CARRIER_VVM_PACKAGE_NAME_STRING = "carrier_vvm_package_name_string";
+ field public static final java.lang.String KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY = "carrier_vvm_package_name_string_array";
field public static final java.lang.String KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL = "carrier_wfc_ims_available_bool";
field public static final java.lang.String KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL = "carrier_wfc_supports_wifi_only_bool";
field public static final java.lang.String KEY_CDMA_DTMF_TONE_DELAY_INT = "cdma_dtmf_tone_delay_int";
@@ -37770,9 +37718,13 @@
field public static final java.lang.String KEY_VOICE_PRIVACY_DISABLE_UI_BOOL = "voice_privacy_disable_ui_bool";
field public static final java.lang.String KEY_VOLTE_REPLACEMENT_RAT_INT = "volte_replacement_rat_int";
field public static final java.lang.String KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL = "vvm_cellular_data_required_bool";
+ field public static final java.lang.String KEY_VVM_CLIENT_PREFIX_STRING = "vvm_client_prefix_string";
field public static final java.lang.String KEY_VVM_DESTINATION_NUMBER_STRING = "vvm_destination_number_string";
+ field public static final java.lang.String KEY_VVM_DISABLED_CAPABILITIES_STRING_ARRAY = "vvm_disabled_capabilities_string_array";
+ field public static final java.lang.String KEY_VVM_LEGACY_MODE_ENABLED_BOOL = "vvm_legacy_mode_enabled_bool";
field public static final java.lang.String KEY_VVM_PORT_NUMBER_INT = "vvm_port_number_int";
field public static final java.lang.String KEY_VVM_PREFETCH_BOOL = "vvm_prefetch_bool";
+ field public static final java.lang.String KEY_VVM_SSL_ENABLED_BOOL = "vvm_ssl_enabled_bool";
field public static final java.lang.String KEY_VVM_TYPE_STRING = "vvm_type_string";
field public static final java.lang.String KEY_WORLD_PHONE_BOOL = "world_phone_bool";
}
@@ -38272,7 +38224,6 @@
method public android.os.PersistableBundle getCarrierConfig();
method public deprecated android.telephony.CellLocation getCellLocation();
method public int getDataActivity();
- method public boolean getDataEnabled();
method public int getDataNetworkType();
method public int getDataState();
method public deprecated java.lang.String getDeviceId();
@@ -38304,6 +38255,7 @@
method public int getSimState();
method public int getSimState(int);
method public java.lang.String getSubscriberId();
+ method public java.lang.String getVisualVoicemailPackageName();
method public java.lang.String getVoiceMailAlphaTag();
method public java.lang.String getVoiceMailNumber();
method public int getVoiceNetworkType();
@@ -38316,6 +38268,8 @@
method public android.telephony.IccOpenLogicalChannelResponse iccOpenLogicalChannel(java.lang.String, int);
method public java.lang.String iccTransmitApduBasicChannel(int, int, int, int, int, java.lang.String);
method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String);
+ method public boolean isConcurrentVoiceAndDataAllowed();
+ method public boolean isDataEnabled();
method public boolean isHearingAidCompatibilitySupported();
method public boolean isNetworkRoaming();
method public boolean isSmsCapable();
@@ -38325,6 +38279,7 @@
method public boolean isWorldPhone();
method public void listen(android.telephony.PhoneStateListener, int);
method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
+ method public void sendUssdRequest(java.lang.String, android.telephony.TelephonyManager.OnReceiveUssdResponseCallback, android.os.Handler);
method public void setDataEnabled(boolean);
method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String);
method public boolean setOperatorBrandOverride(java.lang.String);
@@ -38399,6 +38354,57 @@
field public static final java.lang.String VVM_TYPE_OMTP = "vvm_type_omtp";
}
+ public static abstract class TelephonyManager.OnReceiveUssdResponseCallback {
+ ctor public TelephonyManager.OnReceiveUssdResponseCallback();
+ method public void onReceiveUssdResponse(java.lang.String, java.lang.CharSequence);
+ method public void onReceiveUssdResponseFailed(java.lang.String, int);
+ }
+
+ public abstract class VisualVoicemailService extends android.app.Service {
+ ctor public VisualVoicemailService();
+ method public android.os.IBinder onBind(android.content.Intent);
+ method public abstract void onCellServiceConnected(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telecom.PhoneAccountHandle);
+ method public abstract void onSimRemoved(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telecom.PhoneAccountHandle);
+ method public abstract void onSmsReceived(android.telephony.VisualVoicemailService.VisualVoicemailTask, android.telephony.VisualVoicemailSms);
+ method public abstract void onStopped(android.telephony.VisualVoicemailService.VisualVoicemailTask);
+ method public static final void sendVisualVoicemailSms(android.content.Context, android.telecom.PhoneAccountHandle, java.lang.String, short, java.lang.String, android.app.PendingIntent);
+ method public static final void setSmsFilterSettings(android.content.Context, android.telecom.PhoneAccountHandle, android.telephony.VisualVoicemailSmsFilterSettings);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.telephony.VisualVoicemailService";
+ }
+
+ public static class VisualVoicemailService.VisualVoicemailTask {
+ method public final void finish();
+ }
+
+ public final class VisualVoicemailSms implements android.os.Parcelable {
+ method public int describeContents();
+ method public android.os.Bundle getFields();
+ method public java.lang.String getMessageBody();
+ method public android.telecom.PhoneAccountHandle getPhoneAccountHandle();
+ method public java.lang.String getPrefix();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.VisualVoicemailSms> CREATOR;
+ }
+
+ public final class VisualVoicemailSmsFilterSettings implements android.os.Parcelable {
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.telephony.VisualVoicemailSmsFilterSettings> CREATOR;
+ field public static final int DESTINATION_PORT_ANY = -1; // 0xffffffff
+ field public static final int DESTINATION_PORT_DATA_SMS = -2; // 0xfffffffe
+ field public final java.lang.String clientPrefix;
+ field public final int destinationPort;
+ field public final java.util.List<java.lang.String> originatingNumbers;
+ }
+
+ public static class VisualVoicemailSmsFilterSettings.Builder {
+ ctor public VisualVoicemailSmsFilterSettings.Builder();
+ method public android.telephony.VisualVoicemailSmsFilterSettings build();
+ method public android.telephony.VisualVoicemailSmsFilterSettings.Builder setClientPrefix(java.lang.String);
+ method public android.telephony.VisualVoicemailSmsFilterSettings.Builder setDestinationPort(int);
+ method public android.telephony.VisualVoicemailSmsFilterSettings.Builder setOriginatingNumbers(java.util.List<java.lang.String>);
+ }
+
}
package android.telephony.cdma {
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 735d84e..ff52f27 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1032,28 +1032,6 @@
}
/**
- * enable or disable Bluetooth HCI snoop log.
- *
- * <p>Requires the {@link android.Manifest.permission#BLUETOOTH_ADMIN}
- * permission
- *
- * @return true to indicate configure HCI log successfully, or false on
- * immediate error
- * @hide
- */
- public boolean configHciSnoopLog(boolean enable) {
- try {
- mServiceLock.readLock().lock();
- if (mService != null) return mService.configHciSnoopLog(enable);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- } finally {
- mServiceLock.readLock().unlock();
- }
- return false;
- }
-
- /**
* Factory reset bluetooth settings.
*
* <p>Requires the {@link android.Manifest.permission#BLUETOOTH_PRIVILEGED}
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index e6cebc0..e0b03d2 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -22,6 +22,8 @@
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.ParcelUuid;
@@ -593,32 +595,38 @@
public static final int TRANSPORT_LE = 2;
/**
- * Bluetooth LE 1M PHY.
+ * Bluetooth LE 1M PHY. Used to refer to LE 1M Physical Channel for advertising, scanning or
+ * connection.
*/
public static final int PHY_LE_1M = 1;
/**
- * Bluetooth LE 2M PHY.
+ * Bluetooth LE 2M PHY. Used to refer to LE 2M Physical Channel for advertising, scanning or
+ * connection.
*/
public static final int PHY_LE_2M = 2;
/**
- * Bluetooth LE Coded PHY.
+ * Bluetooth LE Coded PHY. Used to refer to LE Coded Physical Channel for advertising, scanning
+ * or connection.
*/
public static final int PHY_LE_CODED = 3;
/**
- * Bluetooth LE 1M PHY mask.
+ * Bluetooth LE 1M PHY mask. Used to specify LE 1M Physical Channel as one of many available
+ * options in a bitmask.
*/
public static final int PHY_LE_1M_MASK = 1;
/**
- * Bluetooth LE 2M PHY mask.
+ * Bluetooth LE 2M PHY mask. Used to specify LE 2M Physical Channel as one of many available
+ * options in a bitmask.
*/
public static final int PHY_LE_2M_MASK = 2;
/**
- * Bluetooth LE Coded PHY mask.
+ * Bluetooth LE Coded PHY mask. Used to specify LE Coded Physical Channel as one of many
+ * available options in a bitmask.
*/
public static final int PHY_LE_CODED_MASK = 4;
@@ -1679,12 +1687,45 @@
* {@link BluetoothDevice#TRANSPORT_BREDR} or {@link BluetoothDevice#TRANSPORT_LE}
* @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of
* {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK},
- * and {@link BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect if
- * {@code autoConnect} is set to true.
- * @throws IllegalArgumentException if callback is null
+ * and {@link BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect
+ * if {@code autoConnect} is set to true.
+ * @throws NullPointerException if callback is null
*/
public BluetoothGatt connectGatt(Context context, boolean autoConnect,
BluetoothGattCallback callback, int transport, int phy) {
+ return connectGatt(context, autoConnect,callback, TRANSPORT_AUTO, PHY_LE_1M_MASK, null);
+ }
+
+ /**
+ * Connect to GATT Server hosted by this device. Caller acts as GATT client.
+ * The callback is used to deliver results to Caller, such as connection status as well
+ * as any further GATT client operations.
+ * The method returns a BluetoothGatt instance. You can use BluetoothGatt to conduct
+ * GATT client operations.
+ * @param callback GATT callback handler that will receive asynchronous callbacks.
+ * @param autoConnect Whether to directly connect to the remote device (false)
+ * or to automatically connect as soon as the remote
+ * device becomes available (true).
+ * @param transport preferred transport for GATT connections to remote dual-mode devices
+ * {@link BluetoothDevice#TRANSPORT_AUTO} or
+ * {@link BluetoothDevice#TRANSPORT_BREDR} or {@link BluetoothDevice#TRANSPORT_LE}
+ * @param phy preferred PHY for connections to remote LE device. Bitwise OR of any of
+ * {@link BluetoothDevice#PHY_LE_1M_MASK}, {@link BluetoothDevice#PHY_LE_2M_MASK},
+ * an d{@link BluetoothDevice#PHY_LE_CODED_MASK}. This option does not take effect
+ * if {@code autoConnect} is set to true.
+ * @param handler The handler to use for the callback. If {@code null}, callbacks will happen
+ * on the service's main thread.
+ * @throws NullPointerException if callback is null
+ */
+ public BluetoothGatt connectGatt(Context context, boolean autoConnect,
+ BluetoothGattCallback callback, int transport, int phy,
+ Handler handler) {
+ if (callback == null)
+ throw new NullPointerException("callback is null");
+
+ if (handler == null)
+ handler = new Handler(Looper.getMainLooper());
+
// TODO(Bluetooth) check whether platform support BLE
// Do the check here or in GattServer?
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
@@ -1696,7 +1737,7 @@
return null;
}
BluetoothGatt gatt = new BluetoothGatt(iGatt, this, transport, phy);
- gatt.connect(autoConnect, callback);
+ gatt.connect(autoConnect, callback, handler);
return gatt;
} catch (RemoteException e) {Log.e(TAG, "", e);}
return null;
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 9144ae7..40f10a8 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -17,6 +17,7 @@
package android.bluetooth;
import android.content.Context;
+import android.os.Handler;
import android.os.ParcelUuid;
import android.os.RemoteException;
import android.util.Log;
@@ -43,6 +44,7 @@
private IBluetoothGatt mService;
private BluetoothGattCallback mCallback;
+ private Handler mHandler;
private int mClientIf;
private BluetoothDevice mDevice;
private boolean mAutoConnect;
@@ -154,8 +156,16 @@
}
mClientIf = clientIf;
if (status != GATT_SUCCESS) {
- mCallback.onConnectionStateChange(BluetoothGatt.this, GATT_FAILURE,
- BluetoothProfile.STATE_DISCONNECTED);
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mCallback != null) {
+ mCallback.onConnectionStateChange(BluetoothGatt.this, GATT_FAILURE,
+ BluetoothProfile.STATE_DISCONNECTED);
+ }
+ }
+ });
+
synchronized(mStateLock) {
mConnState = CONN_STATE_IDLE;
}
@@ -181,11 +191,14 @@
return;
}
- try {
- mCallback.onPhyUpdate(BluetoothGatt.this, txPhy, rxPhy, status);
- } catch (Exception ex) {
- Log.w(TAG, "Unhandled exception in callback", ex);
- }
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mCallback != null) {
+ mCallback.onPhyUpdate(BluetoothGatt.this, txPhy, rxPhy, status);
+ }
+ }
+ });
}
/**
@@ -200,11 +213,14 @@
return;
}
- try {
- mCallback.onPhyRead(BluetoothGatt.this, txPhy, rxPhy, status);
- } catch (Exception ex) {
- Log.w(TAG, "Unhandled exception in callback", ex);
- }
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mCallback != null) {
+ mCallback.onPhyRead(BluetoothGatt.this, txPhy, rxPhy, status);
+ }
+ }
+ });
}
/**
@@ -221,11 +237,16 @@
}
int profileState = connected ? BluetoothProfile.STATE_CONNECTED :
BluetoothProfile.STATE_DISCONNECTED;
- try {
- mCallback.onConnectionStateChange(BluetoothGatt.this, status, profileState);
- } catch (Exception ex) {
- Log.w(TAG, "Unhandled exception in callback", ex);
- }
+
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mCallback != null) {
+ mCallback.onConnectionStateChange(BluetoothGatt.this, status,
+ profileState);
+ }
+ }
+ });
synchronized(mStateLock) {
if (connected) {
@@ -279,11 +300,14 @@
}
}
- try {
- mCallback.onServicesDiscovered(BluetoothGatt.this, status);
- } catch (Exception ex) {
- Log.w(TAG, "Unhandled exception in callback", ex);
- }
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mCallback != null) {
+ mCallback.onServicesDiscovered(BluetoothGatt.this, status);
+ }
+ }
+ });
}
/**
@@ -328,11 +352,15 @@
if (status == 0) characteristic.setValue(value);
- try {
- mCallback.onCharacteristicRead(BluetoothGatt.this, characteristic, status);
- } catch (Exception ex) {
- Log.w(TAG, "Unhandled exception in callback", ex);
- }
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mCallback != null) {
+ mCallback.onCharacteristicRead(BluetoothGatt.this, characteristic,
+ status);
+ }
+ }
+ });
}
/**
@@ -373,11 +401,15 @@
mAuthRetryState = AUTH_RETRY_STATE_IDLE;
- try {
- mCallback.onCharacteristicWrite(BluetoothGatt.this, characteristic, status);
- } catch (Exception ex) {
- Log.w(TAG, "Unhandled exception in callback", ex);
- }
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mCallback != null) {
+ mCallback.onCharacteristicWrite(BluetoothGatt.this, characteristic,
+ status);
+ }
+ }
+ });
}
/**
@@ -398,11 +430,14 @@
characteristic.setValue(value);
- try {
- mCallback.onCharacteristicChanged(BluetoothGatt.this, characteristic);
- } catch (Exception ex) {
- Log.w(TAG, "Unhandled exception in callback", ex);
- }
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mCallback != null) {
+ mCallback.onCharacteristicChanged(BluetoothGatt.this, characteristic);
+ }
+ }
+ });
}
/**
@@ -442,11 +477,14 @@
mAuthRetryState = AUTH_RETRY_STATE_IDLE;
- try {
- mCallback.onDescriptorRead(BluetoothGatt.this, descriptor, status);
- } catch (Exception ex) {
- Log.w(TAG, "Unhandled exception in callback", ex);
- }
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mCallback != null) {
+ mCallback.onDescriptorRead(BluetoothGatt.this, descriptor, status);
+ }
+ }
+ });
}
/**
@@ -485,11 +523,14 @@
mAuthRetryState = AUTH_RETRY_STATE_IDLE;
- try {
- mCallback.onDescriptorWrite(BluetoothGatt.this, descriptor, status);
- } catch (Exception ex) {
- Log.w(TAG, "Unhandled exception in callback", ex);
- }
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mCallback != null) {
+ mCallback.onDescriptorWrite(BluetoothGatt.this, descriptor, status);
+ }
+ }
+ });
}
/**
@@ -508,11 +549,14 @@
mDeviceBusy = false;
}
- try {
- mCallback.onReliableWriteCompleted(BluetoothGatt.this, status);
- } catch (Exception ex) {
- Log.w(TAG, "Unhandled exception in callback", ex);
- }
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mCallback != null) {
+ mCallback.onReliableWriteCompleted(BluetoothGatt.this, status);
+ }
+ }
+ });
}
/**
@@ -526,11 +570,14 @@
if (!address.equals(mDevice.getAddress())) {
return;
}
- try {
- mCallback.onReadRemoteRssi(BluetoothGatt.this, rssi, status);
- } catch (Exception ex) {
- Log.w(TAG, "Unhandled exception in callback", ex);
- }
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mCallback != null) {
+ mCallback.onReadRemoteRssi(BluetoothGatt.this, rssi, status);
+ }
+ }
+ });
}
/**
@@ -544,11 +591,15 @@
if (!address.equals(mDevice.getAddress())) {
return;
}
- try {
- mCallback.onMtuChanged(BluetoothGatt.this, mtu, status);
- } catch (Exception ex) {
- Log.w(TAG, "Unhandled exception in callback", ex);
- }
+
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mCallback != null) {
+ mCallback.onMtuChanged(BluetoothGatt.this, mtu, status);
+ }
+ }
+ });
}
/**
@@ -564,12 +615,16 @@
if (!address.equals(mDevice.getAddress())) {
return;
}
- try {
- mCallback.onConnectionUpdated(BluetoothGatt.this, interval, latency,
- timeout, status);
- } catch (Exception ex) {
- Log.w(TAG, "Unhandled exception in callback", ex);
- }
+
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mCallback != null) {
+ mCallback.onConnectionUpdated(BluetoothGatt.this, interval, latency,
+ timeout, status);
+ }
+ }
+ });
}
};
@@ -659,11 +714,12 @@
* @return If true, the callback will be called to notify success or failure,
* false on immediate error
*/
- private boolean registerApp(BluetoothGattCallback callback) {
+ private boolean registerApp(BluetoothGattCallback callback, Handler handler) {
if (DBG) Log.d(TAG, "registerApp()");
if (mService == null) return false;
mCallback = callback;
+ mHandler = handler;
UUID uuid = UUID.randomUUID();
if (DBG) Log.d(TAG, "registerApp() - UUID=" + uuid);
@@ -716,7 +772,8 @@
* device becomes available (true).
* @return true, if the connection attempt was initiated successfully
*/
- /*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback) {
+ /*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback,
+ Handler handler) {
if (DBG) Log.d(TAG, "connect() - device: " + mDevice.getAddress() + ", auto: " + autoConnect);
synchronized(mStateLock) {
if (mConnState != CONN_STATE_IDLE) {
@@ -727,7 +784,7 @@
mAutoConnect = autoConnect;
- if (!registerApp(callback)) {
+ if (!registerApp(callback, handler)) {
synchronized(mStateLock) {
mConnState = CONN_STATE_IDLE;
}
diff --git a/core/java/android/bluetooth/BluetoothGattCallback.java b/core/java/android/bluetooth/BluetoothGattCallback.java
index 11a15c6..c6f82ff 100644
--- a/core/java/android/bluetooth/BluetoothGattCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattCallback.java
@@ -30,7 +30,8 @@
* {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
* @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
* {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
- * @param status status of the operation
+ * @param status Status of the PHY update operation.
+ * {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
*/
public void onPhyUpdate(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
}
@@ -43,7 +44,8 @@
* {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
* @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
* {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}.
- * @param status status of the operation
+ * @param status Status of the PHY read operation.
+ * {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
*/
public void onPhyRead(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
}
diff --git a/core/java/android/bluetooth/BluetoothGattServerCallback.java b/core/java/android/bluetooth/BluetoothGattServerCallback.java
index 3b8f962..02307bd 100644
--- a/core/java/android/bluetooth/BluetoothGattServerCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattServerCallback.java
@@ -167,7 +167,8 @@
* {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
* @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
* {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
- * @param status status of the operation
+ * @param status Status of the PHY update operation.
+ * {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
*/
public void onPhyUpdate(BluetoothDevice device, int txPhy, int rxPhy, int status) {
}
@@ -180,7 +181,8 @@
* {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
* @param rxPhy the receiver PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
* {@link BluetoothDevice#PHY_LE_2M}, and {@link BluetoothDevice#PHY_LE_CODED}
- * @param status status of the operation
+ * @param status Status of the PHY read operation.
+ * {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
*/
public void onPhyRead(BluetoothDevice device, int txPhy, int rxPhy, int status) {
}
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index b337817..43c5ae4 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -97,7 +97,6 @@
ParcelFileDescriptor connectSocket(in BluetoothDevice device, int type, in ParcelUuid uuid, int port, int flag);
ParcelFileDescriptor createSocketChannel(int type, in String serviceName, in ParcelUuid uuid, int port, int flag);
- boolean configHciSnoopLog(boolean enable);
boolean factoryReset();
boolean isMultiAdvertisementSupported();
diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl
index a2066cb..fb6b893 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -31,7 +31,6 @@
import android.bluetooth.IBluetoothGattCallback;
import android.bluetooth.IBluetoothGattServerCallback;
-import android.bluetooth.le.IAdvertiserCallback;
import android.bluetooth.le.IAdvertisingSetCallback;
import android.bluetooth.le.IPeriodicAdvertisingCallback;
import android.bluetooth.le.IScannerCallback;
diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
index 21e9497..67d56d5 100644
--- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
+++ b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
@@ -22,7 +22,6 @@
import android.bluetooth.BluetoothUuid;
import android.bluetooth.IBluetoothGatt;
import android.bluetooth.IBluetoothManager;
-import android.bluetooth.le.IAdvertiserCallback;
import android.os.Handler;
import android.os.Looper;
import android.os.ParcelUuid;
diff --git a/core/java/android/bluetooth/le/IAdvertiserCallback.aidl b/core/java/android/bluetooth/le/IAdvertiserCallback.aidl
deleted file mode 100644
index c58b1df..0000000
--- a/core/java/android/bluetooth/le/IAdvertiserCallback.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2016 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.bluetooth.le;
-
-import android.bluetooth.le.AdvertiseSettings;
-
-/**
- * Callback definitions for interacting with Advertiser
- * @hide
- */
-oneway interface IAdvertiserCallback {
- void onAdvertiserRegistered(in int status, in int advertiserId);
-
- void onMultiAdvertiseCallback(in int status, boolean isStart,
- in AdvertiseSettings advertiseSettings);
-}
diff --git a/core/java/android/bluetooth/le/ScanResult.java b/core/java/android/bluetooth/le/ScanResult.java
index 5b2fa40..e552398 100644
--- a/core/java/android/bluetooth/le/ScanResult.java
+++ b/core/java/android/bluetooth/le/ScanResult.java
@@ -52,6 +52,16 @@
public static final int SID_NOT_PRESENT = 0xFF;
/**
+ * TX power is not present in the packet.
+ */
+ public static final int TX_POWER_NOT_PRESENT = 0x7F;
+
+ /**
+ * Periodic advertising interval is not present in the packet.
+ */
+ public static final int PERIODIC_INTERVAL_NOT_PRESENT = 0x00;
+
+ /**
* Mask for checking whether event type represents legacy advertisement.
*/
private static final int ET_LEGACY_MASK = 0x10;
@@ -265,15 +275,16 @@
/**
* Returns the transmit power in dBm.
- * Valid range is [-127, 126]. A value of 127 indicates that the
- * advertisement did not indicate TX power.
+ * Valid range is [-127, 126]. A value of {@link ScanResult#TX_POWER_NOT_PRESENT}
+ * indicates that the TX power is not present.
*/
public int getTxPower() { return mTxPower; }
/**
* Returns the periodic advertising interval in units of 1.25ms.
- * Valid range is 6 (7.5ms) to 65536 (81918.75ms). A value of 0 means
- * periodic advertising is not used for this scan result.
+ * Valid range is 6 (7.5ms) to 65536 (81918.75ms). A value of
+ * {@link ScanResult#PERIODIC_INTERVAL_NOT_PRESENT} means periodic
+ * advertising interval is not present.
*/
public int getPeriodicAdvertisingInterval() {
return mPeriodicAdvertisingInterval;
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index fed36b0..3bbbe1c 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2761,9 +2761,6 @@
* <dt> {@link #CONNECTIVITY_SERVICE} ("connection")
* <dd> A {@link android.net.ConnectivityManager ConnectivityManager} for
* handling management of network connections.
- * <dt> {@link #IPSEC_SERVICE} ("ipsec")
- * <dd> A {@link android.net.IpSecManager IpSecManager} for managing IPSec on
- * sockets and networks.
* <dt> {@link #WIFI_SERVICE} ("wifi")
* <dd> A {@link android.net.wifi.WifiManager WifiManager} for management of Wi-Fi
* connectivity. On releases before NYC, it should only be obtained from an application
@@ -3098,6 +3095,7 @@
* {@link android.net.IpSecManager} for encrypting Sockets or Networks with
* IPSec.
*
+ * @hide
* @see #getSystemService
*/
public static final String IPSEC_SERVICE = "ipsec";
diff --git a/core/java/android/net/IpSecAlgorithm.java b/core/java/android/net/IpSecAlgorithm.java
index ce7894f..48b095d 100644
--- a/core/java/android/net/IpSecAlgorithm.java
+++ b/core/java/android/net/IpSecAlgorithm.java
@@ -24,6 +24,8 @@
/**
* IpSecAlgorithm specifies a single algorithm that can be applied to an IpSec Transform. Refer to
* RFC 4301.
+ *
+ * @hide
*/
public final class IpSecAlgorithm implements Parcelable {
diff --git a/core/java/android/net/IpSecManager.java b/core/java/android/net/IpSecManager.java
index 375b7ee..114e46e 100644
--- a/core/java/android/net/IpSecManager.java
+++ b/core/java/android/net/IpSecManager.java
@@ -37,6 +37,8 @@
* <p>An IpSecManager may be obtained by calling {@link
* android.content.Context#getSystemService(String) Context#getSystemService(String)} with {@link
* android.content.Context#IPSEC_SERVICE Context#IPSEC_SERVICE}
+ *
+ * @hide
*/
public final class IpSecManager {
private static final String TAG = "IpSecManager";
diff --git a/core/java/android/net/IpSecTransform.java b/core/java/android/net/IpSecTransform.java
index 801e98c..639d1f2 100644
--- a/core/java/android/net/IpSecTransform.java
+++ b/core/java/android/net/IpSecTransform.java
@@ -45,6 +45,8 @@
*
* <p>An IpSecTransform may either represent a tunnel mode transform that operates on a wide array
* of traffic or may represent a transport mode transform operating on a Socket or Sockets.
+ *
+ * @hide
*/
public final class IpSecTransform implements AutoCloseable {
private static final String TAG = "IpSecTransform";
diff --git a/core/java/android/net/NetworkSpecifier.java b/core/java/android/net/NetworkSpecifier.java
index 87a2b05..9ce2a5b 100644
--- a/core/java/android/net/NetworkSpecifier.java
+++ b/core/java/android/net/NetworkSpecifier.java
@@ -33,4 +33,20 @@
* @hide
*/
public abstract boolean satisfiedBy(NetworkSpecifier other);
+
+ /**
+ * Optional method which can be overriden by concrete implementations of NetworkSpecifier to
+ * check a self-reported UID. A concrete implementation may contain a UID which would be self-
+ * reported by the caller (since NetworkSpecifier implementations should be non-mutable). This
+ * function is called by ConnectivityService and is passed the actual UID of the caller -
+ * allowing the verification of the self-reported UID. In cases of mismatch the implementation
+ * should throw a SecurityException.
+ *
+ * @param requestorUid The UID of the requestor as obtained from its binder.
+ *
+ * @hide
+ */
+ public void assertValidFromUid(int requestorUid) {
+ // empty
+ }
}
diff --git a/core/java/android/os/HwParcel.java b/core/java/android/os/HwParcel.java
index 94fd5b0..4ba1144 100644
--- a/core/java/android/os/HwParcel.java
+++ b/core/java/android/os/HwParcel.java
@@ -209,10 +209,11 @@
public native final IHwBinder readStrongBinder();
// Handle is stored as part of the blob.
- public native final HwBlob readBuffer();
+ public native final HwBlob readBuffer(long expectedSize);
public native final HwBlob readEmbeddedBuffer(
- long parentHandle, long offset, boolean nullable);
+ long expectedSize, long parentHandle, long offset,
+ boolean nullable);
public native final void writeBuffer(HwBlob blob);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3f3f859..35a3c0c 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4720,13 +4720,6 @@
public static final String VOICE_INTERACTION_SERVICE = "voice_interaction_service";
/**
- * bluetooth HCI snoop log configuration
- * @hide
- */
- public static final String BLUETOOTH_HCI_LOG =
- "bluetooth_hci_log";
-
- /**
* @deprecated Use {@link android.provider.Settings.Global#DEVICE_PROVISIONED} instead
*/
@Deprecated
diff --git a/core/java/android/provider/VoicemailContract.java b/core/java/android/provider/VoicemailContract.java
index 1e54163..a8b094e 100644
--- a/core/java/android/provider/VoicemailContract.java
+++ b/core/java/android/provider/VoicemailContract.java
@@ -107,15 +107,7 @@
/**
* Broadcast intent to inform a new visual voicemail SMS has been received. This intent will
- * only be delivered to the voicemail client. The intent will have the following extra values:
- *
- * <ul>
- * <li><em>{@link #EXTRA_VOICEMAIL_SMS_TYPE}</em> - (String) The event type of the SMS. Common
- * values are "SYNC" or "STATUS"</li>
- * <li><em>{@link #EXTRA_VOICEMAIL_SMS_DATA}</em> - (Bundle) The fields sent by the SMS</li>
- * <li><em>{@link #EXTRA_VOICEMAIL_SMS_SUBID}</em> - (Integer) The subscription ID of the
- * phone account that received the SMS</li>
- * </ul>
+ * only be delivered to the telephony service. {@link #EXTRA_VOICEMAIL_SMS} will be included.
*/
/** @hide */
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@@ -123,42 +115,11 @@
"android.intent.action.VOICEMAIL_SMS_RECEIVED";
/**
- * Optional extra included in {@link #ACTION_VOICEMAIL_SMS_RECEIVED} broadcast intents to
- * indicate the event type of the SMS. Common values are "SYNC" or "STATUS". The extra will not
- * exist if the framework cannot parse the SMS as voicemail but the carrier pattern indicates
- * it is.
- */
- /** @hide */
- public static final String EXTRA_VOICEMAIL_SMS_PREFIX =
- "com.android.voicemail.extra.VOICEMAIL_SMS_PREFIX";
-
- /**
- * Optional extra included in {@link #ACTION_VOICEMAIL_SMS_RECEIVED} broadcast intents to
- * indicate the fields sent by the SMS. The extra will not exist if the framework cannot
- * parse the SMS as voicemail but the carrier pattern indicates it is.
- */
- /** @hide */
- public static final String EXTRA_VOICEMAIL_SMS_FIELDS =
- "com.android.voicemail.extra.VOICEMAIL_SMS_FIELDS";
-
- /**
- * Extra included in {@link #ACTION_VOICEMAIL_SMS_RECEIVED} broadcast intents to indicate the
- * message body of the SMS. This extra is included if the framework cannot
- * parse the SMS as voicemail but the carrier pattern indicates it is.
- */
- /**
+ * Extra in {@link #ACTION_VOICEMAIL_SMS_RECEIVED} indicating the content of the SMS.
+ *
* @hide
*/
- public static final String EXTRA_VOICEMAIL_SMS_MESSAGE_BODY =
- "com.android.voicemail.extra.VOICEMAIL_SMS_MESSAGE_BODY";
-
- /**
- * Extra included in {@link #ACTION_VOICEMAIL_SMS_RECEIVED} broadcast intents to indicate he
- * subscription ID of the phone account that received the SMS.
- */
- /** @hide */
- public static final String EXTRA_VOICEMAIL_SMS_SUBID =
- "com.android.voicemail.extra.VOICEMAIL_SMS_SUBID";
+ public static final String EXTRA_VOICEMAIL_SMS = "android.provider.extra.VOICEMAIL_SMS";
/**
* Extra included in {@link Intent#ACTION_PROVIDER_CHANGED} broadcast intents to indicate if the
@@ -323,8 +284,6 @@
* not.
*
* <P>Type: INTEGER (boolean)</P>
- *
- * @hide
*/
public static final String BACKED_UP = "backed_up";
@@ -333,8 +292,6 @@
* restored, 0 if not.
*
* <P>Type: INTEGER (boolean)</P>
- *
- * @hide
*/
public static final String RESTORED = "restored";
@@ -344,19 +301,19 @@
* if not.
*
* <P>Type: INTEGER (boolean)</P>
- *
- * @hide
*/
public static final String ARCHIVED = "archived";
/**
* Flag to indicate the voicemail is a OMTP voicemail handled by the {@link
* android.telephony.VisualVoicemailService}. The UI should only show OMTP voicemails from
- * the current visual voicemail package.
+ * the current visual voicemail package. For example, the selection could be
+ * {@code WHERE (IS_OMTP_VOICEMAIL == 0) OR ( IS_OMTP_VOICEMAIL == 1 AND SOURCE_PACKAGE ==
+ * "current.vvm.package")}
*
* <P>Type: INTEGER (boolean)</P>
*
- * @hide
+ * @see android.telephony.TelephonyManager#getVisualVoicemailPackageName
*/
public static final String IS_OMTP_VOICEMAIL = "is_omtp_voicemail";
diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java
index d857bf7..951aa8d 100644
--- a/core/java/android/util/Log.java
+++ b/core/java/android/util/Log.java
@@ -89,8 +89,9 @@
/**
* Exception class used to capture a stack trace in {@link #wtf}.
+ * @hide
*/
- private static class TerribleFailure extends Exception {
+ public static class TerribleFailure extends Exception {
TerribleFailure(String msg, Throwable cause) { super(msg, cause); }
}
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 898c27e..a48d785 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -529,7 +529,7 @@
/*
* Reads a "property" into "buffer". If the property is non-empty, it
* is treated as a dex2oat compiler option that should be
- * passed as a quoted option, e.g. "-Ximage-compiler-option --compiler-filter=verify-none".
+ * passed as a quoted option, e.g. "-Ximage-compiler-option --compiler-filter=assume-verified".
*
* The "compilerArg" is a prefix for the option such as "--compiler-filter=".
*
@@ -605,6 +605,7 @@
{
JavaVMInitArgs initArgs;
char propBuf[PROPERTY_VALUE_MAX];
+ char stackTraceDirBuf[sizeof("-Xstacktracedir:")-1 + PROPERTY_VALUE_MAX];
char stackTraceFileBuf[sizeof("-Xstacktracefile:")-1 + PROPERTY_VALUE_MAX];
char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX];
char heapstartsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
@@ -682,7 +683,12 @@
executionMode = kEMJitCompiler;
}
- parseRuntimeOption("dalvik.vm.stack-trace-file", stackTraceFileBuf, "-Xstacktracefile:");
+ // If dalvik.vm.stack-trace-dir is set, it enables the "new" stack trace
+ // dump scheme and a new file is created for each stack dump. If it isn't set,
+ // the old scheme is enabled.
+ if (!parseRuntimeOption("dalvik.vm.stack-trace-dir", stackTraceDirBuf, "-Xstacktracedir:")) {
+ parseRuntimeOption("dalvik.vm.stack-trace-file", stackTraceFileBuf, "-Xstacktracefile:");
+ }
strcpy(jniOptsBuf, "-Xjniopts:");
if (parseRuntimeOption("dalvik.vm.jniopts", jniOptsBuf, "-Xjniopts:")) {
@@ -777,7 +783,7 @@
"-Xmx", "-Ximage-compiler-option");
if (skip_compilation) {
addOption("-Ximage-compiler-option");
- addOption("--compiler-filter=verify-none");
+ addOption("--compiler-filter=assume-verified");
} else {
parseCompilerOption("dalvik.vm.image-dex2oat-filter", dex2oatImageCompilerFilterBuf,
"--compiler-filter=", "-Ximage-compiler-option");
@@ -808,7 +814,7 @@
"-Xmx", "-Xcompiler-option");
if (skip_compilation) {
addOption("-Xcompiler-option");
- addOption("--compiler-filter=verify-none");
+ addOption("--compiler-filter=assume-verified");
// We skip compilation when a minimal runtime is brought up for decryption. In that case
// /data is temporarily backed by a tmpfs, which is usually small.
diff --git a/core/jni/android_os_HwParcel.cpp b/core/jni/android_os_HwParcel.cpp
index 678041f..b21ea828 100644
--- a/core/jni/android_os_HwParcel.cpp
+++ b/core/jni/android_os_HwParcel.cpp
@@ -574,7 +574,7 @@
size_t parentHandle;
const hidl_string *s;
- status_t err = parcel->readBuffer(&parentHandle,
+ status_t err = parcel->readBuffer(sizeof(*s), &parentHandle,
reinterpret_cast<const void**>(&s));
if (err != OK) {
@@ -583,7 +583,7 @@
}
err = ::android::hardware::readEmbeddedFromParcel(
- const_cast<hidl_string *>(s),
+ const_cast<hidl_string &>(*s),
*parcel, parentHandle, 0 /* parentOffset */);
if (err != OK) {
@@ -602,7 +602,7 @@
size_t parentHandle; \
\
const hidl_vec<Type> *vec; \
- status_t err = parcel->readBuffer(&parentHandle, \
+ status_t err = parcel->readBuffer(sizeof(*vec), &parentHandle, \
reinterpret_cast<const void**>(&vec)); \
\
if (err != OK) { \
@@ -613,7 +613,7 @@
size_t childHandle; \
\
err = ::android::hardware::readEmbeddedFromParcel( \
- const_cast<hidl_vec<Type> *>(vec), \
+ const_cast<hidl_vec<Type> &>(*vec), \
*parcel, \
parentHandle, \
0 /* parentOffset */, \
@@ -645,7 +645,7 @@
size_t parentHandle;
const hidl_vec<bool> *vec;
- status_t err = parcel->readBuffer(&parentHandle,
+ status_t err = parcel->readBuffer(sizeof(*vec), &parentHandle,
reinterpret_cast<const void**>(&vec));
if (err != OK) {
@@ -656,7 +656,7 @@
size_t childHandle;
err = ::android::hardware::readEmbeddedFromParcel(
- const_cast<hidl_vec<bool> *>(vec),
+ const_cast<hidl_vec<bool> &>(*vec),
*parcel,
parentHandle,
0 /* parentOffset */,
@@ -709,7 +709,7 @@
size_t parentHandle;
const string_vec *vec;
- status_t err = parcel->readBuffer(&parentHandle,
+ status_t err = parcel->readBuffer(sizeof(*vec), &parentHandle,
reinterpret_cast<const void **>(&vec));
if (err != OK) {
@@ -719,16 +719,15 @@
size_t childHandle;
err = ::android::hardware::readEmbeddedFromParcel(
- const_cast<string_vec *>(vec),
+ const_cast<string_vec &>(*vec),
*parcel, parentHandle, 0 /* parentOffset */, &childHandle);
for (size_t i = 0; (err == OK) && (i < vec->size()); ++i) {
err = android::hardware::readEmbeddedFromParcel(
- const_cast<hidl_vec<hidl_string> *>(vec),
+ const_cast<hidl_string &>((*vec)[i]),
*parcel,
childHandle,
- i * sizeof(hidl_string),
- nullptr /* childHandle */);
+ i * sizeof(hidl_string) /* parentOffset */);
}
if (err != OK) {
@@ -810,13 +809,20 @@
return JHwRemoteBinder::NewObject(env, binder);
}
-static jobject JHwParcel_native_readBuffer(JNIEnv *env, jobject thiz) {
+static jobject JHwParcel_native_readBuffer(JNIEnv *env, jobject thiz,
+ jlong expectedSize) {
hardware::Parcel *parcel =
JHwParcel::GetNativeContext(env, thiz)->getParcel();
size_t handle;
const void *ptr;
- status_t status = parcel->readBuffer(&handle, &ptr);
+
+ if (expectedSize < 0) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ return nullptr;
+ }
+
+ status_t status = parcel->readBuffer(expectedSize, &handle, &ptr);
if (status != OK) {
jniThrowException(env, "java/util/NoSuchElementException", NULL);
@@ -827,8 +833,8 @@
}
static jobject JHwParcel_native_readEmbeddedBuffer(
- JNIEnv *env, jobject thiz, jlong parentHandle, jlong offset,
- jboolean nullable) {
+ JNIEnv *env, jobject thiz, jlong expectedSize,
+ jlong parentHandle, jlong offset, jboolean nullable) {
hardware::Parcel *parcel =
JHwParcel::GetNativeContext(env, thiz)->getParcel();
@@ -836,8 +842,13 @@
const void *ptr;
status_t status =
- parcel->readNullableEmbeddedBuffer(&childHandle, parentHandle, offset,
- &ptr);
+ parcel->readNullableEmbeddedBuffer(expectedSize,
+ &childHandle, parentHandle, offset, &ptr);
+
+ if (expectedSize < 0) {
+ jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
+ return nullptr;
+ }
if (status != OK) {
jniThrowException(env, "java/util/NoSuchElementException", NULL);
@@ -952,10 +963,10 @@
{ "send", "()V", (void *)JHwParcel_native_send },
- { "readBuffer", "()L" PACKAGE_PATH "/HwBlob;",
+ { "readBuffer", "(J)L" PACKAGE_PATH "/HwBlob;",
(void *)JHwParcel_native_readBuffer },
- { "readEmbeddedBuffer", "(JJZ)L" PACKAGE_PATH "/HwBlob;",
+ { "readEmbeddedBuffer", "(JJJZ)L" PACKAGE_PATH "/HwBlob;",
(void *)JHwParcel_native_readEmbeddedBuffer },
{ "writeBuffer", "(L" PACKAGE_PATH "/HwBlob;)V",
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index b95258b..6000fb5 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -685,11 +685,14 @@
// Grant CAP_WAKE_ALARM to the Bluetooth process.
// Additionally, allow bluetooth to open packet sockets so it can start the DHCP client.
+ // Grant CAP_SYS_NICE to allow Bluetooth to set RT priority for
+ // audio-related threads.
// TODO: consider making such functionality an RPC to netd.
if (multiuser_get_app_id(uid) == AID_BLUETOOTH) {
capabilities |= (1LL << CAP_WAKE_ALARM);
capabilities |= (1LL << CAP_NET_RAW);
capabilities |= (1LL << CAP_NET_BIND_SERVICE);
+ capabilities |= (1LL << CAP_SYS_NICE);
}
// Grant CAP_BLOCK_SUSPEND to processes that belong to GID "wakelock"
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9e7bf27..f5f67d06 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1560,6 +1560,14 @@
<permission android:name="android.permission.BIND_INCALL_SERVICE"
android:protectionLevel="signature|privileged" />
+ <!-- Must be required by a link {@link android.telephony.VisualVoicemailService} to ensure that
+ only the system can bind to it.
+ <p>Protection level: signature|privileged
+ -->
+ <permission
+ android:name="android.permission.BIND_VISUAL_VOICEMAIL_SERVICE"
+ android:protectionLevel="signature|privileged"/>
+
<!-- Must be required by a {@link android.telecom.CallScreeningService},
to ensure that only the system can bind to it.
<p>Protection level: signature|privileged
diff --git a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothInstrumentation.java b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothInstrumentation.java
index 411a3f8..37b2a50 100644
--- a/core/tests/bluetoothtests/src/android/bluetooth/BluetoothInstrumentation.java
+++ b/core/tests/bluetoothtests/src/android/bluetooth/BluetoothInstrumentation.java
@@ -72,8 +72,6 @@
getAddress();
} else if ("getBondedDevices".equals(command)) {
getBondedDevices();
- } else if ("enableBtSnoop".equals(command)) {
- enableBtSnoop();
} else {
finish(null);
}
@@ -116,12 +114,6 @@
finish(mSuccessResult);
}
- public void enableBtSnoop() {
- Assert.assertTrue("failed to enable snoop log",
- getBluetoothAdapter().configHciSnoopLog(true));
- finish(mSuccessResult);
- }
-
public void finish(Bundle result) {
if (result == null) {
result = new Bundle();
diff --git a/packages/CarrierDefaultApp/AndroidManifest.xml b/packages/CarrierDefaultApp/AndroidManifest.xml
index e450283..2ef1cf5 100644
--- a/packages/CarrierDefaultApp/AndroidManifest.xml
+++ b/packages/CarrierDefaultApp/AndroidManifest.xml
@@ -33,6 +33,7 @@
<receiver android:name="com.android.carrierdefaultapp.CarrierDefaultBroadcastReceiver">
<intent-filter>
<action android:name="com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED" />
+ <action android:name="com.android.internal.telephony.CARRIER_SIGNAL_RESET" />
</intent-filter>
</receiver>
<service android:name="com.android.carrierdefaultapp.ProvisionObserver"
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java
index e1125d9..d5d0b79 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CustomConfigLoader.java
@@ -91,6 +91,10 @@
arg1 = intent.getStringExtra(TelephonyIntents.EXTRA_APN_TYPE_KEY);
arg2 = intent.getStringExtra(TelephonyIntents.EXTRA_ERROR_CODE_KEY);
break;
+ case TelephonyIntents.ACTION_CARRIER_SIGNAL_RESET:
+ configs = b.getStringArray(CarrierConfigManager
+ .KEY_CARRIER_DEFAULT_ACTIONS_ON_RESET);
+ break;
default:
Rlog.e(TAG, "load carrier config failure with un-configured key: " +
intent.getAction());
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 5eb4db4..1262d88 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -1496,16 +1496,6 @@
if (mGetNameAddressOnly) return;
}
- try {
- boolean enableHciSnoopLog = (Settings.Secure.getInt(mContentResolver,
- Settings.Secure.BLUETOOTH_HCI_LOG, 0) == 1);
- if (!mBluetooth.configHciSnoopLog(enableHciSnoopLog)) {
- Slog.e(TAG,"IBluetooth.configHciSnoopLog return false");
- }
- } catch (RemoteException e) {
- Slog.e(TAG,"Unable to call configHciSnoopLog", e);
- }
-
//Register callback object
try {
mBluetooth.registerCallback(mBluetoothCallback);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 616a8c0..88bc54d 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -49,7 +49,6 @@
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
-import android.content.res.Resources;
import android.database.ContentObserver;
import android.net.ConnectivityManager;
import android.net.ConnectivityManager.PacketKeepalive;
@@ -70,6 +69,7 @@
import android.net.NetworkMisc;
import android.net.NetworkQuotaInfo;
import android.net.NetworkRequest;
+import android.net.NetworkSpecifier;
import android.net.NetworkState;
import android.net.NetworkUtils;
import android.net.Proxy;
@@ -110,7 +110,6 @@
import android.util.LocalLog;
import android.util.LocalLog.ReadOnlyLocalLog;
import android.util.Log;
-import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@@ -4131,6 +4130,18 @@
0, 0, thresholds);
}
+ private void ensureValidNetworkSpecifier(NetworkCapabilities nc) {
+ if (nc == null) {
+ return;
+ }
+ NetworkSpecifier ns = nc.getNetworkSpecifier();
+ if (ns == null) {
+ return;
+ }
+ MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(ns);
+ ns.assertValidFromUid(Binder.getCallingUid());
+ }
+
@Override
public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
Messenger messenger, int timeoutMs, IBinder binder, int legacyType) {
@@ -4156,9 +4167,7 @@
if (timeoutMs < 0) {
throw new IllegalArgumentException("Bad timeout specified");
}
-
- MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(
- networkCapabilities.getNetworkSpecifier());
+ ensureValidNetworkSpecifier(networkCapabilities);
NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, legacyType,
nextNetworkRequestId(), type);
@@ -4230,9 +4239,7 @@
enforceNetworkRequestPermissions(networkCapabilities);
enforceMeteredApnPolicy(networkCapabilities);
ensureRequestableCapabilities(networkCapabilities);
-
- MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(
- networkCapabilities.getNetworkSpecifier());
+ ensureValidNetworkSpecifier(networkCapabilities);
NetworkRequest networkRequest = new NetworkRequest(networkCapabilities, TYPE_NONE,
nextNetworkRequestId(), NetworkRequest.Type.REQUEST);
@@ -4294,9 +4301,7 @@
// can't request networks.
nc.addCapability(NET_CAPABILITY_FOREGROUND);
}
-
- MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(
- networkCapabilities.getNetworkSpecifier());
+ ensureValidNetworkSpecifier(networkCapabilities);
NetworkRequest networkRequest = new NetworkRequest(nc, TYPE_NONE, nextNetworkRequestId(),
NetworkRequest.Type.LISTEN);
@@ -4314,9 +4319,7 @@
if (!hasWifiNetworkListenPermission(networkCapabilities)) {
enforceAccessPermission();
}
-
- MatchAllNetworkSpecifier.checkNotMatchAllNetworkSpecifier(
- networkCapabilities.getNetworkSpecifier());
+ ensureValidNetworkSpecifier(networkCapabilities);
NetworkRequest networkRequest = new NetworkRequest(
new NetworkCapabilities(networkCapabilities), TYPE_NONE, nextNetworkRequestId(),
diff --git a/services/core/java/com/android/server/NsdService.java b/services/core/java/com/android/server/NsdService.java
index a691af9..55bca64 100644
--- a/services/core/java/com/android/server/NsdService.java
+++ b/services/core/java/com/android/server/NsdService.java
@@ -26,6 +26,8 @@
import android.net.nsd.INsdManager;
import android.net.nsd.NsdManager;
import android.os.Binder;
+import android.os.HandlerThread;
+import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import android.os.UserHandle;
@@ -37,9 +39,11 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.net.InetAddress;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.concurrent.CountDownLatch;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
import com.android.internal.util.State;
@@ -59,10 +63,10 @@
private static final boolean DBG = true;
private final Context mContext;
- private final ContentResolver mContentResolver;
+ private final NsdSettings mNsdSettings;
private final NsdStateMachine mNsdStateMachine;
- private final NativeDaemonConnector mNativeConnector;
- private final CountDownLatch mNativeDaemonConnected = new CountDownLatch(1);
+ private final DaemonConnection mDaemon;
+ private final NativeCallbackReceiver mDaemonCallback;
/**
* Clients receiving asynchronous messages
@@ -108,8 +112,8 @@
false, contentObserver);
}
- NsdStateMachine(String name) {
- super(name);
+ NsdStateMachine(String name, Handler handler) {
+ super(name, handler);
addState(mDefaultState);
addState(mDisabledState, mDefaultState);
addState(mEnabledState, mDefaultState);
@@ -541,36 +545,35 @@
return sb.toString();
}
- private NsdService(Context context) {
- mContext = context;
- mContentResolver = context.getContentResolver();
-
- mNativeConnector = new NativeDaemonConnector(new NativeCallbackReceiver(), "mdns", 10,
- MDNS_TAG, 25, null);
-
- mNsdStateMachine = new NsdStateMachine(TAG);
+ @VisibleForTesting
+ NsdService(Context ctx, NsdSettings settings, Handler handler, DaemonConnectionSupplier fn) {
+ mContext = ctx;
+ mNsdSettings = settings;
+ mNsdStateMachine = new NsdStateMachine(TAG, handler);
mNsdStateMachine.start();
-
- Thread th = new Thread(mNativeConnector, MDNS_TAG);
- th.start();
+ mDaemonCallback = new NativeCallbackReceiver();
+ mDaemon = fn.get(mDaemonCallback);
}
public static NsdService create(Context context) throws InterruptedException {
- NsdService service = new NsdService(context);
- service.mNativeDaemonConnected.await();
+ NsdSettings settings = NsdSettings.makeDefault(context);
+ HandlerThread thread = new HandlerThread(TAG);
+ thread.start();
+ Handler handler = new Handler(thread.getLooper());
+ NsdService service = new NsdService(context, settings, handler, DaemonConnection::new);
+ service.mDaemonCallback.awaitConnection();
return service;
}
public Messenger getMessenger() {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INTERNET,
- "NsdService");
+ mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INTERNET, "NsdService");
return new Messenger(mNsdStateMachine.getHandler());
}
public void setEnabled(boolean enable) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CONNECTIVITY_INTERNAL,
"NsdService");
- Settings.Global.putInt(mContentResolver, Settings.Global.NSD_ON, enable ? 1 : 0);
+ mNsdSettings.putEnabledStatus(enable);
if (enable) {
mNsdStateMachine.sendMessage(NsdManager.ENABLE);
} else {
@@ -590,8 +593,10 @@
}
private boolean isNsdEnabled() {
- boolean ret = Settings.Global.getInt(mContentResolver, Settings.Global.NSD_ON, 1) == 1;
- if (DBG) Slog.d(TAG, "Network service discovery enabled " + ret);
+ boolean ret = mNsdSettings.isEnabled();
+ if (DBG) {
+ Slog.d(TAG, "Network service discovery is " + (ret ? "enabled" : "disabled"));
+ }
return ret;
}
@@ -655,14 +660,23 @@
}
class NativeCallbackReceiver implements INativeDaemonConnectorCallbacks {
- public void onDaemonConnected() {
- mNativeDaemonConnected.countDown();
+ private final CountDownLatch connected = new CountDownLatch(1);
+
+ public void awaitConnection() throws InterruptedException {
+ connected.await();
}
+ @Override
+ public void onDaemonConnected() {
+ connected.countDown();
+ }
+
+ @Override
public boolean onCheckHoldWakeLock(int code) {
return false;
}
+ @Override
public boolean onEvent(int code, String raw, String[] cooked) {
// TODO: NDC translates a message to a callback, we could enhance NDC to
// directly interact with a state machine through messages
@@ -672,132 +686,102 @@
}
}
- private boolean startMDnsDaemon() {
- if (DBG) Slog.d(TAG, "startMDnsDaemon");
- try {
- mNativeConnector.execute("mdnssd", "start-service");
- } catch(NativeDaemonConnectorException e) {
- Slog.e(TAG, "Failed to start daemon" + e);
- return false;
+ interface DaemonConnectionSupplier {
+ DaemonConnection get(NativeCallbackReceiver callback);
+ }
+
+ @VisibleForTesting
+ public static class DaemonConnection {
+ final NativeDaemonConnector mNativeConnector;
+
+ DaemonConnection(NativeCallbackReceiver callback) {
+ mNativeConnector = new NativeDaemonConnector(callback, "mdns", 10, MDNS_TAG, 25, null);
+ new Thread(mNativeConnector, MDNS_TAG).start();
}
- return true;
+
+ public boolean execute(Object... args) {
+ if (DBG) {
+ Slog.d(TAG, "mdnssd " + Arrays.toString(args));
+ }
+ try {
+ mNativeConnector.execute("mdnssd", args);
+ } catch (NativeDaemonConnectorException e) {
+ Slog.e(TAG, "Failed to execute mdnssd " + Arrays.toString(args), e);
+ return false;
+ }
+ return true;
+ }
+
+ public boolean execute(Command cmd) {
+ if (DBG) {
+ Slog.d(TAG, cmd.toString());
+ }
+ try {
+ mNativeConnector.execute(cmd);
+ } catch (NativeDaemonConnectorException e) {
+ Slog.e(TAG, "Failed to execute " + cmd, e);
+ return false;
+ }
+ return true;
+ }
+ }
+
+ private boolean startMDnsDaemon() {
+ return mDaemon.execute("start-service");
}
private boolean stopMDnsDaemon() {
- if (DBG) Slog.d(TAG, "stopMDnsDaemon");
- try {
- mNativeConnector.execute("mdnssd", "stop-service");
- } catch(NativeDaemonConnectorException e) {
- Slog.e(TAG, "Failed to start daemon" + e);
- return false;
- }
- return true;
+ return mDaemon.execute("stop-service");
}
private boolean registerService(int regId, NsdServiceInfo service) {
- if (DBG) Slog.d(TAG, "registerService: " + regId + " " + service);
- try {
- Command cmd = new Command("mdnssd", "register", regId, service.getServiceName(),
- service.getServiceType(), service.getPort(),
- Base64.encodeToString(service.getTxtRecord(), Base64.DEFAULT)
- .replace("\n", ""));
-
- mNativeConnector.execute(cmd);
- } catch(NativeDaemonConnectorException e) {
- Slog.e(TAG, "Failed to execute registerService " + e);
- return false;
+ if (DBG) {
+ Slog.d(TAG, "registerService: " + regId + " " + service);
}
- return true;
+ String name = service.getServiceName();
+ String type = service.getServiceType();
+ int port = service.getPort();
+ byte[] textRecord = service.getTxtRecord();
+ String record = Base64.encodeToString(textRecord, Base64.DEFAULT).replace("\n", "");
+ Command cmd = new Command("mdnssd", "register", regId, name, type, port, record);
+ return mDaemon.execute(cmd);
}
private boolean unregisterService(int regId) {
- if (DBG) Slog.d(TAG, "unregisterService: " + regId);
- try {
- mNativeConnector.execute("mdnssd", "stop-register", regId);
- } catch(NativeDaemonConnectorException e) {
- Slog.e(TAG, "Failed to execute unregisterService " + e);
- return false;
- }
- return true;
+ return mDaemon.execute("stop-register", regId);
}
private boolean updateService(int regId, DnsSdTxtRecord t) {
- if (DBG) Slog.d(TAG, "updateService: " + regId + " " + t);
- try {
- if (t == null) return false;
- mNativeConnector.execute("mdnssd", "update", regId, t.size(), t.getRawData());
- } catch(NativeDaemonConnectorException e) {
- Slog.e(TAG, "Failed to updateServices " + e);
+ if (t == null) {
return false;
}
- return true;
+ return mDaemon.execute("update", regId, t.size(), t.getRawData());
}
private boolean discoverServices(int discoveryId, String serviceType) {
- if (DBG) Slog.d(TAG, "discoverServices: " + discoveryId + " " + serviceType);
- try {
- mNativeConnector.execute("mdnssd", "discover", discoveryId, serviceType);
- } catch(NativeDaemonConnectorException e) {
- Slog.e(TAG, "Failed to discoverServices " + e);
- return false;
- }
- return true;
+ return mDaemon.execute("discover", discoveryId, serviceType);
}
private boolean stopServiceDiscovery(int discoveryId) {
- if (DBG) Slog.d(TAG, "stopServiceDiscovery: " + discoveryId);
- try {
- mNativeConnector.execute("mdnssd", "stop-discover", discoveryId);
- } catch(NativeDaemonConnectorException e) {
- Slog.e(TAG, "Failed to stopServiceDiscovery " + e);
- return false;
- }
- return true;
+ return mDaemon.execute("stop-discover", discoveryId);
}
private boolean resolveService(int resolveId, NsdServiceInfo service) {
- if (DBG) Slog.d(TAG, "resolveService: " + resolveId + " " + service);
- try {
- mNativeConnector.execute("mdnssd", "resolve", resolveId, service.getServiceName(),
- service.getServiceType(), "local.");
- } catch(NativeDaemonConnectorException e) {
- Slog.e(TAG, "Failed to resolveService " + e);
- return false;
- }
- return true;
+ String name = service.getServiceName();
+ String type = service.getServiceType();
+ return mDaemon.execute("resolve", resolveId, name, type, "local.");
}
private boolean stopResolveService(int resolveId) {
- if (DBG) Slog.d(TAG, "stopResolveService: " + resolveId);
- try {
- mNativeConnector.execute("mdnssd", "stop-resolve", resolveId);
- } catch(NativeDaemonConnectorException e) {
- Slog.e(TAG, "Failed to stop resolve " + e);
- return false;
- }
- return true;
+ return mDaemon.execute("stop-resolve", resolveId);
}
private boolean getAddrInfo(int resolveId, String hostname) {
- if (DBG) Slog.d(TAG, "getAdddrInfo: " + resolveId);
- try {
- mNativeConnector.execute("mdnssd", "getaddrinfo", resolveId, hostname);
- } catch(NativeDaemonConnectorException e) {
- Slog.e(TAG, "Failed to getAddrInfo " + e);
- return false;
- }
- return true;
+ return mDaemon.execute("getaddrinfo", resolveId, hostname);
}
private boolean stopGetAddrInfo(int resolveId) {
- if (DBG) Slog.d(TAG, "stopGetAdddrInfo: " + resolveId);
- try {
- mNativeConnector.execute("mdnssd", "stop-getaddrinfo", resolveId);
- } catch(NativeDaemonConnectorException e) {
- Slog.e(TAG, "Failed to stopGetAddrInfo " + e);
- return false;
- }
- return true;
+ return mDaemon.execute("stop-getaddrinfo", resolveId);
}
@Override
@@ -927,4 +911,25 @@
return -1;
}
}
+
+ @VisibleForTesting
+ public interface NsdSettings {
+ boolean isEnabled();
+ void putEnabledStatus(boolean isEnabled);
+
+ static NsdSettings makeDefault(Context context) {
+ ContentResolver resolver = context.getContentResolver();
+ return new NsdSettings() {
+ @Override
+ public boolean isEnabled() {
+ return Settings.Global.getInt(resolver, Settings.Global.NSD_ON, 1) == 1;
+ }
+
+ @Override
+ public void putEnabledStatus(boolean isEnabled) {
+ Settings.Global.putInt(resolver, Settings.Global.NSD_ON, isEnabled ? 1 : 0);
+ }
+ };
+ }
+ }
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5ae4d67..c5fc038 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5324,35 +5324,61 @@
return tracesFile;
}
+ public static class DumpStackFileObserver extends FileObserver {
+ // Keep in sync with frameworks/native/cmds/dumpstate/utils.cpp
+ private static final int TRACE_DUMP_TIMEOUT_MS = 10000; // 10 seconds
+ static final int TRACE_DUMP_TIMEOUT_SECONDS = TRACE_DUMP_TIMEOUT_MS / 1000;
+
+ private final String mTracesPath;
+ private boolean mClosed;
+
+ public DumpStackFileObserver(String tracesPath) {
+ super(tracesPath, FileObserver.CLOSE_WRITE);
+ mTracesPath = tracesPath;
+ }
+
+ @Override
+ public synchronized void onEvent(int event, String path) {
+ mClosed = true;
+ notify();
+ }
+
+ public void dumpWithTimeout(int pid) {
+ Process.sendSignal(pid, Process.SIGNAL_QUIT);
+ synchronized (this) {
+ try {
+ wait(TRACE_DUMP_TIMEOUT_MS); // Wait for traces file to be closed.
+ } catch (InterruptedException e) {
+ Slog.wtf(TAG, e);
+ }
+ }
+ if (!mClosed) {
+ Slog.w(TAG, "Didn't see close of " + mTracesPath + " for pid " + pid +
+ ". Attempting native stack collection.");
+ Debug.dumpNativeBacktraceToFileTimeout(pid, mTracesPath, TRACE_DUMP_TIMEOUT_SECONDS);
+ }
+ mClosed = false;
+ }
+ }
+
private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
// Use a FileObserver to detect when traces finish writing.
// The order of traces is considered important to maintain for legibility.
- FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
- @Override
- public synchronized void onEvent(int event, String path) { notify(); }
- };
-
+ DumpStackFileObserver observer = new DumpStackFileObserver(tracesPath);
try {
observer.startWatching();
// First collect all of the stacks of the most important pids.
if (firstPids != null) {
- try {
- int num = firstPids.size();
- for (int i = 0; i < num; i++) {
- synchronized (observer) {
- if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
- + firstPids.get(i));
- final long sime = SystemClock.elapsedRealtime();
- Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
- observer.wait(1000); // Wait for write-close, give up after 1 sec
- if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
- + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
- }
- }
- } catch (InterruptedException e) {
- Slog.wtf(TAG, e);
+ int num = firstPids.size();
+ for (int i = 0; i < num; i++) {
+ if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
+ + firstPids.get(i));
+ final long sime = SystemClock.elapsedRealtime();
+ observer.dumpWithTimeout(firstPids.get(i));
+ if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
+ + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
}
}
@@ -5364,7 +5390,8 @@
if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
final long sime = SystemClock.elapsedRealtime();
- Debug.dumpNativeBacktraceToFileTimeout(pid, tracesPath, 10);
+ Debug.dumpNativeBacktraceToFileTimeout(
+ pid, tracesPath, DumpStackFileObserver.TRACE_DUMP_TIMEOUT_SECONDS);
if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
+ " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
}
@@ -5391,19 +5418,12 @@
ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
if (lastPids.indexOfKey(stats.pid) >= 0) {
numProcs++;
- try {
- synchronized (observer) {
- if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
- + stats.pid);
- final long stime = SystemClock.elapsedRealtime();
- Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
- observer.wait(1000); // Wait for write-close, give up after 1 sec
- if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
- + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
- }
- } catch (InterruptedException e) {
- Slog.wtf(TAG, e);
- }
+ if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
+ + stats.pid);
+ final long stime = SystemClock.elapsedRealtime();
+ observer.dumpWithTimeout(stats.pid);
+ if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
+ + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
} else if (DEBUG_ANR) {
Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
+ stats.pid);
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 71c7fd3..2e74eb9 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -493,8 +493,9 @@
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
runningIntent.setData(Uri.fromParts("package",
appInfo.packageName, null));
- PendingIntent pi = PendingIntent.getActivity(ams.mContext, 0,
- runningIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+ PendingIntent pi = PendingIntent.getActivityAsUser(ams.mContext, 0,
+ runningIntent, PendingIntent.FLAG_UPDATE_CURRENT, null,
+ UserHandle.of(userId));
notiBuilder.setColor(ams.mContext.getColor(
com.android.internal
.R.color.system_notification_accent_color));
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index e667680..b0ed2b8 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -219,6 +219,10 @@
return (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
}
+ private WifiManager getWifiManager() {
+ return (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+ }
+
private void updateConfiguration() {
mConfig = new TetheringConfiguration(mContext);
}
@@ -411,8 +415,7 @@
private int setWifiTethering(final boolean enable) {
synchronized (mPublicSync) {
mWifiTetherRequested = enable;
- final WifiManager wifiManager =
- (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
+ final WifiManager wifiManager = getWifiManager();
if ((enable && wifiManager.startSoftAp(null /* use existing wifi config */)) ||
(!enable && wifiManager.stopSoftAp())) {
return ConnectivityManager.TETHER_ERROR_NO_ERROR;
@@ -1334,12 +1337,37 @@
} else {
mForwardedDownstreams.remove(who);
}
+
+ // If this is a Wi-Fi interface, notify WifiManager of the active serving state.
+ if (who.interfaceType() == ConnectivityManager.TETHERING_WIFI) {
+ final WifiManager mgr = getWifiManager();
+ final String iface = who.interfaceName();
+ switch (mode) {
+ case IControlsTethering.STATE_TETHERED:
+ mgr.updateInterfaceIpState(iface, WifiManager.IFACE_IP_MODE_TETHERED);
+ break;
+ case IControlsTethering.STATE_LOCAL_ONLY:
+ mgr.updateInterfaceIpState(iface, WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
+ break;
+ default:
+ Log.wtf(TAG, "Unknown active serving mode: " + mode);
+ break;
+ }
+ }
}
private void handleInterfaceServingStateInactive(TetherInterfaceStateMachine who) {
mNotifyList.remove(who);
mIPv6TetheringCoordinator.removeActiveDownstream(who);
mForwardedDownstreams.remove(who);
+
+ // If this is a Wi-Fi interface, tell WifiManager of any errors.
+ if (who.interfaceType() == ConnectivityManager.TETHERING_WIFI) {
+ if (who.lastError() != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+ getWifiManager().updateInterfaceIpState(
+ who.interfaceName(), WifiManager.IFACE_IP_MODE_CONFIGURATION_ERROR);
+ }
+ }
}
class InitialState extends State {
@@ -1661,7 +1689,7 @@
public void notifyInterfaceStateChange(String iface, TetherInterfaceStateMachine who,
int state, int error) {
synchronized (mPublicSync) {
- TetherState tetherState = mTetherStates.get(iface);
+ final TetherState tetherState = mTetherStates.get(iface);
if (tetherState != null && tetherState.stateMachine.equals(who)) {
tetherState.lastState = state;
tetherState.lastError = error;
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
index e21349a..d3cfd87 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
@@ -117,9 +117,11 @@
setInitialState(mInitialState);
}
- public int interfaceType() {
- return mInterfaceType;
- }
+ public String interfaceName() { return mIfaceName; }
+
+ public int interfaceType() { return mInterfaceType; }
+
+ public int lastError() { return mLastError; }
// configured when we start tethering and unconfig'd on error or conclusion
private boolean configureIfaceIp(boolean enabled) {
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index cc41060..f97a672 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -866,7 +866,7 @@
final int uid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
try {
- if (uid != Process.BLUETOOTH_UID) {
+ if (!UserHandle.isSameApp(uid, Process.BLUETOOTH_UID)) {
throw new SecurityException("Only Bluetooth service processes can set"
+ " Callback");
}
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index 4e14408..d93d620 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -139,7 +139,7 @@
// (by default is speed-profile) they will be interepreted/JITed. This in itself is
// not a problem as we will end up doing profile guided compilation. However, some
// core apps may be loaded by system server which doesn't JIT and we need to make
- // sure we don't interpret-only
+ // sure we are not interpreting all their code in that process.
int compilationReason = p.coreApp
? PackageManagerService.REASON_CORE_APP
: PackageManagerService.REASON_AB_OTA;
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index d696f49..8e0997b 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -360,10 +360,10 @@
boolean vmSafeMode = (flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0;
if (vmSafeMode) {
// For the compilation, it doesn't really matter what we return here because installd
- // will replace the filter with interpret-only anyway.
+ // will replace the filter with 'quicken' anyway.
// However, we return a non profile guided filter so that we simplify the logic of
// merging profiles.
- // TODO(calin): safe mode path could be simplified if we pass interpret-only from
+ // TODO(calin): safe mode path could be simplified if we pass 'quicken' from
// here rather than letting installd decide on the filter.
return getNonProfileGuidedCompilerFilter(targetCompilerFilter);
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index b207b81..3196b09 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -7364,20 +7364,7 @@
// are verify-profile but for preopted apps there's no profile.
// Do a hacky check to ensure that if we have no profiles (a reasonable indication
// that before the OTA the app was preopted) the app gets compiled with a non-profile
- // filter (by default interpret-only).
- // Note that at this stage unused apps are already filtered.
- if (isSystemApp(pkg) &&
- DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
- !Environment.getReferenceProfile(pkg.packageName).exists()) {
- compilerFilter = getNonProfileGuidedCompilerFilter(compilerFilter);
- }
-
- // If the OTA updates a system app which was previously preopted to a non-preopted state
- // the app might end up being verified at runtime. That's because by default the apps
- // are verify-profile but for preopted apps there's no profile.
- // Do a hacky check to ensure that if we have no profiles (a reasonable indication
- // that before the OTA the app was preopted) the app gets compiled with a non-profile
- // filter (by default interpret-only).
+ // filter (by default 'quicken').
// Note that at this stage unused apps are already filtered.
if (isSystemApp(pkg) &&
DexFile.isProfileGuidedCompilerFilter(compilerFilter) &&
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 1bfc157..2f000c2 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -1454,10 +1454,10 @@
pw.println(" -f: force compilation even if not needed");
pw.println(" -m: select compilation mode");
pw.println(" MODE is one of the dex2oat compiler filters:");
- pw.println(" verify-none");
- pw.println(" verify-at-runtime");
- pw.println(" verify-profile");
- pw.println(" interpret-only");
+ pw.println(" assume-verified");
+ pw.println(" extract");
+ pw.println(" verify");
+ pw.println(" quicken");
pw.println(" space-profile");
pw.println(" space");
pw.println(" speed-profile");
diff --git a/services/net/java/android/net/apf/ApfCapabilities.java b/services/net/java/android/net/apf/ApfCapabilities.java
index b0e0230..703b415 100644
--- a/services/net/java/android/net/apf/ApfCapabilities.java
+++ b/services/net/java/android/net/apf/ApfCapabilities.java
@@ -46,7 +46,7 @@
}
public String toString() {
- return String.format("%s{version: %d, maxSize: %d format: %d}", getClass().getSimpleName(),
+ return String.format("%s{version: %d, maxSize: %d, format: %d}", getClass().getSimpleName(),
apfVersionSupported, maximumApfProgramSize, apfPacketFormat);
}
}
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index 745764b..6608167 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -524,7 +524,7 @@
try {
mNwService.registerObserver(mNetlinkTracker);
} catch (RemoteException e) {
- Log.e(mTag, "Couldn't register NetlinkTracker: " + e.toString());
+ logError("Couldn't register NetlinkTracker: %s", e);
}
mMultinetworkPolicyTracker.start();
@@ -611,19 +611,36 @@
return;
}
+ // Thread-unsafe access to mApfFilter but just used for debugging.
+ final ApfFilter apfFilter = mApfFilter;
+ final ProvisioningConfiguration provisioningConfig = mConfiguration;
+ final ApfCapabilities apfCapabilities = (provisioningConfig != null)
+ ? provisioningConfig.mApfCapabilities : null;
+
IndentingPrintWriter pw = new IndentingPrintWriter(writer, " ");
pw.println(mTag + " APF dump:");
pw.increaseIndent();
- // Thread-unsafe access to mApfFilter but just used for debugging.
- ApfFilter apfFilter = mApfFilter;
if (apfFilter != null) {
apfFilter.dump(pw);
} else {
- pw.println("No apf support");
+ pw.print("No active ApfFilter; ");
+ if (provisioningConfig == null) {
+ pw.println("IpManager not yet started.");
+ } else if (apfCapabilities == null || apfCapabilities.apfVersionSupported == 0) {
+ pw.println("Hardware does not support APF.");
+ } else {
+ pw.println("ApfFilter not yet started, APF capabilities: " + apfCapabilities);
+ }
}
pw.decreaseIndent();
pw.println();
+ pw.println(mTag + " current ProvisioningConfiguration:");
+ pw.increaseIndent();
+ pw.println(Objects.toString(provisioningConfig, "N/A"));
+ pw.decreaseIndent();
+
+ pw.println();
pw.println(mTag + " StateMachine dump:");
pw.increaseIndent();
mLocalLog.readOnlyLocalLog().dump(fd, pw, args);
@@ -684,7 +701,9 @@
// TODO: Migrate all Log.e(...) to logError(...).
private void logError(String fmt, Object... args) {
- mLocalLog.log("ERROR " + String.format(fmt, args));
+ final String msg = "ERROR " + String.format(fmt, args);
+ Log.e(mTag, msg);
+ mLocalLog.log(msg);
}
private void getNetworkInterface() {
@@ -692,7 +711,7 @@
mNetworkInterface = NetworkInterface.getByName(mInterfaceName);
} catch (SocketException | NullPointerException e) {
// TODO: throw new IllegalStateException.
- Log.e(mTag, "ALERT: Failed to get interface object: ", e);
+ logError("Failed to get interface object: %s", e);
}
}
@@ -948,7 +967,7 @@
ifcg.setLinkAddress(new LinkAddress("0.0.0.0/0"));
mNwService.setInterfaceConfig(mInterfaceName, ifcg);
} catch (IllegalStateException | RemoteException e) {
- Log.e(mTag, "ALERT: Failed to clear IPv4 address on interface " + mInterfaceName, e);
+ logError("Failed to clear IPv4 address on interface %s: %s", mInterfaceName, e);
}
}
@@ -1074,13 +1093,13 @@
try {
mNwService.disableIpv6(mInterfaceName);
} catch (Exception e) {
- Log.e(mTag, "Failed to disable IPv6" + e);
+ logError("Failed to disable IPv6: %s", e);
}
try {
mNwService.clearInterfaceAddresses(mInterfaceName);
} catch (Exception e) {
- Log.e(mTag, "Failed to clear addresses " + e);
+ logError("Failed to clear addresses: %s", e);
}
}
@@ -1404,7 +1423,7 @@
if (setIPv4Address(ipAddress)) {
mDhcpClient.sendMessage(DhcpClient.EVENT_LINKADDRESS_CONFIGURED);
} else {
- Log.e(mTag, "Failed to set IPv4 address!");
+ logError("Failed to set IPv4 address.");
dispatchCallback(ProvisioningChange.LOST_PROVISIONING,
new LinkProperties(mLinkProperties));
transitionTo(mStoppingState);
diff --git a/services/net/java/android/net/util/ConnectivityPacketSummary.java b/services/net/java/android/net/util/ConnectivityPacketSummary.java
index 5b068c0..dae93af 100644
--- a/services/net/java/android/net/util/ConnectivityPacketSummary.java
+++ b/services/net/java/android/net/util/ConnectivityPacketSummary.java
@@ -368,9 +368,9 @@
byte[] bytes = new byte[ETHER_ADDR_LEN];
mac.get(bytes, 0, bytes.length);
- Byte[] printableBytes = new Byte[bytes.length];
+ Object[] printableBytes = new Object[bytes.length];
int i = 0;
- for (byte b : bytes) printableBytes[i++] = b;
+ for (byte b : bytes) printableBytes[i++] = new Byte(b);
final String MAC48_FORMAT = "%02x:%02x:%02x:%02x:%02x:%02x";
return String.format(MAC48_FORMAT, printableBytes);
diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java
index c42a835..5530cb7 100644
--- a/telecomm/java/android/telecom/PhoneAccount.java
+++ b/telecomm/java/android/telecom/PhoneAccount.java
@@ -43,6 +43,15 @@
/**
* {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which determines the
+ * sort order for {@link PhoneAccount}s from the same
+ * {@link android.telecom.ConnectionService}.
+ * @hide
+ */
+ public static final String EXTRA_SORT_ORDER =
+ "android.telecom.extra.SORT_ORDER";
+
+ /**
+ * {@link PhoneAccount} extras key (see {@link PhoneAccount#getExtras()}) which determines the
* maximum permitted length of a call subject specified via the
* {@link TelecomManager#EXTRA_CALL_SUBJECT} extra on an
* {@link android.content.Intent#ACTION_CALL} intent. Ultimately a {@link ConnectionService} is
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 5fa5070f..e1239d0 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -604,6 +604,38 @@
"vvm_cellular_data_required_bool";
/**
+ * The default OMTP visual voicemail client prefix to use. Defaulted to "//VVM"
+ */
+ public static final String KEY_VVM_CLIENT_PREFIX_STRING =
+ "vvm_client_prefix_string";
+
+ /**
+ * Whether to use SSL to connect to the visual voicemail IMAP server. Defaulted to false.
+ */
+ public static final String KEY_VVM_SSL_ENABLED_BOOL = "vvm_ssl_enabled_bool";
+
+ /**
+ * A set of capabilities that should not be used even if it is reported by the visual voicemail
+ * IMAP CAPABILITY command.
+ */
+ public static final String KEY_VVM_DISABLED_CAPABILITIES_STRING_ARRAY =
+ "vvm_disabled_capabilities_string_array";
+
+ /**
+ * Whether legacy mode should be used when the visual voicemail client is disabled.
+ *
+ * <p>Legacy mode is a mode that on the carrier side visual voicemail is still activated, but on
+ * the client side all network operations are disabled. SMSs are still monitored so a new
+ * message SYNC SMS will be translated to show a message waiting indicator, like traditional
+ * voicemails.
+ *
+ * <p>This is for carriers that does not support VVM deactivation so voicemail can continue to
+ * function without the data cost.
+ */
+ public static final String KEY_VVM_LEGACY_MODE_ENABLED_BOOL =
+ "vvm_legacy_mode_enabled_bool";
+
+ /**
* Whether to prefetch audio data on new voicemail arrival, defaulted to true.
*/
public static final String KEY_VVM_PREFETCH_BOOL = "vvm_prefetch_bool";
@@ -611,10 +643,20 @@
/**
* The package name of the carrier's visual voicemail app to ensure that dialer visual voicemail
* and carrier visual voicemail are not active at the same time.
+ *
+ * @deprecated use {@link #KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY}.
*/
+ @Deprecated
public static final String KEY_CARRIER_VVM_PACKAGE_NAME_STRING = "carrier_vvm_package_name_string";
/**
+ * A list of the carrier's visual voicemail app package names to ensure that dialer visual
+ * voicemail and carrier visual voicemail are not active at the same time.
+ */
+ public static final String KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY =
+ "carrier_vvm_package_name_string_array";
+
+ /**
* Flag specifying whether ICCID is showed in SIM Status screen, default to false.
*/
public static final String KEY_SHOW_ICCID_IN_SIM_STATUS_BOOL = "show_iccid_in_sim_status_bool";
@@ -942,6 +984,20 @@
"carrier_default_actions_on_dcfailure_string_array";
/**
+ * Defines carrier-specific actions which act upon
+ * com.android.internal.telephony.CARRIER_SIGNAL_RESET, used for customization of the
+ * default carrier app
+ * Format: "CARRIER_ACTION_IDX, ..."
+ * Where {@code CARRIER_ACTION_IDX} is an integer defined in
+ * {@link com.android.carrierdefaultapp.CarrierActionUtils CarrierActionUtils}
+ * Example:
+ * {@link com.android.carrierdefaultapp.CarrierActionUtils
+ * #CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS clear all notifications on reset}
+ * @hide
+ */
+ public static final String KEY_CARRIER_DEFAULT_ACTIONS_ON_RESET =
+ "carrier_default_actions_on_reset_string_array";
+ /**
* Defines a list of acceptable redirection url for default carrier app
* @hides
*/
@@ -1344,8 +1400,13 @@
sDefaults.putInt(KEY_VVM_PORT_NUMBER_INT, 0);
sDefaults.putString(KEY_VVM_TYPE_STRING, "");
sDefaults.putBoolean(KEY_VVM_CELLULAR_DATA_REQUIRED_BOOL, false);
+ sDefaults.putString(KEY_VVM_CLIENT_PREFIX_STRING,"//VVM");
+ sDefaults.putBoolean(KEY_VVM_SSL_ENABLED_BOOL,false);
+ sDefaults.putStringArray(KEY_VVM_DISABLED_CAPABILITIES_STRING_ARRAY, null);
+ sDefaults.putBoolean(KEY_VVM_LEGACY_MODE_ENABLED_BOOL,false);
sDefaults.putBoolean(KEY_VVM_PREFETCH_BOOL, true);
sDefaults.putString(KEY_CARRIER_VVM_PACKAGE_NAME_STRING, "");
+ sDefaults.putStringArray(KEY_CARRIER_VVM_PACKAGE_NAME_STRING_ARRAY, null);
sDefaults.putBoolean(KEY_SHOW_ICCID_IN_SIM_STATUS_BOOL, false);
sDefaults.putBoolean(KEY_CI_ACTION_ON_SYS_UPDATE_BOOL, false);
sDefaults.putString(KEY_CI_ACTION_ON_SYS_UPDATE_INTENT_STRING, "");
@@ -1457,7 +1518,8 @@
sDefaults.putStringArray(KEY_CARRIER_APP_WAKE_SIGNAL_CONFIG_STRING_ARRAY,
new String[]{
"com.android.carrierdefaultapp/.CarrierDefaultBroadcastReceiver:" +
- "com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED"
+ "com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED," +
+ "com.android.internal.telephony.CARRIER_SIGNAL_RESET"
});
sDefaults.putStringArray(KEY_CARRIER_APP_NO_WAKE_SIGNAL_CONFIG_STRING_ARRAY, null);
@@ -1468,6 +1530,9 @@
//4: CARRIER_ACTION_DISABLE_METERED_APNS
//1: CARRIER_ACTION_SHOW_PORTAL_NOTIFICATION
});
+ sDefaults.putStringArray(KEY_CARRIER_DEFAULT_ACTIONS_ON_RESET, new String[]{
+ "6" //6: CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS
+ });
sDefaults.putStringArray(KEY_CARRIER_DEFAULT_REDIRECTION_URL_STRING_ARRAY, null);
// Rat families: {GPRS, EDGE}, {EVDO, EVDO_A, EVDO_B}, {UMTS, HSPA, HSDPA, HSUPA, HSPAP},
diff --git a/telephony/java/android/telephony/MbmsDownloadManager.java b/telephony/java/android/telephony/MbmsDownloadManager.java
index ad61d02..bb4bf1e 100644
--- a/telephony/java/android/telephony/MbmsDownloadManager.java
+++ b/telephony/java/android/telephony/MbmsDownloadManager.java
@@ -35,35 +35,29 @@
private int mSubId = INVALID_SUBSCRIPTION_ID;
/**
- * should use createManager to create/initialize a copy
+ * Create a new MbmsDownloadManager using the system default data subscription ID.
+ *
+ * Note that this call will bind a remote service and that may take a bit. This
+ * may throw an Illegal ArgumentException or RemoteException.
+ *
* @hide
*/
- public MbmsDownloadManager(Context context) {
+ public MbmsDownloadManager(Context context, IMbmsDownloadManagerListener listener,
+ String downloadAppName) {
mContext = context;
}
- public static MbmsDownloadManager createManager(Context context,
- IMbmsDownloadManagerListener listener, String downloadAppName) {
-// MbmsDownloadManager mdm = context.getSystemService(Context.MBMS_DOWNLOAD_SERVICE);
-// if (mdm == null) return mdm;
-// mdm.initialize(listener, downloadAppName,
-// SubscriptionManager.getDefaultSubscriptionId());
-// return mdm;
- return null;
- }
-
- public static MbmsDownloadManager createManager(Context context,
- IMbmsDownloadManagerListener listener, String downloadAppName, int subId) {
-// MbmsDownloadManager mdm = context.getSystemService(Context.MBMS_DOWNLOAD_SERVICE);
-// if (mdm == null) return mdm;
-// mdm.initialize(listener, downloadAppName, subId);
-// return mdm;
- return null;
- }
-
- private void initialize(IMbmsDownloadManagerListener listener, String downloadAppName,
- int subId) {
- // assert all empty and set
+ /**
+ * Create a new MbmsDownloadManager using the given subscription ID.
+ *
+ * Note that this call will bind a remote service and that may take a bit. This
+ * may throw an Illegal ArgumentException or RemoteException.
+ *
+ * @hide
+ */
+ public MbmsDownloadManager(Context context, IMbmsDownloadManagerListener listener,
+ String downloadAppName, int subId) {
+ mContext = context;
}
/**
@@ -71,6 +65,19 @@
* They may occur at times far in the future.
* servicesClasses lets the app filter on types of files and is opaque data between
* the app and the carrier
+ *
+ * Multiple calls replace trhe list of serviceClasses of interest.
+ *
+ * May throw an IllegalArgumentException or RemoteException.
+ *
+ * Synchronous responses include
+ * <li>SUCCESS</li>
+ * <li>ERROR_MSDC_CONCURRENT_SERVICE_LIMIT_REACHED</li>
+ *
+ * Asynchronous errors through the listener include any of the errors except
+ * <li>ERROR_MSDC_UNABLE_TO_)START_SERVICE</li>
+ * <li>ERROR_MSDC_INVALID_SERVICE_ID</li>
+ * <li>ERROR_MSDC_END_OF_SESSION</li>
*/
public int getFileServices(List<String> serviceClasses) {
return 0;
@@ -106,15 +113,39 @@
* of a currently occuring download. Note this can only run while the calling app
* is running, so future downloads will simply result in resultIntents being sent
* for completed or errored-out downloads. A NULL indicates no callbacks are needed.
+ *
+ * May throw an IllegalArgumentException or RemoteExcpetion.
+ *
+ * Asynchronous errors through the listener include any of the errors
*/
public DownloadRequest download(DownloadRequest downloadRequest, DownloadListener listener) {
return null;
}
+ /**
+ * Returns a list DownloadRequests that originated from this application (UID).
+ *
+ * May throw a RemoteException.
+ *
+ * Asynchronous errors through the listener include any of the errors except
+ * <li>ERROR_UNABLED_TO_START_SERVICE</li>
+ * <li>ERROR_MSDC_INVALID_SERVICE_ID</li>
+ * <li>ERROR_MSDC_END_OF_SESSION</li>
+ */
public List<DownloadRequest> listPendingDownloads() {
return null;
}
+ /**
+ * Attempts to cancel the specified DownloadRequest.
+ *
+ * May throw a RemoteException.
+ *
+ * Synchronous responses may include
+ * <li>SUCCESS</li>
+ * <li>ERROR_MSDC_CONCURRENT_SERVICE_LIMIT_REACHED</li>
+ * <li>ERROR_MSDC_UNKNOWN_REQUEST</li>
+ */
public int cancelDownload(DownloadRequest downloadRequest) {
return 0;
}
@@ -127,6 +158,10 @@
* Future downloads include counts of files with pending repair operations, counts of
* files with future downloads and indication of scheduled download times with unknown
* file details.
+ *
+ * May throw an IllegalArgumentException or RemoteException.
+ *
+ * If the DownloadRequest is unknown the results will be null.
*/
public DownloadStatus getDownloadStatus(DownloadRequest downloadRequest) {
return null;
@@ -140,8 +175,15 @@
* content, even if that content has since been deleted. If this function is called
* repeated content will be downloaded again when available. This does not interrupt
* in-progress downloads.
+ *
+ * May throw an IllegalArgumentException or RemoteException.
+ *
+ * <li>SUCCESS</li>
+ * <li>ERROR_MSDC_CONCURRENT_SERVICE_LIMIT_REACHED</li>
+ * <li>ERROR_MSDC_UNKNOWN_REQUEST</li>
*/
- public void resetDownloadKnowledge(DownloadRequest downloadRequest) {
+ public int resetDownloadKnowledge(DownloadRequest downloadRequest) {
+ return 0;
}
public void dispose() {
diff --git a/telephony/java/android/telephony/MbmsStreamingManager.java b/telephony/java/android/telephony/MbmsStreamingManager.java
index 0bcde2f..9a2ba6d 100644
--- a/telephony/java/android/telephony/MbmsStreamingManager.java
+++ b/telephony/java/android/telephony/MbmsStreamingManager.java
@@ -39,7 +39,7 @@
* Create a new MbmsStreamingManager using the system default data subscription ID.
*
* Note that this call will bind a remote service and that may take a bit. This
- * may throw an IllegalArgumentException.
+ * may throw an IllegalArgumentException or RemoteException.
*/
public MbmsStreamingManager(Context context, IMbmsStreamingManagerListener listener,
String streamingAppName) {
@@ -47,10 +47,10 @@
}
/**
- * Create a new MbmsStreamingManager using the give subscription ID.
+ * Create a new MbmsStreamingManager using the given subscription ID.
*
* Note that this call will bind a remote service and that may take a bit. This
- * may throw an IllegalArgumentException.
+ * may throw an IllegalArgumentException or RemoteException.
*/
public MbmsStreamingManager(Context context, IMbmsStreamingManagerListener listener,
String streamingAppName, int subId) {
@@ -72,10 +72,17 @@
* the app and the carrier.
*
* Multiple calls replace the list of serviceClasses of interest.
- * The return value is a success/error-code with the following possible values:
+ *
+ * May throw an IllegalArgumentException or RemoteException.
+ *
+ * Synchronous responses include
* <li>SUCCESS</li>
- * <li>NO_MIDDLEWARE</li>
- * <li>QUEUE_LIMIT</li>
+ * <li>ERROR_MSDC_CONCURRENT_SERVICE_LIMIT_REACHED</li>
+ *
+ * Asynchronous errors through the listener include any of the errors except
+ * <li>ERROR_MSDC_UNABLE_TO_)START_SERVICE</li>
+ * <li>ERROR_MSDC_INVALID_SERVICE_ID</li>
+ * <li>ERROR_MSDC_END_OF_SESSION</li>
*/
public int getStreamingServices(List<String> classList) {
return 0;
@@ -85,6 +92,9 @@
* Starts streaming a requested service, reporting status to the indicated listener.
* Returns an object used to control that stream.
*
+ * May throw an IllegalArgumentException or RemoteException.
+ *
+ * Asynchronous errors through the listener include any of the errors
*/
public StreamingService startStreaming(StreamingServiceInfo serviceInfo,
IStreamingServiceListener listener) {
@@ -96,10 +106,17 @@
* on this given subId. Results are returned asynchronously through the previously
* registered callback.
*
+ * May throw a RemoteException.
+ *
* The return value is a success/error-code with the following possible values:
* <li>SUCCESS</li>
- * <li>NO_MIDDLEWARE</li>
- * <li>QUEU_LIMIT</li>
+ * <li>ERROR_MSDC_CONCURRENT_SERVICE_LIMIT_REACHED</li>
+ *
+ * Asynchronous errors through the listener include any of the errors except
+ * <li>ERROR_UNABLED_TO_START_SERVICE</li>
+ * <li>ERROR_MSDC_INVALID_SERVICE_ID</li>
+ * <li>ERROR_MSDC_END_OF_SESSION</li>
+ *
*/
public int getActiveStreamingServices() {
return 0;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 1c020ae..5985813 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -16,24 +16,32 @@
package android.telephony;
+import static com.android.internal.util.Preconditions.checkNotNull;
+
import android.annotation.IntDef;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.WorkerThread;
+import android.annotation.SystemApi;
import android.app.ActivityThread;
+import android.app.PendingIntent;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.BatteryStats;
-import android.os.ResultReceiver;
+import android.os.Binder;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.os.Bundle;
+import android.os.Handler;
import android.os.PersistableBundle;
import android.os.RemoteException;
+import android.os.ResultReceiver;
import android.os.ServiceManager;
import android.os.SystemProperties;
import android.service.carrier.CarrierIdentifier;
@@ -61,6 +69,7 @@
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -838,6 +847,29 @@
*/
public static final String VVM_TYPE_CVVM = "vvm_type_cvvm";
+ /**
+ * @hide
+ */
+ public static final String USSD_RESPONSE = "USSD_RESPONSE";
+
+ /**
+ * USSD return code success.
+ * @hide
+ */
+ public static final int USSD_RETURN_SUCCESS = 100;
+
+ /**
+ * USSD return code for failure case.
+ * @hide
+ */
+ public static final int USSD_RETURN_FAILURE = -1;
+
+ /**
+ * USSD return code for failure case.
+ * @hide
+ */
+ public static final int USSD_ERROR_SERVICE_UNAVAIL = -2;
+
//
//
// Device Info
@@ -853,7 +885,7 @@
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getDeviceSoftwareVersion() {
- return getDeviceSoftwareVersion(getDefaultSim());
+ return getDeviceSoftwareVersion(getSlotIndex());
}
/**
@@ -939,7 +971,7 @@
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getImei() {
- return getImei(getDefaultSim());
+ return getImei(getSlotIndex());
}
/**
@@ -971,7 +1003,7 @@
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
public String getMeid() {
- return getMeid(getDefaultSim());
+ return getMeid(getSlotIndex());
}
/**
@@ -1001,7 +1033,7 @@
*/
/** {@hide}*/
public String getNai() {
- return getNai(getDefaultSim());
+ return getNai(getSlotIndex());
}
/**
@@ -1245,7 +1277,7 @@
}
private int getPhoneTypeFromProperty() {
- return getPhoneTypeFromProperty(getDefaultPhone());
+ return getPhoneTypeFromProperty(getPhoneId());
}
/** {@hide} */
@@ -1259,7 +1291,7 @@
}
private int getPhoneTypeFromNetworkType() {
- return getPhoneTypeFromNetworkType(getDefaultPhone());
+ return getPhoneTypeFromNetworkType(getPhoneId());
}
/** {@hide} */
@@ -1442,7 +1474,7 @@
* on a CDMA network).
*/
public String getNetworkOperator() {
- return getNetworkOperatorForPhone(getDefaultPhone());
+ return getNetworkOperatorForPhone(getPhoneId());
}
/**
@@ -1478,18 +1510,23 @@
/**
- * Returns the network specifier of the subscription ID pinned to the TelephonyManager.
+ * Returns the network specifier of the subscription ID pinned to the TelephonyManager. The
+ * network specifier is used by {@link
+ * android.net.NetworkRequest.Builder#setNetworkSpecifier(String)} to create a {@link
+ * android.net.NetworkRequest} that connects through the subscription.
*
* @see android.net.NetworkRequest.Builder#setNetworkSpecifier(String)
* @see #createForSubscriptionId(int)
* @see #createForPhoneAccountHandle(PhoneAccountHandle)
*/
public String getNetworkSpecifier() {
- return String.valueOf(mSubId);
+ return String.valueOf(getSubId());
}
/**
- * Returns the carrier config of the subscription ID pinned to the TelephonyManager.
+ * Returns the carrier config of the subscription ID pinned to the TelephonyManager. If an
+ * invalid subscription ID is pinned to the TelephonyManager, the returned config will contain
+ * default values.
*
* <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
* READ_PHONE_STATE}
@@ -1498,10 +1535,11 @@
* @see #createForSubscriptionId(int)
* @see #createForPhoneAccountHandle(PhoneAccountHandle)
*/
+ @WorkerThread
public PersistableBundle getCarrierConfig() {
CarrierConfigManager carrierConfigManager = mContext
.getSystemService(CarrierConfigManager.class);
- return carrierConfigManager.getConfigForSubId(mSubId);
+ return carrierConfigManager.getConfigForSubId(getSubId());
}
/**
@@ -1538,7 +1576,7 @@
* on a CDMA network).
*/
public String getNetworkCountryIso() {
- return getNetworkCountryIsoForPhone(getDefaultPhone());
+ return getNetworkCountryIsoForPhone(getPhoneId());
}
/**
@@ -1684,6 +1722,9 @@
* Returns a constant indicating the radio technology (network type)
* currently in use on the device for data transmission.
*
+ * If this object has been created with {@link #createForSubscriptionId}, applies to the given
+ * subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+ *
* <p>
* Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
@@ -1708,7 +1749,7 @@
* @see #NETWORK_TYPE_HSPAP
*/
public int getDataNetworkType() {
- return getDataNetworkType(getSubId());
+ return getDataNetworkType(getSubId(SubscriptionManager.getDefaultDataSubscriptionId()));
}
/**
@@ -1932,7 +1973,7 @@
* @return true if a ICC card is present
*/
public boolean hasIccCard() {
- return hasIccCard(getDefaultSim());
+ return hasIccCard(getSlotIndex());
}
/**
@@ -1973,7 +2014,7 @@
* @see #SIM_STATE_CARD_RESTRICTED
*/
public int getSimState() {
- int slotIndex = getDefaultSim();
+ int slotIndex = getSlotIndex();
// slotIndex may be invalid due to sim being absent. In that case query all slots to get
// sim state
if (slotIndex < 0) {
@@ -2102,7 +2143,7 @@
* @see #getSimState
*/
public String getSimOperatorName() {
- return getSimOperatorNameForPhone(getDefaultPhone());
+ return getSimOperatorNameForPhone(getPhoneId());
}
/**
@@ -2134,7 +2175,7 @@
* Returns the ISO country code equivalent for the SIM provider's country code.
*/
public String getSimCountryIso() {
- return getSimCountryIsoForPhone(getDefaultPhone());
+ return getSimCountryIsoForPhone(getPhoneId());
}
/**
@@ -2682,6 +2723,33 @@
return false;
}
+
+ /**
+ * Returns the package responsible of processing visual voicemail for the subscription ID pinned
+ * to the TelephonyManager. Returns {@code null} when there is no package responsible for
+ * processing visual voicemail for the subscription.
+ *
+ * <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
+ * READ_PHONE_STATE}
+ *
+ * @see #createForSubscriptionId(int)
+ * @see #createForPhoneAccountHandle(PhoneAccountHandle)
+ * @see VisualVoicemailService
+ */
+ @Nullable
+ public String getVisualVoicemailPackageName() {
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ return telephony
+ .getVisualVoicemailPackageName(mContext.getOpPackageName(), getSubId());
+ }
+ } catch (RemoteException ex) {
+ } catch (NullPointerException ex) {
+ }
+ return null;
+ }
+
/**
* Enables the visual voicemail SMS filter for a phone account. When the filter is
* enabled, Incoming SMS messages matching the OMTP VVM SMS interface will be redirected to the
@@ -2758,18 +2826,17 @@
/**
* @returns the settings of the visual voicemail SMS filter for a phone account set by the
- * package, or {@code null} if the filter is disabled.
+ * current active visual voicemail client, or {@code null} if the filter is disabled.
*
* <p>Requires the calling app to have READ_PRIVILEGED_PHONE_STATE permission.
*/
/** @hide */
@Nullable
- public VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(String packageName,
- int subId) {
+ public VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId) {
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
- return telephony.getSystemVisualVoicemailSmsFilterSettings(packageName, subId);
+ return telephony.getActiveVisualVoicemailSmsFilterSettings(subId);
}
} catch (RemoteException ex) {
} catch (NullPointerException ex) {
@@ -2779,6 +2846,35 @@
}
/**
+ * Send a visual voicemail SMS. The IPC caller must be the current default dialer.
+ *
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#SEND_SMS SEND_SMS}
+ *
+ * @param phoneAccountHandle The account to send the SMS with.
+ * @param number The destination number.
+ * @param port The destination port for data SMS, or 0 for text SMS.
+ * @param text The message content. For data sms, it will be encoded as a UTF-8 byte stream.
+ * @param sentIntent The sent intent passed to the {@link SmsManager}
+ *
+ * @see SmsManager#sendDataMessage(String, String, short, byte[], PendingIntent, PendingIntent)
+ * @see SmsManager#sendTextMessage(String, String, String, PendingIntent, PendingIntent)
+ *
+ * @hide
+ */
+ public void sendVisualVoicemailSmsForSubscriber(int subId, String number, int port,
+ String text, PendingIntent sentIntent) {
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ telephony.sendVisualVoicemailSmsForSubscriber(
+ mContext.getOpPackageName(), subId, number, port, text, sentIntent);
+ }
+ } catch (RemoteException ex) {
+ }
+ }
+
+ /**
* Initial SIM activation state, unknown. Not set by any carrier apps.
* @hide
*/
@@ -3924,35 +4020,67 @@
* subId is returned. Otherwise, the default subId will be returned.
*/
private int getSubId() {
- if (mSubId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
- return getDefaultSubscription();
+ if (SubscriptionManager.isUsableSubIdValue(mSubId)) {
+ return mSubId;
}
- return mSubId;
+ return SubscriptionManager.getDefaultSubscriptionId();
}
/**
- * Returns Default subscription.
+ * Return an appropriate subscription ID for any situation.
+ *
+ * If this object has been created with {@link #createForSubscriptionId}, then the provided
+ * subId is returned. Otherwise, the preferred subId which is based on caller's context is
+ * returned.
+ * {@see SubscriptionManager#getDefaultDataSubscriptionId()}
+ * {@see SubscriptionManager#getDefaultVoiceSubscriptionId()}
+ * {@see SubscriptionManager#getDefaultSmsSubscriptionId()}
*/
- private static int getDefaultSubscription() {
- return SubscriptionManager.getDefaultSubscriptionId();
+ private int getSubId(int preferredSubId) {
+ if (SubscriptionManager.isUsableSubIdValue(mSubId)) {
+ return mSubId;
+ }
+ return preferredSubId;
}
/**
- * Returns Default phone.
+ * Return an appropriate phone ID for any situation.
+ *
+ * If this object has been created with {@link #createForSubscriptionId}, then the phoneId
+ * associated with the provided subId is returned. Otherwise, the default phoneId associated
+ * with the default subId will be returned.
*/
- private static int getDefaultPhone() {
- return SubscriptionManager.getPhoneId(SubscriptionManager.getDefaultSubscriptionId());
+ private int getPhoneId() {
+ return SubscriptionManager.getPhoneId(getSubId());
}
/**
- * @return default SIM's slot index. If SIM is not inserted, return default SIM slot index.
+ * Return an appropriate phone ID for any situation.
+ *
+ * If this object has been created with {@link #createForSubscriptionId}, then the phoneId
+ * associated with the provided subId is returned. Otherwise, return the phoneId associated
+ * with the preferred subId based on caller's context.
+ * {@see SubscriptionManager#getDefaultDataSubscriptionId()}
+ * {@see SubscriptionManager#getDefaultVoiceSubscriptionId()}
+ * {@see SubscriptionManager#getDefaultSmsSubscriptionId()}
+ */
+ private int getPhoneId(int preferredSubId) {
+ return SubscriptionManager.getPhoneId(getSubId(preferredSubId));
+ }
+
+ /**
+ * Return an appropriate slot index for any situation.
+ *
+ * if this object has been created with {@link #createForSubscriptionId}, then the slot index
+ * associated with the provided subId is returned. Otherwise, return the slot index associated
+ * with the default subId.
+ * If SIM is not inserted, return default SIM slot index.
*
* {@hide}
*/
@VisibleForTesting
- public int getDefaultSim() {
- int slotIndex = SubscriptionManager.getSlotIndex(
- SubscriptionManager.getDefaultSubscriptionId());
+ public int getSlotIndex() {
+ int slotIndex = SubscriptionManager.getSlotIndex(getSubId());
if (slotIndex == SubscriptionManager.SIM_NOT_INSERTED) {
slotIndex = SubscriptionManager.DEFAULT_SIM_SLOT_INDEX;
}
@@ -4769,7 +4897,7 @@
/** @hide */
@SystemApi
public List<String> getCarrierPackageNamesForIntent(Intent intent) {
- return getCarrierPackageNamesForIntentAndPhone(intent, getDefaultPhone());
+ return getCarrierPackageNamesForIntentAndPhone(intent, getPhoneId());
}
/** @hide */
@@ -4965,6 +5093,80 @@
return new int[0];
}
+ public static abstract class OnReceiveUssdResponseCallback {
+ /**
+ ** Called when USSD has succeeded.
+ **/
+ public void onReceiveUssdResponse(String request, CharSequence response) {};
+
+ /**
+ ** Called when USSD has failed.
+ **/
+ public void onReceiveUssdResponseFailed(String request, int failureCode) {};
+ }
+
+ /**
+ * Sends an Unstructured Supplementary Service Data (USSD) request to the cellular network and
+ * informs the caller of the response via {@code callback}.
+ * <p>Carriers define USSD codes which can be sent by the user to request information such as
+ * the user's current data balance or minutes balance.
+ * <p>Requires permission:
+ * {@link android.Manifest.permission#CALL_PHONE}
+ * @param ussdRequest the USSD command to be executed.
+ * @param callback called by the framework to inform the caller of the result of executing the
+ * USSD request (see {@link OnReceiveUssdResponseCallback}).
+ * @param handler the {@link Handler} to run the request on.
+ */
+ @RequiresPermission(android.Manifest.permission.CALL_PHONE)
+ public void sendUssdRequest(String ussdRequest,
+ final OnReceiveUssdResponseCallback callback, Handler handler) {
+ checkNotNull(callback, "OnReceiveUssdResponseCallback cannot be null.");
+
+ ResultReceiver wrappedCallback = new ResultReceiver(handler) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle ussdResponse) {
+ Rlog.d(TAG, "USSD:" + resultCode);
+ checkNotNull(ussdResponse, "ussdResponse cannot be null.");
+ UssdResponse response = ussdResponse.getParcelable(USSD_RESPONSE);
+
+ if (resultCode == USSD_RETURN_SUCCESS) {
+ callback.onReceiveUssdResponse(response.getUssdRequest(),
+ response.getReturnMessage());
+ } else {
+ callback.onReceiveUssdResponseFailed(response.getUssdRequest(), resultCode);
+ }
+ }
+ };
+
+ try {
+ ITelephony telephony = getITelephony();
+ if (telephony != null) {
+ telephony.handleUssdRequest(getSubId(), ussdRequest, wrappedCallback);
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelephony#sendUSSDCode", e);
+ UssdResponse response = new UssdResponse(ussdRequest, "");
+ Bundle returnData = new Bundle();
+ returnData.putParcelable(USSD_RESPONSE, response);
+ wrappedCallback.send(USSD_ERROR_SERVICE_UNAVAIL, returnData);
+ }
+ }
+
+ /*
+ * @return true, if the device is currently on a technology (e.g. UMTS or LTE) which can support
+ * voice and data simultaneously. This can change based on location or network condition.
+ */
+ public boolean isConcurrentVoiceAndDataAllowed() {
+ try {
+ ITelephony telephony = getITelephony();
+ return (telephony == null ? false : telephony.isConcurrentVoiceAndDataAllowed(
+ getSubId()));
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelephony#isConcurrentVoiceAndDataAllowed", e);
+ }
+ return false;
+ }
+
/** @hide */
@SystemApi
public boolean handlePinMmi(String dialString) {
@@ -5095,6 +5297,8 @@
/**
* Turns mobile data on or off.
+ * If this object has been created with {@link #createForSubscriptionId}, applies to the given
+ * subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
*
* <p>Requires Permission:
* {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the
@@ -5105,7 +5309,7 @@
* @see #hasCarrierPrivileges
*/
public void setDataEnabled(boolean enable) {
- setDataEnabled(getSubId(), enable);
+ setDataEnabled(getSubId(SubscriptionManager.getDefaultDataSubscriptionId()), enable);
}
/** @hide */
@@ -5121,23 +5325,45 @@
}
}
+
+ /**
+ * @deprecated use {@link #isDataEnabled()} instead.
+ * @hide
+ */
+ @SystemApi
+ @Deprecated
+ public boolean getDataEnabled() {
+ return isDataEnabled();
+ }
+
/**
* Returns whether mobile data is enabled or not.
*
- * <p>Requires Permission:
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE ACCESS_NETWORK_STATE},
- * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}, or that the
- * calling app has carrier privileges.
+ * If this object has been created with {@link #createForSubscriptionId}, applies to the given
+ * subId. Otherwise, applies to {@link SubscriptionManager#getDefaultDataSubscriptionId()}
+ *
+ * <p>Requires one of the following permissions:
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE ACCESS_NETWORK_STATE},
+ * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}, or that the
+ * calling app has carrier privileges.
+ *
+ * <p>Note that this does not take into account any data restrictions that may be present on the
+ * calling app. Such restrictions may be inspected with
+ * {@link ConnectivityManager#getRestrictBackgroundStatus}.
*
* @return true if mobile data is enabled.
*
* @see #hasCarrierPrivileges
*/
- public boolean getDataEnabled() {
- return getDataEnabled(getSubId());
+ @SuppressWarnings("deprecation")
+ public boolean isDataEnabled() {
+ return getDataEnabled(getSubId(SubscriptionManager.getDefaultDataSubscriptionId()));
}
- /** @hide */
+ /**
+ * @deprecated use {@link #isDataEnabled(int)} instead.
+ * @hide
+ */
@SystemApi
public boolean getDataEnabled(int subId) {
boolean retVal = false;
@@ -5381,7 +5607,7 @@
* @hide
*/
public void setSimOperatorNumeric(String numeric) {
- int phoneId = getDefaultPhone();
+ int phoneId = getPhoneId();
setSimOperatorNumericForPhone(phoneId, numeric);
}
@@ -5401,7 +5627,7 @@
* @hide
*/
public void setSimOperatorName(String name) {
- int phoneId = getDefaultPhone();
+ int phoneId = getPhoneId();
setSimOperatorNameForPhone(phoneId, name);
}
@@ -5421,7 +5647,7 @@
* @hide
*/
public void setSimCountryIso(String iso) {
- int phoneId = getDefaultPhone();
+ int phoneId = getPhoneId();
setSimCountryIsoForPhone(phoneId, iso);
}
@@ -5441,7 +5667,7 @@
* @hide
*/
public void setSimState(String state) {
- int phoneId = getDefaultPhone();
+ int phoneId = getPhoneId();
setSimStateForPhone(phoneId, state);
}
@@ -5466,7 +5692,7 @@
* @hide
**/
public void setSimPowerState(boolean powerUp) {
- setSimPowerStateForSlot(getDefaultSim(), powerUp);
+ setSimPowerStateForSlot(getSlotIndex(), powerUp);
}
/**
@@ -5500,7 +5726,7 @@
* @hide
*/
public void setBasebandVersion(String version) {
- int phoneId = getDefaultPhone();
+ int phoneId = getPhoneId();
setBasebandVersionForPhone(phoneId, version);
}
@@ -5527,7 +5753,7 @@
* @hide
*/
public void setPhoneType(int type) {
- int phoneId = getDefaultPhone();
+ int phoneId = getPhoneId();
setPhoneType(phoneId, type);
}
@@ -5555,7 +5781,7 @@
* @hide
*/
public String getOtaSpNumberSchema(String defaultValue) {
- int phoneId = getDefaultPhone();
+ int phoneId = getPhoneId();
return getOtaSpNumberSchemaForPhone(phoneId, defaultValue);
}
@@ -5586,7 +5812,7 @@
* @hide
*/
public boolean getSmsReceiveCapable(boolean defaultValue) {
- int phoneId = getDefaultPhone();
+ int phoneId = getPhoneId();
return getSmsReceiveCapableForPhone(phoneId, defaultValue);
}
@@ -5617,7 +5843,7 @@
* @hide
*/
public boolean getSmsSendCapable(boolean defaultValue) {
- int phoneId = getDefaultPhone();
+ int phoneId = getPhoneId();
return getSmsSendCapableForPhone(phoneId, defaultValue);
}
@@ -5645,7 +5871,7 @@
* @hide
*/
public void setNetworkOperatorName(String name) {
- int phoneId = getDefaultPhone();
+ int phoneId = getPhoneId();
setNetworkOperatorNameForPhone(phoneId, name);
}
@@ -5667,7 +5893,7 @@
* @hide
*/
public void setNetworkOperatorNumeric(String numeric) {
- int phoneId = getDefaultPhone();
+ int phoneId = getPhoneId();
setNetworkOperatorNumericForPhone(phoneId, numeric);
}
@@ -5687,7 +5913,7 @@
* @hide
*/
public void setNetworkRoaming(boolean isRoaming) {
- int phoneId = getDefaultPhone();
+ int phoneId = getPhoneId();
setNetworkRoamingForPhone(phoneId, isRoaming);
}
@@ -5711,7 +5937,7 @@
* @hide
*/
public void setNetworkCountryIso(String iso) {
- int phoneId = getDefaultPhone();
+ int phoneId = getPhoneId();
setNetworkCountryIsoForPhone(phoneId, iso);
}
@@ -5731,11 +5957,15 @@
/**
* Set the network type currently in use on the device for data transmission.
+ *
+ * If this object has been created with {@link #createForSubscriptionId}, applies to the
+ * phoneId associated with the given subId. Otherwise, applies to the phoneId associated with
+ * {@link SubscriptionManager#getDefaultDataSubscriptionId()}
* @param type the network type currently in use on the device for data transmission
* @hide
*/
public void setDataNetworkType(int type) {
- int phoneId = getDefaultPhone();
+ int phoneId = getPhoneId(SubscriptionManager.getDefaultDataSubscriptionId());
setDataNetworkTypeForPhone(phoneId, type);
}
@@ -5907,7 +6137,7 @@
* @hide
*/
public String getAidForAppType(int appType) {
- return getAidForAppType(getDefaultSubscription(), appType);
+ return getAidForAppType(getSubId(), appType);
}
/**
@@ -5941,7 +6171,7 @@
* @hide
*/
public String getEsn() {
- return getEsn(getDefaultSubscription());
+ return getEsn(getSubId());
}
/**
@@ -5974,7 +6204,7 @@
* @hide
*/
public String getCdmaPrlVersion() {
- return getCdmaPrlVersion(getDefaultSubscription());
+ return getCdmaPrlVersion(getSubId());
}
/**
diff --git a/telephony/java/android/telephony/UssdResponse.aidl b/telephony/java/android/telephony/UssdResponse.aidl
new file mode 100644
index 0000000..add28a0
--- /dev/null
+++ b/telephony/java/android/telephony/UssdResponse.aidl
@@ -0,0 +1,20 @@
+/*
+**
+** Copyright 2007, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.telephony;
+
+parcelable UssdResponse;
diff --git a/telephony/java/android/telephony/UssdResponse.java b/telephony/java/android/telephony/UssdResponse.java
new file mode 100644
index 0000000..5df681d
--- /dev/null
+++ b/telephony/java/android/telephony/UssdResponse.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+/**
+ * Represents the Ussd response, including
+ * the message and the return code.
+ * @hide
+ */
+public final class UssdResponse implements Parcelable {
+ private CharSequence mReturnMessage;
+ private String mUssdRequest;
+
+
+ /**
+ * Implement the Parcelable interface
+ */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mUssdRequest);
+ TextUtils.writeToParcel(mReturnMessage, dest, 0);
+ }
+
+ public String getUssdRequest() {
+ return mUssdRequest;
+ }
+
+ public CharSequence getReturnMessage() {
+ return mReturnMessage;
+ }
+
+ /**
+ * Implement the Parcelable interface
+ */
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * * Initialize the object from the request and return message.
+ */
+ public UssdResponse(String ussdRequest, CharSequence returnMessage) {
+ mUssdRequest = ussdRequest;
+ mReturnMessage = returnMessage;
+ }
+
+ public static final Parcelable.Creator<UssdResponse> CREATOR = new Creator<UssdResponse>() {
+
+ @Override
+ public UssdResponse createFromParcel(Parcel in) {
+ String request = in.readString();
+ CharSequence message = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+ return new UssdResponse(request, message);
+ }
+
+ @Override
+ public UssdResponse[] newArray(int size) {
+ return new UssdResponse[size];
+ }
+ };
+}
diff --git a/telephony/java/android/telephony/VisualVoicemailService.java b/telephony/java/android/telephony/VisualVoicemailService.java
new file mode 100644
index 0000000..84833e3
--- /dev/null
+++ b/telephony/java/android/telephony/VisualVoicemailService.java
@@ -0,0 +1,281 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.MainThread;
+import android.annotation.SdkConstant;
+import android.app.PendingIntent;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.RemoteException;
+import android.telecom.PhoneAccountHandle;
+import android.telecom.TelecomManager;
+import android.util.Log;
+
+/**
+ * This service is implemented by dialer apps that wishes to handle OMTP or similar visual
+ * voicemails. Telephony binds to this service when the cell service is first connected, a visual
+ * voicemail SMS has been received, or when a SIM has been removed. Telephony will only bind to the
+ * default dialer for such events (See {@link TelecomManager#getDefaultDialerPackage()}). The
+ * {@link android.service.carrier.CarrierMessagingService} precedes the VisualVoicemailService in
+ * the SMS filtering chain and may intercept the visual voicemail SMS before it reaches this
+ * service.
+ * <p>
+ * Below is an example manifest registration for a {@code VisualVoicemailService}.
+ * <pre>
+ * {@code
+ * <service android:name="your.package.YourVisualVoicemailServiceImplementation"
+ * android:permission="android.permission.BIND_VISUAL_VOICEMAIL_SERVICE">
+ * <intent-filter>
+ * <action android:name="android.telephony.VisualVoicemailService"/>
+ * </intent-filter>
+ * </service>
+ * }
+ * </pre>
+ */
+public abstract class VisualVoicemailService extends Service {
+
+ private static final String TAG = "VvmService";
+
+ /**
+ * The {@link Intent} that must be declared as handled by the service.
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+ public static final String SERVICE_INTERFACE = "android.telephony.VisualVoicemailService";
+
+ /**
+ * @hide
+ */
+ public static final int MSG_ON_CELL_SERVICE_CONNECTED = 1;
+ /**
+ * @hide
+ */
+ public static final int MSG_ON_SMS_RECEIVED = 2;
+ /**
+ * @hide
+ */
+ public static final int MSG_ON_SIM_REMOVED = 3;
+ /**
+ * @hide
+ */
+ public static final int MSG_TASK_ENDED = 4;
+ /**
+ * @hide
+ */
+ public static final int MSG_TASK_STOPPED = 5;
+
+ /**
+ * @hide
+ */
+ public static final String DATA_PHONE_ACCOUNT_HANDLE = "data_phone_account_handle";
+ /**
+ * @hide
+ */
+ public static final String DATA_SMS = "data_sms";
+
+ /**
+ * Represents a visual voicemail event which needs to be handled. While the task is being
+ * processed telephony will hold a wakelock for the VisualVoicemailService. The service can
+ * unblock the main thread and pass the task to a worker thread. Once the task is finished,
+ * {@link VisualVoicemailTask#finish()} should be called to signal telephony to release the
+ * resources. Telephony will call {@link VisualVoicemailService#onStopped(VisualVoicemailTask)}
+ * when the task is going to be terminated before completion.
+ *
+ * @see #onCellServiceConnected(VisualVoicemailTask, PhoneAccountHandle)
+ * @see #onSmsReceived(VisualVoicemailTask, VisualVoicemailSms)
+ * @see #onSimRemoved(VisualVoicemailTask, PhoneAccountHandle)
+ * @see #onStopped(VisualVoicemailTask)
+ */
+ public static class VisualVoicemailTask {
+
+ private final int mTaskId;
+ private final Messenger mReplyTo;
+
+ private VisualVoicemailTask(Messenger replyTo, int taskId) {
+ mTaskId = taskId;
+ mReplyTo = replyTo;
+ }
+
+ /**
+ * Call to signal telephony the task has completed. Must be called for every task.
+ */
+ public final void finish() {
+ Message message = Message.obtain();
+ try {
+ message.what = MSG_TASK_ENDED;
+ message.arg1 = mTaskId;
+ mReplyTo.send(message);
+ } catch (RemoteException e) {
+ Log.e(TAG,
+ "Cannot send MSG_TASK_ENDED, remote handler no longer exist");
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof VisualVoicemailTask)) {
+ return false;
+ }
+ return mTaskId == ((VisualVoicemailTask) obj).mTaskId;
+ }
+
+ @Override
+ public int hashCode() {
+ return mTaskId;
+ }
+ }
+
+ /**
+ * Handles messages sent by telephony.
+ */
+ private final Messenger mMessenger = new Messenger(new Handler() {
+ @Override
+ public void handleMessage(final Message msg) {
+ final PhoneAccountHandle handle = msg.getData()
+ .getParcelable(DATA_PHONE_ACCOUNT_HANDLE);
+ VisualVoicemailTask task = new VisualVoicemailTask(msg.replyTo, msg.arg1);
+ switch (msg.what) {
+ case MSG_ON_CELL_SERVICE_CONNECTED:
+ onCellServiceConnected(task, handle);
+ break;
+ case MSG_ON_SMS_RECEIVED:
+ VisualVoicemailSms sms = msg.getData().getParcelable(DATA_SMS);
+ onSmsReceived(task, sms);
+ break;
+ case MSG_ON_SIM_REMOVED:
+ onSimRemoved(task, handle);
+ break;
+ case MSG_TASK_STOPPED:
+ onStopped(task);
+ break;
+ default:
+ super.handleMessage(msg);
+ break;
+ }
+ }
+ });
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return mMessenger.getBinder();
+ }
+
+ /**
+ * Called when the cellular service is connected on a {@link PhoneAccountHandle} for the first
+ * time, or when the carrier config has changed. It will not be called when the signal is lost
+ * then restored.
+ *
+ * @param task The task representing this event. {@link VisualVoicemailTask#finish()} must be
+ * called when the task is completed.
+ * @param phoneAccountHandle The {@link PhoneAccountHandle} triggering this event.
+ */
+ @MainThread
+ public abstract void onCellServiceConnected(VisualVoicemailTask task,
+ PhoneAccountHandle phoneAccountHandle);
+
+ /**
+ * Called when a SMS matching the {@link VisualVoicemailSmsFilterSettings} set by
+ * {@link #setSmsFilterSettings(Context, PhoneAccountHandle, VisualVoicemailSmsFilterSettings)}
+ * is received.
+ *
+ * @param task The task representing this event. {@link VisualVoicemailTask#finish()} must be
+ * called when the task is completed.
+ * @param sms The content of the received SMS.
+ */
+ @MainThread
+ public abstract void onSmsReceived(VisualVoicemailTask task,
+ VisualVoicemailSms sms);
+
+ /**
+ * Called when a SIM is removed.
+ *
+ * @param task The task representing this event. {@link VisualVoicemailTask#finish()} must be
+ * called when the task is completed.
+ * @param phoneAccountHandle The {@link PhoneAccountHandle} triggering this event.
+ */
+ @MainThread
+ public abstract void onSimRemoved(VisualVoicemailTask task,
+ PhoneAccountHandle phoneAccountHandle);
+
+ /**
+ * Called before the system is about to terminate a task. The service should persist any
+ * necessary data and call finish on the task immediately.
+ */
+ @MainThread
+ public abstract void onStopped(VisualVoicemailTask task);
+
+ /**
+ * Set the visual voicemail SMS filter settings for the VisualVoicemailService.
+ * {@link #onSmsReceived(VisualVoicemailTask, VisualVoicemailSms)} will be called when
+ * a SMS matching the settings is received. The caller should have
+ * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} and implements a
+ * VisualVoicemailService.
+ * <p>
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+ *
+ * @param phoneAccountHandle The account to apply the settings to.
+ * @param settings The settings for the filter, or {@code null} to disable the filter.
+ */
+ public final static void setSmsFilterSettings(Context context,
+ PhoneAccountHandle phoneAccountHandle,
+ VisualVoicemailSmsFilterSettings settings) {
+ TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
+ int subId = getSubId(context, phoneAccountHandle);
+ if (settings == null) {
+ telephonyManager.disableVisualVoicemailSmsFilter(subId);
+ } else {
+ telephonyManager.enableVisualVoicemailSmsFilter(subId, settings);
+ }
+ }
+
+ /**
+ * Send a visual voicemail SMS. The caller must be the current default dialer.
+ * <p>
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#SEND_SMS SEND_SMS}
+ *
+ * @param phoneAccountHandle The account to send the SMS with.
+ * @param number The destination number.
+ * @param port The destination port for data SMS, or 0 for text SMS.
+ * @param text The message content. For data sms, it will be encoded as a UTF-8 byte stream.
+ * @param sentIntent The sent intent passed to the {@link SmsManager}
+ * @see SmsManager#sendDataMessage(String, String, short, byte[], PendingIntent, PendingIntent)
+ * @see SmsManager#sendTextMessage(String, String, String, PendingIntent, PendingIntent)
+ */
+ public final static void sendVisualVoicemailSms(Context context,
+ PhoneAccountHandle phoneAccountHandle, String number,
+ short port, String text, PendingIntent sentIntent) {
+ TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
+ telephonyManager.sendVisualVoicemailSmsForSubscriber(getSubId(context, phoneAccountHandle),
+ number, port, text, sentIntent);
+ }
+
+ private static int getSubId(Context context, PhoneAccountHandle phoneAccountHandle) {
+ TelephonyManager telephonyManager = context.getSystemService(TelephonyManager.class);
+ TelecomManager telecomManager = context.getSystemService(TelecomManager.class);
+ return telephonyManager
+ .getSubIdForPhoneAccount(telecomManager.getPhoneAccount(phoneAccountHandle));
+ }
+
+}
diff --git a/telephony/java/android/telephony/VisualVoicemailSms.java b/telephony/java/android/telephony/VisualVoicemailSms.java
new file mode 100644
index 0000000..1e6ea4b
--- /dev/null
+++ b/telephony/java/android/telephony/VisualVoicemailSms.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony;
+
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.telecom.PhoneAccountHandle;
+import android.telephony.VisualVoicemailService.VisualVoicemailTask;
+
+/**
+ * Represents the content of a visual voicemail SMS. If a incoming SMS matches the {@link
+ * VisualVoicemailSmsFilterSettings} set by the default dialer, {@link
+ * VisualVoicemailService#onSmsReceived(VisualVoicemailTask, VisualVoicemailSms)} will be called.
+ */
+public final class VisualVoicemailSms implements Parcelable {
+
+ private final PhoneAccountHandle mPhoneAccountHandle;
+ @Nullable
+ private final String mPrefix;
+
+ @Nullable
+ private final Bundle mFields;
+
+ private final String mMessageBody;
+
+ VisualVoicemailSms(Builder builder) {
+ mPhoneAccountHandle = builder.mPhoneAccountHandle;
+ mPrefix = builder.mPrefix;
+ mFields = builder.mFields;
+ mMessageBody = builder.mMessageBody;
+ }
+
+ /**
+ * The {@link PhoneAccountHandle} that received the SMS.
+ */
+ public PhoneAccountHandle getPhoneAccountHandle() {
+ return mPhoneAccountHandle;
+ }
+
+ /**
+ * The event type of the SMS or {@code null} if the framework cannot parse the SMS as voicemail
+ * but the carrier pattern indicates it is. Common values are "SYNC" or "STATUS".
+ */
+ public String getPrefix() {
+ return mPrefix;
+ }
+
+ /**
+ * The key-value pairs sent by the SMS, or {@code null} if the framework cannot parse the SMS as
+ * voicemail but the carrier pattern indicates it is. The interpretation of the fields is
+ * carrier dependent.
+ */
+ public Bundle getFields() {
+ return mFields;
+ }
+
+ /**
+ * Raw message body of the received SMS.
+ */
+ public String getMessageBody() {
+ return mMessageBody;
+ }
+
+ /**
+ * Builder for the {@link VisualVoicemailSms}. Internal use only.
+ *
+ * @hide
+ */
+ public static class Builder {
+
+ private PhoneAccountHandle mPhoneAccountHandle;
+ private String mPrefix;
+ private Bundle mFields;
+ private String mMessageBody;
+
+ public VisualVoicemailSms build() {
+ return new VisualVoicemailSms(this);
+ }
+
+ public Builder setPhoneAccountHandle(PhoneAccountHandle phoneAccountHandle) {
+ this.mPhoneAccountHandle = phoneAccountHandle;
+ return this;
+ }
+
+ public Builder setPrefix(String prefix) {
+ this.mPrefix = prefix;
+ return this;
+ }
+
+ public Builder setFields(Bundle fields) {
+ this.mFields = fields;
+ return this;
+ }
+
+ public Builder setMessageBody(String messageBody) {
+ this.mMessageBody = messageBody;
+ return this;
+ }
+
+ }
+
+
+ public static final Creator<VisualVoicemailSms> CREATOR =
+ new Creator<VisualVoicemailSms>() {
+ @Override
+ public VisualVoicemailSms createFromParcel(Parcel in) {
+ return new Builder()
+ .setPhoneAccountHandle((PhoneAccountHandle) in.readParcelable(null))
+ .setPrefix(in.readString())
+ .setFields(in.readBundle())
+ .setMessageBody(in.readString())
+ .build();
+ }
+
+ @Override
+ public VisualVoicemailSms[] newArray(int size) {
+ return new VisualVoicemailSms[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeParcelable(getPhoneAccountHandle(), flags);
+ dest.writeString(getPrefix());
+ dest.writeBundle(getFields());
+ dest.writeString(getMessageBody());
+ }
+}
diff --git a/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java b/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java
index 5b81027..56a8c62 100644
--- a/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java
+++ b/telephony/java/android/telephony/VisualVoicemailSmsFilterSettings.java
@@ -15,9 +15,12 @@
*/
package android.telephony;
+import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telecom.PhoneAccountHandle;
+import android.telephony.VisualVoicemailService.VisualVoicemailTask;
import java.util.Collections;
import java.util.List;
@@ -28,42 +31,44 @@
* <p>[clientPrefix]:[prefix]:([key]=[value];)*
*
* <p>will be regarded as a visual voicemail SMS, and removed before reaching the SMS provider. The
- * intent {@link android.provider.VoicemailContract#ACTION_VOICEMAIL_SMS_RECEIVED} will then be sent
- * to the default dialer with the information extracted from the SMS.
+ * {@link VisualVoicemailService} in the current default dialer will be bound and
+ * {@link VisualVoicemailService#onSmsReceived(VisualVoicemailTask, VisualVoicemailSms)}
+ * will called with the information extracted from the SMS.
*
* <p>Use {@link android.telephony.VisualVoicemailSmsFilterSettings.Builder} to construct this
* class.
*
- * @see android.telephony.TelephonyManager#enableVisualVoicemailSmsFilter
- *
- * @hide
+ * @see VisualVoicemailService#setSmsFilterSettings(Context, PhoneAccountHandle, VisualVoicemailSmsFilterSettings)
*/
-public class VisualVoicemailSmsFilterSettings implements Parcelable {
+public final class VisualVoicemailSmsFilterSettings implements Parcelable {
/**
* The visual voicemail SMS message does not have to be a data SMS, and can be directed to any
* port.
- *
- * @hide
*/
public static final int DESTINATION_PORT_ANY = -1;
/**
* The visual voicemail SMS message can be directed to any port, but must be a data SMS.
- *
- * @hide
*/
public static final int DESTINATION_PORT_DATA_SMS = -2;
+ /**
+ * @hide
+ */
public static final String DEFAULT_CLIENT_PREFIX = "//VVM";
+ /**
+ * @hide
+ */
public static final List<String> DEFAULT_ORIGINATING_NUMBERS = Collections.emptyList();
+ /**
+ * @hide
+ */
public static final int DEFAULT_DESTINATION_PORT = DESTINATION_PORT_ANY;
/**
* Builder class for {@link VisualVoicemailSmsFilterSettings} objects.
- *
- * @hide
*/
public static class Builder {
@@ -171,4 +176,13 @@
dest.writeInt(destinationPort);
}
+ @Override
+ public String toString(){
+ return "[VisualVoicemailSmsFilterSettings "
+ + "clientPrefix=" + clientPrefix
+ + ", originatingNumbers=" + originatingNumbers
+ + ", destinationPort=" + destinationPort
+ + "]";
+ }
+
}
diff --git a/telephony/java/android/telephony/ims/ImsServiceProxy.java b/telephony/java/android/telephony/ims/ImsServiceProxy.java
index 38ea6e6f..a75cd86 100644
--- a/telephony/java/android/telephony/ims/ImsServiceProxy.java
+++ b/telephony/java/android/telephony/ims/ImsServiceProxy.java
@@ -120,7 +120,7 @@
public int startSession(PendingIntent incomingCallIntent, IImsRegistrationListener listener)
throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
return getServiceInterface(mBinder).startSession(mSlotId, mSupportedFeature,
incomingCallIntent, listener);
}
@@ -129,7 +129,7 @@
@Override
public void endSession(int sessionId) throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
getServiceInterface(mBinder).endSession(mSlotId, mSupportedFeature, sessionId);
}
}
@@ -138,7 +138,7 @@
public boolean isConnected(int callServiceType, int callType)
throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
return getServiceInterface(mBinder).isConnected(mSlotId, mSupportedFeature,
callServiceType, callType);
}
@@ -147,7 +147,7 @@
@Override
public boolean isOpened() throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
return getServiceInterface(mBinder).isOpened(mSlotId, mSupportedFeature);
}
}
@@ -156,7 +156,7 @@
public void addRegistrationListener(IImsRegistrationListener listener)
throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
getServiceInterface(mBinder).addRegistrationListener(mSlotId, mSupportedFeature,
listener);
}
@@ -166,7 +166,7 @@
public void removeRegistrationListener(IImsRegistrationListener listener)
throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
getServiceInterface(mBinder).removeRegistrationListener(mSlotId, mSupportedFeature,
listener);
}
@@ -176,7 +176,7 @@
public ImsCallProfile createCallProfile(int sessionId, int callServiceType, int callType)
throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
return getServiceInterface(mBinder).createCallProfile(mSlotId, mSupportedFeature,
sessionId, callServiceType, callType);
}
@@ -186,7 +186,7 @@
public IImsCallSession createCallSession(int sessionId, ImsCallProfile profile,
IImsCallSessionListener listener) throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
return getServiceInterface(mBinder).createCallSession(mSlotId, mSupportedFeature,
sessionId, profile, listener);
}
@@ -196,7 +196,7 @@
public IImsCallSession getPendingCallSession(int sessionId, String callId)
throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
return getServiceInterface(mBinder).getPendingCallSession(mSlotId, mSupportedFeature,
sessionId, callId);
}
@@ -205,7 +205,7 @@
@Override
public IImsUt getUtInterface() throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
return getServiceInterface(mBinder).getUtInterface(mSlotId, mSupportedFeature);
}
}
@@ -213,7 +213,7 @@
@Override
public IImsConfig getConfigInterface() throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
return getServiceInterface(mBinder).getConfigInterface(mSlotId, mSupportedFeature);
}
}
@@ -221,7 +221,7 @@
@Override
public void turnOnIms() throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
getServiceInterface(mBinder).turnOnIms(mSlotId, mSupportedFeature);
}
}
@@ -229,7 +229,7 @@
@Override
public void turnOffIms() throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
getServiceInterface(mBinder).turnOffIms(mSlotId, mSupportedFeature);
}
}
@@ -237,7 +237,7 @@
@Override
public IImsEcbm getEcbmInterface() throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
return getServiceInterface(mBinder).getEcbmInterface(mSlotId, mSupportedFeature);
}
}
@@ -246,7 +246,7 @@
public void setUiTTYMode(int uiTtyMode, Message onComplete)
throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
getServiceInterface(mBinder).setUiTTYMode(mSlotId, mSupportedFeature, uiTtyMode,
onComplete);
}
@@ -255,7 +255,7 @@
@Override
public IImsMultiEndpoint getMultiEndpointInterface() throws RemoteException {
synchronized (mLock) {
- checkBinderConnection();
+ checkServiceIsReady();
return getServiceInterface(mBinder).getMultiEndpointInterface(mSlotId,
mSupportedFeature);
}
@@ -264,7 +264,8 @@
@Override
public int getFeatureStatus() {
synchronized (mLock) {
- if (mFeatureStatusCached != null) {
+ if (isBinderAlive() && mFeatureStatusCached != null) {
+ Log.i(LOG_TAG, "getFeatureStatus - returning cached: " + mFeatureStatusCached);
return mFeatureStatusCached;
}
}
@@ -277,6 +278,7 @@
// Cache only non-null value for feature status.
mFeatureStatusCached = status;
}
+ Log.i(LOG_TAG, "getFeatureStatus - returning " + status);
return status;
}
@@ -301,10 +303,28 @@
mStatusCallback = c;
}
+ /**
+ * @return Returns true if the ImsService is ready to take commands, false otherwise. If this
+ * method returns false, it doesn't mean that the Binder connection is not available (use
+ * {@link #isBinderReady()} to check that), but that the ImsService is not accepting commands
+ * at this time.
+ *
+ * For example, for DSDS devices, only one slot can be {@link ImsFeature#STATE_READY} to take
+ * commands at a time, so the other slot must stay at {@link ImsFeature#STATE_NOT_AVAILABLE}.
+ */
+ public boolean isBinderReady() {
+ return isBinderAlive() && getFeatureStatus() == ImsFeature.STATE_READY;
+ }
+
@Override
public boolean isBinderAlive() {
- return mIsAvailable && getFeatureStatus() == ImsFeature.STATE_READY && mBinder != null &&
- mBinder.isBinderAlive();
+ return mIsAvailable && mBinder != null && mBinder.isBinderAlive();
+ }
+
+ protected void checkServiceIsReady() throws RemoteException {
+ if (!isBinderReady()) {
+ throw new RemoteException("ImsServiceProxy is not ready to accept commands.");
+ }
}
private IImsServiceController getServiceInterface(IBinder b) {
diff --git a/telephony/java/android/telephony/ims/feature/ImsFeature.java b/telephony/java/android/telephony/ims/feature/ImsFeature.java
index 988dd58..395f1cc 100644
--- a/telephony/java/android/telephony/ims/feature/ImsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/ImsFeature.java
@@ -150,7 +150,7 @@
private void notifyFeatureState(@ImsState int state) {
if (mStatusCallback != null) {
try {
- Log.i(LOG_TAG, "notifying ImsFeatureState");
+ Log.i(LOG_TAG, "notifying ImsFeatureState=" + state);
mStatusCallback.notifyImsFeatureStatus(state);
} catch (RemoteException e) {
mStatusCallback = null;
diff --git a/telephony/java/android/telephony/mbms/StreamingService.java b/telephony/java/android/telephony/mbms/StreamingService.java
index f93b1a8..ee0d894 100644
--- a/telephony/java/android/telephony/mbms/StreamingService.java
+++ b/telephony/java/android/telephony/mbms/StreamingService.java
@@ -37,7 +37,9 @@
}
/**
- * Retreive the Uri used to play this stream
+ * Retreive the Uri used to play this stream.
+ *
+ * This may throw a RemoteException.
*/
public Uri getPlaybackUri() {
return null;
@@ -52,6 +54,8 @@
/**
* Retreive the current state of this stream.
+ *
+ * This may throw a RemoteException.
*/
public int getState() {
return STATE_STOPPED;
@@ -59,12 +63,19 @@
/**
* Stop streaming this service. Terminal.
+ *
+ * This may throw a RemoteException.
*/
public void stopStreaming() {
}
/**
* Switch this stream to a different service. Used for smooth transitions.
+ *
+ * This may throw a RemoteException.
+ *
+ * Asynchronous errors through the listener include any of the errors except
+ * <li>ERROR_MSDC_UNABLE_TO_INITIALIZE</li>
*/
public void switchStream(StreamingServiceInfo streamingServiceInfo) {
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index c6b750e..f2e1e26 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -16,6 +16,7 @@
package com.android.internal.telephony;
+import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.os.ResultReceiver;
@@ -273,6 +274,16 @@
*/
boolean handlePinMmi(String dialString);
+
+ /**
+ * Handles USSD commands.
+ *
+ * @param subId The subscription to use.
+ * @param ussdRequest the USSD command to be executed.
+ * @param wrappedCallback receives a callback result.
+ */
+ void handleUssdRequest(int subId, String ussdRequest, in ResultReceiver wrappedCallback);
+
/**
* Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated
* without SEND (so <code>dial</code> is not appropriate) for
@@ -481,12 +492,20 @@
*/
int getVoiceMessageCountForSubscriber(int subId);
+ /**
+ * Returns true if current state supports both voice and data
+ * simultaneously. This can change based on location or network condition.
+ */
+ boolean isConcurrentVoiceAndDataAllowed(int subId);
+
oneway void setVisualVoicemailEnabled(String callingPackage,
in PhoneAccountHandle accountHandle, boolean enabled);
boolean isVisualVoicemailEnabled(String callingPackage,
in PhoneAccountHandle accountHandle);
+ String getVisualVoicemailPackageName(String callingPackage, int subId);
+
// Not oneway, caller needs to make sure the vaule is set before receiving a SMS
void enableVisualVoicemailSmsFilter(String callingPackage, int subId,
in VisualVoicemailSmsFilterSettings settings);
@@ -497,9 +516,18 @@
VisualVoicemailSmsFilterSettings getVisualVoicemailSmsFilterSettings(String callingPackage,
int subId);
- // Get settings set by the package, requires READ_PRIVILEGED_PHONE_STATE permission
- VisualVoicemailSmsFilterSettings getSystemVisualVoicemailSmsFilterSettings(String packageName,
- int subId);
+ /**
+ * Get settings set by the current default dialer, Internal use only.
+ * Requires READ_PRIVILEGED_PHONE_STATE permission.
+ */
+ VisualVoicemailSmsFilterSettings getActiveVisualVoicemailSmsFilterSettings(int subId);
+
+ /**
+ * Send a visual voicemail SMS. Internal use only.
+ * Requires caller to be the default dialer and have SEND_SMS permission
+ */
+ oneway void sendVisualVoicemailSmsForSubscriber(in String callingPackage, in int subId,
+ in String number, in int port, in String text, in PendingIntent sentIntent);
/**
* Returns the network type for data transmission
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 1e1d7a6..954b17f 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -414,6 +414,7 @@
int RIL_REQUEST_SEND_DEVICE_STATE = 138;
int RIL_REQUEST_SET_UNSOLICITED_RESPONSE_FILTER = 139;
int RIL_REQUEST_SET_SIM_CARD_POWER = 140;
+ int RIL_REQUEST_SET_CARRIER_INFO_IMSI_ENCRYPTION = 141;
int RIL_RESPONSE_ACKNOWLEDGEMENT = 800;
@@ -465,4 +466,5 @@
int RIL_UNSOL_STK_CC_ALPHA_NOTIFY = 1044;
int RIL_UNSOL_LCEDATA_RECV = 1045;
int RIL_UNSOL_PCO_DATA = 1046;
+ int RIL_UNSOL_CARRIER_INFO_IMSI_ENCRYPTION = 1047;
}
diff --git a/telephony/java/com/android/internal/telephony/TelephonyIntents.java b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
index ce4e7e2..55a8b0b 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyIntents.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyIntents.java
@@ -402,7 +402,7 @@
* <ul>
* <li>apnType</li><dd>A string with the apn type.</dd>
* <li>redirectionUrl</li><dd>redirection url string</dd>
- * <li>subId</dt><li>Sub Id which associated the data connection failure.</dd>
+ * <li>subId</li><dd>Sub Id which associated the data connection failure.</dd>
* </ul>
* <p class="note">This is a protected intent that can only be sent by the system.</p>
*/
@@ -415,7 +415,7 @@
* <ul>
* <li>apnType</li><dd>A string with the apn type.</dd>
* <li>errorCode</li><dd>A integer with dataFailCause.</dd>
- * <li>subId</dt><li>Sub Id which associated the data connection failure.</dd>
+ * <li>subId</li><dd>Sub Id which associated the data connection failure.</dd>
* </ul>
* <p class="note">This is a protected intent that can only be sent by the system. </p>
*/
@@ -432,13 +432,25 @@
* IPV4V6)</dd>
* <li>pcoId</li><dd>An integer indicating the pco id for the data.</dd>
* <li>pcoValue</li><dd>A byte array of pco data read from modem.</dd>
- * <li>subId</dt><li>Sub Id which associated the data connection.</dd>
+ * <li>subId</li><dd>Sub Id which associated the data connection.</dd>
* </ul>
* <p class="note">This is a protected intent that can only be sent by the system. </p>
*/
public static final String ACTION_CARRIER_SIGNAL_PCO_VALUE =
"com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE";
+ /**
+ * <p>Broadcast Action: when framework reset all carrier actions on sim load or absent.
+ * intended for carrier apps clean up (clear UI e.g.) and only sent to the specified carrier app
+ * The intent will have the following extra values:</p>
+ * <ul>
+ * <li>subId</li><dd>Sub Id which associated the data connection failure.</dd>
+ * </ul>
+ * <p class="note">This is a protected intent that can only be sent by the system.</p>
+ */
+ public static final String ACTION_CARRIER_SIGNAL_RESET =
+ "com.android.internal.telephony.CARRIER_SIGNAL_RESET";
+
// CARRIER_SIGNAL_ACTION extra keys
public static final String EXTRA_REDIRECTION_URL_KEY = "redirectionUrl";
public static final String EXTRA_ERROR_CODE_KEY = "errorCode";
diff --git a/tests/net/java/android/net/nsd/NsdManagerTest.java b/tests/net/java/android/net/nsd/NsdManagerTest.java
index 2418450..b8ed766 100644
--- a/tests/net/java/android/net/nsd/NsdManagerTest.java
+++ b/tests/net/java/android/net/nsd/NsdManagerTest.java
@@ -18,6 +18,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.reset;
@@ -42,6 +43,8 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.function.Consumer;
+
@RunWith(AndroidJUnit4.class)
@SmallTest
public class NsdManagerTest {
@@ -101,7 +104,71 @@
verify(listener1, timeout(mTimeoutMs).times(1)).onServiceResolved(reply);
verify(listener2, timeout(mTimeoutMs).times(1)).onServiceResolved(reply);
- }
+ }
+
+ @Test
+ public void testInvalidCalls() {
+ NsdManager manager = new NsdManager(mContext, mService);
+
+ NsdManager.RegistrationListener listener1 = mock(NsdManager.RegistrationListener.class);
+ NsdManager.DiscoveryListener listener2 = mock(NsdManager.DiscoveryListener.class);
+ NsdManager.ResolveListener listener3 = mock(NsdManager.ResolveListener.class);
+
+ NsdServiceInfo invalidService = new NsdServiceInfo(null, null);
+ NsdServiceInfo validService = new NsdServiceInfo("a_name", "a_type");
+ validService.setPort(2222);
+
+ int protocol = NsdManager.PROTOCOL_DNS_SD;
+
+ // Service registration
+ // - invalid arguments
+ mustFail(() -> { manager.unregisterService(null); });
+ mustFail(() -> { manager.registerService(null, -1, null); });
+ mustFail(() -> { manager.registerService(null, protocol, listener1); });
+ mustFail(() -> { manager.registerService(invalidService, protocol, listener1); });
+ mustFail(() -> { manager.registerService(validService, -1, listener1); });
+ mustFail(() -> { manager.registerService(validService, protocol, null); });
+ manager.registerService(validService, protocol, listener1);
+ // - listener already registered
+ mustFail(() -> { manager.registerService(validService, protocol, listener1); });
+ manager.unregisterService(listener1);
+ // TODO: make listener immediately reusable
+ //mustFail(() -> { manager.unregisterService(listener1); });
+ //manager.registerService(validService, protocol, listener1);
+
+ // Discover service
+ // - invalid arguments
+ mustFail(() -> { manager.stopServiceDiscovery(null); });
+ mustFail(() -> { manager.discoverServices(null, -1, null); });
+ mustFail(() -> { manager.discoverServices(null, protocol, listener2); });
+ mustFail(() -> { manager.discoverServices("a_service", -1, listener2); });
+ mustFail(() -> { manager.discoverServices("a_service", protocol, null); });
+ manager.discoverServices("a_service", protocol, listener2);
+ // - listener already registered
+ mustFail(() -> { manager.discoverServices("another_service", protocol, listener2); });
+ manager.stopServiceDiscovery(listener2);
+ // TODO: make listener immediately reusable
+ //mustFail(() -> { manager.stopServiceDiscovery(listener2); });
+ //manager.discoverServices("another_service", protocol, listener2);
+
+ // Resolver service
+ // - invalid arguments
+ mustFail(() -> { manager.resolveService(null, null); });
+ mustFail(() -> { manager.resolveService(null, listener3); });
+ mustFail(() -> { manager.resolveService(invalidService, listener3); });
+ mustFail(() -> { manager.resolveService(validService, null); });
+ manager.resolveService(validService, listener3);
+ // - listener already registered:w
+ mustFail(() -> { manager.resolveService(validService, listener3); });
+ }
+
+ public void mustFail(Runnable fn) {
+ try {
+ fn.run();
+ fail();
+ } catch (Exception expected) {
+ }
+ }
NsdManager makeManager() {
NsdManager manager = new NsdManager(mContext, mService);
diff --git a/tests/net/java/android/net/nsd/NsdServiceTest.java b/tests/net/java/android/net/nsd/NsdServiceTest.java
new file mode 100644
index 0000000..acc390c
--- /dev/null
+++ b/tests/net/java/android/net/nsd/NsdServiceTest.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.test.TestLooper;
+import android.content.Context;
+import android.content.ContentResolver;
+import android.net.nsd.NsdManager;
+import com.android.server.NsdService.DaemonConnection;
+import com.android.server.NsdService.DaemonConnectionSupplier;
+import com.android.server.NsdService.NativeCallbackReceiver;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+// TODOs:
+// - test client disconnects
+// - test client can send requests and receive replies
+// - test NSD_ON ENABLE/DISABLED listening
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class NsdServiceTest {
+
+ @Mock Context mContext;
+ @Mock ContentResolver mResolver;
+ @Mock NsdService.NsdSettings mSettings;
+ @Mock DaemonConnection mDaemon;
+ NativeCallbackReceiver mDaemonCallback;
+ TestLooper mLooper;
+ TestHandler mHandler;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mLooper = new TestLooper();
+ mHandler = new TestHandler(mLooper.getLooper());
+ when(mContext.getContentResolver()).thenReturn(mResolver);
+ }
+
+ @Test
+ public void testClientsCanConnect() {
+ when(mSettings.isEnabled()).thenReturn(true);
+
+ NsdService service = makeService();
+
+ NsdManager client1 = connectClient(service);
+ verify(mDaemon, timeout(100).times(1)).execute("start-service");
+
+ NsdManager client2 = connectClient(service);
+
+ // TODO: disconnect client1
+ // TODO: disconnect client2
+ }
+
+ NsdService makeService() {
+ DaemonConnectionSupplier supplier = (callback) -> {
+ mDaemonCallback = callback;
+ return mDaemon;
+ };
+ NsdService service = new NsdService(mContext, mSettings, mHandler, supplier);
+ verify(mDaemon, never()).execute(any(String.class));
+ return service;
+ }
+
+ NsdManager connectClient(NsdService service) {
+ mLooper.startAutoDispatch();
+ NsdManager client = new NsdManager(mContext, service);
+ mLooper.stopAutoDispatch();
+ return client;
+ }
+
+ public static class TestHandler extends Handler {
+ public Message lastMessage;
+
+ TestHandler(Looper looper) {
+ super(looper);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ lastMessage = obtainMessage();
+ lastMessage.copyFrom(msg);
+ }
+ }
+}
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 1be8d5e..5173278 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -1993,6 +1993,40 @@
}
@SmallTest
+ public void testNetworkSpecifierUidSpoofSecurityException() {
+ class UidAwareNetworkSpecifier extends NetworkSpecifier implements Parcelable {
+ @Override
+ public boolean satisfiedBy(NetworkSpecifier other) {
+ return true;
+ }
+
+ @Override
+ public void assertValidFromUid(int requestorUid) {
+ throw new SecurityException("failure");
+ }
+
+ @Override
+ public int describeContents() { return 0; }
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {}
+ }
+
+ mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
+ mWiFiNetworkAgent.connect(false);
+
+ UidAwareNetworkSpecifier networkSpecifier = new UidAwareNetworkSpecifier();
+ NetworkRequest networkRequest = newWifiRequestBuilder().setNetworkSpecifier(
+ networkSpecifier).build();
+ TestNetworkCallback networkCallback = new TestNetworkCallback();
+ try {
+ mCm.requestNetwork(networkRequest, networkCallback);
+ fail("Network request with spoofed UID did not throw a SecurityException");
+ } catch (SecurityException e) {
+ // expected
+ }
+ }
+
+ @SmallTest
public void testRegisterDefaultNetworkCallback() throws Exception {
final TestNetworkCallback defaultNetworkCallback = new TestNetworkCallback();
mCm.registerDefaultNetworkCallback(defaultNetworkCallback);
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index b2c1244..7a1c239 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -236,6 +236,9 @@
verify(mNMService, times(1)).setIpForwardingEnabled(true);
verify(mNMService, times(1)).startTethering(any(String[].class));
verifyNoMoreInteractions(mNMService);
+ verify(mWifiManager).updateInterfaceIpState(
+ mTestIfname, WifiManager.IFACE_IP_MODE_LOCAL_ONLY);
+ verifyNoMoreInteractions(mWifiManager);
verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_ACTIVE_LOCAL_ONLY);
// UpstreamNetworkMonitor will be started, and will register two callbacks:
// a "listen all" and a "track default".
@@ -261,6 +264,7 @@
verify(mNMService, times(1)).stopTethering();
verify(mNMService, times(1)).setIpForwardingEnabled(false);
verifyNoMoreInteractions(mNMService);
+ verifyNoMoreInteractions(mWifiManager);
// Asking for the last error after the per-interface state machine
// has been reaped yields an unknown interface error.
assertEquals(ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE,
@@ -292,6 +296,9 @@
verify(mNMService, times(1)).setIpForwardingEnabled(true);
verify(mNMService, times(1)).startTethering(any(String[].class));
verifyNoMoreInteractions(mNMService);
+ verify(mWifiManager).updateInterfaceIpState(
+ mTestIfname, WifiManager.IFACE_IP_MODE_TETHERED);
+ verifyNoMoreInteractions(mWifiManager);
verifyTetheringBroadcast(mTestIfname, ConnectivityManager.EXTRA_ACTIVE_TETHER);
// UpstreamNetworkMonitor will be started, and will register two callbacks:
// a "listen all" and a "track default".
@@ -338,6 +345,7 @@
verify(mNMService, times(1)).stopTethering();
verify(mNMService, times(1)).setIpForwardingEnabled(false);
verifyNoMoreInteractions(mNMService);
+ verifyNoMoreInteractions(mWifiManager);
// Asking for the last error after the per-interface state machine
// has been reaped yields an unknown interface error.
assertEquals(ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE,
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 69e1029..ad9f9b8 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -125,6 +125,8 @@
void setWifiApEnabled(in WifiConfiguration wifiConfig, boolean enable);
+ void updateInterfaceIpState(String ifaceName, int mode);
+
boolean startSoftAp(in WifiConfiguration wifiConfig);
boolean stopSoftAp();
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index ae8a224..b7fe9c7 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -20,7 +20,6 @@
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
-import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.net.ConnectivityManager;
@@ -46,9 +45,9 @@
import com.android.server.net.NetworkPinner;
import java.net.InetAddress;
+import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
-import java.util.Collections;
/**
* This class provides the primary API for managing all aspects of Wi-Fi
@@ -446,6 +445,35 @@
* @hide
*/
public static final int SAP_START_FAILURE_NO_CHANNEL = 1;
+
+ /**
+ * Interface IP mode for configuration error.
+ *
+ * @see updateInterfaceIpState(String, int)
+ *
+ * @hide
+ */
+ public static final int IFACE_IP_MODE_CONFIGURATION_ERROR = 0;
+
+ /**
+ * Interface IP mode for tethering.
+ *
+ * @see updateInterfaceIpState(String, int)
+ *
+ * @hide
+ */
+ public static final int IFACE_IP_MODE_TETHERED = 1;
+
+ /**
+ * Interface IP mode for Local Only Hotspot.
+ *
+ * @see updateInterfaceIpState(String, int)
+ *
+ * @hide
+ */
+ public static final int IFACE_IP_MODE_LOCAL_ONLY = 2;
+
+
/**
* Broadcast intent action indicating that a connection to the supplicant has
* been established (and it is now possible
@@ -1718,6 +1746,26 @@
}
/**
+ * Call allowing ConnectivityService to update WifiService with interface mode changes.
+ *
+ * The possible modes include: {@link IFACE_IP_MODE_TETHERED},
+ * {@link IFACE_IP_MODE_LOCAL_ONLY},
+ * {@link IFACE_IP_MODE_CONFIGURATION_ERROR}
+ *
+ * @param ifaceName String name of the updated interface
+ * @param mode int representing the new mode
+ *
+ * @hide
+ */
+ public void updateInterfaceIpState(String ifaceName, int mode) {
+ try {
+ mService.updateInterfaceIpState(ifaceName, mode);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Start SoftAp mode with the specified configuration.
* Note that starting in access point mode disables station
* mode operation
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
index 3fcbd4b..b9ce61c 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
@@ -31,6 +31,7 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
import android.util.SparseArray;
@@ -453,7 +454,8 @@
peerHandle != null ? peerHandle.peerId : 0, // 0 is an invalid peer ID
null, // peerMac (not used in this method)
pmk,
- passphrase);
+ passphrase,
+ Process.myUid());
}
/** @hide */
@@ -490,7 +492,8 @@
0, // 0 is an invalid peer ID
peer,
pmk,
- passphrase);
+ passphrase,
+ Process.myUid());
}
private static class WifiAwareEventCallbackProxy extends IWifiAwareEventCallback.Stub {
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
index 5993480..e152f6c 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareNetworkSpecifier.java
@@ -19,6 +19,7 @@
import android.net.NetworkSpecifier;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.Log;
import java.util.Arrays;
import java.util.Objects;
@@ -115,9 +116,18 @@
*/
public final String passphrase;
+ /**
+ * The UID of the process initializing this network specifier. Validated by receiver using
+ * checkUidIfNecessary() and is used by satisfiedBy() to determine whether matches the
+ * offered network.
+ *
+ * @hide
+ */
+ public final int requestorUid;
+
/** @hide */
public WifiAwareNetworkSpecifier(int type, int role, int clientId, int sessionId, int peerId,
- byte[] peerMac, byte[] pmk, String passphrase) {
+ byte[] peerMac, byte[] pmk, String passphrase, int requestorUid) {
this.type = type;
this.role = role;
this.clientId = clientId;
@@ -126,6 +136,7 @@
this.peerMac = peerMac;
this.pmk = pmk;
this.passphrase = passphrase;
+ this.requestorUid = requestorUid;
}
public static final Creator<WifiAwareNetworkSpecifier> CREATOR =
@@ -140,7 +151,8 @@
in.readInt(), // peerId
in.createByteArray(), // peerMac
in.createByteArray(), // pmk
- in.readString()); // passphrase
+ in.readString(), // passphrase
+ in.readInt()); // requestorUid
}
@Override
@@ -164,6 +176,7 @@
dest.writeByteArray(peerMac);
dest.writeByteArray(pmk);
dest.writeString(passphrase);
+ dest.writeInt(requestorUid);
}
/** @hide */
@@ -186,6 +199,7 @@
result = 31 * result + Arrays.hashCode(peerMac);
result = 31 * result + Arrays.hashCode(pmk);
result = 31 * result + Objects.hashCode(passphrase);
+ result = 31 * result + requestorUid;
return result;
}
@@ -210,7 +224,8 @@
&& peerId == lhs.peerId
&& Arrays.equals(peerMac, lhs.peerMac)
&& Arrays.equals(pmk, lhs.pmk)
- && Objects.equals(passphrase, lhs.passphrase);
+ && Objects.equals(passphrase, lhs.passphrase)
+ && requestorUid == lhs.requestorUid;
}
/** @hide */
@@ -228,7 +243,16 @@
.append(", pmk=").append((pmk == null) ? "<null>" : "<non-null>")
// masking PII
.append(", passphrase=").append((passphrase == null) ? "<null>" : "<non-null>")
+ .append(", requestorUid=").append(requestorUid)
.append("]");
return sb.toString();
}
+
+ /** @hide */
+ @Override
+ public void assertValidFromUid(int requestorUid) {
+ if (this.requestorUid != requestorUid) {
+ throw new SecurityException("mismatched UIDs");
+ }
+ }
}