Merge "make carrier default app direct boot aware"
diff --git a/api/current.txt b/api/current.txt
index b5a99ca..db44f3b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -6694,6 +6694,7 @@
method public android.bluetooth.le.BluetoothLeScanner getBluetoothLeScanner();
method public java.util.Set<android.bluetooth.BluetoothDevice> getBondedDevices();
method public static synchronized android.bluetooth.BluetoothAdapter getDefaultAdapter();
+ method public int getLeMaximumAdvertisingDataLength();
method public java.lang.String getName();
method public android.bluetooth.le.PeriodicAdvertisingManager getPeriodicAdvertisingManager();
method public int getProfileConnectionState(int);
@@ -7076,9 +7077,7 @@
public final class BluetoothDevice implements android.os.Parcelable {
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.BluetoothGattCallbackExt);
- method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallbackExt, int);
- method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallbackExt, int, int);
+ method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int);
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;
@@ -7174,12 +7173,8 @@
field public static final int GATT_WRITE_NOT_PERMITTED = 3; // 0x3
}
- public abstract deprecated class BluetoothGattCallback extends android.bluetooth.BluetoothGattCallbackExt {
+ public abstract class BluetoothGattCallback {
ctor public BluetoothGattCallback();
- }
-
- public abstract class BluetoothGattCallbackExt {
- ctor public BluetoothGattCallbackExt();
method public void onCharacteristicChanged(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic);
method public void onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int);
method public void onCharacteristicWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int);
@@ -7288,12 +7283,8 @@
method public void setPreferredPhy(android.bluetooth.BluetoothDevice, int, int, int);
}
- public abstract deprecated class BluetoothGattServerCallback extends android.bluetooth.BluetoothGattServerCallbackExt {
+ public abstract class BluetoothGattServerCallback {
ctor public BluetoothGattServerCallback();
- }
-
- public abstract class BluetoothGattServerCallbackExt {
- ctor public BluetoothGattServerCallbackExt();
method public void onCharacteristicReadRequest(android.bluetooth.BluetoothDevice, int, int, android.bluetooth.BluetoothGattCharacteristic);
method public void onCharacteristicWriteRequest(android.bluetooth.BluetoothDevice, int, android.bluetooth.BluetoothGattCharacteristic, boolean, boolean, int, byte[]);
method public void onConnectionStateChange(android.bluetooth.BluetoothDevice, int, int);
@@ -7505,11 +7496,11 @@
}
public final class AdvertisingSet {
- method public void enableAdvertising(boolean);
- method public void periodicAdvertisingEnable(boolean);
+ method public void enableAdvertising(boolean, int);
method public void setAdvertisingData(android.bluetooth.le.AdvertiseData);
method public void setAdvertisingParameters(android.bluetooth.le.AdvertisingSetParameters);
method public void setPeriodicAdvertisingData(android.bluetooth.le.AdvertiseData);
+ method public void setPeriodicAdvertisingEnable(boolean);
method public void setPeriodicAdvertisingParameters(android.bluetooth.le.PeriodicAdvertisingParameters);
method public void setScanResponseData(android.bluetooth.le.AdvertiseData);
}
@@ -7518,11 +7509,11 @@
ctor public AdvertisingSetCallback();
method public void onAdvertisingDataSet(android.bluetooth.le.AdvertisingSet, int);
method public void onAdvertisingEnabled(android.bluetooth.le.AdvertisingSet, boolean, int);
- method public void onAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int);
- method public void onAdvertisingSetStarted(android.bluetooth.le.AdvertisingSet, int);
+ method public void onAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int, int);
+ method public void onAdvertisingSetStarted(android.bluetooth.le.AdvertisingSet, int, int);
method public void onAdvertisingSetStopped(android.bluetooth.le.AdvertisingSet);
method public void onPeriodicAdvertisingDataSet(android.bluetooth.le.AdvertisingSet, int);
- method public void onPeriodicAdvertisingEnable(android.bluetooth.le.AdvertisingSet, boolean, int);
+ method public void onPeriodicAdvertisingEnabled(android.bluetooth.le.AdvertisingSet, boolean, int);
method public void onPeriodicAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int);
method public void onScanResponseDataSet(android.bluetooth.le.AdvertisingSet, int);
field public static final int ADVERTISE_FAILED_ALREADY_STARTED = 3; // 0x3
@@ -7538,12 +7529,12 @@
method public int getInterval();
method public int getPrimaryPhy();
method public int getSecondaryPhy();
- method public int getTimeout();
method public int getTxPowerLevel();
method public boolean includeTxPower();
method public boolean isAnonymous();
method public boolean isConnectable();
method public boolean isLegacy();
+ method public boolean isScannable();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertisingSetParameters> CREATOR;
field public static final int INTERVAL_HIGH = 160; // 0xa0
@@ -7565,14 +7556,14 @@
public static final class AdvertisingSetParameters.Builder {
ctor public AdvertisingSetParameters.Builder();
method public android.bluetooth.le.AdvertisingSetParameters build();
- method public android.bluetooth.le.AdvertisingSetParameters.Builder setAnonymouus(boolean);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setAnonymous(boolean);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setConnectable(boolean);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setIncludeTxPower(boolean);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setInterval(int);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setLegacyMode(boolean);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setPrimaryPhy(int);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setScannable(boolean);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setSecondaryPhy(int);
- method public android.bluetooth.le.AdvertisingSetParameters.Builder setTimeout(int);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setTxPowerLevel(int);
}
@@ -7581,6 +7572,8 @@
method public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback);
method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
+ method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, android.bluetooth.le.AdvertisingSetCallback);
+ method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
method public void stopAdvertising(android.bluetooth.le.AdvertiseCallback);
method public void stopAdvertisingSet(android.bluetooth.le.AdvertisingSetCallback);
}
@@ -23812,7 +23805,9 @@
method public boolean isDefaultNetworkActive();
method public static deprecated boolean isNetworkTypeValid(int);
method public void registerDefaultNetworkCallback(android.net.ConnectivityManager.NetworkCallback);
+ method public void registerDefaultNetworkCallback(android.net.ConnectivityManager.NetworkCallback, android.os.Handler);
method public void registerNetworkCallback(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback);
+ method public void registerNetworkCallback(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback, android.os.Handler);
method public void registerNetworkCallback(android.net.NetworkRequest, android.app.PendingIntent);
method public void releaseNetworkRequest(android.app.PendingIntent);
method public void removeDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
@@ -23821,6 +23816,8 @@
method public boolean requestBandwidthUpdate(android.net.Network);
method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback);
method public void requestNetwork(android.net.NetworkRequest, int, android.net.ConnectivityManager.NetworkCallback);
+ method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback, android.os.Handler);
+ method public void requestNetwork(android.net.NetworkRequest, int, android.net.ConnectivityManager.NetworkCallback, android.os.Handler);
method public void requestNetwork(android.net.NetworkRequest, android.app.PendingIntent);
method public deprecated boolean requestRouteToHost(int, int);
method public deprecated void setNetworkPreference(int);
@@ -25011,7 +25008,7 @@
public class WifiManager {
method public int addNetwork(android.net.wifi.WifiConfiguration);
- method public boolean addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
+ method public void addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
method public static int calculateSignalLevel(int, int);
method public void cancelWps(android.net.wifi.WifiManager.WpsCallback);
method public static int compareSignalLevel(int, int);
@@ -25040,7 +25037,7 @@
method public boolean reassociate();
method public boolean reconnect();
method public boolean removeNetwork(int);
- method public boolean removePasspointConfiguration(java.lang.String);
+ method public void removePasspointConfiguration(java.lang.String);
method public deprecated boolean saveConfiguration();
method public void setTdlsEnabled(java.net.InetAddress, boolean);
method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
@@ -25055,26 +25052,22 @@
field public static final java.lang.String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
field public static final java.lang.String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE";
field public static final int ERROR_AUTHENTICATING = 1; // 0x1
+ field public static final java.lang.String EXTRA_ANQP_ELEMENT_DATA = "android.net.wifi.extra.ANQP_ELEMENT_DATA";
field public static final java.lang.String EXTRA_BSSID = "bssid";
+ field public static final java.lang.String EXTRA_BSSID_LONG = "android.net.wifi.extra.BSSID_LONG";
+ field public static final java.lang.String EXTRA_DELAY = "android.net.wifi.extra.DELAY";
+ field public static final java.lang.String EXTRA_ESS = "android.net.wifi.extra.ESS";
+ field public static final java.lang.String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME";
+ field public static final java.lang.String EXTRA_ICON = "android.net.wifi.extra.ICON";
field public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
field public static final java.lang.String EXTRA_NEW_RSSI = "newRssi";
field public static final java.lang.String EXTRA_NEW_STATE = "newState";
- field public static final java.lang.String EXTRA_PASSPOINT_DEAUTH_IMMINENT_BSSID = "android.net.wifi.extra.PASSPOINT_DEAUTH_IMMINENT_BSSID";
- field public static final java.lang.String EXTRA_PASSPOINT_DEAUTH_IMMINENT_ESS = "android.net.wifi.extra.PASSPOINT_DEAUTH_IMMINENT_ESS";
- field public static final java.lang.String EXTRA_PASSPOINT_DEAUTH_IMMINENT_REASON_URL = "android.net.wifi.extra.PASSPOINT_DEAUTH_IMMINENT_REASON_URL";
- field public static final java.lang.String EXTRA_PASSPOINT_DEAUTH_IMMINENT_REAUTH_DELAY = "android.net.wifi.extra.PASSPOINT_DEAUTH_IMMINENT_REAUTH_DELAY";
- field public static final java.lang.String EXTRA_PASSPOINT_ICON_BSSID = "android.net.wifi.extra.PASSPOINT_ICON_BSSID";
- field public static final java.lang.String EXTRA_PASSPOINT_ICON_DATA = "android.net.wifi.extra.PASSPOINT_ICON_DATA";
- field public static final java.lang.String EXTRA_PASSPOINT_ICON_FILENAME = "android.net.wifi.extra.PASSPOINT_ICON_FILENAME";
- field public static final java.lang.String EXTRA_PASSPOINT_OSU_PROVIDERS_LIST_BSSID = "android.net.wifi.extra.PASSPOINT_OSU_PROVIDERS_LIST_BSSID";
- field public static final java.lang.String EXTRA_PASSPOINT_OSU_PROVIDERS_LIST_DATA = "android.net.wifi.extra.PASSPOINT_OSU_PROVIDERS_LIST_DATA";
- field public static final java.lang.String EXTRA_PASSPOINT_SUBSCRIPTION_REMEDIATION_BSSID = "android.net.wifi.extra.PASSPOINT_SUBSCRIPTION_REMEDIATION_BSSID";
- field public static final java.lang.String EXTRA_PASSPOINT_SUBSCRIPTION_REMEDIATION_SERVER_METHOD = "android.net.wifi.extra.PASSPOINT_SUBSCRIPTION_REMEDIATION_SERVER_METHOD";
- field public static final java.lang.String EXTRA_PASSPOINT_SUBSCRIPTION_REMEDIATION_SERVER_URL = "android.net.wifi.extra.PASSPOINT_SUBSCRIPTION_REMEDIATION_SERVER_URL";
field public static final java.lang.String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state";
field public static final java.lang.String EXTRA_RESULTS_UPDATED = "resultsUpdated";
+ field public static final java.lang.String EXTRA_SUBSCRIPTION_REMEDIATION_METHOD = "android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD";
field public static final java.lang.String EXTRA_SUPPLICANT_CONNECTED = "connected";
field public static final java.lang.String EXTRA_SUPPLICANT_ERROR = "supplicantError";
+ field public static final java.lang.String EXTRA_URL = "android.net.wifi.extra.URL";
field public static final java.lang.String EXTRA_WIFI_INFO = "wifiInfo";
field public static final java.lang.String EXTRA_WIFI_STATE = "wifi_state";
field public static final java.lang.String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED";
@@ -25293,7 +25286,6 @@
method public void setUsageLimitStartTimeInMs(long);
method public void setUsageLimitTimeLimitInMinutes(long);
method public void setUsageLimitUsageTimePeriodInMinutes(long);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.PasspointConfiguration> CREATOR;
}
@@ -25334,7 +25326,6 @@
method public void setRealm(java.lang.String);
method public void setSimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
method public void setUserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential> CREATOR;
}
@@ -25347,7 +25338,6 @@
method public java.lang.String getCertType();
method public void setCertSha256Fingerprint(byte[]);
method public void setCertType(java.lang.String);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.CertificateCredential> CREATOR;
}
@@ -25360,7 +25350,6 @@
method public java.lang.String getImsi();
method public void setEapType(int);
method public void setImsi(java.lang.String);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.SimCredential> CREATOR;
}
@@ -25383,7 +25372,6 @@
method public void setPassword(java.lang.String);
method public void setSoftTokenApp(java.lang.String);
method public void setUsername(java.lang.String);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.UserCredential> CREATOR;
}
@@ -25408,7 +25396,6 @@
method public void setMatchAnyOis(long[]);
method public void setOtherHomePartners(java.lang.String[]);
method public void setRoamingConsortiumOis(long[]);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.HomeSp> CREATOR;
}
@@ -25435,7 +25422,6 @@
method public void setPolicyUpdate(android.net.wifi.hotspot2.pps.UpdateParameter);
method public void setPreferredRoamingPartnerList(java.util.List<android.net.wifi.hotspot2.pps.Policy.RoamingPartner>);
method public void setRequiredProtoPortMap(java.util.Map<java.lang.Integer, java.lang.String>);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Policy> CREATOR;
}
@@ -25452,7 +25438,6 @@
method public void setFqdn(java.lang.String);
method public void setFqdnExactMatch(boolean);
method public void setPriority(int);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Policy.RoamingPartner> CREATOR;
}
@@ -25477,7 +25462,6 @@
method public void setUpdateIntervalInMinutes(long);
method public void setUpdateMethod(java.lang.String);
method public void setUsername(java.lang.String);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.UpdateParameter> CREATOR;
field public static final long UPDATE_CHECK_INTERVAL_NEVER = 4294967295L; // 0xffffffffL
@@ -38207,13 +38191,17 @@
method public boolean getDataEnabled();
method public int getDataNetworkType();
method public int getDataState();
- method public java.lang.String getDeviceId();
- method public java.lang.String getDeviceId(int);
+ method public deprecated java.lang.String getDeviceId();
+ method public deprecated java.lang.String getDeviceId(int);
method public java.lang.String getDeviceSoftwareVersion();
method public java.lang.String[] getForbiddenPlmns();
method public java.lang.String getGroupIdLevel1();
method public java.lang.String getIccAuthentication(int, int, java.lang.String);
+ method public java.lang.String getImei();
+ method public java.lang.String getImei(int);
method public java.lang.String getLine1Number();
+ method public java.lang.String getMeid();
+ method public java.lang.String getMeid(int);
method public java.lang.String getMmsUAProfUrl();
method public java.lang.String getMmsUserAgent();
method public deprecated java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo();
@@ -53163,6 +53151,7 @@
public class GenericSignatureFormatError extends java.lang.ClassFormatError {
ctor public GenericSignatureFormatError();
+ ctor public GenericSignatureFormatError(java.lang.String);
}
public abstract interface InvocationHandler {
diff --git a/api/system-current.txt b/api/system-current.txt
index c2338d8..20697d4 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -87,6 +87,7 @@
field public static final java.lang.String CLEAR_APP_CACHE = "android.permission.CLEAR_APP_CACHE";
field public static final java.lang.String CLEAR_APP_USER_DATA = "android.permission.CLEAR_APP_USER_DATA";
field public static final java.lang.String CONNECTIVITY_INTERNAL = "android.permission.CONNECTIVITY_INTERNAL";
+ field public static final java.lang.String CONNECTIVITY_USE_RESTRICTED_NETWORKS = "android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS";
field public static final java.lang.String CONTROL_INCALL_EXPERIENCE = "android.permission.CONTROL_INCALL_EXPERIENCE";
field public static final java.lang.String CONTROL_LOCATION_UPDATES = "android.permission.CONTROL_LOCATION_UPDATES";
field public static final java.lang.String CONTROL_VPN = "android.permission.CONTROL_VPN";
@@ -6992,6 +6993,7 @@
method public android.bluetooth.le.BluetoothLeScanner getBluetoothLeScanner();
method public java.util.Set<android.bluetooth.BluetoothDevice> getBondedDevices();
method public static synchronized android.bluetooth.BluetoothAdapter getDefaultAdapter();
+ method public int getLeMaximumAdvertisingDataLength();
method public java.lang.String getName();
method public android.bluetooth.le.PeriodicAdvertisingManager getPeriodicAdvertisingManager();
method public int getProfileConnectionState(int);
@@ -7378,9 +7380,7 @@
public final class BluetoothDevice implements android.os.Parcelable {
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.BluetoothGattCallbackExt);
- method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallbackExt, int);
- method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallbackExt, int, int);
+ method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int);
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;
@@ -7478,12 +7478,8 @@
field public static final int GATT_WRITE_NOT_PERMITTED = 3; // 0x3
}
- public abstract deprecated class BluetoothGattCallback extends android.bluetooth.BluetoothGattCallbackExt {
+ public abstract class BluetoothGattCallback {
ctor public BluetoothGattCallback();
- }
-
- public abstract class BluetoothGattCallbackExt {
- ctor public BluetoothGattCallbackExt();
method public void onCharacteristicChanged(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic);
method public void onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int);
method public void onCharacteristicWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int);
@@ -7592,12 +7588,8 @@
method public void setPreferredPhy(android.bluetooth.BluetoothDevice, int, int, int);
}
- public abstract deprecated class BluetoothGattServerCallback extends android.bluetooth.BluetoothGattServerCallbackExt {
+ public abstract class BluetoothGattServerCallback {
ctor public BluetoothGattServerCallback();
- }
-
- public abstract class BluetoothGattServerCallbackExt {
- ctor public BluetoothGattServerCallbackExt();
method public void onCharacteristicReadRequest(android.bluetooth.BluetoothDevice, int, int, android.bluetooth.BluetoothGattCharacteristic);
method public void onCharacteristicWriteRequest(android.bluetooth.BluetoothDevice, int, android.bluetooth.BluetoothGattCharacteristic, boolean, boolean, int, byte[]);
method public void onConnectionStateChange(android.bluetooth.BluetoothDevice, int, int);
@@ -7809,11 +7801,11 @@
}
public final class AdvertisingSet {
- method public void enableAdvertising(boolean);
- method public void periodicAdvertisingEnable(boolean);
+ method public void enableAdvertising(boolean, int);
method public void setAdvertisingData(android.bluetooth.le.AdvertiseData);
method public void setAdvertisingParameters(android.bluetooth.le.AdvertisingSetParameters);
method public void setPeriodicAdvertisingData(android.bluetooth.le.AdvertiseData);
+ method public void setPeriodicAdvertisingEnable(boolean);
method public void setPeriodicAdvertisingParameters(android.bluetooth.le.PeriodicAdvertisingParameters);
method public void setScanResponseData(android.bluetooth.le.AdvertiseData);
}
@@ -7822,11 +7814,11 @@
ctor public AdvertisingSetCallback();
method public void onAdvertisingDataSet(android.bluetooth.le.AdvertisingSet, int);
method public void onAdvertisingEnabled(android.bluetooth.le.AdvertisingSet, boolean, int);
- method public void onAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int);
- method public void onAdvertisingSetStarted(android.bluetooth.le.AdvertisingSet, int);
+ method public void onAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int, int);
+ method public void onAdvertisingSetStarted(android.bluetooth.le.AdvertisingSet, int, int);
method public void onAdvertisingSetStopped(android.bluetooth.le.AdvertisingSet);
method public void onPeriodicAdvertisingDataSet(android.bluetooth.le.AdvertisingSet, int);
- method public void onPeriodicAdvertisingEnable(android.bluetooth.le.AdvertisingSet, boolean, int);
+ method public void onPeriodicAdvertisingEnabled(android.bluetooth.le.AdvertisingSet, boolean, int);
method public void onPeriodicAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int);
method public void onScanResponseDataSet(android.bluetooth.le.AdvertisingSet, int);
field public static final int ADVERTISE_FAILED_ALREADY_STARTED = 3; // 0x3
@@ -7842,12 +7834,12 @@
method public int getInterval();
method public int getPrimaryPhy();
method public int getSecondaryPhy();
- method public int getTimeout();
method public int getTxPowerLevel();
method public boolean includeTxPower();
method public boolean isAnonymous();
method public boolean isConnectable();
method public boolean isLegacy();
+ method public boolean isScannable();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertisingSetParameters> CREATOR;
field public static final int INTERVAL_HIGH = 160; // 0xa0
@@ -7869,14 +7861,14 @@
public static final class AdvertisingSetParameters.Builder {
ctor public AdvertisingSetParameters.Builder();
method public android.bluetooth.le.AdvertisingSetParameters build();
- method public android.bluetooth.le.AdvertisingSetParameters.Builder setAnonymouus(boolean);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setAnonymous(boolean);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setConnectable(boolean);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setIncludeTxPower(boolean);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setInterval(int);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setLegacyMode(boolean);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setPrimaryPhy(int);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setScannable(boolean);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setSecondaryPhy(int);
- method public android.bluetooth.le.AdvertisingSetParameters.Builder setTimeout(int);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setTxPowerLevel(int);
}
@@ -7885,6 +7877,8 @@
method public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback);
method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
+ method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, android.bluetooth.le.AdvertisingSetCallback);
+ method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
method public void stopAdvertising(android.bluetooth.le.AdvertiseCallback);
method public void stopAdvertisingSet(android.bluetooth.le.AdvertisingSetCallback);
}
@@ -25599,7 +25593,9 @@
method public static deprecated boolean isNetworkTypeValid(int);
method public boolean isTetheringSupported();
method public void registerDefaultNetworkCallback(android.net.ConnectivityManager.NetworkCallback);
+ method public void registerDefaultNetworkCallback(android.net.ConnectivityManager.NetworkCallback, android.os.Handler);
method public void registerNetworkCallback(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback);
+ method public void registerNetworkCallback(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback, android.os.Handler);
method public void registerNetworkCallback(android.net.NetworkRequest, android.app.PendingIntent);
method public void releaseNetworkRequest(android.app.PendingIntent);
method public void removeDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
@@ -25608,6 +25604,8 @@
method public boolean requestBandwidthUpdate(android.net.Network);
method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback);
method public void requestNetwork(android.net.NetworkRequest, int, android.net.ConnectivityManager.NetworkCallback);
+ method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback, android.os.Handler);
+ method public void requestNetwork(android.net.NetworkRequest, int, android.net.ConnectivityManager.NetworkCallback, android.os.Handler);
method public void requestNetwork(android.net.NetworkRequest, android.app.PendingIntent);
method public deprecated boolean requestRouteToHost(int, int);
method public deprecated void setNetworkPreference(int);
@@ -27389,7 +27387,7 @@
public class WifiManager {
method public int addNetwork(android.net.wifi.WifiConfiguration);
- method public boolean addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
+ method public void addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
method public static int calculateSignalLevel(int, int);
method public void cancelWps(android.net.wifi.WifiManager.WpsCallback);
method public static int compareSignalLevel(int, int);
@@ -27429,7 +27427,7 @@
method public boolean reassociate();
method public boolean reconnect();
method public boolean removeNetwork(int);
- method public boolean removePasspointConfiguration(java.lang.String);
+ method public void removePasspointConfiguration(java.lang.String);
method public deprecated boolean saveConfiguration();
method public void setTdlsEnabled(java.net.InetAddress, boolean);
method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
@@ -27452,29 +27450,25 @@
field public static final int CHANGE_REASON_REMOVED = 1; // 0x1
field public static final java.lang.String CONFIGURED_NETWORKS_CHANGED_ACTION = "android.net.wifi.CONFIGURED_NETWORKS_CHANGE";
field public static final int ERROR_AUTHENTICATING = 1; // 0x1
+ field public static final java.lang.String EXTRA_ANQP_ELEMENT_DATA = "android.net.wifi.extra.ANQP_ELEMENT_DATA";
field public static final java.lang.String EXTRA_BSSID = "bssid";
+ field public static final java.lang.String EXTRA_BSSID_LONG = "android.net.wifi.extra.BSSID_LONG";
field public static final java.lang.String EXTRA_CHANGE_REASON = "changeReason";
+ field public static final java.lang.String EXTRA_DELAY = "android.net.wifi.extra.DELAY";
+ field public static final java.lang.String EXTRA_ESS = "android.net.wifi.extra.ESS";
+ field public static final java.lang.String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME";
+ field public static final java.lang.String EXTRA_ICON = "android.net.wifi.extra.ICON";
field public static final java.lang.String EXTRA_MULTIPLE_NETWORKS_CHANGED = "multipleChanges";
field public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
field public static final java.lang.String EXTRA_NEW_RSSI = "newRssi";
field public static final java.lang.String EXTRA_NEW_STATE = "newState";
- field public static final java.lang.String EXTRA_PASSPOINT_DEAUTH_IMMINENT_BSSID = "android.net.wifi.extra.PASSPOINT_DEAUTH_IMMINENT_BSSID";
- field public static final java.lang.String EXTRA_PASSPOINT_DEAUTH_IMMINENT_ESS = "android.net.wifi.extra.PASSPOINT_DEAUTH_IMMINENT_ESS";
- field public static final java.lang.String EXTRA_PASSPOINT_DEAUTH_IMMINENT_REASON_URL = "android.net.wifi.extra.PASSPOINT_DEAUTH_IMMINENT_REASON_URL";
- field public static final java.lang.String EXTRA_PASSPOINT_DEAUTH_IMMINENT_REAUTH_DELAY = "android.net.wifi.extra.PASSPOINT_DEAUTH_IMMINENT_REAUTH_DELAY";
- field public static final java.lang.String EXTRA_PASSPOINT_ICON_BSSID = "android.net.wifi.extra.PASSPOINT_ICON_BSSID";
- field public static final java.lang.String EXTRA_PASSPOINT_ICON_DATA = "android.net.wifi.extra.PASSPOINT_ICON_DATA";
- field public static final java.lang.String EXTRA_PASSPOINT_ICON_FILENAME = "android.net.wifi.extra.PASSPOINT_ICON_FILENAME";
- field public static final java.lang.String EXTRA_PASSPOINT_OSU_PROVIDERS_LIST_BSSID = "android.net.wifi.extra.PASSPOINT_OSU_PROVIDERS_LIST_BSSID";
- field public static final java.lang.String EXTRA_PASSPOINT_OSU_PROVIDERS_LIST_DATA = "android.net.wifi.extra.PASSPOINT_OSU_PROVIDERS_LIST_DATA";
- field public static final java.lang.String EXTRA_PASSPOINT_SUBSCRIPTION_REMEDIATION_BSSID = "android.net.wifi.extra.PASSPOINT_SUBSCRIPTION_REMEDIATION_BSSID";
- field public static final java.lang.String EXTRA_PASSPOINT_SUBSCRIPTION_REMEDIATION_SERVER_METHOD = "android.net.wifi.extra.PASSPOINT_SUBSCRIPTION_REMEDIATION_SERVER_METHOD";
- field public static final java.lang.String EXTRA_PASSPOINT_SUBSCRIPTION_REMEDIATION_SERVER_URL = "android.net.wifi.extra.PASSPOINT_SUBSCRIPTION_REMEDIATION_SERVER_URL";
field public static final java.lang.String EXTRA_PREVIOUS_WIFI_AP_STATE = "previous_wifi_state";
field public static final java.lang.String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state";
field public static final java.lang.String EXTRA_RESULTS_UPDATED = "resultsUpdated";
+ field public static final java.lang.String EXTRA_SUBSCRIPTION_REMEDIATION_METHOD = "android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD";
field public static final java.lang.String EXTRA_SUPPLICANT_CONNECTED = "connected";
field public static final java.lang.String EXTRA_SUPPLICANT_ERROR = "supplicantError";
+ field public static final java.lang.String EXTRA_URL = "android.net.wifi.extra.URL";
field public static final java.lang.String EXTRA_WIFI_AP_STATE = "wifi_state";
field public static final java.lang.String EXTRA_WIFI_CONFIGURATION = "wifiConfiguration";
field public static final java.lang.String EXTRA_WIFI_CREDENTIAL_EVENT_TYPE = "et";
@@ -27853,7 +27847,6 @@
method public void setUsageLimitStartTimeInMs(long);
method public void setUsageLimitTimeLimitInMinutes(long);
method public void setUsageLimitUsageTimePeriodInMinutes(long);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.PasspointConfiguration> CREATOR;
}
@@ -27894,7 +27887,6 @@
method public void setRealm(java.lang.String);
method public void setSimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
method public void setUserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential> CREATOR;
}
@@ -27907,7 +27899,6 @@
method public java.lang.String getCertType();
method public void setCertSha256Fingerprint(byte[]);
method public void setCertType(java.lang.String);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.CertificateCredential> CREATOR;
}
@@ -27920,7 +27911,6 @@
method public java.lang.String getImsi();
method public void setEapType(int);
method public void setImsi(java.lang.String);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.SimCredential> CREATOR;
}
@@ -27943,7 +27933,6 @@
method public void setPassword(java.lang.String);
method public void setSoftTokenApp(java.lang.String);
method public void setUsername(java.lang.String);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.UserCredential> CREATOR;
}
@@ -27968,7 +27957,6 @@
method public void setMatchAnyOis(long[]);
method public void setOtherHomePartners(java.lang.String[]);
method public void setRoamingConsortiumOis(long[]);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.HomeSp> CREATOR;
}
@@ -27995,7 +27983,6 @@
method public void setPolicyUpdate(android.net.wifi.hotspot2.pps.UpdateParameter);
method public void setPreferredRoamingPartnerList(java.util.List<android.net.wifi.hotspot2.pps.Policy.RoamingPartner>);
method public void setRequiredProtoPortMap(java.util.Map<java.lang.Integer, java.lang.String>);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Policy> CREATOR;
}
@@ -28012,7 +27999,6 @@
method public void setFqdn(java.lang.String);
method public void setFqdnExactMatch(boolean);
method public void setPriority(int);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Policy.RoamingPartner> CREATOR;
}
@@ -28037,7 +28023,6 @@
method public void setUpdateIntervalInMinutes(long);
method public void setUpdateMethod(java.lang.String);
method public void setUsername(java.lang.String);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.UpdateParameter> CREATOR;
field public static final long UPDATE_CHECK_INTERVAL_NEVER = 4294967295L; // 0xffffffffL
@@ -41425,8 +41410,8 @@
method public boolean getDataEnabled(int);
method public int getDataNetworkType();
method public int getDataState();
- method public java.lang.String getDeviceId();
- method public java.lang.String getDeviceId(int);
+ method public deprecated java.lang.String getDeviceId();
+ method public deprecated java.lang.String getDeviceId(int);
method public java.lang.String getDeviceSoftwareVersion();
method public java.lang.String[] getForbiddenPlmns();
method public java.lang.String getGroupIdLevel1();
@@ -41434,6 +41419,8 @@
method public java.lang.String getImei();
method public java.lang.String getImei(int);
method public java.lang.String getLine1Number();
+ method public java.lang.String getMeid();
+ method public java.lang.String getMeid(int);
method public java.lang.String getMmsUAProfUrl();
method public java.lang.String getMmsUserAgent();
method public deprecated java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo();
@@ -56793,6 +56780,7 @@
public class GenericSignatureFormatError extends java.lang.ClassFormatError {
ctor public GenericSignatureFormatError();
+ ctor public GenericSignatureFormatError(java.lang.String);
}
public abstract interface InvocationHandler {
diff --git a/api/test-current.txt b/api/test-current.txt
index bc0b5b0..8b29697 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -6703,6 +6703,7 @@
method public android.bluetooth.le.BluetoothLeScanner getBluetoothLeScanner();
method public java.util.Set<android.bluetooth.BluetoothDevice> getBondedDevices();
method public static synchronized android.bluetooth.BluetoothAdapter getDefaultAdapter();
+ method public int getLeMaximumAdvertisingDataLength();
method public java.lang.String getName();
method public android.bluetooth.le.PeriodicAdvertisingManager getPeriodicAdvertisingManager();
method public int getProfileConnectionState(int);
@@ -7085,9 +7086,7 @@
public final class BluetoothDevice implements android.os.Parcelable {
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.BluetoothGattCallbackExt);
- method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallbackExt, int);
- method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallbackExt, int, int);
+ method public android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int);
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;
@@ -7183,12 +7182,8 @@
field public static final int GATT_WRITE_NOT_PERMITTED = 3; // 0x3
}
- public abstract deprecated class BluetoothGattCallback extends android.bluetooth.BluetoothGattCallbackExt {
+ public abstract class BluetoothGattCallback {
ctor public BluetoothGattCallback();
- }
-
- public abstract class BluetoothGattCallbackExt {
- ctor public BluetoothGattCallbackExt();
method public void onCharacteristicChanged(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic);
method public void onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int);
method public void onCharacteristicWrite(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int);
@@ -7297,12 +7292,8 @@
method public void setPreferredPhy(android.bluetooth.BluetoothDevice, int, int, int);
}
- public abstract deprecated class BluetoothGattServerCallback extends android.bluetooth.BluetoothGattServerCallbackExt {
+ public abstract class BluetoothGattServerCallback {
ctor public BluetoothGattServerCallback();
- }
-
- public abstract class BluetoothGattServerCallbackExt {
- ctor public BluetoothGattServerCallbackExt();
method public void onCharacteristicReadRequest(android.bluetooth.BluetoothDevice, int, int, android.bluetooth.BluetoothGattCharacteristic);
method public void onCharacteristicWriteRequest(android.bluetooth.BluetoothDevice, int, android.bluetooth.BluetoothGattCharacteristic, boolean, boolean, int, byte[]);
method public void onConnectionStateChange(android.bluetooth.BluetoothDevice, int, int);
@@ -7514,11 +7505,11 @@
}
public final class AdvertisingSet {
- method public void enableAdvertising(boolean);
- method public void periodicAdvertisingEnable(boolean);
+ method public void enableAdvertising(boolean, int);
method public void setAdvertisingData(android.bluetooth.le.AdvertiseData);
method public void setAdvertisingParameters(android.bluetooth.le.AdvertisingSetParameters);
method public void setPeriodicAdvertisingData(android.bluetooth.le.AdvertiseData);
+ method public void setPeriodicAdvertisingEnable(boolean);
method public void setPeriodicAdvertisingParameters(android.bluetooth.le.PeriodicAdvertisingParameters);
method public void setScanResponseData(android.bluetooth.le.AdvertiseData);
}
@@ -7527,11 +7518,11 @@
ctor public AdvertisingSetCallback();
method public void onAdvertisingDataSet(android.bluetooth.le.AdvertisingSet, int);
method public void onAdvertisingEnabled(android.bluetooth.le.AdvertisingSet, boolean, int);
- method public void onAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int);
- method public void onAdvertisingSetStarted(android.bluetooth.le.AdvertisingSet, int);
+ method public void onAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int, int);
+ method public void onAdvertisingSetStarted(android.bluetooth.le.AdvertisingSet, int, int);
method public void onAdvertisingSetStopped(android.bluetooth.le.AdvertisingSet);
method public void onPeriodicAdvertisingDataSet(android.bluetooth.le.AdvertisingSet, int);
- method public void onPeriodicAdvertisingEnable(android.bluetooth.le.AdvertisingSet, boolean, int);
+ method public void onPeriodicAdvertisingEnabled(android.bluetooth.le.AdvertisingSet, boolean, int);
method public void onPeriodicAdvertisingParametersUpdated(android.bluetooth.le.AdvertisingSet, int);
method public void onScanResponseDataSet(android.bluetooth.le.AdvertisingSet, int);
field public static final int ADVERTISE_FAILED_ALREADY_STARTED = 3; // 0x3
@@ -7547,12 +7538,12 @@
method public int getInterval();
method public int getPrimaryPhy();
method public int getSecondaryPhy();
- method public int getTimeout();
method public int getTxPowerLevel();
method public boolean includeTxPower();
method public boolean isAnonymous();
method public boolean isConnectable();
method public boolean isLegacy();
+ method public boolean isScannable();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.bluetooth.le.AdvertisingSetParameters> CREATOR;
field public static final int INTERVAL_HIGH = 160; // 0xa0
@@ -7574,14 +7565,14 @@
public static final class AdvertisingSetParameters.Builder {
ctor public AdvertisingSetParameters.Builder();
method public android.bluetooth.le.AdvertisingSetParameters build();
- method public android.bluetooth.le.AdvertisingSetParameters.Builder setAnonymouus(boolean);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setAnonymous(boolean);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setConnectable(boolean);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setIncludeTxPower(boolean);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setInterval(int);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setLegacyMode(boolean);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setPrimaryPhy(int);
+ method public android.bluetooth.le.AdvertisingSetParameters.Builder setScannable(boolean);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setSecondaryPhy(int);
- method public android.bluetooth.le.AdvertisingSetParameters.Builder setTimeout(int);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setTxPowerLevel(int);
}
@@ -7590,6 +7581,8 @@
method public void startAdvertising(android.bluetooth.le.AdvertiseSettings, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseCallback);
method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback);
method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
+ method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, android.bluetooth.le.AdvertisingSetCallback);
+ method public void startAdvertisingSet(android.bluetooth.le.AdvertisingSetParameters, android.bluetooth.le.AdvertiseData, android.bluetooth.le.AdvertiseData, android.bluetooth.le.PeriodicAdvertisingParameters, android.bluetooth.le.AdvertiseData, int, android.bluetooth.le.AdvertisingSetCallback, android.os.Handler);
method public void stopAdvertising(android.bluetooth.le.AdvertiseCallback);
method public void stopAdvertisingSet(android.bluetooth.le.AdvertisingSetCallback);
}
@@ -23885,7 +23878,9 @@
method public boolean isDefaultNetworkActive();
method public static deprecated boolean isNetworkTypeValid(int);
method public void registerDefaultNetworkCallback(android.net.ConnectivityManager.NetworkCallback);
+ method public void registerDefaultNetworkCallback(android.net.ConnectivityManager.NetworkCallback, android.os.Handler);
method public void registerNetworkCallback(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback);
+ method public void registerNetworkCallback(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback, android.os.Handler);
method public void registerNetworkCallback(android.net.NetworkRequest, android.app.PendingIntent);
method public void releaseNetworkRequest(android.app.PendingIntent);
method public void removeDefaultNetworkActiveListener(android.net.ConnectivityManager.OnNetworkActiveListener);
@@ -23894,6 +23889,8 @@
method public boolean requestBandwidthUpdate(android.net.Network);
method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback);
method public void requestNetwork(android.net.NetworkRequest, int, android.net.ConnectivityManager.NetworkCallback);
+ method public void requestNetwork(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback, android.os.Handler);
+ method public void requestNetwork(android.net.NetworkRequest, int, android.net.ConnectivityManager.NetworkCallback, android.os.Handler);
method public void requestNetwork(android.net.NetworkRequest, android.app.PendingIntent);
method public deprecated boolean requestRouteToHost(int, int);
method public deprecated void setNetworkPreference(int);
@@ -25084,7 +25081,7 @@
public class WifiManager {
method public int addNetwork(android.net.wifi.WifiConfiguration);
- method public boolean addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
+ method public void addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
method public static int calculateSignalLevel(int, int);
method public void cancelWps(android.net.wifi.WifiManager.WpsCallback);
method public static int compareSignalLevel(int, int);
@@ -25113,7 +25110,7 @@
method public boolean reassociate();
method public boolean reconnect();
method public boolean removeNetwork(int);
- method public boolean removePasspointConfiguration(java.lang.String);
+ method public void removePasspointConfiguration(java.lang.String);
method public deprecated boolean saveConfiguration();
method public void setTdlsEnabled(java.net.InetAddress, boolean);
method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
@@ -25128,26 +25125,22 @@
field public static final java.lang.String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
field public static final java.lang.String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE";
field public static final int ERROR_AUTHENTICATING = 1; // 0x1
+ field public static final java.lang.String EXTRA_ANQP_ELEMENT_DATA = "android.net.wifi.extra.ANQP_ELEMENT_DATA";
field public static final java.lang.String EXTRA_BSSID = "bssid";
+ field public static final java.lang.String EXTRA_BSSID_LONG = "android.net.wifi.extra.BSSID_LONG";
+ field public static final java.lang.String EXTRA_DELAY = "android.net.wifi.extra.DELAY";
+ field public static final java.lang.String EXTRA_ESS = "android.net.wifi.extra.ESS";
+ field public static final java.lang.String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME";
+ field public static final java.lang.String EXTRA_ICON = "android.net.wifi.extra.ICON";
field public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
field public static final java.lang.String EXTRA_NEW_RSSI = "newRssi";
field public static final java.lang.String EXTRA_NEW_STATE = "newState";
- field public static final java.lang.String EXTRA_PASSPOINT_DEAUTH_IMMINENT_BSSID = "android.net.wifi.extra.PASSPOINT_DEAUTH_IMMINENT_BSSID";
- field public static final java.lang.String EXTRA_PASSPOINT_DEAUTH_IMMINENT_ESS = "android.net.wifi.extra.PASSPOINT_DEAUTH_IMMINENT_ESS";
- field public static final java.lang.String EXTRA_PASSPOINT_DEAUTH_IMMINENT_REASON_URL = "android.net.wifi.extra.PASSPOINT_DEAUTH_IMMINENT_REASON_URL";
- field public static final java.lang.String EXTRA_PASSPOINT_DEAUTH_IMMINENT_REAUTH_DELAY = "android.net.wifi.extra.PASSPOINT_DEAUTH_IMMINENT_REAUTH_DELAY";
- field public static final java.lang.String EXTRA_PASSPOINT_ICON_BSSID = "android.net.wifi.extra.PASSPOINT_ICON_BSSID";
- field public static final java.lang.String EXTRA_PASSPOINT_ICON_DATA = "android.net.wifi.extra.PASSPOINT_ICON_DATA";
- field public static final java.lang.String EXTRA_PASSPOINT_ICON_FILENAME = "android.net.wifi.extra.PASSPOINT_ICON_FILENAME";
- field public static final java.lang.String EXTRA_PASSPOINT_OSU_PROVIDERS_LIST_BSSID = "android.net.wifi.extra.PASSPOINT_OSU_PROVIDERS_LIST_BSSID";
- field public static final java.lang.String EXTRA_PASSPOINT_OSU_PROVIDERS_LIST_DATA = "android.net.wifi.extra.PASSPOINT_OSU_PROVIDERS_LIST_DATA";
- field public static final java.lang.String EXTRA_PASSPOINT_SUBSCRIPTION_REMEDIATION_BSSID = "android.net.wifi.extra.PASSPOINT_SUBSCRIPTION_REMEDIATION_BSSID";
- field public static final java.lang.String EXTRA_PASSPOINT_SUBSCRIPTION_REMEDIATION_SERVER_METHOD = "android.net.wifi.extra.PASSPOINT_SUBSCRIPTION_REMEDIATION_SERVER_METHOD";
- field public static final java.lang.String EXTRA_PASSPOINT_SUBSCRIPTION_REMEDIATION_SERVER_URL = "android.net.wifi.extra.PASSPOINT_SUBSCRIPTION_REMEDIATION_SERVER_URL";
field public static final java.lang.String EXTRA_PREVIOUS_WIFI_STATE = "previous_wifi_state";
field public static final java.lang.String EXTRA_RESULTS_UPDATED = "resultsUpdated";
+ field public static final java.lang.String EXTRA_SUBSCRIPTION_REMEDIATION_METHOD = "android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD";
field public static final java.lang.String EXTRA_SUPPLICANT_CONNECTED = "connected";
field public static final java.lang.String EXTRA_SUPPLICANT_ERROR = "supplicantError";
+ field public static final java.lang.String EXTRA_URL = "android.net.wifi.extra.URL";
field public static final java.lang.String EXTRA_WIFI_INFO = "wifiInfo";
field public static final java.lang.String EXTRA_WIFI_STATE = "wifi_state";
field public static final java.lang.String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED";
@@ -25366,7 +25359,6 @@
method public void setUsageLimitStartTimeInMs(long);
method public void setUsageLimitTimeLimitInMinutes(long);
method public void setUsageLimitUsageTimePeriodInMinutes(long);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.PasspointConfiguration> CREATOR;
}
@@ -25407,7 +25399,6 @@
method public void setRealm(java.lang.String);
method public void setSimCredential(android.net.wifi.hotspot2.pps.Credential.SimCredential);
method public void setUserCredential(android.net.wifi.hotspot2.pps.Credential.UserCredential);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential> CREATOR;
}
@@ -25420,7 +25411,6 @@
method public java.lang.String getCertType();
method public void setCertSha256Fingerprint(byte[]);
method public void setCertType(java.lang.String);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.CertificateCredential> CREATOR;
}
@@ -25433,7 +25423,6 @@
method public java.lang.String getImsi();
method public void setEapType(int);
method public void setImsi(java.lang.String);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.SimCredential> CREATOR;
}
@@ -25456,7 +25445,6 @@
method public void setPassword(java.lang.String);
method public void setSoftTokenApp(java.lang.String);
method public void setUsername(java.lang.String);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Credential.UserCredential> CREATOR;
}
@@ -25481,7 +25469,6 @@
method public void setMatchAnyOis(long[]);
method public void setOtherHomePartners(java.lang.String[]);
method public void setRoamingConsortiumOis(long[]);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.HomeSp> CREATOR;
}
@@ -25508,7 +25495,6 @@
method public void setPolicyUpdate(android.net.wifi.hotspot2.pps.UpdateParameter);
method public void setPreferredRoamingPartnerList(java.util.List<android.net.wifi.hotspot2.pps.Policy.RoamingPartner>);
method public void setRequiredProtoPortMap(java.util.Map<java.lang.Integer, java.lang.String>);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Policy> CREATOR;
}
@@ -25525,7 +25511,6 @@
method public void setFqdn(java.lang.String);
method public void setFqdnExactMatch(boolean);
method public void setPriority(int);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.Policy.RoamingPartner> CREATOR;
}
@@ -25550,7 +25535,6 @@
method public void setUpdateIntervalInMinutes(long);
method public void setUpdateMethod(java.lang.String);
method public void setUsername(java.lang.String);
- method public boolean validate();
method public void writeToParcel(android.os.Parcel, int);
field public static final android.os.Parcelable.Creator<android.net.wifi.hotspot2.pps.UpdateParameter> CREATOR;
field public static final long UPDATE_CHECK_INTERVAL_NEVER = 4294967295L; // 0xffffffffL
@@ -38289,13 +38273,17 @@
method public boolean getDataEnabled();
method public int getDataNetworkType();
method public int getDataState();
- method public java.lang.String getDeviceId();
- method public java.lang.String getDeviceId(int);
+ method public deprecated java.lang.String getDeviceId();
+ method public deprecated java.lang.String getDeviceId(int);
method public java.lang.String getDeviceSoftwareVersion();
method public java.lang.String[] getForbiddenPlmns();
method public java.lang.String getGroupIdLevel1();
method public java.lang.String getIccAuthentication(int, int, java.lang.String);
+ method public java.lang.String getImei();
+ method public java.lang.String getImei(int);
method public java.lang.String getLine1Number();
+ method public java.lang.String getMeid();
+ method public java.lang.String getMeid(int);
method public java.lang.String getMmsUAProfUrl();
method public java.lang.String getMmsUserAgent();
method public deprecated java.util.List<android.telephony.NeighboringCellInfo> getNeighboringCellInfo();
@@ -53254,6 +53242,7 @@
public class GenericSignatureFormatError extends java.lang.ClassFormatError {
ctor public GenericSignatureFormatError();
+ ctor public GenericSignatureFormatError(java.lang.String);
}
public abstract interface InvocationHandler {
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 0dd9c63..bcdf3f4 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1761,7 +1761,9 @@
if (this.actions != null) {
that.actions = new Action[this.actions.length];
for(int i=0; i<this.actions.length; i++) {
- that.actions[i] = this.actions[i].clone();
+ if ( this.actions[i] != null) {
+ that.actions[i] = this.actions[i].clone();
+ }
}
}
@@ -3108,7 +3110,9 @@
* @param action The action to add.
*/
public Builder addAction(Action action) {
- mActions.add(action);
+ if (action != null) {
+ mActions.add(action);
+ }
return this;
}
@@ -3122,7 +3126,9 @@
public Builder setActions(Action... actions) {
mActions.clear();
for (int i = 0; i < actions.length; i++) {
- mActions.add(actions[i]);
+ if (actions[i] != null) {
+ mActions.add(actions[i]);
+ }
}
return this;
}
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 8186937..27640e7 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1447,9 +1447,9 @@
}
/**
- * Return true if LE Periodic Advertising feature is supported.
+ * Return true if LE Extended Advertising feature is supported.
*
- * @return true if chipset supports LE Periodic Advertising feature
+ * @return true if chipset supports LE Extended Advertising feature
*/
public boolean isLeExtendedAdvertisingSupported() {
if (!getLeAccess()) return false;
@@ -1483,6 +1483,25 @@
}
/**
+ * Return the maximum LE advertising data length,
+ * if LE Extended Advertising feature is supported.
+ *
+ * @return the maximum LE advertising data length.
+ */
+ public int getLeMaximumAdvertisingDataLength() {
+ if (!getLeAccess()) return 0;
+ try {
+ mServiceLock.readLock().lock();
+ if (mService != null) return mService.getLeMaximumAdvertisingDataLength();
+ } catch (RemoteException e) {
+ Log.e(TAG, "failed to get getLeMaximumAdvertisingDataLength, error: ", e);
+ } finally {
+ mServiceLock.readLock().unlock();
+ }
+ return 0;
+ }
+
+ /**
* Return true if hardware has entries available for matching beacons
*
* @return true if there are hw entries available for matching beacons
diff --git a/core/java/android/bluetooth/BluetoothDevice.java b/core/java/android/bluetooth/BluetoothDevice.java
index 31fc294..cb6fa05 100644
--- a/core/java/android/bluetooth/BluetoothDevice.java
+++ b/core/java/android/bluetooth/BluetoothDevice.java
@@ -1664,43 +1664,6 @@
* @param autoConnect Whether to directly connect to the remote device (false)
* or to automatically connect as soon as the remote
* device becomes available (true).
- * @throws IllegalArgumentException if callback is null
- */
- public BluetoothGatt connectGatt(Context context, boolean autoConnect,
- BluetoothGattCallbackExt callback) {
- return (connectGatt(context, autoConnect,callback, TRANSPORT_AUTO));
- }
-
- /**
- * 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}
- * @throws IllegalArgumentException if callback is null
- */
- public BluetoothGatt connectGatt(Context context, boolean autoConnect,
- BluetoothGattCallbackExt callback, int transport) {
- return (connectGatt(context, autoConnect,callback, TRANSPORT_AUTO, PHY_LE_1M));
- }
-
- /**
- * 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}
@@ -1711,7 +1674,7 @@
* @throws IllegalArgumentException if callback is null
*/
public BluetoothGatt connectGatt(Context context, boolean autoConnect,
- BluetoothGattCallbackExt callback, int transport, int phy) {
+ BluetoothGattCallback callback, int transport, int phy) {
// TODO(Bluetooth) check whether platform support BLE
// Do the check here or in GattServer?
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
diff --git a/core/java/android/bluetooth/BluetoothGatt.java b/core/java/android/bluetooth/BluetoothGatt.java
index 0cb69ae..a314aaf 100644
--- a/core/java/android/bluetooth/BluetoothGatt.java
+++ b/core/java/android/bluetooth/BluetoothGatt.java
@@ -31,7 +31,7 @@
* <p>This class provides Bluetooth GATT functionality to enable communication
* with Bluetooth Smart or Smart Ready devices.
*
- * <p>To connect to a remote peripheral device, create a {@link BluetoothGattCallbackExt}
+ * <p>To connect to a remote peripheral device, create a {@link BluetoothGattCallback}
* and call {@link BluetoothDevice#connectGatt} to get a instance of this class.
* GATT capable devices can be discovered using the Bluetooth device discovery or BLE
* scan process.
@@ -42,7 +42,7 @@
private static final boolean VDBG = false;
private IBluetoothGatt mService;
- private BluetoothGattCallbackExt mCallback;
+ private BluetoothGattCallback mCallback;
private int mClientIf;
private BluetoothDevice mDevice;
private boolean mAutoConnect;
@@ -133,14 +133,15 @@
/*package*/ static final int AUTHENTICATION_MITM = 2;
/**
- * Bluetooth GATT callbacks. Overrides the default BluetoothGattCallbackExt implementation.
+ * Bluetooth GATT callbacks. Overrides the default BluetoothGattCallback implementation.
*/
- private final IBluetoothGattCallbackExt mBluetoothGattCallbackExt =
+ private final IBluetoothGattCallbackExt mBluetoothGattCallback =
new IBluetoothGattCallbackExt.Stub() {
/**
* Application interface registered - app is ready to go
* @hide
*/
+ @Override
public void onClientRegistered(int status, int clientIf) {
if (DBG) Log.d(TAG, "onClientRegistered() - status=" + status
+ " clientIf=" + clientIf);
@@ -210,6 +211,7 @@
* Client connection state changed
* @hide
*/
+ @Override
public void onClientConnectionState(int status, int clientIf,
boolean connected, String address) {
if (DBG) Log.d(TAG, "onClientConnectionState() - status=" + status
@@ -245,6 +247,7 @@
* we are done at this point.
* @hide
*/
+ @Override
public void onSearchComplete(String address, List<BluetoothGattService> services,
int status) {
if (DBG) Log.d(TAG, "onSearchComplete() = Device=" + address + " Status=" + status);
@@ -288,6 +291,7 @@
* Updates the internal value.
* @hide
*/
+ @Override
public void onCharacteristicRead(String address, int status, int handle, byte[] value) {
if (VDBG) Log.d(TAG, "onCharacteristicRead() - Device=" + address
+ " handle=" + handle + " Status=" + status);
@@ -336,6 +340,7 @@
* Let the app know how we did...
* @hide
*/
+ @Override
public void onCharacteristicWrite(String address, int status, int handle) {
if (VDBG) Log.d(TAG, "onCharacteristicWrite() - Device=" + address
+ " handle=" + handle + " Status=" + status);
@@ -380,6 +385,7 @@
* Updates the internal value.
* @hide
*/
+ @Override
public void onNotify(String address, int handle, byte[] value) {
if (VDBG) Log.d(TAG, "onNotify() - Device=" + address + " handle=" + handle);
@@ -403,6 +409,7 @@
* Descriptor has been read.
* @hide
*/
+ @Override
public void onDescriptorRead(String address, int status, int handle, byte[] value) {
if (VDBG) Log.d(TAG, "onDescriptorRead() - Device=" + address + " handle=" + handle);
@@ -446,6 +453,7 @@
* Descriptor write operation complete.
* @hide
*/
+ @Override
public void onDescriptorWrite(String address, int status, int handle) {
if (VDBG) Log.d(TAG, "onDescriptorWrite() - Device=" + address + " handle=" + handle);
@@ -488,6 +496,7 @@
* Prepared write transaction completed (or aborted)
* @hide
*/
+ @Override
public void onExecuteWrite(String address, int status) {
if (VDBG) Log.d(TAG, "onExecuteWrite() - Device=" + address
+ " status=" + status);
@@ -510,6 +519,7 @@
* Remote device RSSI has been read
* @hide
*/
+ @Override
public void onReadRemoteRssi(String address, int rssi, int status) {
if (VDBG) Log.d(TAG, "onReadRemoteRssi() - Device=" + address +
" rssi=" + rssi + " status=" + status);
@@ -527,6 +537,7 @@
* Callback invoked when the MTU for a given connection changes
* @hide
*/
+ @Override
public void onConfigureMTU(String address, int mtu, int status) {
if (DBG) Log.d(TAG, "onConfigureMTU() - Device=" + address +
" mtu=" + mtu + " status=" + status);
@@ -539,6 +550,27 @@
Log.w(TAG, "Unhandled exception in callback", ex);
}
}
+
+ /**
+ * Callback invoked when the given connection is updated
+ * @hide
+ */
+ @Override
+ public void onConnectionUpdated(String address, int interval, int latency,
+ int timeout, int status) {
+ if (DBG) Log.d(TAG, "onConnectionUpdated() - Device=" + address +
+ " interval=" + interval + " latency=" + latency +
+ " timeout=" + timeout + " status=" + status);
+ 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);
+ }
+ }
};
/*package*/ BluetoothGatt(IBluetoothGatt iGatt, BluetoothDevice device,
@@ -618,7 +650,7 @@
/**
* Register an application callback to start using GATT.
*
- * <p>This is an asynchronous call. The callback {@link BluetoothGattCallbackExt#onAppRegistered}
+ * <p>This is an asynchronous call. The callback {@link BluetoothGattCallback#onAppRegistered}
* is used to notify success or failure if the function returns true.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
@@ -627,7 +659,7 @@
* @return If true, the callback will be called to notify success or failure,
* false on immediate error
*/
- private boolean registerApp(BluetoothGattCallbackExt callback) {
+ private boolean registerApp(BluetoothGattCallback callback) {
if (DBG) Log.d(TAG, "registerApp()");
if (mService == null) return false;
@@ -636,7 +668,7 @@
if (DBG) Log.d(TAG, "registerApp() - UUID=" + uuid);
try {
- mService.registerClient(new ParcelUuid(uuid), mBluetoothGattCallbackExt);
+ mService.registerClient(new ParcelUuid(uuid), mBluetoothGattCallback);
} catch (RemoteException e) {
Log.e(TAG,"",e);
return false;
@@ -666,7 +698,7 @@
*
* <p>The connection may not be established right away, but will be
* completed when the remote device is available. A
- * {@link BluetoothGattCallbackExt#onConnectionStateChange} callback will be
+ * {@link BluetoothGattCallback#onConnectionStateChange} callback will be
* invoked when the connection state changes as a result of this function.
*
* <p>The autoConnect parameter determines whether to actively connect to
@@ -684,7 +716,7 @@
* device becomes available (true).
* @return true, if the connection attempt was initiated successfully
*/
- /*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallbackExt callback) {
+ /*package*/ boolean connect(Boolean autoConnect, BluetoothGattCallback callback) {
if (DBG) Log.d(TAG, "connect() - device: " + mDevice.getAddress() + ", auto: " + autoConnect);
synchronized(mStateLock) {
if (mConnState != CONN_STATE_IDLE) {
@@ -749,7 +781,7 @@
* recommendation, wether the PHY change will happen depends on other applications peferences,
* local and remote controller capabilities. Controller can override these settings.
* <p>
- * {@link BluetoothGattCallbackExt#onPhyUpdate} will be triggered as a result of this call, even
+ * {@link BluetoothGattCallback#onPhyUpdate} will be triggered as a result of this call, even
* if no PHY change happens. It is also triggered when remote device updates the PHY.
*
* @param txPhy preferred transmitter PHY. Bitwise OR of any of
@@ -773,7 +805,7 @@
/**
* Read the current transmitter PHY and receiver PHY of the connection. The values are returned
- * in {@link BluetoothGattCallbackExt#onPhyRead}
+ * in {@link BluetoothGattCallback#onPhyRead}
*/
public void readPhy() {
try {
@@ -797,7 +829,7 @@
* characteristics and descriptors.
*
* <p>This is an asynchronous operation. Once service discovery is completed,
- * the {@link BluetoothGattCallbackExt#onServicesDiscovered} callback is
+ * the {@link BluetoothGattCallback#onServicesDiscovered} callback is
* triggered. If the discovery was successful, the remote services can be
* retrieved using the {@link #getServices} function.
*
@@ -876,7 +908,7 @@
* Reads the requested characteristic from the associated remote device.
*
* <p>This is an asynchronous operation. The result of the read operation
- * is reported by the {@link BluetoothGattCallbackExt#onCharacteristicRead}
+ * is reported by the {@link BluetoothGattCallback#onCharacteristicRead}
* callback.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
@@ -918,7 +950,7 @@
* Writes a given characteristic and its values to the associated remote device.
*
* <p>Once the write operation has been completed, the
- * {@link BluetoothGattCallbackExt#onCharacteristicWrite} callback is invoked,
+ * {@link BluetoothGattCallback#onCharacteristicWrite} callback is invoked,
* reporting the result of the operation.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
@@ -962,7 +994,7 @@
* Reads the value for a given descriptor from the associated remote device.
*
* <p>Once the read operation has been completed, the
- * {@link BluetoothGattCallbackExt#onDescriptorRead} callback is
+ * {@link BluetoothGattCallback#onDescriptorRead} callback is
* triggered, signaling the result of the operation.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
@@ -1003,7 +1035,7 @@
/**
* Write the value of a given descriptor to the associated remote device.
*
- * <p>A {@link BluetoothGattCallbackExt#onDescriptorWrite} callback is
+ * <p>A {@link BluetoothGattCallback#onDescriptorWrite} callback is
* triggered to report the result of the write operation.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
@@ -1047,7 +1079,7 @@
* <p>Once a reliable write transaction has been initiated, all calls
* to {@link #writeCharacteristic} are sent to the remote device for
* verification and queued up for atomic execution. The application will
- * receive an {@link BluetoothGattCallbackExt#onCharacteristicWrite} callback
+ * receive an {@link BluetoothGattCallback#onCharacteristicWrite} callback
* in response to every {@link #writeCharacteristic} call and is responsible
* for verifying if the value has been transmitted accurately.
*
@@ -1081,7 +1113,7 @@
* <p>This function will commit all queued up characteristic write
* operations for a given remote device.
*
- * <p>A {@link BluetoothGattCallbackExt#onReliableWriteCompleted} callback is
+ * <p>A {@link BluetoothGattCallback#onReliableWriteCompleted} callback is
* invoked to indicate whether the transaction has been executed correctly.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
@@ -1138,7 +1170,7 @@
* Enable or disable notifications/indications for a given characteristic.
*
* <p>Once notifications are enabled for a characteristic, a
- * {@link BluetoothGattCallbackExt#onCharacteristicChanged} callback will be
+ * {@link BluetoothGattCallback#onCharacteristicChanged} callback will be
* triggered if the remote device indicates that the given characteristic
* has changed.
*
@@ -1193,7 +1225,7 @@
/**
* Read the RSSI for a connected remote device.
*
- * <p>The {@link BluetoothGattCallbackExt#onReadRemoteRssi} callback will be
+ * <p>The {@link BluetoothGattCallback#onReadRemoteRssi} callback will be
* invoked when the RSSI value has been read.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
@@ -1221,7 +1253,7 @@
* the data sent is truncated to the MTU size. This function may be used
* to request a larger MTU size to be able to send more data at once.
*
- * <p>A {@link BluetoothGattCallbackExt#onMtuChanged} callback will indicate
+ * <p>A {@link BluetoothGattCallback#onMtuChanged} callback will indicate
* whether this operation was successful.
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
diff --git a/core/java/android/bluetooth/BluetoothGattCallback.java b/core/java/android/bluetooth/BluetoothGattCallback.java
index 4da106d..11a15c6 100644
--- a/core/java/android/bluetooth/BluetoothGattCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattCallback.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2013 The Android Open Source Project
+ * 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.
@@ -18,22 +18,183 @@
/**
* This abstract class is used to implement {@link BluetoothGatt} callbacks.
- * @deprecated use {@link BluetoothGattCallbackExt}
*/
-public abstract class BluetoothGattCallback extends BluetoothGattCallbackExt {
+public abstract class BluetoothGattCallback{
/**
- * @hide
+ * Callback triggered as result of {@link BluetoothGatt#setPreferredPhy}, or as a result of
+ * remote device changing the PHY.
+ *
+ * @param gatt GATT client
+ * @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
+ * {@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
*/
- @Override
public void onPhyUpdate(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
}
/**
- * @hide
+ * Callback triggered as result of {@link BluetoothGatt#readPhy}
+ *
+ * @param gatt GATT client
+ * @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
+ * {@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
*/
- @Override
public void onPhyRead(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
}
+ /**
+ * Callback indicating when GATT client has connected/disconnected to/from a remote
+ * GATT server.
+ *
+ * @param gatt GATT client
+ * @param status Status of the connect or disconnect operation.
+ * {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
+ * @param newState Returns the new connection state. Can be one of
+ * {@link BluetoothProfile#STATE_DISCONNECTED} or
+ * {@link BluetoothProfile#STATE_CONNECTED}
+ */
+ public void onConnectionStateChange(BluetoothGatt gatt, int status,
+ int newState) {
+ }
+
+ /**
+ * Callback invoked when the list of remote services, characteristics and descriptors
+ * for the remote device have been updated, ie new services have been discovered.
+ *
+ * @param gatt GATT client invoked {@link BluetoothGatt#discoverServices}
+ * @param status {@link BluetoothGatt#GATT_SUCCESS} if the remote device
+ * has been explored successfully.
+ */
+ public void onServicesDiscovered(BluetoothGatt gatt, int status) {
+ }
+
+ /**
+ * Callback reporting the result of a characteristic read operation.
+ *
+ * @param gatt GATT client invoked {@link BluetoothGatt#readCharacteristic}
+ * @param characteristic Characteristic that was read from the associated
+ * remote device.
+ * @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation
+ * was completed successfully.
+ */
+ public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
+ int status) {
+ }
+
+ /**
+ * Callback indicating the result of a characteristic write operation.
+ *
+ * <p>If this callback is invoked while a reliable write transaction is
+ * in progress, the value of the characteristic represents the value
+ * reported by the remote device. An application should compare this
+ * value to the desired value to be written. If the values don't match,
+ * the application must abort the reliable write transaction.
+ *
+ * @param gatt GATT client invoked {@link BluetoothGatt#writeCharacteristic}
+ * @param characteristic Characteristic that was written to the associated
+ * remote device.
+ * @param status The result of the write operation
+ * {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
+ */
+ public void onCharacteristicWrite(BluetoothGatt gatt,
+ BluetoothGattCharacteristic characteristic, int status) {
+ }
+
+ /**
+ * Callback triggered as a result of a remote characteristic notification.
+ *
+ * @param gatt GATT client the characteristic is associated with
+ * @param characteristic Characteristic that has been updated as a result
+ * of a remote notification event.
+ */
+ public void onCharacteristicChanged(BluetoothGatt gatt,
+ BluetoothGattCharacteristic characteristic) {
+ }
+
+ /**
+ * Callback reporting the result of a descriptor read operation.
+ *
+ * @param gatt GATT client invoked {@link BluetoothGatt#readDescriptor}
+ * @param descriptor Descriptor that was read from the associated
+ * remote device.
+ * @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation
+ * was completed successfully
+ */
+ public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
+ int status) {
+ }
+
+ /**
+ * Callback indicating the result of a descriptor write operation.
+ *
+ * @param gatt GATT client invoked {@link BluetoothGatt#writeDescriptor}
+ * @param descriptor Descriptor that was writte to the associated
+ * remote device.
+ * @param status The result of the write operation
+ * {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
+ */
+ public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
+ int status) {
+ }
+
+ /**
+ * Callback invoked when a reliable write transaction has been completed.
+ *
+ * @param gatt GATT client invoked {@link BluetoothGatt#executeReliableWrite}
+ * @param status {@link BluetoothGatt#GATT_SUCCESS} if the reliable write
+ * transaction was executed successfully
+ */
+ public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
+ }
+
+ /**
+ * Callback reporting the RSSI for a remote device connection.
+ *
+ * This callback is triggered in response to the
+ * {@link BluetoothGatt#readRemoteRssi} function.
+ *
+ * @param gatt GATT client invoked {@link BluetoothGatt#readRemoteRssi}
+ * @param rssi The RSSI value for the remote device
+ * @param status {@link BluetoothGatt#GATT_SUCCESS} if the RSSI was read successfully
+ */
+ public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
+ }
+
+ /**
+ * Callback indicating the MTU for a given device connection has changed.
+ *
+ * This callback is triggered in response to the
+ * {@link BluetoothGatt#requestMtu} function, or in response to a connection
+ * event.
+ *
+ * @param gatt GATT client invoked {@link BluetoothGatt#requestMtu}
+ * @param mtu The new MTU size
+ * @param status {@link BluetoothGatt#GATT_SUCCESS} if the MTU has been changed successfully
+ */
+ public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
+ }
+
+ /**
+ * Callback indicating the connection parameters were updated.
+ *
+ * @param gatt GATT client involved
+ * @param interval Connection interval used on this connection, 1.25ms unit. Valid
+ * range is from 6 (7.5ms) to 3200 (4000ms).
+ * @param latency Slave latency for the connection in number of connection events. Valid
+ * range is from 0 to 499
+ * @param timeout Supervision timeout for this connection, in 10ms unit. Valid range is
+ * from 10 (0.1s) to 3200 (32s)
+ * @param status {@link BluetoothGatt#GATT_SUCCESS} if the connection has been updated
+ * successfully
+ * @hide
+ */
+ public void onConnectionUpdated(BluetoothGatt gatt, int interval, int latency, int timeout,
+ int status) {
+ }
}
diff --git a/core/java/android/bluetooth/BluetoothGattCallbackExt.java b/core/java/android/bluetooth/BluetoothGattCallbackExt.java
deleted file mode 100644
index 63774c8..0000000
--- a/core/java/android/bluetooth/BluetoothGattCallbackExt.java
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * 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 android.bluetooth;
-
-/**
- * This abstract class is used to implement {@link BluetoothGatt} callbacks.
- */
-public abstract class BluetoothGattCallbackExt {
-
- /**
- * Callback triggered as result of {@link BluetoothGatt#setPreferredPhy}, or as a result of
- * remote device changing the PHY.
- *
- * @param gatt GATT client
- * @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
- * {@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
- */
- public void onPhyUpdate(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
- }
-
- /**
- * Callback triggered as result of {@link BluetoothGatt#readPhy}
- *
- * @param gatt GATT client
- * @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
- * {@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
- */
- public void onPhyRead(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
- }
-
- /**
- * Callback indicating when GATT client has connected/disconnected to/from a remote
- * GATT server.
- *
- * @param gatt GATT client
- * @param status Status of the connect or disconnect operation.
- * {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
- * @param newState Returns the new connection state. Can be one of
- * {@link BluetoothProfile#STATE_DISCONNECTED} or
- * {@link BluetoothProfile#STATE_CONNECTED}
- */
- public void onConnectionStateChange(BluetoothGatt gatt, int status,
- int newState) {
- }
-
- /**
- * Callback invoked when the list of remote services, characteristics and descriptors
- * for the remote device have been updated, ie new services have been discovered.
- *
- * @param gatt GATT client invoked {@link BluetoothGatt#discoverServices}
- * @param status {@link BluetoothGatt#GATT_SUCCESS} if the remote device
- * has been explored successfully.
- */
- public void onServicesDiscovered(BluetoothGatt gatt, int status) {
- }
-
- /**
- * Callback reporting the result of a characteristic read operation.
- *
- * @param gatt GATT client invoked {@link BluetoothGatt#readCharacteristic}
- * @param characteristic Characteristic that was read from the associated
- * remote device.
- * @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation
- * was completed successfully.
- */
- public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
- int status) {
- }
-
- /**
- * Callback indicating the result of a characteristic write operation.
- *
- * <p>If this callback is invoked while a reliable write transaction is
- * in progress, the value of the characteristic represents the value
- * reported by the remote device. An application should compare this
- * value to the desired value to be written. If the values don't match,
- * the application must abort the reliable write transaction.
- *
- * @param gatt GATT client invoked {@link BluetoothGatt#writeCharacteristic}
- * @param characteristic Characteristic that was written to the associated
- * remote device.
- * @param status The result of the write operation
- * {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
- */
- public void onCharacteristicWrite(BluetoothGatt gatt,
- BluetoothGattCharacteristic characteristic, int status) {
- }
-
- /**
- * Callback triggered as a result of a remote characteristic notification.
- *
- * @param gatt GATT client the characteristic is associated with
- * @param characteristic Characteristic that has been updated as a result
- * of a remote notification event.
- */
- public void onCharacteristicChanged(BluetoothGatt gatt,
- BluetoothGattCharacteristic characteristic) {
- }
-
- /**
- * Callback reporting the result of a descriptor read operation.
- *
- * @param gatt GATT client invoked {@link BluetoothGatt#readDescriptor}
- * @param descriptor Descriptor that was read from the associated
- * remote device.
- * @param status {@link BluetoothGatt#GATT_SUCCESS} if the read operation
- * was completed successfully
- */
- public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
- int status) {
- }
-
- /**
- * Callback indicating the result of a descriptor write operation.
- *
- * @param gatt GATT client invoked {@link BluetoothGatt#writeDescriptor}
- * @param descriptor Descriptor that was writte to the associated
- * remote device.
- * @param status The result of the write operation
- * {@link BluetoothGatt#GATT_SUCCESS} if the operation succeeds.
- */
- public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
- int status) {
- }
-
- /**
- * Callback invoked when a reliable write transaction has been completed.
- *
- * @param gatt GATT client invoked {@link BluetoothGatt#executeReliableWrite}
- * @param status {@link BluetoothGatt#GATT_SUCCESS} if the reliable write
- * transaction was executed successfully
- */
- public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
- }
-
- /**
- * Callback reporting the RSSI for a remote device connection.
- *
- * This callback is triggered in response to the
- * {@link BluetoothGatt#readRemoteRssi} function.
- *
- * @param gatt GATT client invoked {@link BluetoothGatt#readRemoteRssi}
- * @param rssi The RSSI value for the remote device
- * @param status {@link BluetoothGatt#GATT_SUCCESS} if the RSSI was read successfully
- */
- public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
- }
-
- /**
- * Callback indicating the MTU for a given device connection has changed.
- *
- * This callback is triggered in response to the
- * {@link BluetoothGatt#requestMtu} function, or in response to a connection
- * event.
- *
- * @param gatt GATT client invoked {@link BluetoothGatt#requestMtu}
- * @param mtu The new MTU size
- * @param status {@link BluetoothGatt#GATT_SUCCESS} if the MTU has been changed successfully
- */
- public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
- }
-}
diff --git a/core/java/android/bluetooth/BluetoothGattServer.java b/core/java/android/bluetooth/BluetoothGattServer.java
index 9ee739f..c991e2f 100644
--- a/core/java/android/bluetooth/BluetoothGattServer.java
+++ b/core/java/android/bluetooth/BluetoothGattServer.java
@@ -46,7 +46,7 @@
private BluetoothAdapter mAdapter;
private IBluetoothGatt mService;
- private BluetoothGattServerCallbackExt mCallback;
+ private BluetoothGattServerCallback mCallback;
private Object mServerIfLock = new Object();
private int mServerIf;
@@ -65,6 +65,7 @@
* Application interface registered - app is ready to go
* @hide
*/
+ @Override
public void onServerRegistered(int status, int serverIf) {
if (DBG) Log.d(TAG, "onServerRegistered() - status=" + status
+ " serverIf=" + serverIf);
@@ -80,18 +81,10 @@
}
/**
- * Callback reporting an LE scan result.
- * @hide
- */
- public void onScanResult(String address, int rssi, byte[] advData) {
- if (VDBG) Log.d(TAG, "onScanResult() - Device=" + address + " RSSI=" +rssi);
- // no op
- }
-
- /**
* Server connection state changed
* @hide
*/
+ @Override
public void onServerConnectionState(int status, int serverIf,
boolean connected, String address) {
if (DBG) Log.d(TAG, "onServerConnectionState() - status=" + status
@@ -109,6 +102,7 @@
* Service has been added
* @hide
*/
+ @Override
public void onServiceAdded(int status, BluetoothGattService service) {
if (DBG) Log.d(TAG, "onServiceAdded() - handle=" + service.getInstanceId()
+ " uuid=" + service.getUuid() + " status=" + status);
@@ -149,6 +143,7 @@
* Remote client characteristic read request.
* @hide
*/
+ @Override
public void onCharacteristicReadRequest(String address, int transId,
int offset, boolean isLong, int handle) {
if (VDBG) Log.d(TAG, "onCharacteristicReadRequest() - handle=" + handle);
@@ -171,6 +166,7 @@
* Remote client descriptor read request.
* @hide
*/
+ @Override
public void onDescriptorReadRequest(String address, int transId,
int offset, boolean isLong, int handle) {
if (VDBG) Log.d(TAG, "onCharacteristicReadRequest() - handle=" + handle);
@@ -193,6 +189,7 @@
* Remote client characteristic write request.
* @hide
*/
+ @Override
public void onCharacteristicWriteRequest(String address, int transId,
int offset, int length, boolean isPrep, boolean needRsp,
int handle, byte[] value) {
@@ -218,6 +215,7 @@
* Remote client descriptor write request.
* @hide
*/
+ @Override
public void onDescriptorWriteRequest(String address, int transId, int offset,
int length, boolean isPrep, boolean needRsp, int handle, byte[] value) {
if (VDBG) Log.d(TAG, "onDescriptorWriteRequest() - handle=" + handle);
@@ -241,6 +239,7 @@
* Execute pending writes.
* @hide
*/
+ @Override
public void onExecuteWrite(String address, int transId,
boolean execWrite) {
if (DBG) Log.d(TAG, "onExecuteWrite() - "
@@ -261,6 +260,7 @@
* A notification/indication has been sent.
* @hide
*/
+ @Override
public void onNotificationSent(String address, int status) {
if (VDBG) Log.d(TAG, "onNotificationSent() - "
+ "device=" + address + ", status=" + status);
@@ -279,6 +279,7 @@
* The MTU for a connection has changed
* @hide
*/
+ @Override
public void onMtuChanged(String address, int mtu) {
if (DBG) Log.d(TAG, "onMtuChanged() - "
+ "device=" + address + ", mtu=" + mtu);
@@ -297,6 +298,7 @@
* The PHY for a connection was updated
* @hide
*/
+ @Override
public void onPhyUpdate(String address, int txPhy, int rxPhy, int status) {
if (DBG) Log.d(TAG, "onPhyUpdate() - " + "device=" + address + ", txPHy=" + txPhy
+ ", rxPHy=" + rxPhy);
@@ -315,6 +317,7 @@
* The PHY for a connection was read
* @hide
*/
+ @Override
public void onPhyRead(String address, int txPhy, int rxPhy, int status) {
if (DBG) Log.d(TAG, "onPhyUpdate() - " + "device=" + address + ", txPHy=" + txPhy
+ ", rxPHy=" + rxPhy);
@@ -328,6 +331,28 @@
Log.w(TAG, "Unhandled exception: " + ex);
}
}
+
+ /**
+ * Callback invoked when the given connection is updated
+ * @hide
+ */
+ @Override
+ public void onConnectionUpdated(String address, int interval, int latency,
+ int timeout, int status) {
+ if (DBG) Log.d(TAG, "onConnectionUpdated() - Device=" + address +
+ " interval=" + interval + " latency=" + latency +
+ " timeout=" + timeout + " status=" + status);
+ BluetoothDevice device = mAdapter.getRemoteDevice(address);
+ if (device == null) return;
+
+ try {
+ mCallback.onConnectionUpdated(device, interval, latency,
+ timeout, status);
+ } catch (Exception ex) {
+ Log.w(TAG, "Unhandled exception: " + ex);
+ }
+ }
+
};
/**
@@ -396,7 +421,7 @@
* @return true, the callback will be called to notify success or failure,
* false on immediate error
*/
- /*package*/ boolean registerCallback(BluetoothGattServerCallbackExt callback) {
+ /*package*/ boolean registerCallback(BluetoothGattServerCallback callback) {
if (DBG) Log.d(TAG, "registerCallback()");
if (mService == null) {
Log.e(TAG, "GATT service not available");
@@ -472,7 +497,7 @@
*
* <p>The connection may not be established right away, but will be
* completed when the remote device is available. A
- * {@link BluetoothGattServerCallbackExt#onConnectionStateChange} callback will be
+ * {@link BluetoothGattServerCallback#onConnectionStateChange} callback will be
* invoked when the connection state changes as a result of this function.
*
* <p>The autoConnect paramter determines whether to actively connect to
@@ -528,7 +553,7 @@
* recommendation, wether the PHY change will happen depends on other applications peferences,
* local and remote controller capabilities. Controller can override these settings.
* <p>
- * {@link BluetoothGattServerCallbackExt#onPhyUpdate} will be triggered as a result of this call, even
+ * {@link BluetoothGattServerCallback#onPhyUpdate} will be triggered as a result of this call, even
* if no PHY change happens. It is also triggered when remote device updates the PHY.
*
* @param device The remote device to send this response to
@@ -553,7 +578,7 @@
/**
* Read the current transmitter PHY and receiver PHY of the connection. The values are returned
- * in {@link BluetoothGattServerCallbackExt#onPhyRead}
+ * in {@link BluetoothGattServerCallback#onPhyRead}
*
* @param device The remote device to send this response to
*/
@@ -572,10 +597,10 @@
* is received by one of these callback methods:
*
* <ul>
- * <li>{@link BluetoothGattServerCallbackExt#onCharacteristicReadRequest}
- * <li>{@link BluetoothGattServerCallbackExt#onCharacteristicWriteRequest}
- * <li>{@link BluetoothGattServerCallbackExt#onDescriptorReadRequest}
- * <li>{@link BluetoothGattServerCallbackExt#onDescriptorWriteRequest}
+ * <li>{@link BluetoothGattServerCallback#onCharacteristicReadRequest}
+ * <li>{@link BluetoothGattServerCallback#onCharacteristicWriteRequest}
+ * <li>{@link BluetoothGattServerCallback#onDescriptorReadRequest}
+ * <li>{@link BluetoothGattServerCallback#onDescriptorWriteRequest}
* </ul>
*
* <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission.
diff --git a/core/java/android/bluetooth/BluetoothGattServerCallback.java b/core/java/android/bluetooth/BluetoothGattServerCallback.java
index 75ceb52..3b8f962 100644
--- a/core/java/android/bluetooth/BluetoothGattServerCallback.java
+++ b/core/java/android/bluetooth/BluetoothGattServerCallback.java
@@ -20,21 +20,187 @@
/**
* This abstract class is used to implement {@link BluetoothGattServer} callbacks.
- * @deprecated please use {@link BluetoothGattServerCallbackExt}
*/
-public abstract class BluetoothGattServerCallback extends BluetoothGattServerCallbackExt {
+public abstract class BluetoothGattServerCallback {
/**
- * @hide
+ * Callback indicating when a remote device has been connected or disconnected.
+ *
+ * @param device Remote device that has been connected or disconnected.
+ * @param status Status of the connect or disconnect operation.
+ * @param newState Returns the new connection state. Can be one of
+ * {@link BluetoothProfile#STATE_DISCONNECTED} or
+ * {@link BluetoothProfile#STATE_CONNECTED}
*/
- @Override
+ public void onConnectionStateChange(BluetoothDevice device, int status,
+ int newState) {
+ }
+
+ /**
+ * Indicates whether a local service has been added successfully.
+ *
+ * @param status Returns {@link BluetoothGatt#GATT_SUCCESS} if the service
+ * was added successfully.
+ * @param service The service that has been added
+ */
+ public void onServiceAdded(int status, BluetoothGattService service) {
+ }
+
+ /**
+ * A remote client has requested to read a local characteristic.
+ *
+ * <p>An application must call {@link BluetoothGattServer#sendResponse}
+ * to complete the request.
+ *
+ * @param device The remote device that has requested the read operation
+ * @param requestId The Id of the request
+ * @param offset Offset into the value of the characteristic
+ * @param characteristic Characteristic to be read
+ */
+ public void onCharacteristicReadRequest(BluetoothDevice device, int requestId,
+ int offset, BluetoothGattCharacteristic characteristic) {
+ }
+
+ /**
+ * A remote client has requested to write to a local characteristic.
+ *
+ * <p>An application must call {@link BluetoothGattServer#sendResponse}
+ * to complete the request.
+ *
+ * @param device The remote device that has requested the write operation
+ * @param requestId The Id of the request
+ * @param characteristic Characteristic to be written to.
+ * @param preparedWrite true, if this write operation should be queued for
+ * later execution.
+ * @param responseNeeded true, if the remote device requires a response
+ * @param offset The offset given for the value
+ * @param value The value the client wants to assign to the characteristic
+ */
+ public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId,
+ BluetoothGattCharacteristic characteristic,
+ boolean preparedWrite, boolean responseNeeded,
+ int offset, byte[] value) {
+ }
+
+ /**
+ * A remote client has requested to read a local descriptor.
+ *
+ * <p>An application must call {@link BluetoothGattServer#sendResponse}
+ * to complete the request.
+ *
+ * @param device The remote device that has requested the read operation
+ * @param requestId The Id of the request
+ * @param offset Offset into the value of the characteristic
+ * @param descriptor Descriptor to be read
+ */
+ public void onDescriptorReadRequest(BluetoothDevice device, int requestId,
+ int offset, BluetoothGattDescriptor descriptor) {
+ }
+
+ /**
+ * A remote client has requested to write to a local descriptor.
+ *
+ * <p>An application must call {@link BluetoothGattServer#sendResponse}
+ * to complete the request.
+ *
+ * @param device The remote device that has requested the write operation
+ * @param requestId The Id of the request
+ * @param descriptor Descriptor to be written to.
+ * @param preparedWrite true, if this write operation should be queued for
+ * later execution.
+ * @param responseNeeded true, if the remote device requires a response
+ * @param offset The offset given for the value
+ * @param value The value the client wants to assign to the descriptor
+ */
+ public void onDescriptorWriteRequest(BluetoothDevice device, int requestId,
+ BluetoothGattDescriptor descriptor,
+ boolean preparedWrite, boolean responseNeeded,
+ int offset, byte[] value) {
+ }
+
+ /**
+ * Execute all pending write operations for this device.
+ *
+ * <p>An application must call {@link BluetoothGattServer#sendResponse}
+ * to complete the request.
+ *
+ * @param device The remote device that has requested the write operations
+ * @param requestId The Id of the request
+ * @param execute Whether the pending writes should be executed (true) or
+ * cancelled (false)
+ */
+ public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
+ }
+
+ /**
+ * Callback invoked when a notification or indication has been sent to
+ * a remote device.
+ *
+ * <p>When multiple notifications are to be sent, an application must
+ * wait for this callback to be received before sending additional
+ * notifications.
+ *
+ * @param device The remote device the notification has been sent to
+ * @param status {@link BluetoothGatt#GATT_SUCCESS} if the operation was successful
+ */
+ public void onNotificationSent(BluetoothDevice device, int status) {
+ }
+
+ /**
+ * Callback indicating the MTU for a given device connection has changed.
+ *
+ * <p>This callback will be invoked if a remote client has requested to change
+ * the MTU for a given connection.
+ *
+ * @param device The remote device that requested the MTU change
+ * @param mtu The new MTU size
+ */
+ public void onMtuChanged(BluetoothDevice device, int mtu) {
+ }
+
+ /**
+ * Callback triggered as result of {@link BluetoothGattServer#setPreferredPhy}, or as a result
+ * of remote device changing the PHY.
+ *
+ * @param device The remote device
+ * @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
+ * {@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
+ */
public void onPhyUpdate(BluetoothDevice device, int txPhy, int rxPhy, int status) {
}
/**
- * @hide
+ * Callback triggered as result of {@link BluetoothGattServer#readPhy}
+ *
+ * @param device The remote device that requested the PHY read
+ * @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
+ * {@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
*/
- @Override
public void onPhyRead(BluetoothDevice device, int txPhy, int rxPhy, int status) {
}
+
+ /**
+ * Callback indicating the connection parameters were updated.
+ *
+ * @param device The remote device involved
+ * @param interval Connection interval used on this connection, 1.25ms unit. Valid
+ * range is from 6 (7.5ms) to 3200 (4000ms).
+ * @param latency Slave latency for the connection in number of connection events. Valid
+ * range is from 0 to 499
+ * @param timeout Supervision timeout for this connection, in 10ms unit. Valid range is
+ * from 10 (0.1s) to 3200 (32s)
+ * @param status {@link BluetoothGatt#GATT_SUCCESS} if the connection has been updated
+ * successfully
+ * @hide
+ */
+ public void onConnectionUpdated(BluetoothDevice gatt, int interval, int latency, int timeout,
+ int status) {
+ }
+
}
diff --git a/core/java/android/bluetooth/BluetoothGattServerCallbackExt.java b/core/java/android/bluetooth/BluetoothGattServerCallbackExt.java
deleted file mode 100644
index 455cce0..0000000
--- a/core/java/android/bluetooth/BluetoothGattServerCallbackExt.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * Copyright (C) 2013 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;
-
-import android.bluetooth.BluetoothDevice;
-
-/**
- * This abstract class is used to implement {@link BluetoothGattServer} callbacks.
- */
-public abstract class BluetoothGattServerCallbackExt {
-
- /**
- * Callback indicating when a remote device has been connected or disconnected.
- *
- * @param device Remote device that has been connected or disconnected.
- * @param status Status of the connect or disconnect operation.
- * @param newState Returns the new connection state. Can be one of
- * {@link BluetoothProfile#STATE_DISCONNECTED} or
- * {@link BluetoothProfile#STATE_CONNECTED}
- */
- public void onConnectionStateChange(BluetoothDevice device, int status,
- int newState) {
- }
-
- /**
- * Indicates whether a local service has been added successfully.
- *
- * @param status Returns {@link BluetoothGatt#GATT_SUCCESS} if the service
- * was added successfully.
- * @param service The service that has been added
- */
- public void onServiceAdded(int status, BluetoothGattService service) {
- }
-
- /**
- * A remote client has requested to read a local characteristic.
- *
- * <p>An application must call {@link BluetoothGattServer#sendResponse}
- * to complete the request.
- *
- * @param device The remote device that has requested the read operation
- * @param requestId The Id of the request
- * @param offset Offset into the value of the characteristic
- * @param characteristic Characteristic to be read
- */
- public void onCharacteristicReadRequest(BluetoothDevice device, int requestId,
- int offset, BluetoothGattCharacteristic characteristic) {
- }
-
- /**
- * A remote client has requested to write to a local characteristic.
- *
- * <p>An application must call {@link BluetoothGattServer#sendResponse}
- * to complete the request.
- *
- * @param device The remote device that has requested the write operation
- * @param requestId The Id of the request
- * @param characteristic Characteristic to be written to.
- * @param preparedWrite true, if this write operation should be queued for
- * later execution.
- * @param responseNeeded true, if the remote device requires a response
- * @param offset The offset given for the value
- * @param value The value the client wants to assign to the characteristic
- */
- public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId,
- BluetoothGattCharacteristic characteristic,
- boolean preparedWrite, boolean responseNeeded,
- int offset, byte[] value) {
- }
-
- /**
- * A remote client has requested to read a local descriptor.
- *
- * <p>An application must call {@link BluetoothGattServer#sendResponse}
- * to complete the request.
- *
- * @param device The remote device that has requested the read operation
- * @param requestId The Id of the request
- * @param offset Offset into the value of the characteristic
- * @param descriptor Descriptor to be read
- */
- public void onDescriptorReadRequest(BluetoothDevice device, int requestId,
- int offset, BluetoothGattDescriptor descriptor) {
- }
-
- /**
- * A remote client has requested to write to a local descriptor.
- *
- * <p>An application must call {@link BluetoothGattServer#sendResponse}
- * to complete the request.
- *
- * @param device The remote device that has requested the write operation
- * @param requestId The Id of the request
- * @param descriptor Descriptor to be written to.
- * @param preparedWrite true, if this write operation should be queued for
- * later execution.
- * @param responseNeeded true, if the remote device requires a response
- * @param offset The offset given for the value
- * @param value The value the client wants to assign to the descriptor
- */
- public void onDescriptorWriteRequest(BluetoothDevice device, int requestId,
- BluetoothGattDescriptor descriptor,
- boolean preparedWrite, boolean responseNeeded,
- int offset, byte[] value) {
- }
-
- /**
- * Execute all pending write operations for this device.
- *
- * <p>An application must call {@link BluetoothGattServer#sendResponse}
- * to complete the request.
- *
- * @param device The remote device that has requested the write operations
- * @param requestId The Id of the request
- * @param execute Whether the pending writes should be executed (true) or
- * cancelled (false)
- */
- public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
- }
-
- /**
- * Callback invoked when a notification or indication has been sent to
- * a remote device.
- *
- * <p>When multiple notifications are to be sent, an application must
- * wait for this callback to be received before sending additional
- * notifications.
- *
- * @param device The remote device the notification has been sent to
- * @param status {@link BluetoothGatt#GATT_SUCCESS} if the operation was successful
- */
- public void onNotificationSent(BluetoothDevice device, int status) {
- }
-
- /**
- * Callback indicating the MTU for a given device connection has changed.
- *
- * <p>This callback will be invoked if a remote client has requested to change
- * the MTU for a given connection.
- *
- * @param device The remote device that requested the MTU change
- * @param mtu The new MTU size
- */
- public void onMtuChanged(BluetoothDevice device, int mtu) {
- }
-
- /**
- * Callback triggered as result of {@link BluetoothGattServer#setPreferredPhy}, or as a result
- * of remote device changing the PHY.
- *
- * @param device The remote device
- * @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
- * {@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
- */
- public void onPhyUpdate(BluetoothDevice device, int txPhy, int rxPhy, int status) {
- }
-
- /**
- * Callback triggered as result of {@link BluetoothGattServer#readPhy}
- *
- * @param device The remote device that requested the PHY read
- * @param txPhy the transmitter PHY in use. One of {@link BluetoothDevice#PHY_LE_1M},
- * {@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
- */
- 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 76ca554..b337817 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -108,6 +108,7 @@
boolean isLeCodedPhySupported();
boolean isLeExtendedAdvertisingSupported();
boolean isLePeriodicAdvertisingSupported();
+ int getLeMaximumAdvertisingDataLength();
BluetoothActivityEnergyInfo reportActivityInfo();
/**
diff --git a/core/java/android/bluetooth/IBluetoothGatt.aidl b/core/java/android/bluetooth/IBluetoothGatt.aidl
index 33fedc7..652a1c60 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -50,26 +50,18 @@
void stopScan(in int scannerId);
void flushPendingBatchResults(in int scannerId);
- void registerAdvertiser(in IAdvertiserCallback callback);
- void unregisterAdvertiser(in int advertiserId);
- void startMultiAdvertising(in int advertiserId,
- in AdvertiseData advertiseData,
- in AdvertiseData scanResponse,
- in AdvertiseSettings settings);
- void stopMultiAdvertising(in int advertiserId);
-
void startAdvertisingSet(in AdvertisingSetParameters parameters, in AdvertiseData advertiseData,
in AdvertiseData scanResponse, in PeriodicAdvertisingParameters periodicParameters,
- in AdvertiseData periodicData, in IAdvertisingSetCallback callback);
+ in AdvertiseData periodicData, in int timeout, in IAdvertisingSetCallback callback);
void stopAdvertisingSet(in IAdvertisingSetCallback callback);
- void enableAdverisingSet(in int advertiserId, in boolean enable);
+ void enableAdvertisingSet(in int advertiserId, in boolean enable, in int timeout);
void setAdvertisingData(in int advertiserId, in AdvertiseData data);
void setScanResponseData(in int advertiserId, in AdvertiseData data);
void setAdvertisingParameters(in int advertiserId, in AdvertisingSetParameters parameters);
void setPeriodicAdvertisingParameters(in int advertiserId, in PeriodicAdvertisingParameters parameters);
void setPeriodicAdvertisingData(in int advertiserId, in AdvertiseData data);
- void periodicAdvertisingEnable(in int advertiserId, in boolean enable);
+ void setPeriodicAdvertisingEnable(in int advertiserId, in boolean enable);
void registerSync(in ScanResult scanResult, in int skip, in int timeout, in IPeriodicAdvertisingCallback callback);
void unregisterSync(in IPeriodicAdvertisingCallback callback);
diff --git a/core/java/android/bluetooth/IBluetoothGattCallbackExt.aidl b/core/java/android/bluetooth/IBluetoothGattCallbackExt.aidl
index 736f4b2..ed69e54 100644
--- a/core/java/android/bluetooth/IBluetoothGattCallbackExt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGattCallbackExt.aidl
@@ -37,4 +37,6 @@
void onNotify(in String address, in int handle, in byte[] value);
void onReadRemoteRssi(in String address, in int rssi, in int status);
void onConfigureMTU(in String address, in int mtu, in int status);
+ void onConnectionUpdated(in String address, in int interval, in int latency,
+ in int timeout, in int status);
}
diff --git a/core/java/android/bluetooth/IBluetoothGattServerCallbackExt.aidl b/core/java/android/bluetooth/IBluetoothGattServerCallbackExt.aidl
index 091ffb3..267e882 100644
--- a/core/java/android/bluetooth/IBluetoothGattServerCallbackExt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGattServerCallbackExt.aidl
@@ -42,4 +42,6 @@
void onMtuChanged(in String address, in int mtu);
void onPhyUpdate(in String address, in int txPhy, in int rxPhy, in int status);
void onPhyRead(in String address, in int txPhy, in int rxPhy, in int status);
+ void onConnectionUpdated(in String address, in int interval, in int latency,
+ in int timeout, in int status);
}
diff --git a/core/java/android/bluetooth/le/AdvertisingSet.java b/core/java/android/bluetooth/le/AdvertisingSet.java
index 1524022..7355b0d 100644
--- a/core/java/android/bluetooth/le/AdvertisingSet.java
+++ b/core/java/android/bluetooth/le/AdvertisingSet.java
@@ -63,9 +63,9 @@
* Requires {@link android.Manifest.permission#BLUETOOTH_ADMIN}
*
*/
- public void enableAdvertising(boolean enable) {
+ public void enableAdvertising(boolean enable, int timeout) {
try {
- gatt.enableAdverisingSet(this.advertiserId, enable);
+ gatt.enableAdvertisingSet(this.advertiserId, enable, timeout);
} catch (RemoteException e) {
Log.e(TAG, "remote exception - ", e);
}
@@ -143,9 +143,9 @@
* Used to enable/disable periodic advertising. This method returns immediately, the operation
* status is delivered through {@code callback.onPeriodicAdvertisingEnable()}.
*/
- public void periodicAdvertisingEnable(boolean enable) {
+ public void setPeriodicAdvertisingEnable(boolean enable) {
try {
- gatt.periodicAdvertisingEnable(this.advertiserId, enable);
+ gatt.setPeriodicAdvertisingEnable(this.advertiserId, enable);
} catch (RemoteException e) {
Log.e(TAG, "remote exception - ", e);
}
diff --git a/core/java/android/bluetooth/le/AdvertisingSetCallback.java b/core/java/android/bluetooth/le/AdvertisingSetCallback.java
index ceed8d9..fe3b1cd 100644
--- a/core/java/android/bluetooth/le/AdvertisingSetCallback.java
+++ b/core/java/android/bluetooth/le/AdvertisingSetCallback.java
@@ -62,9 +62,10 @@
* null, and status will be set to proper error code.
*
* @param advertisingSet The advertising set that was started or null if error.
+ * @param txPower tx power that will be used for this set.
* @param status Status of the operation.
*/
- public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int status) {}
+ public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int txPower, int status) {}
/**
* Callback triggered in response to {@link BluetoothLeAdvertiser#stopAdvertisingSet}
@@ -106,10 +107,11 @@
* indicating result of the operation.
*
* @param advertisingSet The advertising set.
+ * @param txPower tx power that will be used for this set.
* @param status Status of the operation.
*/
public void onAdvertisingParametersUpdated(AdvertisingSet advertisingSet,
- int status) {}
+ int txPower, int status) {}
/**
* Callback triggered in response to {@link AdvertisingSet#setPeriodicAdvertisingParameters}
@@ -133,12 +135,12 @@
int status) {}
/**
- * Callback triggered in response to {@link AdvertisingSet#periodicAdvertisingEnable}
+ * Callback triggered in response to {@link AdvertisingSet#setPeriodicAdvertisingEnable}
* indicating result of the operation.
*
* @param advertisingSet The advertising set.
* @param status Status of the operation.
*/
- public void onPeriodicAdvertisingEnable(AdvertisingSet advertisingSet, boolean enable,
+ public void onPeriodicAdvertisingEnabled(AdvertisingSet advertisingSet, boolean enable,
int status) {}
}
\ No newline at end of file
diff --git a/core/java/android/bluetooth/le/AdvertisingSetParameters.java b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
index 03a01e1..fe1f425 100644
--- a/core/java/android/bluetooth/le/AdvertisingSetParameters.java
+++ b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
@@ -116,16 +116,16 @@
private final int primaryPhy;
private final int secondaryPhy;
private final boolean connectable;
+ private final boolean scannable;
private final int interval;
private final int txPowerLevel;
- private final int timeoutMillis;
- private AdvertisingSetParameters(boolean connectable, boolean isLegacy,
+ private AdvertisingSetParameters(boolean connectable, boolean scannable, boolean isLegacy,
boolean isAnonymous, boolean includeTxPower,
int primaryPhy, int secondaryPhy,
- int interval, int txPowerLevel,
- int timeoutMillis) {
+ int interval, int txPowerLevel) {
this.connectable = connectable;
+ this.scannable = scannable;
this.isLegacy = isLegacy;
this.isAnonymous = isAnonymous;
this.includeTxPower = includeTxPower;
@@ -133,11 +133,11 @@
this.secondaryPhy = secondaryPhy;
this.interval = interval;
this.txPowerLevel = txPowerLevel;
- this.timeoutMillis = timeoutMillis;
}
private AdvertisingSetParameters(Parcel in) {
connectable = in.readInt() != 0 ? true : false;
+ scannable = in.readInt() != 0 ? true : false;
isLegacy = in.readInt() != 0 ? true : false;
isAnonymous = in.readInt() != 0 ? true : false;
includeTxPower = in.readInt() != 0 ? true : false;
@@ -145,7 +145,6 @@
secondaryPhy = in.readInt();
interval = in.readInt();
txPowerLevel = in.readInt();
- timeoutMillis = in.readInt();
}
/**
@@ -154,6 +153,11 @@
public boolean isConnectable() { return connectable; }
/**
+ * Returns whether the advertisement will be scannable.
+ */
+ public boolean isScannable() { return scannable; }
+
+ /**
* Returns whether the legacy advertisement will be used.
*/
public boolean isLegacy() { return isLegacy; }
@@ -188,11 +192,6 @@
*/
public int getTxPowerLevel() { return txPowerLevel; }
- /**
- * Returns the advertising time limit in milliseconds.
- */
- public int getTimeout() { return timeoutMillis; }
-
@Override
public String toString() {
return "AdvertisingSetParameters [connectable=" + connectable
@@ -202,8 +201,7 @@
+ ", primaryPhy=" + primaryPhy
+ ", secondaryPhy=" + secondaryPhy
+ ", interval=" + interval
- + ", txPowerLevel=" + txPowerLevel
- + ", timeoutMillis=" + timeoutMillis + "]";
+ + ", txPowerLevel=" + txPowerLevel + "]";
}
@Override
@@ -214,6 +212,7 @@
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(connectable ? 1 : 0);
+ dest.writeInt(scannable ? 1 : 0);
dest.writeInt(isLegacy ? 1 : 0);
dest.writeInt(isAnonymous ? 1 : 0);
dest.writeInt(includeTxPower ? 1 : 0);
@@ -221,7 +220,6 @@
dest.writeInt(secondaryPhy);
dest.writeInt(interval);
dest.writeInt(txPowerLevel);
- dest.writeInt(timeoutMillis);
}
public static final Parcelable.Creator<AdvertisingSetParameters> CREATOR =
@@ -243,6 +241,7 @@
public static final class Builder {
private boolean connectable = true;
+ private boolean scannable = true;
private boolean isLegacy = false;
private boolean isAnonymous = false;
private boolean includeTxPower = false;
@@ -250,7 +249,6 @@
private int secondaryPhy = PHY_LE_1M;
private int interval = INTERVAL_LOW;
private int txPowerLevel = TX_POWER_MEDIUM;
- private int timeoutMillis = 0;
/**
* Set whether the advertisement type should be connectable or
@@ -266,6 +264,18 @@
}
/**
+ * Set whether the advertisement type should be scannable
+ * Legacy advertisements can be both connectable and scannable. Other
+ * advertisements can be scannable only if not connectable.
+ * @param scannable Controls whether the advertisment type will be
+ * scannable (true) or non-scannable (false).
+ */
+ public Builder setScannable(boolean scannable) {
+ this.scannable = scannable;
+ return this;
+ }
+
+ /**
* When set to true, advertising set will advertise 4.x Spec compliant
* advertisements.
*
@@ -284,7 +294,7 @@
*
* @param isAnonymous wether anonymous advertising should be used.
*/
- public Builder setAnonymouus(boolean isAnonymous) {
+ public Builder setAnonymous(boolean isAnonymous) {
this.isAnonymous = isAnonymous;
return this;
}
@@ -380,30 +390,12 @@
}
/**
- * Limit advertising to a given amount of time.
- * @param timeoutMillis Advertising time limit. May not exceed 180000
- * milliseconds. A value of 0 will disable the time limit.
- * @throws IllegalArgumentException If the provided timeout is over 180000
- * ms.
- */
- public Builder setTimeout(int timeoutMillis) {
- if (timeoutMillis < 0 || timeoutMillis > LIMITED_ADVERTISING_MAX_MILLIS) {
- throw new IllegalArgumentException("timeoutMillis invalid (must be 0-" +
- LIMITED_ADVERTISING_MAX_MILLIS +
- " milliseconds)");
- }
- this.timeoutMillis = timeoutMillis;
- return this;
- }
-
- /**
* Build the {@link AdvertisingSetParameters} object.
*/
public AdvertisingSetParameters build() {
- return new AdvertisingSetParameters(connectable, isLegacy, isAnonymous,
+ return new AdvertisingSetParameters(connectable, scannable, isLegacy, isAnonymous,
includeTxPower, primaryPhy,
- secondaryPhy, interval, txPowerLevel,
- timeoutMillis);
+ secondaryPhy, interval, txPowerLevel);
}
}
}
\ No newline at end of file
diff --git a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
index e03c947..242ee77 100644
--- a/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
+++ b/core/java/android/bluetooth/le/BluetoothLeAdvertiser.java
@@ -28,6 +28,7 @@
import android.os.RemoteException;
import android.util.Log;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@@ -60,11 +61,12 @@
private final IBluetoothManager mBluetoothManager;
private final Handler mHandler;
private BluetoothAdapter mBluetoothAdapter;
- private final Map<AdvertiseCallback, AdvertiseCallbackWrapper>
- mLeAdvertisers = new HashMap<AdvertiseCallback, AdvertiseCallbackWrapper>();
+ private final Map<AdvertiseCallback, AdvertisingSetCallback>
+ mLegacyAdvertisers = new HashMap<>();
private final Map<AdvertisingSetCallback, IAdvertisingSetCallback>
- advertisingSetCallbackWrappers = new HashMap<>();
- private final Map<Integer, AdvertisingSet> advertisingSets = new HashMap<>();
+ mCallbackWrappers = Collections.synchronizedMap(new HashMap<>());
+ private final Map<Integer, AdvertisingSet>
+ mAdvertisingSets = Collections.synchronizedMap(new HashMap<>());
/**
* Use BluetoothAdapter.getLeAdvertiser() instead.
@@ -109,7 +111,7 @@
public void startAdvertising(AdvertiseSettings settings,
AdvertiseData advertiseData, AdvertiseData scanResponse,
final AdvertiseCallback callback) {
- synchronized (mLeAdvertisers) {
+ synchronized (mLegacyAdvertisers) {
BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
if (callback == null) {
throw new IllegalArgumentException("callback cannot be null");
@@ -120,25 +122,69 @@
postStartFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_DATA_TOO_LARGE);
return;
}
- if (mLeAdvertisers.containsKey(callback)) {
+ if (mLegacyAdvertisers.containsKey(callback)) {
postStartFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_ALREADY_STARTED);
return;
}
- IBluetoothGatt gatt;
- try {
- gatt = mBluetoothManager.getBluetoothGatt();
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to get Bluetooth gatt - ", e);
- postStartFailure(callback, AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR);
- return;
+ AdvertisingSetParameters.Builder parameters = new AdvertisingSetParameters.Builder();
+ parameters.setLegacyMode(true);
+ parameters.setConnectable(isConnectable);
+ parameters.setScannable(true); // legacy advertisements we support are always scannable
+ if (settings.getMode() == AdvertiseSettings.ADVERTISE_MODE_LOW_POWER) {
+ parameters.setInterval(1600); // 1s
+ } else if (settings.getMode() == AdvertiseSettings.ADVERTISE_MODE_BALANCED) {
+ parameters.setInterval(400); // 250ms
+ } else if (settings.getMode() == AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY) {
+ parameters.setInterval(160); // 100ms
}
- AdvertiseCallbackWrapper wrapper = new AdvertiseCallbackWrapper(callback, advertiseData,
- scanResponse, settings, gatt);
- wrapper.startRegisteration();
+
+ if (settings.getTxPowerLevel() == AdvertiseSettings.ADVERTISE_TX_POWER_ULTRA_LOW) {
+ parameters.setTxPowerLevel(-21);
+ } else if (settings.getTxPowerLevel() == AdvertiseSettings.ADVERTISE_TX_POWER_LOW) {
+ parameters.setTxPowerLevel(-15);
+ } else if (settings.getTxPowerLevel() == AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM) {
+ parameters.setTxPowerLevel(-7);
+ } else if (settings.getTxPowerLevel() == AdvertiseSettings.ADVERTISE_TX_POWER_HIGH) {
+ parameters.setTxPowerLevel(1);
+ }
+
+ AdvertisingSetCallback wrapped = wrapOldCallback(callback, settings);
+ mLegacyAdvertisers.put(callback, wrapped);
+ startAdvertisingSet(parameters.build(), advertiseData, scanResponse, null, null,
+ settings.getTimeout(), wrapped);
}
}
+ AdvertisingSetCallback wrapOldCallback(AdvertiseCallback callback, AdvertiseSettings settings) {
+ return new AdvertisingSetCallback() {
+ @Override
+ public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int txPower,
+ int status) {
+ if (status != AdvertisingSetCallback.ADVERTISE_SUCCESS) {
+ postStartFailure(callback, status);
+ return;
+ }
+
+ postStartSuccess(callback, settings);
+ }
+
+ /* Legacy advertiser is disabled on timeout */
+ @Override
+ public void onAdvertisingEnabled(AdvertisingSet advertisingSet, boolean enabled,
+ int status) {
+ if (enabled == true) {
+ Log.e(TAG, "Legacy advertiser should be only disabled on timeout," +
+ " but was enabled!");
+ return;
+ }
+
+ stopAdvertising(callback);
+ }
+
+ };
+ }
+
/**
* Stop Bluetooth LE advertising. The {@code callback} must be the same one use in
* {@link BluetoothLeAdvertiser#startAdvertising}.
@@ -148,20 +194,21 @@
* @param callback {@link AdvertiseCallback} identifies the advertising instance to stop.
*/
public void stopAdvertising(final AdvertiseCallback callback) {
- synchronized (mLeAdvertisers) {
+ synchronized (mLegacyAdvertisers) {
if (callback == null) {
throw new IllegalArgumentException("callback cannot be null");
}
- AdvertiseCallbackWrapper wrapper = mLeAdvertisers.get(callback);
+ AdvertisingSetCallback wrapper = mLegacyAdvertisers.get(callback);
if (wrapper == null) return;
- wrapper.stopAdvertising();
+
+ stopAdvertisingSet(wrapper);
}
}
/**
* Creates a new advertising set. If operation succeed, device will start advertising. This
* method returns immediately, the operation status is delivered through
- * {@code callback.onNewAdvertisingSet()}.
+ * {@code callback.onAdvertisingSetStarted()}.
* <p>
* @param parameters advertising set parameters.
* @param advertiseData Advertisement data to be broadcasted.
@@ -173,14 +220,14 @@
AdvertiseData advertiseData, AdvertiseData scanResponse,
PeriodicAdvertisingParameters periodicParameters,
AdvertiseData periodicData, AdvertisingSetCallback callback) {
- startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
- periodicData, callback, new Handler(Looper.getMainLooper()));
+ startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
+ periodicData, 0, callback, new Handler(Looper.getMainLooper()));
}
/**
* Creates a new advertising set. If operation succeed, device will start advertising. This
* method returns immediately, the operation status is delivered through
- * {@code callback.onNewAdvertisingSet()}.
+ * {@code callback.onAdvertisingSetStarted()}.
* <p>
* @param parameters advertising set parameters.
* @param advertiseData Advertisement data to be broadcasted.
@@ -194,6 +241,49 @@
PeriodicAdvertisingParameters periodicParameters,
AdvertiseData periodicData, AdvertisingSetCallback callback,
Handler handler) {
+ startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
+ periodicData, 0, callback, handler);
+ }
+
+ /**
+ * Creates a new advertising set. If operation succeed, device will start advertising. This
+ * method returns immediately, the operation status is delivered through
+ * {@code callback.onAdvertisingSetStarted()}.
+ * <p>
+ * @param parameters advertising set parameters.
+ * @param advertiseData Advertisement data to be broadcasted.
+ * @param scanResponse Scan response associated with the advertisement data.
+ * @param periodicData Periodic advertising data.
+ * @param timeoutMillis Advertising time limit. May not exceed 180000
+ * @param callback Callback for advertising set.
+ */
+ public void startAdvertisingSet(AdvertisingSetParameters parameters,
+ AdvertiseData advertiseData, AdvertiseData scanResponse,
+ PeriodicAdvertisingParameters periodicParameters,
+ AdvertiseData periodicData, int timeoutMillis,
+ AdvertisingSetCallback callback) {
+ startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
+ periodicData, timeoutMillis, callback, new Handler(Looper.getMainLooper()));
+ }
+
+ /**
+ * Creates a new advertising set. If operation succeed, device will start advertising. This
+ * method returns immediately, the operation status is delivered through
+ * {@code callback.onAdvertisingSetStarted()}.
+ * <p>
+ * @param parameters advertising set parameters.
+ * @param advertiseData Advertisement data to be broadcasted.
+ * @param scanResponse Scan response associated with the advertisement data.
+ * @param periodicData Periodic advertising data.
+ * @param timeoutMillis Advertising time limit. May not exceed 180000
+ * @param callback Callback for advertising set.
+ * @param handler thread upon which the callbacks will be invoked.
+ */
+ public void startAdvertisingSet(AdvertisingSetParameters parameters,
+ AdvertiseData advertiseData, AdvertiseData scanResponse,
+ PeriodicAdvertisingParameters periodicParameters,
+ AdvertiseData periodicData, int timeoutMillis,
+ AdvertisingSetCallback callback, Handler handler) {
BluetoothLeUtils.checkAdapterStateOn(mBluetoothAdapter);
if (callback == null) {
@@ -209,11 +299,14 @@
}
IAdvertisingSetCallback wrapped = wrap(callback, handler);
- advertisingSetCallbackWrappers.put(callback, wrapped);
+ if (mCallbackWrappers.putIfAbsent(callback, wrapped) != null) {
+ throw new IllegalArgumentException(
+ "callback instance already associated with advertising");
+ }
try {
gatt.startAdvertisingSet(parameters, advertiseData, scanResponse, periodicParameters,
- periodicData, wrapped);
+ periodicData, timeoutMillis, wrapped);
} catch (RemoteException e) {
Log.e(TAG, "Failed to start advertising set - ", e);
throw new IllegalStateException("Failed to start advertising set");
@@ -229,10 +322,9 @@
throw new IllegalArgumentException("callback cannot be null");
}
- IAdvertisingSetCallback wrapped = advertisingSetCallbackWrappers.remove(callback);
+ IAdvertisingSetCallback wrapped = mCallbackWrappers.remove(callback);
if (wrapped == null) {
- throw new IllegalArgumentException(
- "callback does not represent valid registered callback.");
+ return;
}
IBluetoothGatt gatt;
@@ -251,7 +343,9 @@
* @hide
*/
public void cleanup() {
- mLeAdvertisers.clear();
+ mLegacyAdvertisers.clear();
+ mCallbackWrappers.clear();
+ mAdvertisingSets.clear();
}
// Compute the size of advertisement data or scan resp
@@ -311,246 +405,117 @@
IAdvertisingSetCallback wrap(AdvertisingSetCallback callback, Handler handler) {
return new IAdvertisingSetCallback.Stub() {
- public void onAdvertisingSetStarted(int advertiserId, int status) {
+ @Override
+ public void onAdvertisingSetStarted(int advertiserId, int txPower, int status) {
handler.post(new Runnable() {
@Override
public void run() {
if (status != AdvertisingSetCallback.ADVERTISE_SUCCESS) {
- callback.onAdvertisingSetStarted(null, status);
- advertisingSetCallbackWrappers.remove(callback);
+ callback.onAdvertisingSetStarted(null, 0, status);
+ mCallbackWrappers.remove(callback);
return;
}
AdvertisingSet advertisingSet =
new AdvertisingSet(advertiserId, mBluetoothManager);
- advertisingSets.put(advertiserId, advertisingSet);
- callback.onAdvertisingSetStarted(advertisingSet, status);
+ mAdvertisingSets.put(advertiserId, advertisingSet);
+ callback.onAdvertisingSetStarted(advertisingSet, txPower, status);
}
});
}
+ @Override
public void onAdvertisingSetStopped(int advertiserId) {
handler.post(new Runnable() {
@Override
public void run() {
- AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
callback.onAdvertisingSetStopped(advertisingSet);
- advertisingSets.remove(advertiserId);
- advertisingSetCallbackWrappers.remove(callback);
+ mAdvertisingSets.remove(advertiserId);
+ mCallbackWrappers.remove(callback);
}
});
}
+ @Override
public void onAdvertisingEnabled(int advertiserId, boolean enabled, int status) {
handler.post(new Runnable() {
@Override
public void run() {
- AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
callback.onAdvertisingEnabled(advertisingSet, enabled, status);
}
});
}
+ @Override
public void onAdvertisingDataSet(int advertiserId, int status) {
handler.post(new Runnable() {
@Override
public void run() {
- AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
callback.onAdvertisingDataSet(advertisingSet, status);
}
});
}
+ @Override
public void onScanResponseDataSet(int advertiserId, int status) {
handler.post(new Runnable() {
@Override
public void run() {
- AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
callback.onScanResponseDataSet(advertisingSet, status);
}
});
}
- public void onAdvertisingParametersUpdated(int advertiserId, int status) {
+ @Override
+ public void onAdvertisingParametersUpdated(int advertiserId, int txPower, int status) {
handler.post(new Runnable() {
@Override
public void run() {
- AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
- callback.onAdvertisingParametersUpdated(advertisingSet, status);
+ AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
+ callback.onAdvertisingParametersUpdated(advertisingSet, txPower, status);
}
});
}
+ @Override
public void onPeriodicAdvertisingParametersUpdated(int advertiserId, int status) {
handler.post(new Runnable() {
@Override
public void run() {
- AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
callback.onPeriodicAdvertisingParametersUpdated(advertisingSet, status);
}
});
}
+ @Override
public void onPeriodicAdvertisingDataSet(int advertiserId, int status) {
handler.post(new Runnable() {
@Override
public void run() {
- AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
callback.onPeriodicAdvertisingDataSet(advertisingSet, status);
}
});
}
- public void onPeriodicAdvertisingEnable(int advertiserId, boolean enable, int status) {
+ @Override
+ public void onPeriodicAdvertisingEnabled(int advertiserId, boolean enable, int status) {
handler.post(new Runnable() {
@Override
public void run() {
- AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
- callback.onPeriodicAdvertisingEnable(advertisingSet, enable, status);
+ AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
+ callback.onPeriodicAdvertisingEnabled(advertisingSet, enable, status);
}
});
}
};
}
- /**
- * Bluetooth GATT interface callbacks for advertising.
- */
- private class AdvertiseCallbackWrapper extends IAdvertiserCallback.Stub {
- private static final int LE_CALLBACK_TIMEOUT_MILLIS = 2000;
- private final AdvertiseCallback mAdvertiseCallback;
- private final AdvertiseData mAdvertisement;
- private final AdvertiseData mScanResponse;
- private final AdvertiseSettings mSettings;
- private final IBluetoothGatt mBluetoothGatt;
-
- // mAdvertiserId -1: not registered
- // -2: advertise stopped or registration timeout
- // >=0: registered and advertising started
- private int mAdvertiserId;
- private boolean mIsAdvertising = false;
- private int registrationError = AdvertiseCallback.ADVERTISE_FAILED_INTERNAL_ERROR;
-
- public AdvertiseCallbackWrapper(AdvertiseCallback advertiseCallback,
- AdvertiseData advertiseData, AdvertiseData scanResponse,
- AdvertiseSettings settings,
- IBluetoothGatt bluetoothGatt) {
- mAdvertiseCallback = advertiseCallback;
- mAdvertisement = advertiseData;
- mScanResponse = scanResponse;
- mSettings = settings;
- mBluetoothGatt = bluetoothGatt;
- mAdvertiserId = -1;
- }
-
- public void startRegisteration() {
- synchronized (this) {
- if (mAdvertiserId == -2) return;
-
- try {
- mBluetoothGatt.registerAdvertiser(this);
- wait(LE_CALLBACK_TIMEOUT_MILLIS);
- } catch (InterruptedException | RemoteException e) {
- Log.e(TAG, "Failed to start registeration", e);
- }
- if (mAdvertiserId >= 0 && mIsAdvertising) {
- mLeAdvertisers.put(mAdvertiseCallback, this);
- } else if (mAdvertiserId < 0) {
-
- // Registration timeout, reset mClientIf to -2 so no subsequent operations can
- // proceed.
- if (mAdvertiserId == -1) mAdvertiserId = -2;
- // Post internal error if registration failed.
- postStartFailure(mAdvertiseCallback, registrationError);
- } else {
- // Unregister application if it's already registered but advertise failed.
- try {
- mBluetoothGatt.unregisterAdvertiser(mAdvertiserId);
- mAdvertiserId = -2;
- } catch (RemoteException e) {
- Log.e(TAG, "remote exception when unregistering", e);
- }
- }
- }
- }
-
- public void stopAdvertising() {
- synchronized (this) {
- try {
- mBluetoothGatt.stopMultiAdvertising(mAdvertiserId);
- wait(LE_CALLBACK_TIMEOUT_MILLIS);
- } catch (InterruptedException | RemoteException e) {
- Log.e(TAG, "Failed to stop advertising", e);
- }
- // Advertise callback should have been removed from LeAdvertisers when
- // onMultiAdvertiseCallback was called. In case onMultiAdvertiseCallback is never
- // invoked and wait timeout expires, remove callback here.
- if (mLeAdvertisers.containsKey(mAdvertiseCallback)) {
- mLeAdvertisers.remove(mAdvertiseCallback);
- }
- }
- }
-
- /**
- * Advertiser interface registered - app is ready to go
- */
- @Override
- public void onAdvertiserRegistered(int status, int advertiserId) {
- Log.d(TAG, "onAdvertiserRegistered() - status=" + status + " advertiserId=" + advertiserId);
- synchronized (this) {
- if (status == BluetoothGatt.GATT_SUCCESS) {
- try {
- if (mAdvertiserId == -2) {
- // Registration succeeds after timeout, unregister advertiser.
- mBluetoothGatt.unregisterAdvertiser(advertiserId);
- } else {
- mAdvertiserId = advertiserId;
- mBluetoothGatt.startMultiAdvertising(mAdvertiserId, mAdvertisement,
- mScanResponse, mSettings);
- }
- return;
- } catch (RemoteException e) {
- Log.e(TAG, "failed to start advertising", e);
- }
- } else if (status == AdvertiseCallback.ADVERTISE_FAILED_TOO_MANY_ADVERTISERS) {
- registrationError = status;
- }
- // Registration failed.
- mAdvertiserId = -2;
- notifyAll();
- }
- }
-
- @Override
- public void onMultiAdvertiseCallback(int status, boolean isStart,
- AdvertiseSettings settings) {
- synchronized (this) {
- if (isStart) {
- if (status == AdvertiseCallback.ADVERTISE_SUCCESS) {
- // Start success
- mIsAdvertising = true;
- postStartSuccess(mAdvertiseCallback, settings);
- } else {
- // Start failure.
- postStartFailure(mAdvertiseCallback, status);
- }
- } else {
- // unregister advertiser for stop.
- try {
- mBluetoothGatt.unregisterAdvertiser(mAdvertiserId);
- mAdvertiserId = -2;
- mIsAdvertising = false;
- mLeAdvertisers.remove(mAdvertiseCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "remote exception when unregistering", e);
- }
- }
- notifyAll();
- }
-
- }
- }
-
private void postStartFailure(final AdvertiseCallback callback, final int error) {
mHandler.post(new Runnable() {
@Override
diff --git a/core/java/android/bluetooth/le/IAdvertisingSetCallback.aidl b/core/java/android/bluetooth/le/IAdvertisingSetCallback.aidl
index 4b0a111..2c9f4ba 100644
--- a/core/java/android/bluetooth/le/IAdvertisingSetCallback.aidl
+++ b/core/java/android/bluetooth/le/IAdvertisingSetCallback.aidl
@@ -20,13 +20,13 @@
* @hide
*/
oneway interface IAdvertisingSetCallback {
- void onAdvertisingSetStarted(in int advertiserId, in int status);
+ void onAdvertisingSetStarted(in int advertiserId, in int tx_power, in int status);
void onAdvertisingSetStopped(in int advertiserId);
void onAdvertisingEnabled(in int advertiserId, in boolean enable, in int status);
void onAdvertisingDataSet(in int advertiserId, in int status);
void onScanResponseDataSet(in int advertiserId, in int status);
- void onAdvertisingParametersUpdated(in int advertiserId, in int status);
+ void onAdvertisingParametersUpdated(in int advertiserId, in int tx_power, in int status);
void onPeriodicAdvertisingParametersUpdated(in int advertiserId, in int status);
void onPeriodicAdvertisingDataSet(in int advertiserId, in int status);
- void onPeriodicAdvertisingEnable(in int advertiserId, in boolean enable, in int status);
+ void onPeriodicAdvertisingEnabled(in int advertiserId, in boolean enable, in int status);
}
diff --git a/core/java/android/bluetooth/le/ScanResult.java b/core/java/android/bluetooth/le/ScanResult.java
index 583ddd2..745cd16 100644
--- a/core/java/android/bluetooth/le/ScanResult.java
+++ b/core/java/android/bluetooth/le/ScanResult.java
@@ -67,12 +67,12 @@
public static final int SID_NOT_PRESENT = 0xFF;
/**
- * Mask for checking wether event type represents legacy advertisement.
+ * Mask for checking whether event type represents legacy advertisement.
*/
private static final int ET_LEGACY_MASK = 0x10;
/**
- * Mask for checking wether event type represents connectable advertisement.
+ * Mask for checking whether event type represents connectable advertisement.
*/
private static final int ET_CONNECTABLE_MASK = 0x01;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index b7876d9..2ce22b4 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -1083,18 +1083,7 @@
* @hide
*/
public static final String ACTION_CALL_PRIVILEGED = "android.intent.action.CALL_PRIVILEGED";
- /**
- * Activity action: Activate the current SIM card. If SIM cards do not require activation,
- * sending this intent is a no-op.
- * <p>Input: No data should be specified. get*Extra may have an optional
- * {@link #EXTRA_SIM_ACTIVATION_RESPONSE} field containing a PendingIntent through which to
- * send the activation result.
- * <p>Output: nothing.
- * @hide
- */
- @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_SIM_ACTIVATION_REQUEST =
- "android.intent.action.SIM_ACTIVATION_REQUEST";
+
/**
* Activity Action: Main entry point for carrier setup apps.
* <p>Carrier apps that provide an implementation for this action may be invoked to configure
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 11d247b..e163365 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -2956,7 +2956,6 @@
* @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
* @throws IllegalArgumentException if {@code request} specifies any mutable
* {@code NetworkCapabilities}.
- * @hide
*/
public void requestNetwork(
NetworkRequest request, NetworkCallback networkCallback, Handler handler) {
@@ -3073,8 +3072,6 @@
* @param networkCallback The {@link NetworkCallback} to be utilized for this request. Note
* the callback must not be shared - it uniquely specifies this request.
* @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
- *
- * @hide
*/
public void requestNetwork(NetworkRequest request, int timeoutMs,
NetworkCallback networkCallback, Handler handler) {
@@ -3214,7 +3211,6 @@
* @param networkCallback The {@link NetworkCallback} that the system will call as suitable
* networks change state.
* @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
- * @hide
*/
public void registerNetworkCallback(
NetworkRequest request, NetworkCallback networkCallback, Handler handler) {
@@ -3288,7 +3284,6 @@
* @param networkCallback The {@link NetworkCallback} that the system will call as the
* system default network changes.
* @param handler {@link Handler} to specify the thread upon which the callback will be invoked.
- * @hide
*/
public void registerDefaultNetworkCallback(NetworkCallback networkCallback, Handler handler) {
// This works because if the NetworkCapabilities are null,
diff --git a/core/java/android/os/HwParcel.java b/core/java/android/os/HwParcel.java
index a265dd0..94fd5b0 100644
--- a/core/java/android/os/HwParcel.java
+++ b/core/java/android/os/HwParcel.java
@@ -219,6 +219,7 @@
public native final void writeStatus(int status);
public native final void verifySuccess();
public native final void releaseTemporaryStorage();
+ public native final void release();
public native final void send();
diff --git a/core/java/android/os/IBatteryPropertiesRegistrar.aidl b/core/java/android/os/IBatteryPropertiesRegistrar.aidl
index fd01802..468b58b 100644
--- a/core/java/android/os/IBatteryPropertiesRegistrar.aidl
+++ b/core/java/android/os/IBatteryPropertiesRegistrar.aidl
@@ -27,4 +27,5 @@
void registerListener(IBatteryPropertiesListener listener);
void unregisterListener(IBatteryPropertiesListener listener);
int getProperty(in int id, out BatteryProperty prop);
+ oneway void scheduleUpdate();
}
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index 2bf3c2c..c520917 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -35,6 +35,12 @@
private static final String TAG = "SystemProperties";
private static final boolean TRACK_KEY_ACCESS = false;
+ /**
+ * Android O removed the property name length limit, but com.amazon.kindle 7.8.1.5
+ * uses reflection to read this whenever text is selected (http://b/36095274).
+ */
+ public static final int PROP_NAME_MAX = Integer.MAX_VALUE;
+
public static final int PROP_VALUE_MAX = 91;
private static final ArrayList<Runnable> sChangeCallbacks = new ArrayList<Runnable>();
diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java
index 6a10743..203b8dd 100644
--- a/core/java/android/widget/ListPopupWindow.java
+++ b/core/java/android/widget/ListPopupWindow.java
@@ -600,6 +600,10 @@
mPopup.setWindowLayoutType(mDropDownWindowLayoutType);
if (mPopup.isShowing()) {
+ if (!getAnchorView().isAttachedToWindow()) {
+ //Don't update position if the anchor view is detached from window.
+ return;
+ }
final int widthSpec;
if (mDropDownWidth == ViewGroup.LayoutParams.MATCH_PARENT) {
// The call to PopupWindow's update method below can accept -1 for any
diff --git a/core/java/com/android/internal/os/WrapperInit.java b/core/java/com/android/internal/os/WrapperInit.java
index dbbebbe7..aced75d 100644
--- a/core/java/com/android/internal/os/WrapperInit.java
+++ b/core/java/com/android/internal/os/WrapperInit.java
@@ -17,6 +17,11 @@
package com.android.internal.os;
import android.os.Process;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.system.StructCapUserData;
+import android.system.StructCapUserHeader;
import android.util.Slog;
import com.android.internal.os.Zygote.MethodAndArgsCaller;
import dalvik.system.VMRuntime;
@@ -119,6 +124,7 @@
command.append(' ');
command.append(targetSdkVersion);
Zygote.appendQuotedShellArgs(command, args);
+ preserveCapabilities();
Zygote.execShell(command.toString());
}
@@ -139,6 +145,74 @@
Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from wrapper");
}
- RuntimeInit.applicationInit(targetSdkVersion, argv, null);
+ // Check whether the first argument is a "-cp" in argv, and assume the next argument is the
+ // classpath. If found, create a PathClassLoader and use it for applicationInit.
+ ClassLoader classLoader = null;
+ if (argv != null && argv.length > 2 && argv[0].equals("-cp")) {
+ classLoader = ZygoteInit.createPathClassLoader(argv[1], targetSdkVersion);
+
+ // Install this classloader as the context classloader, too.
+ Thread.currentThread().setContextClassLoader(classLoader);
+
+ // Remove the classpath from the arguments.
+ String removedArgs[] = new String[argv.length - 2];
+ System.arraycopy(argv, 2, removedArgs, 0, argv.length - 2);
+ argv = removedArgs;
+ }
+
+ RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
+ }
+
+ /**
+ * Copy current capabilities to ambient capabilities. This is required for apps using
+ * capabilities, as execv will re-evaluate the capability set, and the set of sh is
+ * empty. Ambient capabilities have to be set to inherit them effectively.
+ *
+ * Note: This is BEST EFFORT ONLY. In case capabilities can't be raised, this function
+ * will silently return. In THIS CASE ONLY, as this is a development feature, it
+ * is better to return and try to run anyways, instead of blocking the wrapped app.
+ * This is acceptable here as failure will leave the wrapped app with strictly less
+ * capabilities, which may make it crash, but not exceed its allowances.
+ */
+ private static void preserveCapabilities() {
+ StructCapUserHeader header = new StructCapUserHeader(
+ OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
+ StructCapUserData[] data;
+ try {
+ data = Os.capget(header);
+ } catch (ErrnoException e) {
+ Slog.e(RuntimeInit.TAG, "RuntimeInit: Failed capget", e);
+ return;
+ }
+
+ if (data[0].permitted != data[0].inheritable ||
+ data[1].permitted != data[1].inheritable) {
+ data[0] = new StructCapUserData(data[0].effective, data[0].permitted,
+ data[0].permitted);
+ data[1] = new StructCapUserData(data[1].effective, data[1].permitted,
+ data[1].permitted);
+ try {
+ Os.capset(header, data);
+ } catch (ErrnoException e) {
+ Slog.e(RuntimeInit.TAG, "RuntimeInit: Failed capset", e);
+ return;
+ }
+ }
+
+ for (int i = 0; i < 64; i++) {
+ int dataIndex = OsConstants.CAP_TO_INDEX(i);
+ int capMask = OsConstants.CAP_TO_MASK(i);
+ if ((data[dataIndex].inheritable & capMask) != 0) {
+ try {
+ Os.prctl(OsConstants.PR_CAP_AMBIENT, OsConstants.PR_CAP_AMBIENT_RAISE, i, 0,
+ 0);
+ } catch (ErrnoException ex) {
+ // Only log here. Try to run the wrapped application even without this
+ // ambient capability. It may crash after fork, but at least we'll try.
+ Slog.e(RuntimeInit.TAG, "RuntimeInit: Failed to raise ambient capability "
+ + i, ex);
+ }
+ }
+ }
}
}
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index 59416dd..e065843 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -100,6 +100,8 @@
int[][] rlimits, int mountExternal, String seInfo, String niceName, int[] fdsToClose,
int[] fdsToIgnore, String instructionSet, String appDataDir) {
VM_HOOKS.preFork();
+ // Resets nice priority for zygote process.
+ resetNicePriority();
int pid = nativeForkAndSpecialize(
uid, gid, gids, debugFlags, rlimits, mountExternal, seInfo, niceName, fdsToClose,
fdsToIgnore, instructionSet, appDataDir);
@@ -144,6 +146,8 @@
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
VM_HOOKS.preFork();
+ // Resets nice priority for zygote process.
+ resetNicePriority();
int pid = nativeForkSystemServer(
uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
// Enable tracing as soon as we enter the system_server.
@@ -173,6 +177,14 @@
VM_HOOKS.postForkChild(debugFlags, isSystemServer, instructionSet);
}
+ /**
+ * Resets the calling thread priority to the default value (Thread.NORM_PRIORITY
+ * or nice value 0). This updates both the priority value in java.lang.Thread and
+ * the nice value (setpriority).
+ */
+ static void resetNicePriority() {
+ Thread.currentThread().setPriority(Thread.NORM_PRIORITY);
+ }
/**
* Executes "/system/bin/sh -c <command>" using the exec() system call.
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 1e0a998..e560c0c7 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -449,7 +449,8 @@
String[] amendedArgs = new String[args.length + 2];
amendedArgs[0] = "-cp";
amendedArgs[1] = systemServerClasspath;
- System.arraycopy(parsedArgs.remainingArgs, 0, amendedArgs, 2, parsedArgs.remainingArgs.length);
+ System.arraycopy(args, 0, amendedArgs, 2, args.length);
+ args = amendedArgs;
}
WrapperInit.execApplication(parsedArgs.invokeWith,
@@ -458,8 +459,7 @@
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
- cl = createSystemServerClassLoader(systemServerClasspath,
- parsedArgs.targetSdkVersion);
+ cl = createPathClassLoader(systemServerClasspath, parsedArgs.targetSdkVersion);
Thread.currentThread().setContextClassLoader(cl);
}
@@ -474,15 +474,14 @@
}
/**
- * Creates a PathClassLoader for the system server. It also creates
- * a shared namespace associated with the classloader to let it access
- * platform-private native libraries.
+ * Creates a PathClassLoader for the given class path that is associated with a shared
+ * namespace, i.e., this classloader can access platform-private native libraries. The
+ * classloader will use java.library.path as the native library path.
*/
- private static PathClassLoader createSystemServerClassLoader(String systemServerClasspath,
- int targetSdkVersion) {
+ static PathClassLoader createPathClassLoader(String classPath, int targetSdkVersion) {
String libraryPath = System.getProperty("java.library.path");
- return PathClassLoaderFactory.createClassLoader(systemServerClasspath,
+ return PathClassLoaderFactory.createClassLoader(classPath,
libraryPath,
libraryPath,
ClassLoader.getSystemClassLoader(),
diff --git a/core/jni/android_os_HwParcel.cpp b/core/jni/android_os_HwParcel.cpp
index 1bd2333..678041f 100644
--- a/core/jni/android_os_HwParcel.cpp
+++ b/core/jni/android_os_HwParcel.cpp
@@ -404,6 +404,11 @@
signalExceptionForError(env, err);
}
+static void JHwParcel_native_release(
+ JNIEnv *env, jobject thiz) {
+ JHwParcel::GetNativeContext(env, thiz)->setParcel(NULL, false /* assumeOwnership */);
+}
+
static void JHwParcel_native_releaseTemporaryStorage(
JNIEnv *env, jobject thiz) {
JHwParcel::GetNativeContext(env, thiz)->getStorage()->release(env);
@@ -955,6 +960,10 @@
{ "writeBuffer", "(L" PACKAGE_PATH "/HwBlob;)V",
(void *)JHwParcel_native_writeBuffer },
+
+ { "release", "()V",
+ (void *)JHwParcel_native_release },
+
};
namespace android {
diff --git a/core/jni/com_android_internal_os_Zygote.cpp b/core/jni/com_android_internal_os_Zygote.cpp
index 3498108..90ad2da 100644
--- a/core/jni/com_android_internal_os_Zygote.cpp
+++ b/core/jni/com_android_internal_os_Zygote.cpp
@@ -155,24 +155,6 @@
}
}
-// Resets nice priority for zygote process. Zygote priority can be set
-// to high value during boot phase to speed it up. We want to ensure
-// zygote is running at normal priority before childs are forked from it.
-//
-// This ends up being called repeatedly before each fork(), but there's
-// no real harm in that.
-static void ResetNicePriority(JNIEnv* env) {
- errno = 0;
- int prio = getpriority(PRIO_PROCESS, 0);
- if (prio == -1 && errno != 0) {
- ALOGW("getpriority failed: %s\n", strerror(errno));
- }
- if (prio != 0 && setpriority(PRIO_PROCESS, 0, 0) != 0) {
- ALOGE("setpriority(%d, 0, 0) failed: %s", PRIO_PROCESS, strerror(errno));
- RuntimeAbort(env, __LINE__, "setpriority failed");
- }
-}
-
// Sets the SIGCHLD handler back to default behavior in zygote children.
static void UnsetSigChldHandler() {
struct sigaction sa;
@@ -512,8 +494,6 @@
RuntimeAbort(env, __LINE__, "Unable to restat file descriptor table.");
}
- ResetNicePriority(env);
-
pid_t pid = fork();
if (pid == 0) {
diff --git a/core/jni/fd_utils.cpp b/core/jni/fd_utils.cpp
index 9660de4..956b724 100644
--- a/core/jni/fd_utils.cpp
+++ b/core/jni/fd_utils.cpp
@@ -26,7 +26,9 @@
#include <sys/un.h>
#include <unistd.h>
+#include <android-base/file.h>
#include <android-base/logging.h>
+#include <android-base/stringprintf.h>
#include <android-base/strings.h>
// Static whitelist of open paths that the zygote is allowed to keep open.
@@ -65,9 +67,10 @@
return true;
}
- static const std::string kFrameworksPrefix = "/system/framework/";
- static const std::string kJarSuffix = ".jar";
- if (StartsWith(path, kFrameworksPrefix) && EndsWith(path, kJarSuffix)) {
+ static const char* kFrameworksPrefix = "/system/framework/";
+ static const char* kJarSuffix = ".jar";
+ if (android::base::StartsWith(path, kFrameworksPrefix)
+ && android::base::EndsWith(path, kJarSuffix)) {
return true;
}
@@ -79,28 +82,31 @@
// /data/resource-cache/system@vendor@overlay@framework-res.apk@idmap
// /data/resource-cache/system@vendor@overlay-subdir@pg@framework-res.apk@idmap
// See AssetManager.cpp for more details on overlay-subdir.
- static const std::string kOverlayDir = "/system/vendor/overlay/";
- static const std::string kVendorOverlayDir = "/vendor/overlay";
- static const std::string kOverlaySubdir = "/system/vendor/overlay-subdir/";
- static const std::string kApkSuffix = ".apk";
+ static const char* kOverlayDir = "/system/vendor/overlay/";
+ static const char* kVendorOverlayDir = "/vendor/overlay";
+ static const char* kOverlaySubdir = "/system/vendor/overlay-subdir/";
+ static const char* kApkSuffix = ".apk";
- if ((StartsWith(path, kOverlayDir) || StartsWith(path, kOverlaySubdir)
- || StartsWith(path, kVendorOverlayDir))
- && EndsWith(path, kApkSuffix)
+ if ((android::base::StartsWith(path, kOverlayDir)
+ || android::base::StartsWith(path, kOverlaySubdir)
+ || android::base::StartsWith(path, kVendorOverlayDir))
+ && android::base::EndsWith(path, kApkSuffix)
&& path.find("/../") == std::string::npos) {
return true;
}
- static const std::string kOverlayIdmapPrefix = "/data/resource-cache/";
- static const std::string kOverlayIdmapSuffix = ".apk@idmap";
- if (StartsWith(path, kOverlayIdmapPrefix) && EndsWith(path, kOverlayIdmapSuffix)
+ static const char* kOverlayIdmapPrefix = "/data/resource-cache/";
+ static const char* kOverlayIdmapSuffix = ".apk@idmap";
+ if (android::base::StartsWith(path, kOverlayIdmapPrefix)
+ && android::base::EndsWith(path, kOverlayIdmapSuffix)
&& path.find("/../") == std::string::npos) {
return true;
}
// All regular files that are placed under this path are whitelisted automatically.
- static const std::string kZygoteWhitelistPath = "/vendor/zygote_whitelist/";
- if (StartsWith(path, kZygoteWhitelistPath) && path.find("/../") == std::string::npos) {
+ static const char* kZygoteWhitelistPath = "/vendor/zygote_whitelist/";
+ if (android::base::StartsWith(path, kZygoteWhitelistPath)
+ && path.find("/../") == std::string::npos) {
return true;
}
@@ -111,24 +117,6 @@
: whitelist_() {
}
-// TODO: Call android::base::StartsWith instead of copying the code here.
-// static
-bool FileDescriptorWhitelist::StartsWith(const std::string& str,
- const std::string& prefix) {
- return str.compare(0, prefix.size(), prefix) == 0;
-}
-
-// TODO: Call android::base::EndsWith instead of copying the code here.
-// static
-bool FileDescriptorWhitelist::EndsWith(const std::string& str,
- const std::string& suffix) {
- if (suffix.size() > str.size()) {
- return false;
- }
-
- return str.compare(str.size() - suffix.size(), suffix.size(), suffix) == 0;
-}
-
FileDescriptorWhitelist* FileDescriptorWhitelist::instance_ = nullptr;
// static
@@ -174,7 +162,8 @@
}
std::string file_path;
- if (!Readlink(fd, &file_path)) {
+ const std::string fd_path = android::base::StringPrintf("/proc/self/fd/%d", fd);
+ if (!android::base::Readlink(fd_path, &file_path)) {
return NULL;
}
@@ -299,30 +288,6 @@
is_sock(false) {
}
-// TODO: Call android::base::Readlink instead of copying the code here.
-// static
-bool FileDescriptorInfo::Readlink(const int fd, std::string* result) {
- char path[64];
- snprintf(path, sizeof(path), "/proc/self/fd/%d", fd);
-
- // Code copied from android::base::Readlink starts here :
-
- // Annoyingly, the readlink system call returns EINVAL for a zero-sized buffer,
- // and truncates to whatever size you do supply, so it can't be used to query.
- // We could call lstat first, but that would introduce a race condition that
- // we couldn't detect.
- // ext2 and ext4 both have PAGE_SIZE limitations, so we assume that here.
- char buf[4096];
- ssize_t len = readlink(path, buf, sizeof(buf));
- if (len == -1) {
- PLOG(ERROR) << "Readlink on " << fd << " failed.";
- return false;
- }
-
- result->assign(buf, len);
- return true;
-}
-
// static
bool FileDescriptorInfo::GetSocketName(const int fd, std::string* result) {
sockaddr_storage ss;
diff --git a/core/jni/fd_utils.h b/core/jni/fd_utils.h
index 03298c3..a39e387 100644
--- a/core/jni/fd_utils.h
+++ b/core/jni/fd_utils.h
@@ -59,10 +59,6 @@
private:
FileDescriptorWhitelist();
- static bool StartsWith(const std::string& str, const std::string& prefix);
-
- static bool EndsWith(const std::string& str, const std::string& suffix);
-
static FileDescriptorWhitelist* instance_;
std::vector<std::string> whitelist_;
@@ -99,8 +95,6 @@
FileDescriptorInfo(struct stat stat, const std::string& file_path, int fd, int open_flags,
int fd_flags, int fs_flags, off_t offset);
- static bool Readlink(const int fd, std::string* result);
-
// Returns the locally-bound name of the socket |fd|. Returns true
// iff. all of the following hold :
//
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 7d4f99d..c3b2aa1 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1300,7 +1300,7 @@
<permission android:name="android.permission.CONNECTIVITY_INTERNAL"
android:protectionLevel="signature|privileged" />
- <!-- Allows an internal user to use restricted Networks.
+ <!-- @SystemApi Allows an internal user to use restricted Networks.
@hide -->
<permission android:name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"
android:protectionLevel="signature|privileged" />
diff --git a/core/res/res/drawable-hdpi/stat_notify_mmcc_indication_icn.png b/core/res/res/drawable-hdpi/stat_notify_mmcc_indication_icn.png
new file mode 100644
index 0000000..d704951
--- /dev/null
+++ b/core/res/res/drawable-hdpi/stat_notify_mmcc_indication_icn.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_notify_mmcc_indication_icn.png b/core/res/res/drawable-xhdpi/stat_notify_mmcc_indication_icn.png
new file mode 100644
index 0000000..5dfc89e
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/stat_notify_mmcc_indication_icn.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/stat_notify_mmcc_indication_icn.png b/core/res/res/drawable-xxhdpi/stat_notify_mmcc_indication_icn.png
new file mode 100644
index 0000000..a648b0b
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/stat_notify_mmcc_indication_icn.png
Binary files differ
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 2b2e18b..beb495de 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -462,6 +462,8 @@
<integer translatable="false" name="config_wifi_framework_LAST_SELECTION_AWARD">480</integer>
<integer translatable="false" name="config_wifi_framework_PASSPOINT_SECURITY_AWARD">40</integer>
<integer translatable="false" name="config_wifi_framework_SECURITY_AWARD">80</integer>
+ <!-- Integer specifying the base interval in seconds for the exponential backoff scan for autojoin -->
+ <integer translatable="false" name="config_wifi_framework_exponential_backoff_scan_base_interval">20</integer>
<!-- Integer parameters of the wifi to cellular handover feature
wifi should not stick to bad networks -->
<integer translatable="false" name="config_wifi_framework_wifi_score_bad_rssi_threshold_5GHz">-82</integer>
@@ -1391,6 +1393,9 @@
<!-- Boolean indicating if current platform supports BLE peripheral mode -->
<bool name="config_bluetooth_le_peripheral_mode_supported">false</bool>
+ <!-- Boolean indicating if current platform supports HFP inband ringing -->
+ <bool name="config_bluetooth_hfp_inband_ringing_support">false</bool>
+
<!-- Max number of scan filters supported by blutooth controller. 0 if the
device does not support hardware scan filters-->
<integer translatable="false" name="config_bluetooth_max_scan_filters">0</integer>
diff --git a/core/res/res/values/locale_config.xml b/core/res/res/values/locale_config.xml
index f07fe70..513bdd1 100644
--- a/core/res/res/values/locale_config.xml
+++ b/core/res/res/values/locale_config.xml
@@ -75,7 +75,7 @@
<item>ce-RU</item> <!-- Chechen (Russia) -->
<item>cgg-UG</item> <!-- Chiga (Uganda) -->
<item>chr-US</item> <!-- Cherokee (United States) -->
- <item>cs-CZ</item> <!-- Czech (Czech Republic) -->
+ <item>cs-CZ</item> <!-- Czech (Czechia) -->
<item>cy-GB</item> <!-- Welsh (United Kingdom) -->
<item>da-DK</item> <!-- Danish (Denmark) -->
<item>da-GL</item> <!-- Danish (Greenland) -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 4231698..5450e98 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4441,4 +4441,25 @@
<!-- Label used by Telephony code, assigned as the display name for conference calls [CHAR LIMIT=60] -->
<string name="conference_call">Conference Call</string>
+
+ <!-- Primary ETWS (Earthquake and Tsunami Warning System) default message for earthquake -->
+ <string name="etws_primary_default_message_earthquake">Stay calm and seek shelter nearby.</string>
+
+ <!-- Primary ETWS (Earthquake and Tsunami Warning System) default message for Tsunami -->
+ <string name="etws_primary_default_message_tsunami">Evacuate immediately from coastal regions and riverside areas to a safer place such as high ground.</string>
+
+ <!-- Primary ETWS (Earthquake and Tsunami Warning System) default message for earthquake and Tsunami -->
+ <string name="etws_primary_default_message_earthquake_and_tsunami">Stay calm and seek shelter nearby.</string>
+
+ <!-- Primary ETWS (Earthquake and Tsunami Warning System) default message for test -->
+ <string name="etws_primary_default_message_test">Emergency messages test</string>
+
+ <!-- Primary ETWS (Earthquake and Tsunami Warning System) default message for others -->
+ <string name="etws_primary_default_message_others"></string>
+
+ <!-- Title of notification when UE fails to register network with MM reject cause code. -->
+ <string name="mmcc_authentication_reject">SIM not allowed</string>
+ <string name="mmcc_imsi_unknown_in_hlr">SIM not provisioned</string>
+ <string name="mmcc_illegal_ms">SIM not allowed</string>
+ <string name="mmcc_illegal_me">Phone not allowed</string>
</resources>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index dbeda0b..a539af2 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -240,6 +240,7 @@
<java-symbol type="bool" name="config_bluetooth_address_validation" />
<java-symbol type="bool" name="config_bluetooth_sco_off_call" />
<java-symbol type="bool" name="config_bluetooth_le_peripheral_mode_supported" />
+ <java-symbol type="bool" name="config_bluetooth_hfp_inband_ringing_support" />
<java-symbol type="bool" name="config_cellBroadcastAppLinks" />
<java-symbol type="bool" name="config_duplicate_port_omadm_wappush" />
<java-symbol type="bool" name="config_enableAutoPowerModes" />
@@ -1290,6 +1291,8 @@
<java-symbol type="drawable" name="ic_sim_card_multi_24px_clr" />
<java-symbol type="drawable" name="ic_sim_card_multi_48px_clr" />
+ <java-symbol type="drawable" name="stat_notify_mmcc_indication_icn" />
+
<java-symbol type="drawable" name="ic_account_circle" />
<java-symbol type="color" name="user_icon_1" />
<java-symbol type="color" name="user_icon_2" />
@@ -1862,6 +1865,10 @@
<java-symbol type="string" name="low_internal_storage_view_text" />
<java-symbol type="string" name="low_internal_storage_view_text_no_boot" />
<java-symbol type="string" name="low_internal_storage_view_title" />
+ <java-symbol type="string" name="mmcc_authentication_reject" />
+ <java-symbol type="string" name="mmcc_imsi_unknown_in_hlr" />
+ <java-symbol type="string" name="mmcc_illegal_ms" />
+ <java-symbol type="string" name="mmcc_illegal_me" />
<java-symbol type="string" name="notification_listener_binding_label" />
<java-symbol type="string" name="vr_listener_binding_label" />
<java-symbol type="string" name="condition_provider_service_binding_label" />
@@ -2742,4 +2749,15 @@
<java-symbol type="array" name="config_networkRecommendationPackageNames" />
<java-symbol type="string" name="config_defaultCellBroadcastReceiverPkg" />
+
+ <!-- ETWS primary messages -->
+ <java-symbol type="string" name="etws_primary_default_message_earthquake" />
+
+ <java-symbol type="string" name="etws_primary_default_message_tsunami" />
+
+ <java-symbol type="string" name="etws_primary_default_message_earthquake_and_tsunami" />
+
+ <java-symbol type="string" name="etws_primary_default_message_test" />
+
+ <java-symbol type="string" name="etws_primary_default_message_others" />
</resources>
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index 29c6b79..1ae922a 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -79,7 +79,7 @@
<!-- Cyprus: 4-6 digits (not confirmed), known premium codes listed, plus EU -->
<shortcode country="cy" pattern="\\d{4,6}" premium="7510" free="116\\d{3}" />
- <!-- Czech Republic: 7-8 digits, starting with 9, plus EU:
+ <!-- Czechia: 7-8 digits, starting with 9, plus EU:
http://www.o2.cz/osobni/en/services-by-alphabet/91670-premium_sms.html -->
<shortcode country="cz" premium="9\\d{6,7}" free="116\\d{3}" />
diff --git a/core/res/res/xml/time_zones_by_country.xml b/core/res/res/xml/time_zones_by_country.xml
index a685e2b..6c1ce44 100644
--- a/core/res/res/xml/time_zones_by_country.xml
+++ b/core/res/res/xml/time_zones_by_country.xml
@@ -336,6 +336,10 @@
<timezone code="ck">Pacific/Rarotonga</timezone>
+ <!-- CHILE, -3:00 -->
+
+ <timezone code="cl">America/Punta_Arenas</timezone>
+
<!-- CHILE, -4:00 -->
<timezone code="cl">America/Santiago</timezone>
diff --git a/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java b/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
index 29020ba..48f2935 100644
--- a/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
+++ b/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java
@@ -32,10 +32,10 @@
import android.test.InstrumentationTestCase;
import com.android.internal.R;
import java.util.List;
-import org.mockito.ArgumentMatcher;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
+import org.mockito.compat.ArgumentMatcher;
public class NetworkScorerAppManagerTest extends InstrumentationTestCase {
@Mock private Context mMockContext;
@@ -218,7 +218,7 @@
when(mMockPm.resolveService(
Mockito.argThat(new ArgumentMatcher<Intent>() {
@Override
- public boolean matches(Object object) {
+ public boolean matchesObject(Object object) {
Intent intent = (Intent) object;
return NetworkScoreManager.ACTION_RECOMMEND_NETWORKS
.equals(intent.getAction())
diff --git a/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java b/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java
index 7a4980a..56e977c 100644
--- a/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java
+++ b/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java
@@ -109,7 +109,7 @@
}
public static String expectedSchedulerGroup(int prio) {
- return prio < Process.THREAD_PRIORITY_BACKGROUND ? "/" : "/bg_non_interactive";
+ return "/";
}
public void testPassPriorityToService() throws Exception {
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index e10db05..38d2a58 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -4320,6 +4320,7 @@
if (curOff > (dtohl(entry.type->header.size)-sizeof(ResTable_map))) {
ALOGW("ResTable_map at %d is beyond type chunk data %d",
(int)curOff, dtohl(entry.type->header.size));
+ free(set);
return BAD_TYPE;
}
map = (const ResTable_map*)(((const uint8_t*)entry.type) + curOff);
@@ -4332,6 +4333,7 @@
if (grp->dynamicRefTable.lookupResourceId(&newName) != NO_ERROR) {
ALOGE("Failed resolving ResTable_map name at %d with ident 0x%08x",
(int) curOff, (int) newName);
+ free(set);
return UNKNOWN_ERROR;
}
}
diff --git a/media/java/android/mtp/MtpDatabase.java b/media/java/android/mtp/MtpDatabase.java
index 760a2d1..56a5737 100755
--- a/media/java/android/mtp/MtpDatabase.java
+++ b/media/java/android/mtp/MtpDatabase.java
@@ -29,6 +29,7 @@
import android.net.Uri;
import android.os.BatteryManager;
import android.os.RemoteException;
+import android.os.SystemProperties;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio;
import android.provider.MediaStore.Files;
@@ -133,6 +134,8 @@
private int mBatteryLevel;
private int mBatteryScale;
+ private int mDeviceType;
+
static {
System.loadLibrary("media_jni");
}
@@ -195,6 +198,7 @@
}
initDeviceProperties(context);
+ mDeviceType = SystemProperties.getInt("sys.usb.mtp.device_type", 0);
mCloseGuard.open("close");
}
@@ -710,6 +714,7 @@
MtpConstants.DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME,
MtpConstants.DEVICE_PROPERTY_IMAGE_SIZE,
MtpConstants.DEVICE_PROPERTY_BATTERY_LEVEL,
+ MtpConstants.DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE,
};
}
@@ -869,6 +874,10 @@
outStringValue[imageSize.length()] = 0;
return MtpConstants.RESPONSE_OK;
+ case MtpConstants.DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE:
+ outIntValue[0] = mDeviceType;
+ return MtpConstants.RESPONSE_OK;
+
// DEVICE_PROPERTY_BATTERY_LEVEL is implemented in the JNI code
default:
diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp
index 34a7f7c..f7f79169 100644
--- a/media/jni/android_mtp_MtpDatabase.cpp
+++ b/media/jni/android_mtp_MtpDatabase.cpp
@@ -76,6 +76,7 @@
static jfieldID field_context;
static jfieldID field_batteryLevel;
static jfieldID field_batteryScale;
+static jfieldID field_deviceType;
// MtpPropertyList fields
static jfieldID field_mCount;
@@ -1030,6 +1031,7 @@
{ MTP_DEVICE_PROPERTY_DEVICE_FRIENDLY_NAME, MTP_TYPE_STR },
{ MTP_DEVICE_PROPERTY_IMAGE_SIZE, MTP_TYPE_STR },
{ MTP_DEVICE_PROPERTY_BATTERY_LEVEL, MTP_TYPE_UINT8 },
+ { MTP_DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE, MTP_TYPE_UINT32 },
};
bool MyMtpDatabase::getObjectPropertyInfo(MtpObjectProperty property, int& type) {
@@ -1209,6 +1211,10 @@
result->setFormRange(0, env->GetIntField(mDatabase, field_batteryScale), 1);
result->mCurrentValue.u.u8 = (uint8_t)env->GetIntField(mDatabase, field_batteryLevel);
break;
+ case MTP_DEVICE_PROPERTY_PERCEIVED_DEVICE_TYPE:
+ result = new MtpProperty(property, MTP_TYPE_UINT32);
+ result->mCurrentValue.u.u32 = (uint32_t)env->GetIntField(mDatabase, field_deviceType);
+ break;
}
checkAndClearExceptionFromCallback(env, __FUNCTION__);
@@ -1388,6 +1394,11 @@
ALOGE("Can't find MtpDatabase.mBatteryScale");
return -1;
}
+ field_deviceType = env->GetFieldID(clazz, "mDeviceType", "I");
+ if (field_deviceType == NULL) {
+ ALOGE("Can't find MtpDatabase.mDeviceType");
+ return -1;
+ }
// now set up fields for MtpPropertyList class
clazz = env->FindClass("android/mtp/MtpPropertyList");
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
index 6c879b9..a519f74 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/integration/CameraDeviceBinderTest.java
@@ -45,8 +45,8 @@
import com.android.mediaframeworktest.MediaFrameworkIntegrationTestRunner;
-import org.mockito.ArgumentMatcher;
import org.mockito.ArgumentCaptor;
+import org.mockito.compat.ArgumentMatcher;
import static org.mockito.Mockito.*;
public class CameraDeviceBinderTest extends AndroidTestCase {
@@ -158,7 +158,7 @@
class IsMetadataNotEmpty extends ArgumentMatcher<CameraMetadataNative> {
@Override
- public boolean matches(Object obj) {
+ public boolean matchesObject(Object obj) {
return !((CameraMetadataNative) obj).isEmpty();
}
}
diff --git a/packages/CarrierDefaultApp/AndroidManifest.xml b/packages/CarrierDefaultApp/AndroidManifest.xml
index 13e7e0d1..e450283 100644
--- a/packages/CarrierDefaultApp/AndroidManifest.xml
+++ b/packages/CarrierDefaultApp/AndroidManifest.xml
@@ -25,7 +25,6 @@
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
<uses-permission android:name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS" />
- <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.SUBSTITUTE_NOTIFICATION_APP_NAME" />
<application
@@ -36,10 +35,16 @@
<action android:name="com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED" />
</intent-filter>
</receiver>
- <activity android:name="com.android.carrierdefaultapp.CaptivePortalLaunchActivity"
- android:theme="@android:style/Theme.Translucent.NoTitleBar"
- android:excludeFromRecents="true"/>
<service android:name="com.android.carrierdefaultapp.ProvisionObserver"
android:permission="android.permission.BIND_JOB_SERVICE"/>
+ <activity
+ android:name="com.android.carrierdefaultapp.CaptivePortalLoginActivity"
+ android:label="@string/action_bar_label"
+ android:theme="@style/AppTheme"
+ android:configChanges="keyboardHidden|orientation|screenSize" >
+ <intent-filter>
+ <category android:name="android.intent.category.DEFAULT"/>
+ </intent-filter>
+ </activity>
</application>
</manifest>
diff --git a/packages/CarrierDefaultApp/assets/quantum_ic_warning_amber_96.png b/packages/CarrierDefaultApp/assets/quantum_ic_warning_amber_96.png
new file mode 100644
index 0000000..08294ce
--- /dev/null
+++ b/packages/CarrierDefaultApp/assets/quantum_ic_warning_amber_96.png
Binary files differ
diff --git a/packages/CarrierDefaultApp/res/drawable/ic_sim_card.xml b/packages/CarrierDefaultApp/res/drawable/ic_sim_card.xml
index dc54fe2..75aa405 100644
--- a/packages/CarrierDefaultApp/res/drawable/ic_sim_card.xml
+++ b/packages/CarrierDefaultApp/res/drawable/ic_sim_card.xml
@@ -22,4 +22,4 @@
<path
android:fillColor="#757575"
android:pathData="M18,2h-8L4.02,8 4,20c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,4c0,-1.1 -0.9,-2 -2,-2zM13,17h-2v-2h2v2zM13,13h-2L11,8h2v5z"/>
-</vector>
\ No newline at end of file
+</vector>
diff --git a/packages/CarrierDefaultApp/res/layout/activity_captive_portal_login.xml b/packages/CarrierDefaultApp/res/layout/activity_captive_portal_login.xml
new file mode 100644
index 0000000..528576b
--- /dev/null
+++ b/packages/CarrierDefaultApp/res/layout/activity_captive_portal_login.xml
@@ -0,0 +1,34 @@
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ tools:context="com.android.carrierdefaultapp.CaptivePortalLoginActivity"
+ tools:ignore="MergeRootFrame">
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/url_bar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="20sp"
+ android:singleLine="true" />
+
+ <ProgressBar
+ android:id="@+id/progress_bar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="?android:attr/progressBarStyleHorizontal" />
+
+ <WebView
+ android:id="@+id/webview"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_alignParentBottom="false"
+ android:layout_alignParentRight="false" />
+
+</LinearLayout>
+</FrameLayout>
diff --git a/packages/CarrierDefaultApp/res/values/dimens.xml b/packages/CarrierDefaultApp/res/values/dimens.xml
index a3c5049..1ea8c35 100644
--- a/packages/CarrierDefaultApp/res/values/dimens.xml
+++ b/packages/CarrierDefaultApp/res/values/dimens.xml
@@ -1,3 +1,6 @@
<resources>
<dimen name="glif_icon_size">32dp</dimen>
+ <!-- Default screen margins, per the Android Design guidelines. -->
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
</resources>
diff --git a/packages/CarrierDefaultApp/res/values/strings.xml b/packages/CarrierDefaultApp/res/values/strings.xml
index fe5669d..f9342b7 100644
--- a/packages/CarrierDefaultApp/res/values/strings.xml
+++ b/packages/CarrierDefaultApp/res/values/strings.xml
@@ -1,14 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">CarrierDefaultApp</string>
- <string name="android_system_label">Android System</string>
+ <string name="android_system_label">Mobile Carrier</string>
<string name="portal_notification_id">Mobile data has run out</string>
- <string name="no_data_notification_id">No Mobile data service</string>
- <string name="portal_notification_detail">Tap to add funds to your %s SIM</string>
+ <string name="no_data_notification_id">Your mobile data has been deactivated</string>
+ <string name="portal_notification_detail">Tap to visit the %s website</string>
<string name="no_data_notification_detail">Please contact your service provider %s</string>
- <string name="progress_dialogue_network_connection">Connecting to captive portal...</string>
- <string name="alert_dialogue_network_timeout">Network timeout, would you like to retry?</string>
- <string name="alert_dialogue_network_timeout_title">Network unavailable</string>
- <string name="quit">Quit</string>
- <string name="wait">Wait</string>
+ <string name="action_bar_label">Sign in to mobile network</string>
+ <string name="ssl_error_warning">The network you’re trying to join has security issues.</string>
+ <string name="ssl_error_example">For example, the login page may not belong to the organization shown.</string>
+ <string name="ssl_error_continue">Continue anyway via browser</string>
</resources>
diff --git a/packages/CarrierDefaultApp/res/values/styles.xml b/packages/CarrierDefaultApp/res/values/styles.xml
index 3d26915..939c1aa 100644
--- a/packages/CarrierDefaultApp/res/values/styles.xml
+++ b/packages/CarrierDefaultApp/res/values/styles.xml
@@ -1,3 +1,16 @@
<resources>
- <style name="AlertDialog" parent="android:Theme.Material.Light.Dialog.Alert"/>
+ <style name="AppBaseTheme" parent="@android:style/Theme.Material.Settings">
+ <!--
+ Theme customizations available in newer API levels can go in
+ res/values-vXX/styles.xml, while customizations related to
+ backward-compatibility can go here.
+ -->
+ </style>
+
+ <!-- Application theme. -->
+ <style name="AppTheme" parent="AppBaseTheme">
+ <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+ <!-- Setting's theme's accent color makes ProgressBar useless, reset back. -->
+ <item name="android:colorAccent">@*android:color/material_deep_teal_500</item>
+ </style>
</resources>
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLaunchActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLaunchActivity.java
deleted file mode 100644
index b7fde12..0000000
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLaunchActivity.java
+++ /dev/null
@@ -1,233 +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 com.android.carrierdefaultapp;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.ProgressDialog;
-import android.content.DialogInterface;
-import android.content.Intent;
-import android.net.CaptivePortal;
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.NetworkRequest;
-import android.os.Bundle;
-import android.telephony.CarrierConfigManager;
-import android.telephony.Rlog;
-import android.telephony.SubscriptionManager;
-import android.text.TextUtils;
-import android.net.ICaptivePortal;
-import android.view.ContextThemeWrapper;
-import android.view.WindowManager;
-import com.android.carrierdefaultapp.R;
-import com.android.internal.telephony.PhoneConstants;
-import com.android.internal.telephony.TelephonyIntents;
-import com.android.internal.util.ArrayUtils;
-
-import static android.net.CaptivePortal.APP_RETURN_DISMISSED;
-
-/**
- * Activity that launches in response to the captive portal notification
- * @see com.android.carrierdefaultapp.CarrierActionUtils#CARRIER_ACTION_SHOW_PORTAL_NOTIFICATION
- * This activity requests network connection if there is no available one, launches the
- * {@link com.android.captiveportallogin portalApp} and keeps track of the portal activation result.
- */
-public class CaptivePortalLaunchActivity extends Activity {
- private static final String TAG = CaptivePortalLaunchActivity.class.getSimpleName();
- private static final boolean DBG = true;
- public static final int NETWORK_REQUEST_TIMEOUT_IN_MS = 5 * 1000;
-
- private ConnectivityManager mCm = null;
- private ConnectivityManager.NetworkCallback mCb = null;
- /* Progress dialogue when request network connection for captive portal */
- private AlertDialog mProgressDialog = null;
- /* Alert dialogue when network request is timeout */
- private AlertDialog mAlertDialog = null;
-
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- mCm = ConnectivityManager.from(this);
- // Check network connection before loading portal
- Network network = getNetworkForCaptivePortal();
- NetworkInfo nwInfo = mCm.getNetworkInfo(network);
- if (nwInfo == null || !nwInfo.isConnected()) {
- if (DBG) logd("Network unavailable, request restricted connection");
- requestNetwork(getIntent());
- } else {
- launchCaptivePortal(getIntent(), network);
- }
- }
-
- // show progress dialog during network connecting
- private void showConnectingProgressDialog() {
- mProgressDialog = new ProgressDialog(getApplicationContext());
- mProgressDialog.setMessage(getString(R.string.progress_dialogue_network_connection));
- mProgressDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
- mProgressDialog.show();
- }
-
- // if network request is timeout, show alert dialog with two option: cancel & wait
- private void showConnectionTimeoutAlertDialog() {
- mAlertDialog = new AlertDialog.Builder(new ContextThemeWrapper(this, R.style.AlertDialog))
- .setMessage(getString(R.string.alert_dialogue_network_timeout))
- .setTitle(getString(R.string.alert_dialogue_network_timeout_title))
- .setNegativeButton(getString(R.string.quit),
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // cancel
- dismissDialog(mAlertDialog);
- finish();
- }
- })
- .setPositiveButton(getString(R.string.wait),
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- // wait, request network again
- dismissDialog(mAlertDialog);
- requestNetwork(getIntent());
- }
- })
- .create();
- mAlertDialog.show();
- }
-
- private void requestNetwork(final Intent intent) {
- NetworkRequest request = new NetworkRequest.Builder()
- .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
- .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
- .build();
-
- mCb = new ConnectivityManager.NetworkCallback() {
- @Override
- public void onAvailable(Network network) {
- if (DBG) logd("Network available: " + network);
- dismissDialog(mProgressDialog);
- mCm.bindProcessToNetwork(network);
- launchCaptivePortal(intent, network);
- }
-
- @Override
- public void onUnavailable() {
- if (DBG) logd("Network unavailable");
- dismissDialog(mProgressDialog);
- showConnectionTimeoutAlertDialog();
- }
- };
- showConnectingProgressDialog();
- mCm.requestNetwork(request, mCb, NETWORK_REQUEST_TIMEOUT_IN_MS);
- }
-
- private void releaseNetworkRequest() {
- logd("release Network Request");
- if (mCb != null) {
- mCm.unregisterNetworkCallback(mCb);
- mCb = null;
- }
- }
-
- private void dismissDialog(AlertDialog dialog) {
- if (dialog != null) {
- dialog.dismiss();
- }
- }
-
- private Network getNetworkForCaptivePortal() {
- Network[] info = mCm.getAllNetworks();
- if (!ArrayUtils.isEmpty(info)) {
- for (Network nw : info) {
- final NetworkCapabilities nc = mCm.getNetworkCapabilities(nw);
- if (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
- && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
- return nw;
- }
- }
- }
- return null;
- }
-
- private void launchCaptivePortal(final Intent intent, Network network) {
- String redirectUrl = intent.getStringExtra(TelephonyIntents.EXTRA_REDIRECTION_URL_KEY);
- int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
- SubscriptionManager.getDefaultVoiceSubscriptionId());
- if (TextUtils.isEmpty(redirectUrl) || !matchUrl(redirectUrl, subId)) {
- loge("Launch portal fails due to incorrect redirection URL: " +
- Rlog.pii(TAG, redirectUrl));
- return;
- }
- final Intent portalIntent = new Intent(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN);
- portalIntent.putExtra(ConnectivityManager.EXTRA_NETWORK, network);
- portalIntent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL,
- new CaptivePortal(new ICaptivePortal.Stub() {
- @Override
- public void appResponse(int response) {
- logd("portal response code: " + response);
- releaseNetworkRequest();
- if (response == APP_RETURN_DISMISSED) {
- // Upon success http response code, trigger re-evaluation
- CarrierActionUtils.applyCarrierAction(
- CarrierActionUtils.CARRIER_ACTION_ENABLE_RADIO, intent,
- getApplicationContext());
- CarrierActionUtils.applyCarrierAction(
- CarrierActionUtils.CARRIER_ACTION_ENABLE_METERED_APNS, intent,
- getApplicationContext());
- CarrierActionUtils.applyCarrierAction(
- CarrierActionUtils.CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS,
- intent, getApplicationContext());
- }
- }
- }));
- portalIntent.putExtra(ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL, redirectUrl);
- portalIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- if (DBG) logd("launching portal");
- startActivity(portalIntent);
- finish();
- }
-
- // match configured redirection url
- private boolean matchUrl(String url, int subId) {
- CarrierConfigManager configManager = getApplicationContext()
- .getSystemService(CarrierConfigManager.class);
- String[] redirectURLs = configManager.getConfigForSubId(subId).getStringArray(
- CarrierConfigManager.KEY_CARRIER_DEFAULT_REDIRECTION_URL_STRING_ARRAY);
- if (ArrayUtils.isEmpty(redirectURLs)) {
- if (DBG) logd("match is unnecessary without any configured redirection url");
- return true;
- }
- for (String redirectURL : redirectURLs) {
- if (url.startsWith(redirectURL)) {
- return true;
- }
- }
- if (DBG) loge("no match found for configured redirection url");
- return false;
- }
-
- private static void logd(String s) {
- Rlog.d(TAG, s);
- }
-
- private static void loge(String s) {
- Rlog.d(TAG, s);
- }
-}
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
new file mode 100644
index 0000000..ec4c00e
--- /dev/null
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CaptivePortalLoginActivity.java
@@ -0,0 +1,433 @@
+/*
+ * 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.carrierdefaultapp;
+
+import android.app.Activity;
+import android.app.LoadedApk;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
+import android.net.Network;
+import android.net.NetworkCapabilities;
+import android.net.NetworkRequest;
+import android.net.Proxy;
+import android.net.TrafficStats;
+import android.net.Uri;
+import android.net.http.SslError;
+import android.os.Bundle;
+import android.telephony.CarrierConfigManager;
+import android.telephony.Rlog;
+import android.telephony.SubscriptionManager;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.TypedValue;
+import android.webkit.SslErrorHandler;
+import android.webkit.WebChromeClient;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import com.android.internal.telephony.PhoneConstants;
+import com.android.internal.telephony.TelephonyIntents;
+import com.android.internal.util.ArrayUtils;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Random;
+
+/**
+ * Activity that launches in response to the captive portal notification
+ * @see com.android.carrierdefaultapp.CarrierActionUtils#CARRIER_ACTION_SHOW_PORTAL_NOTIFICATION
+ * This activity requests network connection if there is no available one before loading the real
+ * portal page and apply carrier actions on the portal activation result.
+ */
+public class CaptivePortalLoginActivity extends Activity {
+ private static final String TAG = CaptivePortalLoginActivity.class.getSimpleName();
+ private static final boolean DBG = true;
+
+ private static final int SOCKET_TIMEOUT_MS = 10 * 1000;
+ private static final int NETWORK_REQUEST_TIMEOUT_MS = 5 * 1000;
+
+ private URL mUrl;
+ private Network mNetwork;
+ private NetworkCallback mNetworkCallback;
+ private ConnectivityManager mCm;
+ private WebView mWebView;
+ private MyWebViewClient mWebViewClient;
+ private boolean mLaunchBrowser = false;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mCm = ConnectivityManager.from(this);
+ mUrl = getUrlForCaptivePortal();
+ if (mUrl == null) {
+ done(false);
+ return;
+ }
+ if (DBG) logd(String.format("onCreate for %s", mUrl.toString()));
+ setContentView(R.layout.activity_captive_portal_login);
+ getActionBar().setDisplayShowHomeEnabled(false);
+
+ mWebView = (WebView) findViewById(R.id.webview);
+ mWebView.clearCache(true);
+ WebSettings webSettings = mWebView.getSettings();
+ webSettings.setJavaScriptEnabled(true);
+ webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
+ mWebViewClient = new MyWebViewClient();
+ mWebView.setWebViewClient(mWebViewClient);
+ mWebView.setWebChromeClient(new MyWebChromeClient());
+
+ mNetwork = getNetworkForCaptivePortal();
+ if (mNetwork == null) {
+ requestNetworkForCaptivePortal();
+ } else {
+ mCm.bindProcessToNetwork(mNetwork);
+ // Start initial page load so WebView finishes loading proxy settings.
+ // Actual load of mUrl is initiated by MyWebViewClient.
+ mWebView.loadData("", "text/html", null);
+ }
+ }
+
+ @Override
+ public void onBackPressed() {
+ WebView myWebView = (WebView) findViewById(R.id.webview);
+ if (myWebView.canGoBack() && mWebViewClient.allowBack()) {
+ myWebView.goBack();
+ } else {
+ super.onBackPressed();
+ }
+ }
+
+ @Override
+ public void onDestroy() {
+ super.onDestroy();
+ releaseNetworkRequest();
+ if (mLaunchBrowser) {
+ // Give time for this network to become default. After 500ms just proceed.
+ for (int i = 0; i < 5; i++) {
+ // TODO: This misses when mNetwork underlies a VPN.
+ if (mNetwork.equals(mCm.getActiveNetwork())) break;
+ try {
+ Thread.sleep(100);
+ } catch (InterruptedException e) {
+ }
+ }
+ final String url = mUrl.toString();
+ if (DBG) logd("starting activity with intent ACTION_VIEW for " + url);
+ startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
+ }
+ }
+
+ // Find WebView's proxy BroadcastReceiver and prompt it to read proxy system properties.
+ private void setWebViewProxy() {
+ LoadedApk loadedApk = getApplication().mLoadedApk;
+ try {
+ Field receiversField = LoadedApk.class.getDeclaredField("mReceivers");
+ receiversField.setAccessible(true);
+ ArrayMap receivers = (ArrayMap) receiversField.get(loadedApk);
+ for (Object receiverMap : receivers.values()) {
+ for (Object rec : ((ArrayMap) receiverMap).keySet()) {
+ Class clazz = rec.getClass();
+ if (clazz.getName().contains("ProxyChangeListener")) {
+ Method onReceiveMethod = clazz.getDeclaredMethod("onReceive", Context.class,
+ Intent.class);
+ Intent intent = new Intent(Proxy.PROXY_CHANGE_ACTION);
+ onReceiveMethod.invoke(rec, getApplicationContext(), intent);
+ Log.v(TAG, "Prompting WebView proxy reload.");
+ }
+ }
+ }
+ } catch (Exception e) {
+ loge("Exception while setting WebView proxy: " + e);
+ }
+ }
+
+ private void done(boolean success) {
+ if (DBG) logd(String.format("Result success %b for %s", success, mUrl.toString()));
+ if (success) {
+ // Trigger re-evaluation upon success http response code
+ CarrierActionUtils.applyCarrierAction(
+ CarrierActionUtils.CARRIER_ACTION_ENABLE_RADIO, getIntent(),
+ getApplicationContext());
+ CarrierActionUtils.applyCarrierAction(
+ CarrierActionUtils.CARRIER_ACTION_ENABLE_METERED_APNS, getIntent(),
+ getApplicationContext());
+ CarrierActionUtils.applyCarrierAction(
+ CarrierActionUtils.CARRIER_ACTION_CANCEL_ALL_NOTIFICATIONS, getIntent(),
+ getApplicationContext());
+
+ }
+ finishAndRemoveTask();
+ }
+
+ private URL getUrlForCaptivePortal() {
+ String url = getIntent().getStringExtra(TelephonyIntents.EXTRA_REDIRECTION_URL_KEY);
+ if (url.isEmpty()) {
+ url = mCm.getCaptivePortalServerUrl();
+ }
+ final CarrierConfigManager configManager = getApplicationContext()
+ .getSystemService(CarrierConfigManager.class);
+ final int subId = getIntent().getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
+ SubscriptionManager.getDefaultVoiceSubscriptionId());
+ final String[] portalURLs = configManager.getConfigForSubId(subId).getStringArray(
+ CarrierConfigManager.KEY_CARRIER_DEFAULT_REDIRECTION_URL_STRING_ARRAY);
+ if (!ArrayUtils.isEmpty(portalURLs)) {
+ for (String portalUrl : portalURLs) {
+ if (url.startsWith(portalUrl)) {
+ break;
+ }
+ }
+ url = null;
+ }
+ try {
+ return new URL(url);
+ } catch (MalformedURLException e) {
+ loge("Invalid captive portal URL " + url);
+ }
+ return null;
+ }
+
+ private void testForCaptivePortal() {
+ new Thread(new Runnable() {
+ public void run() {
+ // Give time for captive portal to open.
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ }
+ HttpURLConnection urlConnection = null;
+ int httpResponseCode = 500;
+ TrafficStats.setThreadStatsTag(TrafficStats.TAG_SYSTEM_PROBE);
+ try {
+ urlConnection = (HttpURLConnection) mNetwork.openConnection(mUrl);
+ urlConnection.setInstanceFollowRedirects(false);
+ urlConnection.setConnectTimeout(SOCKET_TIMEOUT_MS);
+ urlConnection.setReadTimeout(SOCKET_TIMEOUT_MS);
+ urlConnection.setUseCaches(false);
+ urlConnection.getInputStream();
+ httpResponseCode = urlConnection.getResponseCode();
+ } catch (IOException e) {
+ } finally {
+ if (urlConnection != null) urlConnection.disconnect();
+ }
+ if (httpResponseCode == 204) {
+ done(true);
+ }
+ }
+ }).start();
+ }
+
+ private Network getNetworkForCaptivePortal() {
+ Network[] info = mCm.getAllNetworks();
+ if (!ArrayUtils.isEmpty(info)) {
+ for (Network nw : info) {
+ final NetworkCapabilities nc = mCm.getNetworkCapabilities(nw);
+ if (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
+ && nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
+ return nw;
+ }
+ }
+ }
+ return null;
+ }
+
+ private void requestNetworkForCaptivePortal() {
+ NetworkRequest request = new NetworkRequest.Builder()
+ .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
+ .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
+ .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
+ .build();
+
+ mNetworkCallback = new ConnectivityManager.NetworkCallback() {
+ @Override
+ public void onAvailable(Network network) {
+ if (DBG) logd("Network available: " + network);
+ mCm.bindProcessToNetwork(network);
+ mNetwork = network;
+ runOnUiThreadIfNotFinishing(() -> {
+ // Start initial page load so WebView finishes loading proxy settings.
+ // Actual load of mUrl is initiated by MyWebViewClient.
+ mWebView.loadData("", "text/html", null);
+ });
+ }
+
+ @Override
+ public void onUnavailable() {
+ if (DBG) logd("Network unavailable");
+ runOnUiThreadIfNotFinishing(() -> {
+ // Instead of not loading anything in webview, simply load the page and return
+ // HTTP error page in the absence of network connection.
+ mWebView.loadUrl(mUrl.toString());
+ });
+ }
+ };
+ logd("request Network for captive portal");
+ mCm.requestNetwork(request, mNetworkCallback, NETWORK_REQUEST_TIMEOUT_MS);
+ }
+
+ private void releaseNetworkRequest() {
+ logd("release Network for captive portal");
+ if (mNetworkCallback != null) {
+ mCm.unregisterNetworkCallback(mNetworkCallback);
+ mNetworkCallback = null;
+ mNetwork = null;
+ }
+ }
+
+ private class MyWebViewClient extends WebViewClient {
+ private static final String INTERNAL_ASSETS = "file:///android_asset/";
+ private final String mBrowserBailOutToken = Long.toString(new Random().nextLong());
+ // How many Android device-independent-pixels per scaled-pixel
+ // dp/sp = (px/sp) / (px/dp) = (1/sp) / (1/dp)
+ private final float mDpPerSp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 1,
+ getResources().getDisplayMetrics())
+ / TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1,
+ getResources().getDisplayMetrics());
+ private int mPagesLoaded;
+
+ // If we haven't finished cleaning up the history, don't allow going back.
+ public boolean allowBack() {
+ return mPagesLoaded > 1;
+ }
+
+ @Override
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {
+ if (url.contains(mBrowserBailOutToken)) {
+ mLaunchBrowser = true;
+ done(false);
+ return;
+ }
+ // The first page load is used only to cause the WebView to
+ // fetch the proxy settings. Don't update the URL bar, and
+ // don't check if the captive portal is still there.
+ if (mPagesLoaded == 0) return;
+ // For internally generated pages, leave URL bar listing prior URL as this is the URL
+ // the page refers to.
+ if (!url.startsWith(INTERNAL_ASSETS)) {
+ final TextView myUrlBar = (TextView) findViewById(R.id.url_bar);
+ myUrlBar.setText(url);
+ }
+ if (mNetwork != null) {
+ testForCaptivePortal();
+ }
+ }
+
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ mPagesLoaded++;
+ if (mPagesLoaded == 1) {
+ // Now that WebView has loaded at least one page we know it has read in the proxy
+ // settings. Now prompt the WebView read the Network-specific proxy settings.
+ setWebViewProxy();
+ // Load the real page.
+ view.loadUrl(mUrl.toString());
+ return;
+ } else if (mPagesLoaded == 2) {
+ // Prevent going back to empty first page.
+ view.clearHistory();
+ }
+ if (mNetwork != null) {
+ testForCaptivePortal();
+ }
+ }
+
+ // Convert Android device-independent-pixels (dp) to HTML size.
+ private String dp(int dp) {
+ // HTML px's are scaled just like dp's, so just add "px" suffix.
+ return Integer.toString(dp) + "px";
+ }
+
+ // Convert Android scaled-pixels (sp) to HTML size.
+ private String sp(int sp) {
+ // Convert sp to dp's.
+ float dp = sp * mDpPerSp;
+ // Apply a scale factor to make things look right.
+ dp *= 1.3;
+ // Convert dp's to HTML size.
+ return dp((int) dp);
+ }
+
+ // A web page consisting of a large broken lock icon to indicate SSL failure.
+ private final String SSL_ERROR_HTML = "<html><head><style>"
+ + "body { margin-left:" + dp(48) + "; margin-right:" + dp(48) + "; "
+ + "margin-top:" + dp(96) + "; background-color:#fafafa; }"
+ + "img { width:" + dp(48) + "; height:" + dp(48) + "; }"
+ + "div.warn { font-size:" + sp(16) + "; margin-top:" + dp(16) + "; "
+ + " opacity:0.87; line-height:1.28; }"
+ + "div.example { font-size:" + sp(14) + "; margin-top:" + dp(16) + "; "
+ + " opacity:0.54; line-height:1.21905; }"
+ + "a { font-size:" + sp(14) + "; text-decoration:none; text-transform:uppercase; "
+ + " margin-top:" + dp(24) + "; display:inline-block; color:#4285F4; "
+ + " height:" + dp(48) + "; font-weight:bold; }"
+ + "</style></head><body><p><img src=quantum_ic_warning_amber_96.png><br>"
+ + "<div class=warn>%s</div>"
+ + "<div class=example>%s</div>" + "<a href=%s>%s</a></body></html>";
+
+ @Override
+ public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
+ Log.w(TAG, "SSL error (error: " + error.getPrimaryError() + " host: "
+ // Only show host to avoid leaking private info.
+ + Uri.parse(error.getUrl()).getHost() + " certificate: "
+ + error.getCertificate() + "); displaying SSL warning.");
+ final String html = String.format(SSL_ERROR_HTML, getString(R.string.ssl_error_warning),
+ getString(R.string.ssl_error_example), mBrowserBailOutToken,
+ getString(R.string.ssl_error_continue));
+ view.loadDataWithBaseURL(INTERNAL_ASSETS, html, "text/HTML", "UTF-8", null);
+ }
+
+ @Override
+ public boolean shouldOverrideUrlLoading(WebView view, String url) {
+ if (url.startsWith("tel:")) {
+ startActivity(new Intent(Intent.ACTION_DIAL, Uri.parse(url)));
+ return true;
+ }
+ return false;
+ }
+ }
+
+ private class MyWebChromeClient extends WebChromeClient {
+ @Override
+ public void onProgressChanged(WebView view, int newProgress) {
+ final ProgressBar myProgressBar = (ProgressBar) findViewById(R.id.progress_bar);
+ myProgressBar.setProgress(newProgress);
+ }
+ }
+
+ private void runOnUiThreadIfNotFinishing(Runnable r) {
+ if (!isFinishing()) {
+ runOnUiThread(r);
+ }
+ }
+
+ private static void logd(String s) {
+ Rlog.d(TAG, s);
+ }
+
+ private static void loge(String s) {
+ Rlog.d(TAG, s);
+ }
+
+}
diff --git a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
index d9bd2fc..73ff3a9 100644
--- a/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
+++ b/packages/CarrierDefaultApp/src/com/android/carrierdefaultapp/CarrierActionUtils.java
@@ -112,8 +112,10 @@
logd("onShowCaptivePortalNotification");
final NotificationManager notificationMgr = context.getSystemService(
NotificationManager.class);
- Intent portalIntent = new Intent(context, CaptivePortalLaunchActivity.class);
+ Intent portalIntent = new Intent(context, CaptivePortalLoginActivity.class);
portalIntent.putExtras(intent);
+ portalIntent.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT
+ | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, portalIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = getNotification(context, R.string.portal_notification_id,
diff --git a/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/LaunchCaptivePortalActivityTest.java b/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/LaunchCaptivePortalActivityTest.java
deleted file mode 100644
index 8a18d72..0000000
--- a/packages/CarrierDefaultApp/tests/unit/src/com/android/carrierdefaultapp/LaunchCaptivePortalActivityTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-package com.android.carrierdefaultapp;
-
-import android.annotation.TargetApi;
-import android.content.Intent;
-import android.net.ConnectivityManager;
-import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkInfo;
-import android.net.NetworkRequest;
-
-import com.android.internal.telephony.TelephonyIntents;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.atLeast;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-public class LaunchCaptivePortalActivityTest extends
- CarrierDefaultActivityTestCase<CaptivePortalLaunchActivity> {
-
- @Mock
- private ConnectivityManager mCm;
- @Mock
- private NetworkInfo mNetworkInfo;
- @Mock
- private Network mNetwork;
-
- @Captor
- private ArgumentCaptor<Integer> mInt;
- @Captor
- private ArgumentCaptor<NetworkRequest> mNetworkReq;
-
- private NetworkCapabilities mNetworkCapabilities;
-
- public LaunchCaptivePortalActivityTest() {
- super(CaptivePortalLaunchActivity.class);
- }
-
- @Before
- public void setUp() throws Exception {
- super.setUp();
- injectSystemService(ConnectivityManager.class, mCm);
- }
-
- @After
- public void tearDown() throws Exception {
- super.tearDown();
- }
-
- @Override
- protected Intent createActivityIntent() {
- Intent intent = new Intent(getInstrumentation().getTargetContext(),
- CaptivePortalLaunchActivity.class);
- intent.putExtra(TelephonyIntents.EXTRA_REDIRECTION_URL_KEY, "url");
- return intent;
- }
-
- @Test
- public void testWithoutInternetConnection() throws Throwable {
- startActivity();
- TestContext.waitForMs(100);
- verify(mCm, atLeast(1)).requestNetwork(mNetworkReq.capture(), any(), mInt.capture());
- // verify network request
- assert(mNetworkReq.getValue().networkCapabilities.hasCapability(
- NetworkCapabilities.NET_CAPABILITY_INTERNET));
- assert(mNetworkReq.getValue().networkCapabilities.hasTransport(
- NetworkCapabilities.TRANSPORT_CELLULAR));
- assertFalse(mNetworkReq.getValue().networkCapabilities.hasCapability(
- NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED));
- assertEquals(CaptivePortalLaunchActivity.NETWORK_REQUEST_TIMEOUT_IN_MS,
- (int) mInt.getValue());
- // verify captive portal app is not launched due to unavailable network
- assertNull(getStartedActivityIntent());
- stopActivity();
- }
-
- @Test
- public void testWithInternetConnection() throws Throwable {
- // Mock internet connection
- mNetworkCapabilities = new NetworkCapabilities()
- .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
- .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
- doReturn(new Network[]{mNetwork}).when(mCm).getAllNetworks();
- doReturn(mNetworkCapabilities).when(mCm).getNetworkCapabilities(eq(mNetwork));
- doReturn(mNetworkInfo).when(mCm).getNetworkInfo(eq(mNetwork));
- doReturn(true).when(mNetworkInfo).isConnected();
-
- startActivity();
- TestContext.waitForMs(100);
- // verify there is no network request with internet connection
- verify(mCm, times(0)).requestNetwork(any(), any(), anyInt());
- // verify captive portal app is launched
- assertNotNull(getStartedActivityIntent());
- assertEquals(ConnectivityManager.ACTION_CAPTIVE_PORTAL_SIGN_IN,
- getStartedActivityIntent().getAction());
- stopActivity();
- }
-}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index a9f6dc9..4c8c036 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1625,7 +1625,7 @@
*/
public void reportSimUnlocked(int subId) {
if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
- int slotId = SubscriptionManager.getSlotId(subId);
+ int slotId = SubscriptionManager.getSlotIndex(subId);
handleSimStateChange(subId, slotId, State.READY);
}
@@ -1794,7 +1794,7 @@
for (int i = 0; i < list.size(); i++) {
final SubscriptionInfo info = list.get(i);
final int id = info.getSubscriptionId();
- int slotId = SubscriptionManager.getSlotId(id);
+ int slotId = SubscriptionManager.getSlotIndex(id);
if (state == getSimState(id) && bestSlotId > slotId ) {
resultId = id;
bestSlotId = slotId;
diff --git a/packages/Osu/src/com/android/MainActivity.java b/packages/Osu/src/com/android/MainActivity.java
index 7e7d49a..9bcc390 100644
--- a/packages/Osu/src/com/android/MainActivity.java
+++ b/packages/Osu/src/com/android/MainActivity.java
@@ -246,6 +246,8 @@
case WifiManager.SCAN_RESULTS_AVAILABLE_ACTION:
mOsuManager.pushScanResults(wifiManager.getScanResults());
break;
+ // TODO(b/32883320): use updated intent.
+ /*
case WifiManager.PASSPOINT_WNM_FRAME_RECEIVED_ACTION:
long bssid = bundle.getLong(WifiManager.EXTRA_PASSPOINT_WNM_BSSID);
String url = bundle.getString(WifiManager.EXTRA_PASSPOINT_WNM_URL);
@@ -282,6 +284,7 @@
bundle.getString(WifiManager.EXTRA_PASSPOINT_ICON_FILE),
bundle.getByteArray(WifiManager.EXTRA_PASSPOINT_ICON_DATA));
break;
+ */
case WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION:
mOsuManager.networkConfigChange((WifiConfiguration)
intent.getParcelableExtra(WifiManager.EXTRA_WIFI_CONFIGURATION));
diff --git a/packages/SettingsLib/res/values/arrays.xml b/packages/SettingsLib/res/values/arrays.xml
index 1f432de..dbfb118 100644
--- a/packages/SettingsLib/res/values/arrays.xml
+++ b/packages/SettingsLib/res/values/arrays.xml
@@ -102,6 +102,19 @@
<!-- Bluetooth settings -->
+ <!-- Titles for Bluetooth AVRCP Versions -->
+ <string-array name="bluetooth_avrcp_versions">
+ <item>AVRCP 1.4 (Default)</item>
+ <item>AVRCP 1.5</item>
+ <item>AVRCP 1.6</item>
+ </string-array>
+
+ <!-- Values for Bluetooth AVRCP Versions -->
+ <string-array name="bluetooth_avrcp_version_values">
+ <item>avrcp14</item>
+ <item>avrcp15</item>
+ <item>avrcp16</item>
+ </string-array>
<!-- Titles for Bluetooth Audio Codec selection preference. [CHAR LIMIT=50] -->
<string-array name="bluetooth_a2dp_codec_titles">
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 064059b..3973a43 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -430,6 +430,11 @@
<!-- Setting Checkbox title for disabling Bluetooth absolute volume -->
<string name="bluetooth_disable_absolute_volume">Disable absolute volume</string>
+ <!-- UI debug setting: Select Bluetooth AVRCP Version -->
+ <string name="bluetooth_select_avrcp_version_string">Bluetooth AVRCP Version</string>
+ <!-- UI debug setting: Select Bluetooth AVRCP Version -->
+ <string name="bluetooth_select_avrcp_version_dialog_title">Select Bluetooth AVRCP Version</string>
+
<!-- UI debug setting: Select Bluetooth Audio Codec -->
<string name="bluetooth_select_a2dp_codec_type">Bluetooth Audio Codec</string>
<!-- UI debug setting: Select Bluetooth Audio Codec -->
diff --git a/packages/SettingsLib/res/xml/timezones.xml b/packages/SettingsLib/res/xml/timezones.xml
index 4426495..12d31cf 100644
--- a/packages/SettingsLib/res/xml/timezones.xml
+++ b/packages/SettingsLib/res/xml/timezones.xml
@@ -21,7 +21,7 @@
<timezone id="America/St_Johns"></timezone>
<timezone id="America/Recife"></timezone>
<timezone id="America/Sao_Paulo"></timezone>
- <timezone id="America/Buenos_Aires"></timezone>
+ <timezone id="America/Argentina/Buenos_Aires"></timezone>
<timezone id="America/Godthab"></timezone>
<timezone id="America/Montevideo"></timezone>
<timezone id="Atlantic/South_Georgia"></timezone>
@@ -58,11 +58,11 @@
<timezone id="Asia/Karachi"></timezone>
<timezone id="Asia/Oral"></timezone>
<timezone id="Asia/Yekaterinburg"></timezone>
- <timezone id="Asia/Calcutta"></timezone>
+ <timezone id="Asia/Kolkata"></timezone>
<timezone id="Asia/Colombo"></timezone>
- <timezone id="Asia/Katmandu"></timezone>
+ <timezone id="Asia/Kathmandu"></timezone>
<timezone id="Asia/Almaty"></timezone>
- <timezone id="Asia/Rangoon"></timezone>
+ <timezone id="Asia/Yangon"></timezone>
<timezone id="Asia/Krasnoyarsk"></timezone>
<timezone id="Asia/Bangkok"></timezone>
<timezone id="Asia/Jakarta"></timezone>
diff --git a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
index f0ec1078..a803e60 100644
--- a/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
+++ b/packages/SettingsLib/src/com/android/settingslib/applications/ApplicationsState.java
@@ -649,7 +649,11 @@
}
if (comparator != null) {
- Collections.sort(filteredApps, comparator);
+ synchronized (mEntriesMap) {
+ // Locking to ensure that the background handler does not mutate
+ // the size of AppEntries used for ordering while sorting.
+ Collections.sort(filteredApps, comparator);
+ }
}
synchronized (mRebuildSync) {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index e00178f..144d439 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -398,10 +398,12 @@
removeUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
} else if (Intent.ACTION_USER_PRESENT.equals(action)) {
// We will update when the automation service dies.
- UserState userState = getCurrentUserStateLocked();
- if (!userState.isUiAutomationSuppressingOtherServices()) {
- if (readConfigurationForUserStateLocked(userState)) {
- onUserStateChangedLocked(userState);
+ synchronized (mLock) {
+ UserState userState = getCurrentUserStateLocked();
+ if (!userState.isUiAutomationSuppressingOtherServices()) {
+ if (readConfigurationForUserStateLocked(userState)) {
+ onUserStateChangedLocked(userState);
+ }
}
}
} else if (Intent.ACTION_SETTING_RESTORED.equals(action)) {
diff --git a/services/core/Android.mk b/services/core/Android.mk
index a61743d..898eb7e 100644
--- a/services/core/Android.mk
+++ b/services/core/Android.mk
@@ -19,7 +19,7 @@
system/netd/server/binder
LOCAL_JAVA_LIBRARIES := services.net telephony-common
-LOCAL_STATIC_JAVA_LIBRARIES := tzdata_update2
+LOCAL_STATIC_JAVA_LIBRARIES := tzdata_shared2 tzdata_update2
LOCAL_PROTOC_OPTIMIZE_TYPE := nano
ifneq ($(INCREMENTAL_BUILDS),)
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 5e9cf74..c7c133d 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -76,15 +76,21 @@
private static final String BLUETOOTH_ADMIN_PERM = android.Manifest.permission.BLUETOOTH_ADMIN;
private static final String BLUETOOTH_PERM = android.Manifest.permission.BLUETOOTH;
- private static final String ACTION_SERVICE_STATE_CHANGED="com.android.bluetooth.btservice.action.STATE_CHANGED";
- private static final String EXTRA_ACTION="action";
+
private static final String SECURE_SETTINGS_BLUETOOTH_ADDR_VALID="bluetooth_addr_valid";
private static final String SECURE_SETTINGS_BLUETOOTH_ADDRESS="bluetooth_address";
private static final String SECURE_SETTINGS_BLUETOOTH_NAME="bluetooth_name";
+
+ private static final int ACTIVE_LOG_MAX_SIZE = 20;
+ private static final int CRASH_LOG_MAX_SIZE = 100;
private static final String REASON_AIRPLANE_MODE = "airplane mode";
+ private static final String REASON_RESTARTED = "automatic restart";
+ private static final String REASON_START_CRASH = "turn-on crash";
private static final String REASON_SYSTEM_BOOT = "system boot";
+ private static final String REASON_UNEXPECTED = "unexpected crash";
+ private static final String REASON_USER_SWITCH = "user switch";
+
private static final int TIMEOUT_BIND_MS = 3000; //Maximum msec to wait for a bind
- private static final int TIMEOUT_SAVE_MS = 500; //Maximum msec to wait for a save
//Maximum msec to wait for service restart
private static final int SERVICE_RESTART_TIME_MS = 200;
//Maximum msec to wait for restart due to error
@@ -149,6 +155,10 @@
private boolean mQuietEnable = false;
private boolean mEnable;
+ private CharSequence timeToLog(long timestamp) {
+ return android.text.format.DateFormat.format("MM-dd HH:mm:ss", timestamp);
+ }
+
/**
* Used for tracking apps that enabled / disabled Bluetooth.
*/
@@ -168,13 +178,15 @@
}
public String toString() {
- return android.text.format.DateFormat.format("MM-dd HH:mm:ss ", mTimestamp) +
- (mEnable ? " Enabled " : " Disabled ") + " by " + mPackageName;
+ return timeToLog(mTimestamp) + (mEnable ? " Enabled " : " Disabled ") + " by "
+ + mPackageName;
}
}
private LinkedList<ActiveLog> mActiveLogs;
+ private LinkedList<Long> mCrashTimestamps;
+ private int mCrashes;
// configuration from external IBinder call which is used to
// synchronize with broadcast receiver.
@@ -308,6 +320,8 @@
com.android.internal.R.bool.config_permissionReviewRequired);
mActiveLogs = new LinkedList<ActiveLog>();
+ mCrashTimestamps = new LinkedList<Long>();
+ mCrashes = 0;
mBluetooth = null;
mBluetoothBinder = null;
mBluetoothGatt = null;
@@ -1565,6 +1579,9 @@
mBluetoothLock.writeLock().unlock();
}
+ // log the unexpected crash
+ addCrashLog();
+ addActiveLog(REASON_UNEXPECTED, false);
if (mEnable) {
mEnable = false;
// Send a Bluetooth Restart message
@@ -1600,6 +1617,7 @@
it doesnt change when IBluetooth
service restarts */
mEnable = true;
+ addActiveLog(REASON_RESTARTED, true);
handleEnable(mQuietEnable);
break;
}
@@ -1654,6 +1672,7 @@
unbindAllBluetoothProfileServices();
// disable
+ addActiveLog(REASON_USER_SWITCH, false);
handleDisable();
// Pbap service need receive STATE_TURNING_OFF intent to close
bluetoothStateChangeHandler(BluetoothAdapter.STATE_ON,
@@ -1691,6 +1710,7 @@
mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
mState = BluetoothAdapter.STATE_OFF;
// enable
+ addActiveLog(REASON_USER_SWITCH, true);
handleEnable(mQuietEnable);
} else if (mBinding || mBluetooth != null) {
Message userMsg = mHandler.obtainMessage(MESSAGE_USER_SWITCHED);
@@ -1945,13 +1965,21 @@
private void addActiveLog(String packageName, boolean enable) {
synchronized (mActiveLogs) {
- if (mActiveLogs.size() > 10) {
+ if (mActiveLogs.size() > ACTIVE_LOG_MAX_SIZE) {
mActiveLogs.remove();
}
mActiveLogs.add(new ActiveLog(packageName, enable, System.currentTimeMillis()));
}
}
+ private void addCrashLog() {
+ synchronized (mCrashTimestamps) {
+ if (mCrashTimestamps.size() == CRASH_LOG_MAX_SIZE) mCrashTimestamps.removeFirst();
+ mCrashTimestamps.add(System.currentTimeMillis());
+ mCrashes++;
+ }
+ }
+
private void recoverBluetoothServiceFromError(boolean clearBle) {
Slog.e(TAG,"recoverBluetoothServiceFromError");
try {
@@ -1969,6 +1997,7 @@
SystemClock.sleep(500);
// disable
+ addActiveLog(REASON_START_CRASH, false);
handleDisable();
waitForOnOff(false, true);
@@ -2070,6 +2099,12 @@
}
}
+ writer.println("Bluetooth crashed " + mCrashes + " time" + (mCrashes == 1 ? "" : "s"));
+ if (mCrashes == CRASH_LOG_MAX_SIZE) writer.println("(last " + CRASH_LOG_MAX_SIZE + ")");
+ for (Long time : mCrashTimestamps) {
+ writer.println(" " + timeToLog(time.longValue()));
+ }
+
String bleAppString = "No BLE Apps registered.";
if (mBleApps.size() == 1) {
bleAppString = "1 BLE App registered:";
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index f58cdba..d23347f 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -3082,13 +3082,22 @@
boolean tetherEnabledInSettings = (Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.TETHER_SUPPORTED, defaultVal) != 0)
&& !mUserManager.hasUserRestriction(UserManager.DISALLOW_CONFIG_TETHERING);
- return tetherEnabledInSettings && mUserManager.isAdminUser() &&
+
+ // Elevate to system UID to avoid caller requiring MANAGE_USERS permission.
+ boolean adminUser = false;
+ final long token = Binder.clearCallingIdentity();
+ try {
+ adminUser = mUserManager.isAdminUser();
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+
+ return tetherEnabledInSettings && adminUser &&
mTethering.hasTetherableConfiguration();
}
@Override
- public void startTethering(int type, ResultReceiver receiver,
- boolean showProvisioningUi) {
+ public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi) {
ConnectivityManager.enforceTetherChangePermission(mContext);
if (!isTetheringSupported()) {
receiver.send(ConnectivityManager.TETHER_ERROR_UNSUPPORTED, null);
diff --git a/services/core/java/com/android/server/connectivity/PacManager.java b/services/core/java/com/android/server/connectivity/PacManager.java
index 58c76ec..46f76b1 100644
--- a/services/core/java/com/android/server/connectivity/PacManager.java
+++ b/services/core/java/com/android/server/connectivity/PacManager.java
@@ -15,6 +15,7 @@
*/
package com.android.server.connectivity;
+import android.annotation.WorkerThread;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
@@ -73,7 +74,7 @@
public static final String KEY_PROXY = "keyProxy";
private String mCurrentPac;
@GuardedBy("mProxyLock")
- private Uri mPacUrl = Uri.EMPTY;
+ private volatile Uri mPacUrl = Uri.EMPTY;
private AlarmManager mAlarmManager;
@GuardedBy("mProxyLock")
@@ -86,29 +87,34 @@
private int mCurrentDelay;
private int mLastPort;
- private boolean mHasSentBroadcast;
- private boolean mHasDownloaded;
+ private volatile boolean mHasSentBroadcast;
+ private volatile boolean mHasDownloaded;
private Handler mConnectivityHandler;
private int mProxyMessage;
/**
- * Used for locking when setting mProxyService and all references to mPacUrl or mCurrentPac.
+ * Used for locking when setting mProxyService and all references to mCurrentPac.
*/
private final Object mProxyLock = new Object();
+ /**
+ * Runnable to download PAC script.
+ * The behavior relies on the assamption it always run on mNetThread to guarantee that the
+ * latest data fetched from mPacUrl is stored in mProxyService.
+ */
private Runnable mPacDownloader = new Runnable() {
@Override
+ @WorkerThread
public void run() {
String file;
- synchronized (mProxyLock) {
- if (Uri.EMPTY.equals(mPacUrl)) return;
- try {
- file = get(mPacUrl);
- } catch (IOException ioe) {
- file = null;
- Log.w(TAG, "Failed to load PAC file: " + ioe);
- }
+ final Uri pacUrl = mPacUrl;
+ if (Uri.EMPTY.equals(pacUrl)) return;
+ try {
+ file = get(pacUrl);
+ } catch (IOException ioe) {
+ file = null;
+ Log.w(TAG, "Failed to load PAC file: " + ioe);
}
if (file != null) {
synchronized (mProxyLock) {
@@ -171,9 +177,7 @@
// Allow to send broadcast, nothing to do.
return false;
}
- synchronized (mProxyLock) {
- mPacUrl = proxy.getPacFileUrl();
- }
+ mPacUrl = proxy.getPacFileUrl();
mCurrentDelay = DELAY_1;
mHasSentBroadcast = false;
mHasDownloaded = false;
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index dfd647c..693292a 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -77,8 +77,8 @@
import com.android.server.connectivity.tethering.IPv6TetheringCoordinator;
import com.android.server.connectivity.tethering.IPv6TetheringInterfaceServices;
import com.android.server.connectivity.tethering.OffloadController;
-import com.android.server.connectivity.tethering.TetheringConfiguration;
import com.android.server.connectivity.tethering.TetherInterfaceStateMachine;
+import com.android.server.connectivity.tethering.TetheringConfiguration;
import com.android.server.connectivity.tethering.UpstreamNetworkMonitor;
import com.android.server.net.BaseNetworkObserver;
@@ -102,8 +102,7 @@
*/
public class Tethering extends BaseNetworkObserver implements IControlsTethering {
- private final Context mContext;
- private final static String TAG = "Tethering";
+ private final static String TAG = Tethering.class.getSimpleName();
private final static boolean DBG = false;
private final static boolean VDBG = false;
@@ -115,48 +114,43 @@
private static final SparseArray<String> sMagicDecoderRing =
MessageUtils.findMessageNames(messageClasses);
- private volatile TetheringConfiguration mConfig;
+ // {@link ComponentName} of the Service used to run tether provisioning.
+ private static final ComponentName TETHER_SERVICE = ComponentName.unflattenFromString(Resources
+ .getSystem().getString(com.android.internal.R.string.config_wifi_tether_enable));
+
+ private static class TetherState {
+ public final TetherInterfaceStateMachine stateMachine;
+ public int lastState;
+ public int lastError;
+ public TetherState(TetherInterfaceStateMachine sm) {
+ stateMachine = sm;
+ // Assume all state machines start out available and with no errors.
+ lastState = IControlsTethering.STATE_AVAILABLE;
+ lastError = ConnectivityManager.TETHER_ERROR_NO_ERROR;
+ }
+ }
// used to synchronize public access to members
private final Object mPublicSync;
-
+ private final Context mContext;
+ private final ArrayMap<String, TetherState> mTetherStates;
+ private final BroadcastReceiver mStateReceiver;
private final INetworkManagementService mNMService;
private final INetworkStatsService mStatsService;
private final INetworkPolicyManager mPolicyManager;
private final Looper mLooper;
private final MockableSystemProperties mSystemProperties;
-
- private static class TetherState {
- public final TetherInterfaceStateMachine mStateMachine;
- public int mLastState;
- public int mLastError;
- public TetherState(TetherInterfaceStateMachine sm) {
- mStateMachine = sm;
- // Assume all state machines start out available and with no errors.
- mLastState = IControlsTethering.STATE_AVAILABLE;
- mLastError = ConnectivityManager.TETHER_ERROR_NO_ERROR;
- }
- }
- private final ArrayMap<String, TetherState> mTetherStates;
-
- private final BroadcastReceiver mStateReceiver;
-
- // {@link ComponentName} of the Service used to run tether provisioning.
- private static final ComponentName TETHER_SERVICE = ComponentName.unflattenFromString(Resources
- .getSystem().getString(com.android.internal.R.string.config_wifi_tether_enable));
-
private final StateMachine mTetherMasterSM;
private final OffloadController mOffloadController;
private final UpstreamNetworkMonitor mUpstreamNetworkMonitor;
- private String mCurrentUpstreamIface;
+ private volatile TetheringConfiguration mConfig;
+ private String mCurrentUpstreamIface;
private Notification.Builder mTetheredNotificationBuilder;
private int mLastNotificationId;
-
private boolean mRndisEnabled; // track the RNDIS function enabled state
private boolean mUsbTetherRequested; // true if USB tethering should be started
// when RNDIS is enabled
-
// True iff WiFi tethering should be started when soft AP is ready.
private boolean mWifiTetherRequested;
@@ -227,7 +221,7 @@
}
} else {
if (interfaceType == ConnectivityManager.TETHERING_BLUETOOTH) {
- tetherState.mStateMachine.sendMessage(
+ tetherState.stateMachine.sendMessage(
TetherInterfaceStateMachine.CMD_INTERFACE_DOWN);
mTetherStates.remove(iface);
} else {
@@ -289,13 +283,12 @@
}
return;
}
- tetherState.mStateMachine.sendMessage(TetherInterfaceStateMachine.CMD_INTERFACE_DOWN);
+ tetherState.stateMachine.sendMessage(TetherInterfaceStateMachine.CMD_INTERFACE_DOWN);
mTetherStates.remove(iface);
}
}
- public void startTethering(int type, ResultReceiver receiver,
- boolean showProvisioningUi) {
+ public void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi) {
if (!isTetherProvisioningRequired()) {
enableTetheringInternal(type, true, receiver);
return;
@@ -527,11 +520,11 @@
}
// Ignore the error status of the interface. If the interface is available,
// the errors are referring to past tethering attempts anyway.
- if (tetherState.mLastState != IControlsTethering.STATE_AVAILABLE) {
+ if (tetherState.lastState != IControlsTethering.STATE_AVAILABLE) {
Log.e(TAG, "Tried to Tether an unavailable iface: " + iface + ", ignoring");
return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE;
}
- tetherState.mStateMachine.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_REQUESTED);
+ tetherState.stateMachine.sendMessage(TetherInterfaceStateMachine.CMD_TETHER_REQUESTED);
return ConnectivityManager.TETHER_ERROR_NO_ERROR;
}
}
@@ -544,11 +537,11 @@
Log.e(TAG, "Tried to Untether an unknown iface :" + iface + ", ignoring");
return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
}
- if (tetherState.mLastState != IControlsTethering.STATE_TETHERED) {
+ if (tetherState.lastState != IControlsTethering.STATE_TETHERED) {
Log.e(TAG, "Tried to untether an untethered iface :" + iface + ", ignoring");
return ConnectivityManager.TETHER_ERROR_UNAVAIL_IFACE;
}
- tetherState.mStateMachine.sendMessage(
+ tetherState.stateMachine.sendMessage(
TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED);
return ConnectivityManager.TETHER_ERROR_NO_ERROR;
}
@@ -568,7 +561,7 @@
", ignoring");
return ConnectivityManager.TETHER_ERROR_UNKNOWN_IFACE;
}
- return tetherState.mLastError;
+ return tetherState.lastError;
}
}
@@ -589,11 +582,11 @@
for (int i = 0; i < mTetherStates.size(); i++) {
TetherState tetherState = mTetherStates.valueAt(i);
String iface = mTetherStates.keyAt(i);
- if (tetherState.mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+ if (tetherState.lastError != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
erroredList.add(iface);
- } else if (tetherState.mLastState == IControlsTethering.STATE_AVAILABLE) {
+ } else if (tetherState.lastState == IControlsTethering.STATE_AVAILABLE) {
availableList.add(iface);
- } else if (tetherState.mLastState == IControlsTethering.STATE_TETHERED) {
+ } else if (tetherState.lastState == IControlsTethering.STATE_TETHERED) {
if (cfg.isUsb(iface)) {
usbTethered = true;
} else if (cfg.isWifi(iface)) {
@@ -766,7 +759,7 @@
// themselves down.
for (int i = 0; i < mTetherStates.size(); i++) {
TetherInterfaceStateMachine tism =
- mTetherStates.valueAt(i).mStateMachine;
+ mTetherStates.valueAt(i).stateMachine;
if (tism.interfaceType() == ConnectivityManager.TETHERING_WIFI) {
tism.sendMessage(
TetherInterfaceStateMachine.CMD_TETHER_UNREQUESTED);
@@ -881,7 +874,7 @@
synchronized (mPublicSync) {
for (int i = 0; i < mTetherStates.size(); i++) {
TetherState tetherState = mTetherStates.valueAt(i);
- if (tetherState.mLastState == IControlsTethering.STATE_TETHERED) {
+ if (tetherState.lastState == IControlsTethering.STATE_TETHERED) {
list.add(mTetherStates.keyAt(i));
}
}
@@ -894,7 +887,7 @@
synchronized (mPublicSync) {
for (int i = 0; i < mTetherStates.size(); i++) {
TetherState tetherState = mTetherStates.valueAt(i);
- if (tetherState.mLastState == IControlsTethering.STATE_AVAILABLE) {
+ if (tetherState.lastState == IControlsTethering.STATE_AVAILABLE) {
list.add(mTetherStates.keyAt(i));
}
}
@@ -911,7 +904,7 @@
synchronized (mPublicSync) {
for (int i = 0; i < mTetherStates.size(); i++) {
TetherState tetherState = mTetherStates.valueAt(i);
- if (tetherState.mLastError != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
+ if (tetherState.lastError != ConnectivityManager.TETHER_ERROR_NO_ERROR) {
list.add(mTetherStates.keyAt(i));
}
}
@@ -1318,7 +1311,7 @@
synchronized (mPublicSync) {
for (int i = 0; i < mTetherStates.size(); i++) {
TetherState tetherState = mTetherStates.valueAt(i);
- if (tetherState.mLastState != IControlsTethering.STATE_TETHERED) {
+ if (tetherState.lastState != IControlsTethering.STATE_TETHERED) {
continue; // Skip interfaces that aren't tethered.
}
String iface = mTetherStates.keyAt(i);
@@ -1591,14 +1584,14 @@
pw.println("Tethering:");
pw.increaseIndent();
- final TetheringConfiguration cfg = mConfig;
- pw.print("preferredUpstreamIfaceTypes:");
- synchronized (mPublicSync) {
- for (Integer netType : cfg.preferredUpstreamIfaceTypes) {
- pw.print(" " + ConnectivityManager.getNetworkTypeName(netType));
- }
- pw.println();
+ pw.println("Configuration:");
+ pw.increaseIndent();
+ final TetheringConfiguration cfg = mConfig;
+ cfg.dump(pw);
+ pw.decreaseIndent();
+
+ synchronized (mPublicSync) {
pw.println("Tether state:");
pw.increaseIndent();
for (int i = 0; i < mTetherStates.size(); i++) {
@@ -1606,7 +1599,7 @@
final TetherState tetherState = mTetherStates.valueAt(i);
pw.print(iface + " - ");
- switch (tetherState.mLastState) {
+ switch (tetherState.lastState) {
case IControlsTethering.STATE_UNAVAILABLE:
pw.print("UnavailableState");
break;
@@ -1620,7 +1613,7 @@
pw.print("UnknownState");
break;
}
- pw.println(" - lastError = " + tetherState.mLastError);
+ pw.println(" - lastError = " + tetherState.lastError);
}
pw.decreaseIndent();
}
@@ -1632,9 +1625,9 @@
int state, int error) {
synchronized (mPublicSync) {
TetherState tetherState = mTetherStates.get(iface);
- if (tetherState != null && tetherState.mStateMachine.equals(who)) {
- tetherState.mLastState = state;
- tetherState.mLastError = error;
+ if (tetherState != null && tetherState.stateMachine.equals(who)) {
+ tetherState.lastState = state;
+ tetherState.lastError = error;
} else {
if (DBG) Log.d(TAG, "got notification from stale iface " + iface);
}
@@ -1678,7 +1671,7 @@
interfaceType, mNMService, mStatsService, this,
new IPv6TetheringInterfaceServices(iface, mNMService)));
mTetherStates.put(iface, tetherState);
- tetherState.mStateMachine.start();
+ tetherState.stateMachine.start();
}
private static String[] copy(String[] strarray) {
diff --git a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java
index dec2f77..8c6430c 100644
--- a/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java
+++ b/services/core/java/com/android/server/connectivity/tethering/IPv6TetheringInterfaceServices.java
@@ -16,6 +16,8 @@
package com.android.server.connectivity.tethering;
+import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH;
+
import android.net.INetd;
import android.net.IpPrefix;
import android.net.LinkAddress;
@@ -48,7 +50,6 @@
public class IPv6TetheringInterfaceServices {
private static final String TAG = IPv6TetheringInterfaceServices.class.getSimpleName();
private static final IpPrefix LINK_LOCAL_PREFIX = new IpPrefix("fe80::/64");
- private static final int RFC7421_IP_PREFIX_LENGTH = 64;
private final String mIfName;
private final INetworkManagementService mNMService;
@@ -124,7 +125,7 @@
params.hasDefaultRoute = v6only.hasIPv6DefaultRoute();
for (LinkAddress linkAddr : v6only.getLinkAddresses()) {
- if (linkAddr.getPrefixLength() != RFC7421_IP_PREFIX_LENGTH) continue;
+ if (linkAddr.getPrefixLength() != RFC7421_PREFIX_LENGTH) continue;
final IpPrefix prefix = new IpPrefix(
linkAddr.getAddress(), linkAddr.getPrefixLength());
@@ -206,7 +207,7 @@
for (Inet6Address dns : deprecatedDnses) {
final String dnsString = dns.getHostAddress();
try {
- netd.interfaceDelAddress(mIfName, dnsString, RFC7421_IP_PREFIX_LENGTH);
+ netd.interfaceDelAddress(mIfName, dnsString, RFC7421_PREFIX_LENGTH);
} catch (ServiceSpecificException | RemoteException e) {
Log.e(TAG, "Failed to remove local dns IP: " + dnsString, e);
}
@@ -223,7 +224,7 @@
for (Inet6Address dns : addedDnses) {
final String dnsString = dns.getHostAddress();
try {
- netd.interfaceAddAddress(mIfName, dnsString, RFC7421_IP_PREFIX_LENGTH);
+ netd.interfaceAddAddress(mIfName, dnsString, RFC7421_PREFIX_LENGTH);
} catch (ServiceSpecificException | RemoteException e) {
Log.e(TAG, "Failed to add local dns IP: " + dnsString, e);
newDnses.remove(dns);
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
index 14d06cc..d38beb3 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetheringConfiguration.java
@@ -22,12 +22,15 @@
import android.content.Context;
import android.content.res.Resources;
+import android.net.ConnectivityManager;
import android.telephony.TelephonyManager;
import android.util.Log;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
+import java.util.StringJoiner;
/**
@@ -97,6 +100,44 @@
return matchesDownstreamRegexs(iface, tetherableBluetoothRegexs);
}
+ public void dump(PrintWriter pw) {
+ dumpStringArray(pw, "tetherableUsbRegexs", tetherableUsbRegexs);
+ dumpStringArray(pw, "tetherableWifiRegexs", tetherableWifiRegexs);
+ dumpStringArray(pw, "tetherableBluetoothRegexs", tetherableBluetoothRegexs);
+
+ pw.print("isDunRequired: ");
+ pw.println(isDunRequired);
+
+ String[] upstreamTypes = null;
+ if (preferredUpstreamIfaceTypes != null) {
+ upstreamTypes = new String[preferredUpstreamIfaceTypes.size()];
+ int i = 0;
+ for (Integer netType : preferredUpstreamIfaceTypes) {
+ upstreamTypes[i] = ConnectivityManager.getNetworkTypeName(netType);
+ i++;
+ }
+ }
+ dumpStringArray(pw, "preferredUpstreamIfaceTypes", upstreamTypes);
+
+ dumpStringArray(pw, "dhcpRanges", dhcpRanges);
+ dumpStringArray(pw, "defaultIPv4DNS", defaultIPv4DNS);
+ }
+
+ private static void dumpStringArray(PrintWriter pw, String label, String[] values) {
+ pw.print(label);
+ pw.print(": ");
+
+ if (values != null) {
+ final StringJoiner sj = new StringJoiner(", ", "[", "]");
+ for (String value : values) { sj.add(value); }
+ pw.print(sj.toString());
+ } else {
+ pw.print("null");
+ }
+
+ pw.println();
+ }
+
private static boolean checkDunRequired(Context ctx) {
final TelephonyManager tm = ctx.getSystemService(TelephonyManager.class);
final int secureSetting =
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 4658c046..060dd73 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -381,6 +381,7 @@
mContext.unregisterReceiver(mTetherReceiver);
mContext.unregisterReceiver(mPollReceiver);
mContext.unregisterReceiver(mRemovedReceiver);
+ mContext.unregisterReceiver(mUserReceiver);
mContext.unregisterReceiver(mShutdownReceiver);
final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index 9418e74..1498693 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -213,6 +213,7 @@
if (getAvailableSpace() > 0) {
dexoptCommandCountExecuted++;
+ Log.d(TAG, "Next command: " + next);
return next;
} else {
if (DEBUG_DEXOPT) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 9452219..42f6502 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -9234,9 +9234,9 @@
ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
+ " (requirer="
- + (requirer == null ? "null" : requirer.pkg.packageName)
+ + (requirer != null ? requirer.pkg : "null")
+ ", scannedPackage="
- + (scannedPackage != null ? scannedPackage.packageName : "null")
+ + (scannedPackage != null ? scannedPackage : "null")
+ ")");
try {
mInstaller.rmdex(ps.codePathString,
diff --git a/services/core/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java
index 522c2e8..9a559ee 100644
--- a/services/core/java/com/android/server/pm/SELinuxMMAC.java
+++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java
@@ -60,8 +60,8 @@
/** Path to MAC permissions on system image */
private static final File[] MAC_PERMISSIONS =
- { new File(Environment.getRootDirectory(), "/etc/security/plat_mac_permissions.xml"),
- new File(Environment.getRootDirectory(), "/etc/security/nonplat_mac_permissions.xml") };
+ { new File(Environment.getRootDirectory(), "/etc/selinux/plat_mac_permissions.xml"),
+ new File(Environment.getVendorDirectory(), "/etc/selinux/nonplat_mac_permissions.xml") };
// Append privapp to existing seinfo label
private static final String PRIVILEGED_APP_STR = ":privapp";
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index de4a55b..c907cf3 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -235,6 +235,15 @@
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
+ //
+ // Default the timezone property to GMT if not set.
+ //
+ String timezoneProperty = SystemProperties.get("persist.sys.timezone");
+ if (timezoneProperty == null || timezoneProperty.isEmpty()) {
+ Slog.w(TAG, "Timezone not set; setting to GMT.");
+ SystemProperties.set("persist.sys.timezone", "GMT");
+ }
+
// If the system has "persist.sys.language" and friends set, replace them with
// "persist.sys.locale". Note that the default locale at this point is calculated
// using the "-Duser.locale" command line flag. That flag is usually populated by
diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index 76b1c90..3e3a19b 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -23,6 +23,7 @@
import android.net.apf.ApfCapabilities;
import android.net.apf.ApfFilter;
import android.net.DhcpResults;
+import android.net.INetd;
import android.net.InterfaceConfiguration;
import android.net.LinkAddress;
import android.net.LinkProperties;
@@ -34,10 +35,12 @@
import android.net.metrics.IpConnectivityLog;
import android.net.metrics.IpManagerEvent;
import android.net.util.MultinetworkPolicyTracker;
+import android.net.util.NetdService;
import android.os.INetworkManagementService;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.LocalLog;
@@ -631,6 +634,13 @@
pw.println();
pw.println(mTag + " connectivity packet log:");
+ pw.println();
+ pw.println("Debug with python and scapy via:");
+ pw.println("shell$ python");
+ pw.println(">>> from scapy import all as scapy");
+ pw.println(">>> scapy.Ether(\"<paste_hex_string>\".decode(\"hex\")).show2()");
+ pw.println();
+
pw.increaseIndent();
mConnectivityPacketLog.readOnlyLocalLog().dump(fd, pw, args);
pw.decreaseIndent();
@@ -1020,14 +1030,16 @@
private boolean startIPv6() {
// Set privacy extensions.
+ final String PREFER_TEMPADDRS = "2";
try {
- mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
+ NetdService.run((INetd netd) -> {
+ netd.setProcSysNet(
+ INetd.IPV6, INetd.CONF, mInterfaceName, "use_tempaddr",
+ PREFER_TEMPADDRS);
+ });
mNwService.enableIpv6(mInterfaceName);
- } catch (RemoteException re) {
- logError("Unable to change interface settings: %s", re);
- return false;
- } catch (IllegalStateException ie) {
- logError("Unable to change interface settings: %s", ie);
+ } catch (IllegalStateException|RemoteException|ServiceSpecificException e) {
+ logError("Unable to change interface settings: %s", e);
return false;
}
diff --git a/services/net/java/android/net/util/NetdService.java b/services/net/java/android/net/util/NetdService.java
index 153cb50..6e69ff5 100644
--- a/services/net/java/android/net/util/NetdService.java
+++ b/services/net/java/android/net/util/NetdService.java
@@ -17,7 +17,10 @@
package android.net.util;
import android.net.INetd;
+import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
+import android.os.SystemClock;
import android.util.Log;
@@ -27,15 +30,24 @@
public class NetdService {
private static final String TAG = NetdService.class.getSimpleName();
private static final String NETD_SERVICE_NAME = "netd";
+ private static final long BASE_TIMEOUT_MS = 100;
+ private static final long MAX_TIMEOUT_MS = 1000;
+
/**
+ * Return an INetd instance, or null if not available.
+ *
* It is the caller's responsibility to check for a null return value
* and to handle RemoteException errors from invocations on the returned
* interface if, for example, netd dies and is restarted.
*
+ * Returned instances of INetd should not be cached.
+ *
* @return an INetd instance or null.
*/
public static INetd getInstance() {
+ // NOTE: ServiceManager does no caching for the netd service,
+ // because netd is not one of the defined common services.
final INetd netdInstance = INetd.Stub.asInterface(
ServiceManager.getService(NETD_SERVICE_NAME));
if (netdInstance == null) {
@@ -43,4 +55,82 @@
}
return netdInstance;
}
+
+ /**
+ * Blocks for a specified time until an INetd instance is available.
+ *
+ * It is the caller's responsibility to handle RemoteException errors
+ * from invocations on the returned interface if, for example, netd
+ * dies after this interface was returned.
+ *
+ * Returned instances of INetd should not be cached.
+ *
+ * Special values of maxTimeoutMs include: 0, meaning try to obtain an
+ * INetd instance only once, and -1 (or any value less than 0), meaning
+ * try to obtain an INetd instance indefinitely.
+ *
+ * @param maxTimeoutMs the maximum time to spend getting an INetd instance
+ * @return an INetd instance or null if no instance is available
+ * within |maxTimeoutMs| milliseconds.
+ */
+ public static INetd get(long maxTimeoutMs) {
+ if (maxTimeoutMs == 0) return getInstance();
+
+ final long stop = (maxTimeoutMs > 0)
+ ? SystemClock.elapsedRealtime() + maxTimeoutMs
+ : Long.MAX_VALUE;
+
+ long timeoutMs = 0;
+ while (true) {
+ final INetd netdInstance = getInstance();
+ if (netdInstance != null) {
+ return netdInstance;
+ }
+
+ final long remaining = stop - SystemClock.elapsedRealtime();
+ if (remaining <= 0) break;
+
+ // No netdInstance was received; sleep and retry.
+ timeoutMs = Math.min(timeoutMs + BASE_TIMEOUT_MS, MAX_TIMEOUT_MS);
+ timeoutMs = Math.min(timeoutMs, remaining);
+ try {
+ Thread.sleep(timeoutMs);
+ } catch (InterruptedException e) {}
+ }
+ return null;
+ }
+
+ /**
+ * Blocks until an INetd instance is available.
+ *
+ * It is the caller's responsibility to handle RemoteException errors
+ * from invocations on the returned interface if, for example, netd
+ * dies after this interface was returned.
+ *
+ * Returned instances of INetd should not be cached.
+ *
+ * @return an INetd instance.
+ */
+ public static INetd get() {
+ return get(-1);
+ }
+
+ public static interface NetdCommand {
+ void run(INetd netd) throws RemoteException;
+ }
+
+ /**
+ * Blocks until an INetd instance is availabe, and retries until either
+ * the command succeeds or a runtime exception is thrown.
+ */
+ public static void run(NetdCommand cmd) {
+ while (true) {
+ try {
+ cmd.run(get());
+ return;
+ } catch (RemoteException re) {
+ Log.e(TAG, "error communicating with netd: " + re);
+ }
+ }
+ }
}
diff --git a/services/net/java/android/net/util/NetworkConstants.java b/services/net/java/android/net/util/NetworkConstants.java
index 362f757..26f3050 100644
--- a/services/net/java/android/net/util/NetworkConstants.java
+++ b/services/net/java/android/net/util/NetworkConstants.java
@@ -97,6 +97,7 @@
public static final int IPV6_SRC_ADDR_OFFSET = 8;
public static final int IPV6_DST_ADDR_OFFSET = 24;
public static final int IPV6_ADDR_LEN = 16;
+ public static final int RFC7421_PREFIX_LENGTH = 64;
/**
* ICMPv6 constants.
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index 43c8957..5553fd6 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -271,8 +271,8 @@
final Bundle bundle = new Bundle();
bundle.putParcelable(EXTRA_RECOMMENDATION_RESULT, providerResult);
doAnswer(invocation -> {
- bundle.putInt(EXTRA_SEQUENCE, invocation.getArgumentAt(2, int.class));
- invocation.getArgumentAt(1, IRemoteCallback.class).sendResult(bundle);
+ bundle.putInt(EXTRA_SEQUENCE, invocation.getArgument(2));
+ invocation.<IRemoteCallback>getArgument(1).sendResult(bundle);
return null;
}).when(mRecommendationProvider)
.requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
@@ -336,7 +336,7 @@
injectProvider();
final Bundle bundle = new Bundle();
doAnswer(invocation -> {
- invocation.getArgumentAt(1, IRemoteCallback.class).sendResult(bundle);
+ invocation.<IRemoteCallback>getArgument(1).sendResult(bundle);
return null;
}).when(mRecommendationProvider)
.requestRecommendation(eq(mRecommendationRequest), isA(IRemoteCallback.class),
@@ -634,7 +634,7 @@
IBinder mockBinder = mock(IBinder.class);
when(mockBinder.queryLocalInterface(anyString()))
.thenReturn(mRecommendationProvider);
- invocation.getArgumentAt(1, ServiceConnection.class)
+ invocation.<ServiceConnection>getArgument(1)
.onServiceConnected(componentName, mockBinder);
return true;
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java b/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java
index 3806da6..e43786c 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/MockUtils.java
@@ -29,6 +29,7 @@
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.mockito.Mockito;
+import org.mockito.hamcrest.MockitoHamcrest;
public class MockUtils {
private MockUtils() {
@@ -47,7 +48,7 @@
description.appendText("UserHandle: user-id= \"" + userId + "\"");
}
};
- return Mockito.argThat(m);
+ return MockitoHamcrest.argThat(m);
}
public static Intent checkIntentComponent(final ComponentName component) {
@@ -63,7 +64,7 @@
description.appendText("Intent: component=\"" + component + "\"");
}
};
- return Mockito.argThat(m);
+ return MockitoHamcrest.argThat(m);
}
public static Intent checkIntentAction(final String action) {
@@ -79,7 +80,7 @@
description.appendText("Intent: action=\"" + action + "\"");
}
};
- return Mockito.argThat(m);
+ return MockitoHamcrest.argThat(m);
}
public static Intent checkIntent(final Intent intent) {
@@ -94,7 +95,7 @@
description.appendText(intent.toString());
}
};
- return Mockito.argThat(m);
+ return MockitoHamcrest.argThat(m);
}
public static Bundle checkUserRestrictions(String... keys) {
@@ -111,7 +112,7 @@
description.appendText("User restrictions=" + getRestrictionsAsString(expected));
}
};
- return Mockito.argThat(m);
+ return MockitoHamcrest.argThat(m);
}
private static String getRestrictionsAsString(Bundle b) {
diff --git a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
index 82c7bdb..1192901 100644
--- a/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/webkit/WebViewUpdateServiceTest.java
@@ -32,14 +32,12 @@
import android.webkit.WebViewProviderInfo;
import android.webkit.WebViewProviderResponse;
-import org.hamcrest.Description;
-
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.Matchers;
-import org.mockito.ArgumentMatcher;
+import org.mockito.compat.ArgumentMatcher;
import java.util.concurrent.CountDownLatch;
@@ -131,14 +129,13 @@
}
@Override
- public boolean matches(Object p) {
+ public boolean matchesObject(Object p) {
return ((PackageInfo) p).packageName.equals(mPackageName);
}
- // Provide a more useful description in case of mismatch
@Override
- public void describeTo (Description description) {
- description.appendText(String.format("PackageInfo with name '%s'", mPackageName));
+ public String toString() {
+ return String.format("PackageInfo with name '%s'", mPackageName);
}
}
diff --git a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
index 1fe5cb7..29d58ce 100644
--- a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
+++ b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
@@ -59,6 +59,7 @@
import org.json.JSONObject;
import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;
+import org.mockito.hamcrest.MockitoHamcrest;
import java.io.BufferedReader;
import java.io.File;
@@ -665,7 +666,7 @@
d.appendText(description);
}
};
- return Mockito.argThat(m);
+ return MockitoHamcrest.argThat(m);
}
public static List<ShortcutInfo> checkShortcutIds(String... ids) {
diff --git a/services/usb/java/com/android/server/usb/UsbDeviceManager.java b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
index 99eb3d2..39da224 100644
--- a/services/usb/java/com/android/server/usb/UsbDeviceManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDeviceManager.java
@@ -743,7 +743,8 @@
}
mMidiEnabled = enabled;
}
- mUsbAlsaManager.setPeripheralMidiState(mMidiEnabled && mConfigured, mMidiCard, mMidiDevice);
+ mUsbAlsaManager.setPeripheralMidiState(
+ mMidiEnabled && mConfigured, mMidiCard, mMidiDevice);
}
@Override
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 1076afc..ce1c3c3 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -315,6 +315,14 @@
public static final String KEY_DEFAULT_VM_NUMBER_STRING = "default_vm_number_string";
/**
+ * Flag indicating whether we should downgrade/terminate VT calls and disable VT when
+ * data enabled changed (e.g. reach data limit or turn off data).
+ * @hide
+ */
+ public static final String KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS =
+ "ignore_data_enabled_changed_for_video_calls";
+
+ /**
* Flag specifying whether WFC over IMS should be available for carrier: independent of
* carrier provisioning. If false: hard disabled. If true: then depends on carrier
* provisioning, availability etc.
@@ -1135,6 +1143,22 @@
public static final String KEY_NOTIFY_INTERNATIONAL_CALL_ON_WFC_BOOL =
"notify_international_call_on_wfc_bool";
+ /**
+ * Offset to be reduced from rsrp threshold while calculating signal strength level.
+ * @hide
+ */
+ public static final String KEY_LTE_EARFCNS_RSRP_BOOST_INT = "lte_earfcns_rsrp_boost_int";
+
+ /**
+ * List of EARFCN (E-UTRA Absolute Radio Frequency Channel Number,
+ * Reference: 3GPP TS 36.104 5.4.3) inclusive ranges on which lte_rsrp_boost_int
+ * will be applied. Format of the String array is expected to be {"erafcn1_start-earfcn1_end",
+ * "earfcn2_start-earfcn2_end" ... }
+ * @hide
+ */
+ public static final String KEY_BOOSTED_LTE_EARFCNS_STRING_ARRAY =
+ "boosted_lte_earfcns_string_array";
+
/** The default value for every variable. */
private final static PersistableBundle sDefaults;
@@ -1152,6 +1176,7 @@
sDefaults.putBoolean(KEY_NOTIFY_HANDOVER_VIDEO_FROM_WIFI_TO_LTE_BOOL, false);
sDefaults.putBoolean(KEY_SUPPORT_DOWNGRADE_VT_TO_AUDIO_BOOL, true);
sDefaults.putString(KEY_DEFAULT_VM_NUMBER_STRING, "");
+ sDefaults.putBoolean(KEY_IGNORE_DATA_ENABLED_CHANGED_FOR_VIDEO_CALLS, false);
sDefaults.putBoolean(KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL, false);
sDefaults.putBoolean(KEY_CARRIER_WFC_SUPPORTS_WIFI_ONLY_BOOL, false);
sDefaults.putBoolean(KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL, false);
@@ -1341,6 +1366,8 @@
sDefaults.putBoolean(KEY_EDITABLE_WFC_ROAMING_MODE_BOOL, false);
sDefaults.putBoolean(KEY_SUPPORT_3GPP_CALL_FORWARDING_WHILE_ROAMING_BOOL, true);
sDefaults.putBoolean(KEY_NOTIFY_INTERNATIONAL_CALL_ON_WFC_BOOL, false);
+ sDefaults.putInt(KEY_LTE_EARFCNS_RSRP_BOOST_INT, 0);
+ sDefaults.putStringArray(KEY_BOOSTED_LTE_EARFCNS_STRING_ARRAY, null);
}
/**
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index 2eba402..0b80d06 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1619,7 +1619,7 @@
//
// Australia: Short codes are six or eight digits in length, starting with the prefix "19"
// followed by an additional four or six digits and two.
- // Czech Republic: Codes are seven digits in length for MO and five (not billed) or
+ // Czechia: Codes are seven digits in length for MO and five (not billed) or
// eight (billed) for MT direction
//
// see http://en.wikipedia.org/wiki/Short_code#Regional_differences for reference
@@ -1896,7 +1896,7 @@
number = extractNetworkPortionAlt(number);
String emergencyNumbers = "";
- int slotId = SubscriptionManager.getSlotId(subId);
+ int slotId = SubscriptionManager.getSlotIndex(subId);
// retrieve the list of emergency numbers
// check read-write ecclist property first
diff --git a/telephony/java/android/telephony/PreciseDisconnectCause.java b/telephony/java/android/telephony/PreciseDisconnectCause.java
index 54ab19d..2516d51 100644
--- a/telephony/java/android/telephony/PreciseDisconnectCause.java
+++ b/telephony/java/android/telephony/PreciseDisconnectCause.java
@@ -25,75 +25,480 @@
public class PreciseDisconnectCause {
/** The disconnect cause is not valid (Not received a disconnect cause)*/
- public static final int NOT_VALID = -1;
+ public static final int NOT_VALID = -1;
/** No disconnect cause provided. Generally a local disconnect or an incoming missed call */
- public static final int NO_DISCONNECT_CAUSE_AVAILABLE = 0;
+ public static final int NO_DISCONNECT_CAUSE_AVAILABLE = 0;
/**
* The destination cannot be reached because the number, although valid,
* is not currently assigned
*/
- public static final int UNOBTAINABLE_NUMBER = 1;
+ public static final int UNOBTAINABLE_NUMBER = 1;
+ /** The user cannot be reached because the network through which the call has been
+ * routed does not serve the destination desired
+ */
+ public static final int NO_ROUTE_TO_DESTINATION = 3;
+ /** The channel most recently identified is not acceptable to the sending entity for
+ * use in this call
+ */
+ public static final int CHANNEL_UNACCEPTABLE = 6;
+ /** The MS has tried to access a service that the MS's network operator or service
+ * provider is not prepared to allow
+ */
+ public static final int OPERATOR_DETERMINED_BARRING = 8;
/** One of the users involved in the call has requested that the call is cleared */
- public static final int NORMAL = 16;
+ public static final int NORMAL = 16;
/** The called user is unable to accept another call */
- public static final int BUSY = 17;
+ public static final int BUSY = 17;
+ /** The user does not respond to a call establishment message with either an alerting
+ * or connect indication within the prescribed period of time allocated
+ */
+ public static final int NO_USER_RESPONDING = 18;
+ /** The user has provided an alerting indication but has not provided a connect
+ * indication within a prescribed period of time
+ */
+ public static final int NO_ANSWER_FROM_USER = 19;
+ /** The equipment sending this cause does not wish to accept this call */
+ public static final int CALL_REJECTED = 21;
/** The called number is no longer assigned */
- public static final int NUMBER_CHANGED = 22;
+ public static final int NUMBER_CHANGED = 22;
+ /** This cause is returned to the network when a mobile station clears an active
+ * call which is being pre-empted by another call with higher precedence
+ */
+ public static final int PREEMPTION = 25;
+ /** The destination indicated by the mobile station cannot be reached because
+ * the interface to the destination is not functioning correctly
+ */
+ public static final int DESTINATION_OUT_OF_ORDER = 27;
+ /** The called party number is not a valid format or is not complete */
+ public static final int INVALID_NUMBER_FORMAT = 28;
+ /** The facility requested by user can not be provided by the network */
+ public static final int FACILITY_REJECTED = 29;
/** Provided in response to a STATUS ENQUIRY message */
- public static final int STATUS_ENQUIRY = 30;
+ public static final int STATUS_ENQUIRY = 30;
/** Reports a normal disconnect only when no other normal cause applies */
- public static final int NORMAL_UNSPECIFIED = 31;
+ public static final int NORMAL_UNSPECIFIED = 31;
/** There is no channel presently available to handle the call */
- public static final int NO_CIRCUIT_AVAIL = 34;
+ public static final int NO_CIRCUIT_AVAIL = 34;
+ /** The network is not functioning correctly and that the condition is likely
+ * to last a relatively long period of time
+ */
+ public static final int NETWORK_OUT_OF_ORDER = 38;
/**
* The network is not functioning correctly and the condition is not likely to last
* a long period of time
*/
- public static final int TEMPORARY_FAILURE = 41;
+ public static final int TEMPORARY_FAILURE = 41;
/** The switching equipment is experiencing a period of high traffic */
- public static final int SWITCHING_CONGESTION = 42;
+ public static final int SWITCHING_CONGESTION = 42;
+ /** The network could not deliver access information to the remote user as requested */
+ public static final int ACCESS_INFORMATION_DISCARDED = 43;
/** The channel cannot be provided */
- public static final int CHANNEL_NOT_AVAIL = 44;
+ public static final int CHANNEL_NOT_AVAIL = 44;
+ /** This cause is used to report a resource unavailable event only when no other
+ * cause in the resource unavailable class applies
+ */
+ public static final int RESOURCES_UNAVAILABLE_OR_UNSPECIFIED = 44;
/** The requested quality of service (ITU-T X.213) cannot be provided */
- public static final int QOS_NOT_AVAIL = 49;
+ public static final int QOS_NOT_AVAIL = 49;
+ /** The facility could not be provided by the network because the user has no
+ * complete subscription
+ */
+ public static final int REQUESTED_FACILITY_NOT_SUBSCRIBED = 50;
+ /** Incoming calls are not allowed within this CUG */
+ public static final int INCOMING_CALLS_BARRED_WITHIN_CUG = 55;
+ /** The mobile station is not authorized to use bearer capability requested */
+ public static final int BEARER_CAPABILITY_NOT_AUTHORIZED = 57;
/** The requested bearer capability is not available at this time */
- public static final int BEARER_NOT_AVAIL = 58;
+ public static final int BEARER_NOT_AVAIL = 58;
+ /** The service option is not availble at this time */
+ public static final int SERVICE_OPTION_NOT_AVAILABLE = 63;
+ /** The equipment sending this cause does not support the bearer capability requested */
+ public static final int BEARER_SERVICE_NOT_IMPLEMENTED = 65;
/** The call clearing is due to ACM being greater than or equal to ACMmax */
- public static final int ACM_LIMIT_EXCEEDED = 68;
+ public static final int ACM_LIMIT_EXCEEDED = 68;
+ /** The equipment sending this cause does not support the requested facility */
+ public static final int REQUESTED_FACILITY_NOT_IMPLEMENTED = 69;
+ /** The equipment sending this cause only supports the restricted version of
+ * the requested bearer capability
+ */
+ public static final int ONLY_DIGITAL_INFORMATION_BEARER_AVAILABLE = 70;
+ /** The service requested is not implemented at network */
+ public static final int SERVICE_OR_OPTION_NOT_IMPLEMENTED = 79;
+ /** The equipment sending this cause has received a message with a transaction identifier
+ * which is not currently in use on the MS-network interface
+ */
+ public static final int INVALID_TRANSACTION_IDENTIFIER = 81;
+ /** The called user for the incoming CUG call is not a member of the specified CUG */
+ public static final int USER_NOT_MEMBER_OF_CUG = 87;
+ /** The equipment sending this cause has received a request which can't be accomodated */
+ public static final int INCOMPATIBLE_DESTINATION = 88;
+ /** This cause is used to report receipt of a message with semantically incorrect contents */
+ public static final int SEMANTICALLY_INCORRECT_MESSAGE = 95;
+ /** The equipment sending this cause has received a message with a non-semantical
+ * mandatory IE error
+ */
+ public static final int INVALID_MANDATORY_INFORMATION = 96;
+ /** This is sent in response to a message which is not defined, or defined but not
+ * implemented by the equipment sending this cause
+ */
+ public static final int MESSAGE_TYPE_NON_IMPLEMENTED = 97;
+ /** The equipment sending this cause has received a message not compatible with the
+ * protocol state
+ */
+ public static final int MESSAGE_TYPE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 98;
+ /** The equipment sending this cause has received a message which includes information
+ * elements not recognized because its identifier is not defined or it is defined but not
+ * implemented by the equipment sending the cause
+ */
+ public static final int INFORMATION_ELEMENT_NON_EXISTENT = 99;
+ /** The equipment sending this cause has received a message with conditional IE errors */
+ public static final int CONDITIONAL_IE_ERROR = 100;
+ /** The message has been received which is incompatible with the protocol state */
+ public static final int MESSAGE_NOT_COMPATIBLE_WITH_PROTOCOL_STATE = 101;
+ /** The procedure has been initiated by the expiry of a timer in association with
+ * 3GPP TS 24.008 error handling procedures
+ */
+ public static final int RECOVERY_ON_TIMER_EXPIRED = 102;
+ /** This protocol error event is reported only when no other cause in the protocol
+ * error class applies
+ */
+ public static final int PROTOCOL_ERROR_UNSPECIFIED = 111;
+ /** interworking with a network which does not provide causes for actions it takes
+ * thus, the precise cause for a message which is being sent cannot be ascertained
+ */
+ public static final int INTERWORKING_UNSPECIFIED = 127;
/** The call is restricted */
- public static final int CALL_BARRED = 240;
+ public static final int CALL_BARRED = 240;
/** The call is blocked by the Fixed Dialing Number list */
- public static final int FDN_BLOCKED = 241;
+ public static final int FDN_BLOCKED = 241;
/** The given IMSI is not known at the VLR */
/** TS 24.008 cause 4 */
- public static final int IMSI_UNKNOWN_IN_VLR = 242;
+ public static final int IMSI_UNKNOWN_IN_VLR = 242;
/**
* The network does not accept emergency call establishment using an IMEI or not accept attach
* procedure for emergency services using an IMEI
*/
- public static final int IMEI_NOT_ACCEPTED = 243;
+ public static final int IMEI_NOT_ACCEPTED = 243;
+ /** The call cannot be established because RADIO is OFF */
+ public static final int RADIO_OFF = 247;
+ /** The call cannot be established because of no cell coverage */
+ public static final int OUT_OF_SRV = 248;
+ /** The call cannot be established because of no valid SIM */
+ public static final int NO_VALID_SIM = 249;
+ /** The call is dropped or failed internally by modem */
+ public static final int RADIO_INTERNAL_ERROR = 250;
+ /** Call failed because of UE timer expired while waiting for a response from network */
+ public static final int NETWORK_RESP_TIMEOUT = 251;
+ /** Call failed because of a network reject */
+ public static final int NETWORK_REJECT = 252;
+ /** Call failed because of radio access failure. ex. RACH failure */
+ public static final int RADIO_ACCESS_FAILURE = 253;
+ /** Call failed/dropped because of a RLF */
+ public static final int RADIO_LINK_FAILURE = 254;
+ /** Call failed/dropped because of radio link lost */
+ public static final int RADIO_LINK_LOST = 255;
+ /** Call failed because of a radio uplink issue */
+ public static final int RADIO_UPLINK_FAILURE = 256;
+ /** Call failed because of a RRC connection setup failure */
+ public static final int RADIO_SETUP_FAILURE = 257;
+ /** Call failed/dropped because of RRC connection release from NW */
+ public static final int RADIO_RELEASE_NORMAL = 258;
+ /** Call failed/dropped because of RRC abnormally released by modem/network */
+ public static final int RADIO_RELEASE_ABNORMAL = 259;
+ /** Call setup failed because of access class barring */
+ public static final int ACCESS_CLASS_BLOCKED = 260;
+ /** Call failed/dropped because of a network detach */
+ public static final int NETWORK_DETACH = 261;
+
/** MS is locked until next power cycle */
- public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000;
+ public static final int CDMA_LOCKED_UNTIL_POWER_CYCLE = 1000;
/** Drop call*/
- public static final int CDMA_DROP = 1001;
+ public static final int CDMA_DROP = 1001;
/** INTERCEPT order received, MS state idle entered */
- public static final int CDMA_INTERCEPT = 1002;
+ public static final int CDMA_INTERCEPT = 1002;
/** MS has been redirected, call is cancelled */
- public static final int CDMA_REORDER = 1003;
+ public static final int CDMA_REORDER = 1003;
/** Service option rejection */
- public static final int CDMA_SO_REJECT = 1004;
+ public static final int CDMA_SO_REJECT = 1004;
/** Requested service is rejected, retry delay is set */
- public static final int CDMA_RETRY_ORDER = 1005;
+ public static final int CDMA_RETRY_ORDER = 1005;
/** Unable to obtain access to the CDMA system */
- public static final int CDMA_ACCESS_FAILURE = 1006;
+ public static final int CDMA_ACCESS_FAILURE = 1006;
/** Not a preempted call */
- public static final int CDMA_PREEMPTED = 1007;
+ public static final int CDMA_PREEMPTED = 1007;
/** Not an emergency call */
- public static final int CDMA_NOT_EMERGENCY = 1008;
+ public static final int CDMA_NOT_EMERGENCY = 1008;
/** Access Blocked by CDMA network */
- public static final int CDMA_ACCESS_BLOCKED = 1009;
+ public static final int CDMA_ACCESS_BLOCKED = 1009;
+
+ /** Mapped from ImsReasonInfo */
+ /* The passed argument is an invalid */
+ public static final int LOCAL_ILLEGAL_ARGUMENT = 1200;
+ // The operation is invoked in invalid call state
+ public static final int LOCAL_ILLEGAL_STATE = 1201;
+ // IMS service internal error
+ public static final int LOCAL_INTERNAL_ERROR = 1202;
+ // IMS service goes down (service connection is lost)
+ public static final int LOCAL_IMS_SERVICE_DOWN = 1203;
+ // No pending incoming call exists
+ public static final int LOCAL_NO_PENDING_CALL = 1204;
+ // Service unavailable; by power off
+ public static final int LOCAL_POWER_OFF = 1205;
+ // Service unavailable; by low battery
+ public static final int LOCAL_LOW_BATTERY = 1206;
+ // Service unavailable; by out of service (data service state)
+ public static final int LOCAL_NETWORK_NO_SERVICE = 1207;
+ /* Service unavailable; by no LTE coverage
+ * (VoLTE is not supported even though IMS is registered)
+ */
+ public static final int LOCAL_NETWORK_NO_LTE_COVERAGE = 1208;
+ /** Service unavailable; by located in roaming area */
+ public static final int LOCAL_NETWORK_ROAMING = 1209;
+ /** Service unavailable; by IP changed */
+ public static final int LOCAL_NETWORK_IP_CHANGED = 1210;
+ /** Service unavailable; other */
+ public static final int LOCAL_SERVICE_UNAVAILABLE = 1211;
+ /* Service unavailable; IMS connection is lost (IMS is not registered) */
+ public static final int LOCAL_NOT_REGISTERED = 1212;
+ /** Max call exceeded */
+ public static final int LOCAL_MAX_CALL_EXCEEDED = 1213;
+ /** Call decline */
+ public static final int LOCAL_CALL_DECLINE = 1214;
+ /** SRVCC is in progress */
+ public static final int LOCAL_CALL_VCC_ON_PROGRESSING = 1215;
+ /** Resource reservation is failed (QoS precondition) */
+ public static final int LOCAL_CALL_RESOURCE_RESERVATION_FAILED = 1216;
+ /** Retry CS call; VoLTE service can't be provided by the network or remote end
+ * Resolve the extra code(EXTRA_CODE_CALL_RETRY_*) if the below code is set
+ */
+ public static final int LOCAL_CALL_CS_RETRY_REQUIRED = 1217;
+ /** Retry VoLTE call; VoLTE service can't be provided by the network temporarily */
+ public static final int LOCAL_CALL_VOLTE_RETRY_REQUIRED = 1218;
+ /** IMS call is already terminated (in TERMINATED state) */
+ public static final int LOCAL_CALL_TERMINATED = 1219;
+ /** Handover not feasible */
+ public static final int LOCAL_HO_NOT_FEASIBLE = 1220;
+
+ /** 1xx waiting timer is expired after sending INVITE request (MO only) */
+ public static final int TIMEOUT_1XX_WAITING = 1221;
+ /** User no answer during call setup operation (MO/MT)
+ * MO : 200 OK to INVITE request is not received,
+ * MT : No action from user after alerting the call
+ */
+ public static final int TIMEOUT_NO_ANSWER = 1222;
+ /** User no answer during call update operation (MO/MT)
+ * MO : 200 OK to re-INVITE request is not received,
+ * MT : No action from user after alerting the call
+ */
+ public static final int TIMEOUT_NO_ANSWER_CALL_UPDATE = 1223;
+
+ /**
+ * STATUSCODE (SIP response code) (IMS -> Telephony)
+ */
+ /** SIP request is redirected */
+ public static final int SIP_REDIRECTED = 1300;
+ /** 4xx responses */
+ /** 400 : Bad Request */
+ public static final int SIP_BAD_REQUEST = 1310;
+ /** 403 : Forbidden */
+ public static final int SIP_FORBIDDEN = 1311;
+ /** 404 : Not Found */
+ public static final int SIP_NOT_FOUND = 1312;
+ /** 415 : Unsupported Media Type
+ * 416 : Unsupported URI Scheme
+ * 420 : Bad Extension
+ */
+ public static final int SIP_NOT_SUPPORTED = 1313;
+ /** 408 : Request Timeout */
+ public static final int SIP_REQUEST_TIMEOUT = 1314;
+ /** 480 : Temporarily Unavailable */
+ public static final int SIP_TEMPRARILY_UNAVAILABLE = 1315;
+ /** 484 : Address Incomplete */
+ public static final int SIP_BAD_ADDRESS = 1316;
+ /** 486 : Busy Here
+ * 600 : Busy Everywhere
+ */
+ public static final int SIP_BUSY = 1317;
+ /** 487 : Request Terminated */
+ public static final int SIP_REQUEST_CANCELLED = 1318;
+ /** 406 : Not Acceptable
+ * 488 : Not Acceptable Here
+ * 606 : Not Acceptable
+ */
+ public static final int SIP_NOT_ACCEPTABLE = 1319;
+ /** 410 : Gone
+ * 604 : Does Not Exist Anywhere
+ */
+ public static final int SIP_NOT_REACHABLE = 1320;
+ /** Others */
+ public static final int SIP_CLIENT_ERROR = 1321;
+ /** 5xx responses
+ * 501 : Server Internal Error
+ */
+ public static final int SIP_SERVER_INTERNAL_ERROR = 1330;
+ /** 503 : Service Unavailable */
+ public static final int SIP_SERVICE_UNAVAILABLE = 1331;
+ /** 504 : Server Time-out */
+ public static final int SIP_SERVER_TIMEOUT = 1332;
+ /** Others */
+ public static final int SIP_SERVER_ERROR = 1333;
+ /** 6xx responses
+ * 603 : Decline
+ */
+ public static final int SIP_USER_REJECTED = 1340;
+ /** Others */
+ public static final int SIP_GLOBAL_ERROR = 1341;
+ /** Emergency failure */
+ public static final int EMERGENCY_TEMP_FAILURE = 1342;
+ public static final int EMERGENCY_PERM_FAILURE = 1343;
+ /** Media resource initialization failed */
+ public static final int MEDIA_INIT_FAILED = 1400;
+ /** RTP timeout (no audio / video traffic in the session) */
+ public static final int MEDIA_NO_DATA = 1401;
+ /** Media is not supported; so dropped the call */
+ public static final int MEDIA_NOT_ACCEPTABLE = 1402;
+ /** Unknown media related errors */
+ public static final int MEDIA_UNSPECIFIED = 1403;
+ /** User triggers the call end */
+ public static final int USER_TERMINATED = 1500;
+ /** No action while an incoming call is ringing */
+ public static final int USER_NOANSWER = 1501;
+ /** User ignores an incoming call */
+ public static final int USER_IGNORE = 1502;
+ /** User declines an incoming call */
+ public static final int USER_DECLINE = 1503;
+ /** Device declines/ends a call due to low battery */
+ public static final int LOW_BATTERY = 1504;
+ /** Device declines call due to blacklisted call ID */
+ public static final int BLACKLISTED_CALL_ID = 1505;
+ /** The call is terminated by the network or remote user */
+ public static final int USER_TERMINATED_BY_REMOTE = 1510;
+
+ /**
+ * UT
+ */
+ public static final int UT_NOT_SUPPORTED = 1800;
+ public static final int UT_SERVICE_UNAVAILABLE = 1801;
+ public static final int UT_OPERATION_NOT_ALLOWED = 1802;
+ public static final int UT_NETWORK_ERROR = 1803;
+ public static final int UT_CB_PASSWORD_MISMATCH = 1804;
+
+ /**
+ * ECBM
+ */
+ public static final int ECBM_NOT_SUPPORTED = 1900;
+
+ /**
+ * Fail code used to indicate that Multi-endpoint is not supported by the Ims framework.
+ */
+ public static final int MULTIENDPOINT_NOT_SUPPORTED = 1901;
+
+ /**
+ * CALL DROP error codes (Call could drop because of many reasons like Network not available,
+ * handover, failed, etc)
+ */
+
+ /**
+ * CALL DROP error code for the case when a device is ePDG capable and when the user is on an
+ * active wifi call and at the edge of coverage and there is no qualified LTE network available
+ * to handover the call to. We get a handover NOT_TRIGERRED message from the modem. This error
+ * code is received as part of the handover message.
+ */
+ public static final int CALL_DROP_IWLAN_TO_LTE_UNAVAILABLE = 2000;
+
+ /**
+ * MT call has ended due to a release from the network
+ * because the call was answered elsewhere
+ */
+ public static final int ANSWERED_ELSEWHERE = 2100;
+
+ /**
+ * For MultiEndpoint - Call Pull request has failed
+ */
+ public static final int CALL_PULL_OUT_OF_SYNC = 2101;
+
+ /**
+ * For MultiEndpoint - Call has been pulled from primary to secondary
+ */
+ public static final int CALL_PULLED = 2102;
+
+ /**
+ * Supplementary services (HOLD/RESUME) failure error codes.
+ * Values for Supplemetary services failure - Failed, Cancelled and Re-Invite collision.
+ */
+ public static final int SUPP_SVC_FAILED = 2300;
+ public static final int SUPP_SVC_CANCELLED = 2301;
+ public static final int SUPP_SVC_REINVITE_COLLISION = 2302;
+
+ /**
+ * DPD Procedure received no response or send failed
+ */
+ public static final int IWLAN_DPD_FAILURE = 2400;
+
+ /**
+ * Establishment of the ePDG Tunnel Failed
+ */
+ public static final int EPDG_TUNNEL_ESTABLISH_FAILURE = 2500;
+
+ /**
+ * Re-keying of the ePDG Tunnel Failed; may not always result in teardown
+ */
+ public static final int EPDG_TUNNEL_REKEY_FAILURE = 2501;
+
+ /**
+ * Connection to the packet gateway is lost
+ */
+ public static final int EPDG_TUNNEL_LOST_CONNECTION = 2502;
+
+ /**
+ * The maximum number of calls allowed has been reached. Used in a multi-endpoint scenario
+ * where the number of calls across all connected devices has reached the maximum.
+ */
+ public static final int MAXIMUM_NUMBER_OF_CALLS_REACHED = 2503;
+
+ /**
+ * Similar to {@link #CODE_LOCAL_CALL_DECLINE}, except indicates that a remote device has
+ * declined the call. Used in a multi-endpoint scenario where a remote device declined an
+ * incoming call.
+ */
+ public static final int REMOTE_CALL_DECLINE = 2504;
+
+ /**
+ * Indicates the call was disconnected due to the user reaching their data limit.
+ */
+ public static final int DATA_LIMIT_REACHED = 2505;
+
+ /**
+ * Indicates the call was disconnected due to the user disabling cellular data.
+ */
+ public static final int DATA_DISABLED = 2506;
+
+ /**
+ * Indicates a call was disconnected due to loss of wifi signal.
+ */
+ public static final int WIFI_LOST = 2507;
+
+
+ /* OEM specific error codes. To be used by OEMs when they don't want to
+ reveal error code which would be replaced by ERROR_UNSPECIFIED */
+ public static final int OEM_CAUSE_1 = 0xf001;
+ public static final int OEM_CAUSE_2 = 0xf002;
+ public static final int OEM_CAUSE_3 = 0xf003;
+ public static final int OEM_CAUSE_4 = 0xf004;
+ public static final int OEM_CAUSE_5 = 0xf005;
+ public static final int OEM_CAUSE_6 = 0xf006;
+ public static final int OEM_CAUSE_7 = 0xf007;
+ public static final int OEM_CAUSE_8 = 0xf008;
+ public static final int OEM_CAUSE_9 = 0xf009;
+ public static final int OEM_CAUSE_10 = 0xf00a;
+ public static final int OEM_CAUSE_11 = 0xf00b;
+ public static final int OEM_CAUSE_12 = 0xf00c;
+ public static final int OEM_CAUSE_13 = 0xf00d;
+ public static final int OEM_CAUSE_14 = 0xf00e;
+ public static final int OEM_CAUSE_15 = 0xf00f;
+
/** Disconnected due to unspecified reasons */
- public static final int ERROR_UNSPECIFIED = 0xffff;
+ public static final int ERROR_UNSPECIFIED = 0xffff;
/** Private constructor to avoid class instantiation. */
private PreciseDisconnectCause() {
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 7a83979..5fb83ab 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -243,6 +243,10 @@
private boolean mIsUsingCarrierAggregation;
+ /* EARFCN stands for E-UTRA Absolute Radio Frequency Channel Number,
+ * Reference: 3GPP TS 36.104 5.4.3 */
+ private int mLteEarfcnRsrpBoost = 0;
+
/**
* get String description of roaming type
* @hide
@@ -322,6 +326,7 @@
mIsEmergencyOnly = s.mIsEmergencyOnly;
mIsDataRoamingFromRegistration = s.mIsDataRoamingFromRegistration;
mIsUsingCarrierAggregation = s.mIsUsingCarrierAggregation;
+ mLteEarfcnRsrpBoost = s.mLteEarfcnRsrpBoost;
}
/**
@@ -351,6 +356,7 @@
mIsEmergencyOnly = in.readInt() != 0;
mIsDataRoamingFromRegistration = in.readInt() != 0;
mIsUsingCarrierAggregation = in.readInt() != 0;
+ mLteEarfcnRsrpBoost = in.readInt();
}
public void writeToParcel(Parcel out, int flags) {
@@ -377,6 +383,7 @@
out.writeInt(mIsEmergencyOnly ? 1 : 0);
out.writeInt(mIsDataRoamingFromRegistration ? 1 : 0);
out.writeInt(mIsUsingCarrierAggregation ? 1 : 0);
+ out.writeInt(mLteEarfcnRsrpBoost);
}
public int describeContents() {
@@ -814,7 +821,8 @@
+ " DefRoamInd=" + mCdmaDefaultRoamingIndicator
+ " EmergOnly=" + mIsEmergencyOnly
+ " IsDataRoamingFromRegistration=" + mIsDataRoamingFromRegistration
- + " IsUsingCarrierAggregation=" + mIsUsingCarrierAggregation);
+ + " IsUsingCarrierAggregation=" + mIsUsingCarrierAggregation
+ + " mLteEarfcnRsrpBoost=" + mLteEarfcnRsrpBoost);
}
private void setNullState(int state) {
@@ -842,6 +850,7 @@
mIsEmergencyOnly = false;
mIsDataRoamingFromRegistration = false;
mIsUsingCarrierAggregation = false;
+ mLteEarfcnRsrpBoost = 0;
}
public void setStateOutOfService() {
@@ -1016,6 +1025,7 @@
mIsEmergencyOnly = m.getBoolean("emergencyOnly");
mIsDataRoamingFromRegistration = m.getBoolean("isDataRoamingFromRegistration");
mIsUsingCarrierAggregation = m.getBoolean("isUsingCarrierAggregation");
+ mLteEarfcnRsrpBoost = m.getInt("LteEarfcnRsrpBoost");
}
/**
@@ -1046,6 +1056,7 @@
m.putBoolean("emergencyOnly", mIsEmergencyOnly);
m.putBoolean("isDataRoamingFromRegistration", mIsDataRoamingFromRegistration);
m.putBoolean("isUsingCarrierAggregation", mIsUsingCarrierAggregation);
+ m.putInt("LteEarfcnRsrpBoost", mLteEarfcnRsrpBoost);
}
/** @hide */
@@ -1081,6 +1092,16 @@
}
/** @hide */
+ public int getLteEarfcnRsrpBoost() {
+ return mLteEarfcnRsrpBoost;
+ }
+
+ /** @hide */
+ public void setLteEarfcnRsrpBoost(int LteEarfcnRsrpBoost) {
+ mLteEarfcnRsrpBoost = LteEarfcnRsrpBoost;
+ }
+
+ /** @hide */
public void setCssIndicator(int css) {
this.mCssIndicator = (css != 0);
}
diff --git a/telephony/java/android/telephony/SignalStrength.java b/telephony/java/android/telephony/SignalStrength.java
index c484fd3..9e02399 100644
--- a/telephony/java/android/telephony/SignalStrength.java
+++ b/telephony/java/android/telephony/SignalStrength.java
@@ -64,6 +64,8 @@
private int mLteRsrq;
private int mLteRssnr;
private int mLteCqi;
+ private int mLteRsrpBoost; // offset to be reduced from the rsrp threshold while calculating
+ // signal strength level
private int mTdScdmaRscp;
private boolean isGsm; // This value is set by the ServiceStateTracker onSignalStrengthResult
@@ -104,6 +106,7 @@
mLteRsrq = INVALID;
mLteRssnr = INVALID;
mLteCqi = INVALID;
+ mLteRsrpBoost = 0;
mTdScdmaRscp = INVALID;
isGsm = true;
}
@@ -129,6 +132,7 @@
mLteRsrq = INVALID;
mLteRssnr = INVALID;
mLteCqi = INVALID;
+ mLteRsrpBoost = 0;
mTdScdmaRscp = INVALID;
isGsm = gsmFlag;
}
@@ -142,10 +146,26 @@
int cdmaDbm, int cdmaEcio,
int evdoDbm, int evdoEcio, int evdoSnr,
int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
+ int lteRsrpBoost, int tdScdmaRscp, boolean gsmFlag) {
+ initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
+ evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
+ lteRsrq, lteRssnr, lteCqi, lteRsrpBoost, gsmFlag);
+ mTdScdmaRscp = tdScdmaRscp;
+ }
+
+ /**
+ * Constructor
+ *
+ * @hide
+ */
+ public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
+ int cdmaDbm, int cdmaEcio,
+ int evdoDbm, int evdoEcio, int evdoSnr,
+ int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
int tdScdmaRscp, boolean gsmFlag) {
initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
- lteRsrq, lteRssnr, lteCqi, gsmFlag);
+ lteRsrq, lteRssnr, lteCqi, 0, gsmFlag);
mTdScdmaRscp = tdScdmaRscp;
}
@@ -161,7 +181,7 @@
boolean gsmFlag) {
initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
- lteRsrq, lteRssnr, lteCqi, gsmFlag);
+ lteRsrq, lteRssnr, lteCqi, 0, gsmFlag);
}
/**
@@ -175,7 +195,7 @@
boolean gsmFlag) {
initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
evdoDbm, evdoEcio, evdoSnr, 99, INVALID,
- INVALID, INVALID, INVALID, gsmFlag);
+ INVALID, INVALID, INVALID, 0, gsmFlag);
}
/**
@@ -209,7 +229,7 @@
boolean gsm) {
initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
evdoDbm, evdoEcio, evdoSnr, 99, INVALID,
- INVALID, INVALID, INVALID, gsm);
+ INVALID, INVALID, INVALID, 0, gsm);
}
/**
@@ -227,6 +247,7 @@
* @param lteRsrq
* @param lteRssnr
* @param lteCqi
+ * @param lteRsrpBoost
* @param gsm
*
* @hide
@@ -235,7 +256,7 @@
int cdmaDbm, int cdmaEcio,
int evdoDbm, int evdoEcio, int evdoSnr,
int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
- boolean gsm) {
+ int lteRsrpBoost, boolean gsm) {
mGsmSignalStrength = gsmSignalStrength;
mGsmBitErrorRate = gsmBitErrorRate;
mCdmaDbm = cdmaDbm;
@@ -248,6 +269,7 @@
mLteRsrq = lteRsrq;
mLteRssnr = lteRssnr;
mLteCqi = lteCqi;
+ mLteRsrpBoost = lteRsrpBoost;
mTdScdmaRscp = INVALID;
isGsm = gsm;
if (DBG) log("initialize: " + toString());
@@ -269,6 +291,7 @@
mLteRsrq = s.mLteRsrq;
mLteRssnr = s.mLteRssnr;
mLteCqi = s.mLteCqi;
+ mLteRsrpBoost = s.mLteRsrpBoost;
mTdScdmaRscp = s.mTdScdmaRscp;
isGsm = s.isGsm;
}
@@ -293,6 +316,7 @@
mLteRsrq = in.readInt();
mLteRssnr = in.readInt();
mLteCqi = in.readInt();
+ mLteRsrpBoost = in.readInt();
mTdScdmaRscp = in.readInt();
isGsm = (in.readInt() != 0);
}
@@ -340,6 +364,7 @@
out.writeInt(mLteRsrq);
out.writeInt(mLteRssnr);
out.writeInt(mLteCqi);
+ out.writeInt(mLteRsrpBoost);
out.writeInt(mTdScdmaRscp);
out.writeInt(isGsm ? 1 : 0);
}
@@ -416,6 +441,18 @@
}
/**
+ * @param lteRsrpBoost - signal strength offset
+ *
+ * Used by phone to set the lte signal strength offset which will be
+ * reduced from rsrp threshold while calculating signal strength level
+ *
+ * @hide
+ */
+ public void setLteRsrpBoost(int lteRsrpBoost) {
+ mLteRsrpBoost = lteRsrpBoost;
+ }
+
+ /**
* Get the GSM Signal Strength, valid values are (0-31, 99) as defined in TS
* 27.007 8.5
*/
@@ -490,6 +527,11 @@
return mLteCqi;
}
+ /** @hide */
+ public int getLteRsrpBoost() {
+ return mLteRsrpBoost;
+ }
+
/**
* Retrieve an abstract level value for the overall signal strength.
*
@@ -793,12 +835,19 @@
Log.wtf(LOG_TAG, "getLteLevel - config_lteDbmThresholds has invalid num of elements."
+ " Cannot evaluate RSRP signal.");
} else {
- if (mLteRsrp > threshRsrp[5]) rsrpIconLevel = -1;
- else if (mLteRsrp >= threshRsrp[4]) rsrpIconLevel = SIGNAL_STRENGTH_GREAT;
- else if (mLteRsrp >= threshRsrp[3]) rsrpIconLevel = SIGNAL_STRENGTH_GOOD;
- else if (mLteRsrp >= threshRsrp[2]) rsrpIconLevel = SIGNAL_STRENGTH_MODERATE;
- else if (mLteRsrp >= threshRsrp[1]) rsrpIconLevel = SIGNAL_STRENGTH_POOR;
- else if (mLteRsrp >= threshRsrp[0]) rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ if (mLteRsrp > threshRsrp[5]) {
+ rsrpIconLevel = -1;
+ } else if (mLteRsrp >= (threshRsrp[4] - mLteRsrpBoost)) {
+ rsrpIconLevel = SIGNAL_STRENGTH_GREAT;
+ } else if (mLteRsrp >= (threshRsrp[3] - mLteRsrpBoost)) {
+ rsrpIconLevel = SIGNAL_STRENGTH_GOOD;
+ } else if (mLteRsrp >= (threshRsrp[2] - mLteRsrpBoost)) {
+ rsrpIconLevel = SIGNAL_STRENGTH_MODERATE;
+ } else if (mLteRsrp >= (threshRsrp[1] - mLteRsrpBoost)) {
+ rsrpIconLevel = SIGNAL_STRENGTH_POOR;
+ } else if (mLteRsrp >= threshRsrp[0]) {
+ rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ }
}
/*
@@ -816,7 +865,8 @@
snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
if (DBG) log("getLTELevel - rsrp:" + mLteRsrp + " snr:" + mLteRssnr + " rsrpIconLevel:"
- + rsrpIconLevel + " snrIconLevel:" + snrIconLevel);
+ + rsrpIconLevel + " snrIconLevel:" + snrIconLevel
+ + " lteRsrpBoost:" + mLteRsrpBoost);
/* Choose a measurement type to use for notification */
if (snrIconLevel != -1 && rsrpIconLevel != -1) {
@@ -939,7 +989,7 @@
+ (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum)
+ (mLteSignalStrength * primeNum) + (mLteRsrp * primeNum)
+ (mLteRsrq * primeNum) + (mLteRssnr * primeNum) + (mLteCqi * primeNum)
- + (mTdScdmaRscp * primeNum) + (isGsm ? 1 : 0));
+ + (mLteRsrpBoost * primeNum) + (mTdScdmaRscp * primeNum) + (isGsm ? 1 : 0));
}
/**
@@ -971,6 +1021,7 @@
&& mLteRsrq == s.mLteRsrq
&& mLteRssnr == s.mLteRssnr
&& mLteCqi == s.mLteCqi
+ && mLteRsrpBoost == s.mLteRsrpBoost
&& mTdScdmaRscp == s.mTdScdmaRscp
&& isGsm == s.isGsm);
}
@@ -993,6 +1044,7 @@
+ " " + mLteRsrq
+ " " + mLteRssnr
+ " " + mLteCqi
+ + " " + mLteRsrpBoost
+ " " + mTdScdmaRscp
+ " " + (isGsm ? "gsm|lte" : "cdma"));
}
@@ -1016,6 +1068,7 @@
mLteRsrq = m.getInt("LteRsrq");
mLteRssnr = m.getInt("LteRssnr");
mLteCqi = m.getInt("LteCqi");
+ mLteRsrpBoost = m.getInt("lteRsrpBoost");
mTdScdmaRscp = m.getInt("TdScdma");
isGsm = m.getBoolean("isGsm");
}
@@ -1039,6 +1092,7 @@
m.putInt("LteRsrq", mLteRsrq);
m.putInt("LteRssnr", mLteRssnr);
m.putInt("LteCqi", mLteCqi);
+ m.putInt("lteRsrpBoost", mLteRsrpBoost);
m.putInt("TdScdma", mTdScdmaRscp);
m.putBoolean("isGsm", isGsm);
}
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index dd6f9cb..201f3ad 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -521,14 +521,14 @@
}
/**
- * Get the active SubscriptionInfo associated with the slotIdx
- * @param slotIdx the slot which the subscription is inserted
+ * Get the active SubscriptionInfo associated with the slotIndex
+ * @param slotIndex the slot which the subscription is inserted
* @return SubscriptionInfo, maybe null if its not active
*/
- public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIdx) {
- if (VDBG) logd("[getActiveSubscriptionInfoForSimSlotIndex]+ slotIdx=" + slotIdx);
- if (!isValidSlotId(slotIdx)) {
- logd("[getActiveSubscriptionInfoForSimSlotIndex]- invalid slotIdx");
+ public SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex) {
+ if (VDBG) logd("[getActiveSubscriptionInfoForSimSlotIndex]+ slotIndex=" + slotIndex);
+ if (!isValidSlotIndex(slotIndex)) {
+ logd("[getActiveSubscriptionInfoForSimSlotIndex]- invalid slotIndex");
return null;
}
@@ -537,7 +537,7 @@
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) {
- result = iSub.getActiveSubscriptionInfoForSimSlotIndex(slotIdx,
+ result = iSub.getActiveSubscriptionInfoForSimSlotIndex(slotIndex,
mContext.getOpPackageName());
}
} catch (RemoteException ex) {
@@ -671,24 +671,24 @@
/**
* Add a new SubscriptionInfo to SubscriptionInfo database if needed
* @param iccId the IccId of the SIM card
- * @param slotId the slot which the SIM is inserted
+ * @param slotIndex the slot which the SIM is inserted
* @return the URL of the newly created row or the updated row
* @hide
*/
- public Uri addSubscriptionInfoRecord(String iccId, int slotId) {
- if (VDBG) logd("[addSubscriptionInfoRecord]+ iccId:" + iccId + " slotId:" + slotId);
+ public Uri addSubscriptionInfoRecord(String iccId, int slotIndex) {
+ if (VDBG) logd("[addSubscriptionInfoRecord]+ iccId:" + iccId + " slotIndex:" + slotIndex);
if (iccId == null) {
logd("[addSubscriptionInfoRecord]- null iccId");
}
- if (!isValidSlotId(slotId)) {
- logd("[addSubscriptionInfoRecord]- invalid slotId");
+ if (!isValidSlotIndex(slotIndex)) {
+ logd("[addSubscriptionInfoRecord]- invalid slotIndex");
}
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) {
// FIXME: This returns 1 on success, 0 on error should should we return it?
- iSub.addSubInfoRecord(iccId, slotId);
+ iSub.addSubInfoRecord(iccId, slotIndex);
}
} catch (RemoteException ex) {
// ignore it
@@ -830,15 +830,15 @@
}
/**
- * Get slotId associated with the subscription.
- * @return slotId as a positive integer or a negative value if an error either
+ * Get slotIndex associated with the subscription.
+ * @return slotIndex as a positive integer or a negative value if an error either
* SIM_NOT_INSERTED or < 0 if an invalid slot index
* @hide
*/
- public static int getSlotId(int subId) {
+ public static int getSlotIndex(int subId) {
if (!isValidSubscriptionId(subId)) {
if (DBG) {
- logd("[getSlotId]- fail");
+ logd("[getSlotIndex]- fail");
}
}
@@ -847,7 +847,7 @@
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) {
- result = iSub.getSlotId(subId);
+ result = iSub.getSlotIndex(subId);
}
} catch (RemoteException ex) {
// ignore it
@@ -858,8 +858,8 @@
}
/** @hide */
- public static int[] getSubId(int slotId) {
- if (!isValidSlotId(slotId)) {
+ public static int[] getSubId(int slotIndex) {
+ if (!isValidSlotIndex(slotIndex)) {
logd("[getSubId]- fail");
return null;
}
@@ -869,7 +869,7 @@
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) {
- subId = iSub.getSubId(slotId);
+ subId = iSub.getSubId(slotIndex);
}
} catch (RemoteException ex) {
// ignore it
@@ -1155,8 +1155,8 @@
}
/** @hide */
- public static boolean isValidSlotId(int slotId) {
- return slotId >= 0 && slotId < TelephonyManager.getDefault().getSimCount();
+ public static boolean isValidSlotIndex(int slotIndex) {
+ return slotIndex >= 0 && slotIndex < TelephonyManager.getDefault().getSimCount();
}
/** @hide */
@@ -1179,7 +1179,7 @@
if (VDBG) logd("putPhoneIdAndSubIdExtra: phoneId=" + phoneId + " subId=" + subId);
intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId);
intent.putExtra(PhoneConstants.PHONE_KEY, phoneId);
- //FIXME this is using phoneId and slotId interchangeably
+ //FIXME this is using phoneId and slotIndex interchangeably
//Eventually, this should be removed as it is not the slot id
intent.putExtra(PhoneConstants.SLOT_KEY, phoneId);
}
@@ -1228,9 +1228,9 @@
}
/**
- * Returns a constant indicating the state of sim for the slot idx.
+ * Returns a constant indicating the state of sim for the slot index.
*
- * @param slotIdx
+ * @param slotIndex
*
* {@See TelephonyManager#SIM_STATE_UNKNOWN}
* {@See TelephonyManager#SIM_STATE_ABSENT}
@@ -1244,13 +1244,13 @@
*
* {@hide}
*/
- public static int getSimStateForSlotIdx(int slotIdx) {
+ public static int getSimStateForSlotIndex(int slotIndex) {
int simState = TelephonyManager.SIM_STATE_UNKNOWN;
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
if (iSub != null) {
- simState = iSub.getSimStateForSlotIdx(slotIdx);
+ simState = iSub.getSimStateForSlotIndex(slotIndex);
}
} catch (RemoteException ex) {
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index c691879..a61496d 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -46,6 +46,7 @@
import com.android.ims.internal.IImsServiceController;
import com.android.ims.internal.IImsServiceFeatureListener;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telecom.ITelecomService;
import com.android.internal.telephony.CellNetworkScanResult;
import com.android.internal.telephony.IPhoneSubInfo;
@@ -863,15 +864,15 @@
* <p>Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*
- * @param slotId of which deviceID is returned
+ * @param slotIndex of which deviceID is returned
*/
/** {@hide} */
- public String getDeviceSoftwareVersion(int slotId) {
+ public String getDeviceSoftwareVersion(int slotIndex) {
ITelephony telephony = getITelephony();
if (telephony == null) return null;
try {
- return telephony.getDeviceSoftwareVersionForSlot(slotId, getOpPackageName());
+ return telephony.getDeviceSoftwareVersionForSlot(slotIndex, getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
@@ -885,7 +886,11 @@
*
* <p>Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+ *
+ * @deprecated Use (@link getImei} which returns IMEI for GSM or (@link getMeid} which returns
+ * MEID for CDMA.
*/
+ @Deprecated
public String getDeviceId() {
try {
ITelephony telephony = getITelephony();
@@ -906,15 +911,19 @@
* <p>Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*
- * @param slotId of which deviceID is returned
+ * @param slotIndex of which deviceID is returned
+ *
+ * @deprecated Use (@link getImei} which returns IMEI for GSM or (@link getMeid} which returns
+ * MEID for CDMA.
*/
- public String getDeviceId(int slotId) {
- // FIXME this assumes phoneId == slotId
+ @Deprecated
+ public String getDeviceId(int slotIndex) {
+ // FIXME this assumes phoneId == slotIndex
try {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null)
return null;
- return info.getDeviceIdForPhone(slotId, mContext.getOpPackageName());
+ return info.getDeviceIdForPhone(slotIndex, mContext.getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
@@ -923,35 +932,62 @@
}
/**
- * Returns the IMEI. Return null if IMEI is not available.
+ * Returns the IMEI (International Mobile Equipment Identity). Return null if IMEI is not
+ * available.
*
* <p>Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
- *
- * @hide
*/
- @SystemApi
public String getImei() {
return getImei(getDefaultSim());
}
/**
- * Returns the IMEI. Return null if IMEI is not available.
+ * Returns the IMEI (International Mobile Equipment Identity). Return null if IMEI is not
+ * available.
*
* <p>Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*
- * @param slotId of which deviceID is returned
- *
- * @hide
+ * @param slotIndex of which IMEI is returned
*/
- @SystemApi
- public String getImei(int slotId) {
+ public String getImei(int slotIndex) {
ITelephony telephony = getITelephony();
if (telephony == null) return null;
try {
- return telephony.getImeiForSlot(slotId, getOpPackageName());
+ return telephony.getImeiForSlot(slotIndex, getOpPackageName());
+ } catch (RemoteException ex) {
+ return null;
+ } catch (NullPointerException ex) {
+ return null;
+ }
+ }
+
+ /**
+ * Returns the MEID (Mobile Equipment Identifier). Return null if MEID is not available.
+ *
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+ */
+ public String getMeid() {
+ return getMeid(getDefaultSim());
+ }
+
+ /**
+ * Returns the MEID (Mobile Equipment Identifier). Return null if MEID is not available.
+ *
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+ *
+ * @param slotIndex of which MEID is returned
+ */
+ public String getMeid(int slotIndex) {
+ ITelephony telephony = getITelephony();
+ if (telephony == null) return null;
+
+ try {
+ return telephony.getMeidForSlot(slotIndex, getOpPackageName());
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
@@ -971,11 +1007,11 @@
/**
* Returns the NAI. Return null if NAI is not available.
*
- * @param slotId of which Nai is returned
+ * @param slotIndex of which Nai is returned
*/
/** {@hide}*/
- public String getNai(int slotId) {
- int[] subId = SubscriptionManager.getSubId(slotId);
+ public String getNai(int slotIndex) {
+ int[] subId = SubscriptionManager.getSubId(slotIndex);
try {
IPhoneSubInfo info = getSubscriberInfo();
if (info == null)
@@ -1171,23 +1207,23 @@
*
* @hide
*/
- public int getCurrentPhoneTypeForSlot(int slotId) {
+ public int getCurrentPhoneTypeForSlot(int slotIndex) {
try{
ITelephony telephony = getITelephony();
if (telephony != null) {
- return telephony.getActivePhoneTypeForSlot(slotId);
+ return telephony.getActivePhoneTypeForSlot(slotIndex);
} else {
// This can happen when the ITelephony interface is not up yet.
- return getPhoneTypeFromProperty(slotId);
+ return getPhoneTypeFromProperty(slotIndex);
}
} catch (RemoteException ex) {
// This shouldn't happen in the normal case, as a backup we
// read from the system property.
- return getPhoneTypeFromProperty(slotId);
+ return getPhoneTypeFromProperty(slotIndex);
} catch (NullPointerException ex) {
// This shouldn't happen in the normal case, as a backup we
// read from the system property.
- return getPhoneTypeFromProperty(slotId);
+ return getPhoneTypeFromProperty(slotIndex);
}
}
@@ -1900,17 +1936,17 @@
/**
* @return true if a ICC card is present for a subscription
*
- * @param slotId for which icc card presence is checked
+ * @param slotIndex for which icc card presence is checked
*/
/** {@hide} */
- // FIXME Input argument slotId should be of type int
- public boolean hasIccCard(int slotId) {
+ // FIXME Input argument slotIndex should be of type int
+ public boolean hasIccCard(int slotIndex) {
try {
ITelephony telephony = getITelephony();
if (telephony == null)
return false;
- return telephony.hasIccCardUsingSlotId(slotId);
+ return telephony.hasIccCardUsingSlotIndex(slotIndex);
} catch (RemoteException ex) {
// Assume no ICC card if remote exception which shouldn't happen
return false;
@@ -1935,31 +1971,31 @@
* @see #SIM_STATE_CARD_RESTRICTED
*/
public int getSimState() {
- int slotIdx = getDefaultSim();
- // slotIdx may be invalid due to sim being absent. In that case query all slots to get
+ int slotIndex = getDefaultSim();
+ // slotIndex may be invalid due to sim being absent. In that case query all slots to get
// sim state
- if (slotIdx < 0) {
+ if (slotIndex < 0) {
// query for all slots and return absent if all sim states are absent, otherwise
// return unknown
for (int i = 0; i < getPhoneCount(); i++) {
int simState = getSimState(i);
if (simState != SIM_STATE_ABSENT) {
- Rlog.d(TAG, "getSimState: default sim:" + slotIdx + ", sim state for " +
- "slotIdx=" + i + " is " + simState + ", return state as unknown");
+ Rlog.d(TAG, "getSimState: default sim:" + slotIndex + ", sim state for " +
+ "slotIndex=" + i + " is " + simState + ", return state as unknown");
return SIM_STATE_UNKNOWN;
}
}
- Rlog.d(TAG, "getSimState: default sim:" + slotIdx + ", all SIMs absent, return " +
+ Rlog.d(TAG, "getSimState: default sim:" + slotIndex + ", all SIMs absent, return " +
"state as absent");
return SIM_STATE_ABSENT;
}
- return getSimState(slotIdx);
+ return getSimState(slotIndex);
}
/**
* Returns a constant indicating the state of the device SIM card in a slot.
*
- * @param slotIdx
+ * @param slotIndex
*
* @see #SIM_STATE_UNKNOWN
* @see #SIM_STATE_ABSENT
@@ -1972,8 +2008,8 @@
* @see #SIM_STATE_CARD_IO_ERROR
* @see #SIM_STATE_CARD_RESTRICTED
*/
- public int getSimState(int slotIdx) {
- int simState = SubscriptionManager.getSimStateForSlotIdx(slotIdx);
+ public int getSimState(int slotIndex) {
+ int simState = SubscriptionManager.getSimStateForSlotIndex(slotIndex);
return simState;
}
@@ -3065,12 +3101,12 @@
*
* @hide
*/
- public int getCallStateForSlot(int slotId) {
+ public int getCallStateForSlot(int slotIndex) {
try {
ITelephony telephony = getITelephony();
if (telephony == null)
return CALL_STATE_IDLE;
- return telephony.getCallStateForSlot(slotId);
+ return telephony.getCallStateForSlot(slotIndex);
} catch (RemoteException ex) {
// the phone process is restarting.
return CALL_STATE_IDLE;
@@ -3204,7 +3240,7 @@
public void listen(PhoneStateListener listener, int events) {
if (mContext == null) return;
try {
- Boolean notifyNow = (getITelephony() != null);
+ boolean notifyNow = (getITelephony() != null);
// If the listener has not explicitly set the subId (for example, created with the
// default constructor), replace the subId so it will listen to the account the
// telephony manager is created with.
@@ -3886,9 +3922,19 @@
return SubscriptionManager.getPhoneId(SubscriptionManager.getDefaultSubscriptionId());
}
- /** {@hide} */
+ /**
+ * @return default SIM's slot index. If SIM is not inserted, return default SIM slot index.
+ *
+ * {@hide}
+ */
+ @VisibleForTesting
public int getDefaultSim() {
- return SubscriptionManager.getSlotId(SubscriptionManager.getDefaultSubscriptionId());
+ int slotIndex = SubscriptionManager.getSlotIndex(
+ SubscriptionManager.getDefaultSubscriptionId());
+ if (slotIndex == SubscriptionManager.SIM_NOT_INSERTED) {
+ slotIndex = SubscriptionManager.DEFAULT_SIM_SLOT_INDEX;
+ }
+ return slotIndex;
}
/**
@@ -4253,7 +4299,7 @@
* feature or {@link null} if the service is not available. If an ImsServiceController is
* available, the {@link IImsServiceFeatureListener} callback is registered as a listener for
* feature updates.
- * @param slotId The SIM slot that we are requesting the {@link IImsServiceController} for.
+ * @param slotIndex The SIM slot that we are requesting the {@link IImsServiceController} for.
* @param feature The IMS Feature we are requesting, corresponding to {@link ImsFeature}.
* @param callback Listener that will send updates to ImsManager when there are updates to
* ImsServiceController.
@@ -4261,12 +4307,12 @@
* it is unavailable.
* @hide
*/
- public IImsServiceController getImsServiceControllerAndListen(int slotId, @Feature int feature,
+ public IImsServiceController getImsServiceControllerAndListen(int slotIndex, @Feature int feature,
IImsServiceFeatureListener callback) {
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
- return telephony.getImsServiceControllerAndListen(slotId, feature, callback);
+ return telephony.getImsServiceControllerAndListen(slotIndex, feature, callback);
}
} catch (RemoteException e) {
Rlog.e(TAG, "getImsServiceControllerAndListen, RemoteException: " + e.getMessage());
@@ -5404,7 +5450,7 @@
/**
* Set SIM card power state. Request is equivalent to inserting or removing the card.
*
- * @param slotId SIM slot id
+ * @param slotIndex SIM slot id
* @param powerUp True if powering up the SIM, otherwise powering down
*
* <p>Requires Permission:
@@ -5412,11 +5458,11 @@
*
* @hide
**/
- public void setSimPowerStateForSlot(int slotId, boolean powerUp) {
+ public void setSimPowerStateForSlot(int slotIndex, boolean powerUp) {
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
- telephony.setSimPowerStateForSlot(slotId, powerUp);
+ telephony.setSimPowerStateForSlot(slotIndex, powerUp);
}
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelephony#setSimPowerStateForSlot", e);
@@ -5952,7 +5998,7 @@
}
/**
- * Set the allowed carrier list for slotId
+ * Set the allowed carrier list for slotIndex
* Require system privileges. In the future we may add this to carrier APIs.
*
* <p>Requires Permission:
@@ -5966,11 +6012,11 @@
* @hide
*/
@SystemApi
- public int setAllowedCarriers(int slotId, List<CarrierIdentifier> carriers) {
+ public int setAllowedCarriers(int slotIndex, List<CarrierIdentifier> carriers) {
try {
ITelephony service = getITelephony();
if (service != null) {
- return service.setAllowedCarriers(slotId, carriers);
+ return service.setAllowedCarriers(slotIndex, carriers);
}
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelephony#setAllowedCarriers", e);
@@ -5981,7 +6027,7 @@
}
/**
- * Get the allowed carrier list for slotId.
+ * Get the allowed carrier list for slotIndex.
* Require system privileges. In the future we may add this to carrier APIs.
*
* <p>Requires Permission:
@@ -5995,11 +6041,11 @@
* @hide
*/
@SystemApi
- public List<CarrierIdentifier> getAllowedCarriers(int slotId) {
+ public List<CarrierIdentifier> getAllowedCarriers(int slotIndex) {
try {
ITelephony service = getITelephony();
if (service != null) {
- return service.getAllowedCarriers(slotId);
+ return service.getAllowedCarriers(slotIndex);
}
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelephony#getAllowedCarriers", e);
diff --git a/telephony/java/com/android/ims/ImsReasonInfo.java b/telephony/java/com/android/ims/ImsReasonInfo.java
index e4f380f..bd8492b3 100644
--- a/telephony/java/com/android/ims/ImsReasonInfo.java
+++ b/telephony/java/com/android/ims/ImsReasonInfo.java
@@ -318,6 +318,66 @@
*/
public static final int CODE_IKEV2_AUTH_FAILURE = 1408;
+ /** The call cannot be established because RADIO is OFF */
+ public static final int CODE_RADIO_OFF = 1500;
+
+ /** The call cannot be established because of no valid SIM */
+ public static final int CODE_NO_VALID_SIM = 1501;
+
+ /** The failure is due internal error at modem */
+ public static final int CODE_RADIO_INTERNAL_ERROR = 1502;
+
+ /** The failure is due to UE timer expired while waiting for a response from network */
+ public static final int CODE_NETWORK_RESP_TIMEOUT = 1503;
+
+ /** The failure is due to explicit reject from network */
+ public static final int CODE_NETWORK_REJECT = 1504;
+
+ /** The failure is due to radio access failure. ex. RACH failure */
+ public static final int CODE_RADIO_ACCESS_FAILURE = 1505;
+
+ /** Call/IMS registration failed/dropped because of a RLF */
+ public static final int CODE_RADIO_LINK_FAILURE = 1506;
+
+ /** Call/IMS registration failed/dropped because of radio link lost */
+ public static final int CODE_RADIO_LINK_LOST = 1507;
+
+ /** The call Call/IMS registration failed because of a radio uplink issue */
+ public static final int CODE_RADIO_UPLINK_FAILURE = 1508;
+
+ /** Call failed because of a RRC connection setup failure */
+ public static final int CODE_RADIO_SETUP_FAILURE = 1509;
+
+ /** Call failed/dropped because of RRC connection release from NW */
+ public static final int CODE_RADIO_RELEASE_NORMAL = 1510;
+
+ /** Call failed/dropped because of RRC abnormally released by modem/network */
+ public static final int CODE_RADIO_RELEASE_ABNORMAL = 1511;
+
+ /** Call failed because of access class barring */
+ public static final int CODE_ACCESS_CLASS_BLOCKED = 1512;
+
+ /** Call/IMS registration is failed/dropped because of a network detach */
+ public static final int CODE_NETWORK_DETACH = 1513;
+
+ /* OEM specific error codes. To be used by OEMs when they don't want to
+ reveal error code which would be replaced by ERROR_UNSPECIFIED */
+ public static final int CODE_OEM_CAUSE_1 = 0xf001;
+ public static final int CODE_OEM_CAUSE_2 = 0xf002;
+ public static final int CODE_OEM_CAUSE_3 = 0xf003;
+ public static final int CODE_OEM_CAUSE_4 = 0xf004;
+ public static final int CODE_OEM_CAUSE_5 = 0xf005;
+ public static final int CODE_OEM_CAUSE_6 = 0xf006;
+ public static final int CODE_OEM_CAUSE_7 = 0xf007;
+ public static final int CODE_OEM_CAUSE_8 = 0xf008;
+ public static final int CODE_OEM_CAUSE_9 = 0xf009;
+ public static final int CODE_OEM_CAUSE_10 = 0xf00a;
+ public static final int CODE_OEM_CAUSE_11 = 0xf00b;
+ public static final int CODE_OEM_CAUSE_12 = 0xf00c;
+ public static final int CODE_OEM_CAUSE_13 = 0xf00d;
+ public static final int CODE_OEM_CAUSE_14 = 0xf00e;
+ public static final int CODE_OEM_CAUSE_15 = 0xf00f;
+
/**
* Network string error messages.
* mExtraMessage may have these values.
diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl
index f6aef08..71f2c6b 100755
--- a/telephony/java/com/android/internal/telephony/ISub.aidl
+++ b/telephony/java/com/android/internal/telephony/ISub.aidl
@@ -52,12 +52,12 @@
SubscriptionInfo getActiveSubscriptionInfoForIccId(String iccId, String callingPackage);
/**
- * Get the active SubscriptionInfo associated with the slotIdx
- * @param slotIdx the slot which the subscription is inserted
+ * Get the active SubscriptionInfo associated with the slotIndex
+ * @param slotIndex the slot which the subscription is inserted
* @param callingPackage The package maing the call.
* @return SubscriptionInfo, maybe null if its not active
*/
- SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIdx, String callingPackage);
+ SubscriptionInfo getActiveSubscriptionInfoForSimSlotIndex(int slotIndex, String callingPackage);
/**
* Get the SubscriptionInfo(s) of the active subscriptions. The records will be sorted
@@ -96,10 +96,10 @@
/**
* Add a new SubscriptionInfo to subinfo database if needed
* @param iccId the IccId of the SIM card
- * @param slotId the slot which the SIM is inserted
+ * @param slotIndex the slot which the SIM is inserted
* @return the URL of the newly created row or the updated row
*/
- int addSubInfoRecord(String iccId, int slotId);
+ int addSubInfoRecord(String iccId, int slotIndex);
/**
* Set SIM icon tint color by simInfo index
@@ -142,9 +142,9 @@
*/
int setDataRoaming(int roaming, int subId);
- int getSlotId(int subId);
+ int getSlotIndex(int subId);
- int[] getSubId(int slotId);
+ int[] getSubId(int slotIndex);
int getDefaultSubId();
@@ -177,10 +177,10 @@
String getSubscriptionProperty(int subId, String propKey, String callingPackage);
/**
- * Get the SIM state for the slot idx
+ * Get the SIM state for the slot index
* @return SIM state as the ordinal of IccCardConstants.State
*/
- int getSimStateForSlotIdx(int slotIdx);
+ int getSimStateForSlotIndex(int slotIndex);
boolean isActiveSubId(int subId);
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index d21efc6..5c37822 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -370,7 +370,7 @@
/**
* Returns the call state for a slot.
*/
- int getCallStateForSlot(int slotId);
+ int getCallStateForSlot(int slotIndex);
int getDataActivity();
int getDataState();
@@ -386,9 +386,9 @@
* Returns the current active phone type as integer for particular slot.
* Returns TelephonyManager.PHONE_TYPE_CDMA if RILConstants.CDMA_PHONE
* and TelephonyManager.PHONE_TYPE_GSM if RILConstants.GSM_PHONE
- * @param slotId - slot to query.
+ * @param slotIndex - slot to query.
*/
- int getActivePhoneTypeForSlot(int slotId);
+ int getActivePhoneTypeForSlot(int slotIndex);
/**
* Returns the CDMA ERI icon index to display
@@ -542,10 +542,10 @@
/**
* Return true if an ICC card is present for a subId.
- * @param slotId user preferred slotId.
+ * @param slotIndex user preferred slotIndex.
* Return true if an ICC card is present
*/
- boolean hasIccCardUsingSlotId(int slotId);
+ boolean hasIccCardUsingSlotIndex(int slotIndex);
/**
* Return if the current radio is LTE on CDMA. This
@@ -746,7 +746,7 @@
* requested as well as registering the ImsServiceController for callbacks using the
* IImsServiceFeatureListener interface.
*/
- IImsServiceController getImsServiceControllerAndListen(int slotId, int feature,
+ IImsServiceController getImsServiceControllerAndListen(int slotIndex, int feature,
IImsServiceFeatureListener callback);
/**
@@ -1054,22 +1054,32 @@
/**
* Returns the IMEI for the given slot.
*
- * @param slotId - device slot.
+ * @param slotIndex - device slot.
* @param callingPackage The package making the call.
* <p>Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
- String getImeiForSlot(int slotId, String callingPackage);
+ String getImeiForSlot(int slotIndex, String callingPackage);
+
+ /**
+ * Returns the MEID for the given slot.
+ *
+ * @param slotIndex - device slot.
+ * @param callingPackage The package making the call.
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+ */
+ String getMeidForSlot(int slotIndex, String callingPackage);
/**
* Returns the device software version.
*
- * @param slotId - device slot.
+ * @param slotIndex - device slot.
* @param callingPackage The package making the call.
* <p>Requires Permission:
* {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
*/
- String getDeviceSoftwareVersionForSlot(int slotId, String callingPackage);
+ String getDeviceSoftwareVersionForSlot(int slotIndex, String callingPackage);
/**
* Returns the subscription ID associated with the specified PhoneAccount.
@@ -1167,22 +1177,22 @@
List<TelephonyHistogram> getTelephonyHistograms();
/**
- * Set the allowed carrier list for slotId
+ * Set the allowed carrier list for slotIndex
* Require system privileges. In the future we may add this to carrier APIs.
*
* @return The number of carriers set successfully. Should match length of
* carriers on success.
*/
- int setAllowedCarriers(int slotId, in List<CarrierIdentifier> carriers);
+ int setAllowedCarriers(int slotIndex, in List<CarrierIdentifier> carriers);
/**
- * Get the allowed carrier list for slotId.
+ * Get the allowed carrier list for slotIndex.
* Require system privileges. In the future we may add this to carrier APIs.
*
* @return List of {@link android.service.carrier.CarrierIdentifier}; empty list
* means all carriers are allowed.
*/
- List<CarrierIdentifier> getAllowedCarriers(int slotId);
+ List<CarrierIdentifier> getAllowedCarriers(int slotIndex);
/**
* Action set from carrier signalling broadcast receivers to enable/disable metered apns
@@ -1229,11 +1239,11 @@
/**
* Set SIM card power state. Request is equivalent to inserting or removing the card.
- * @param slotId SIM slot id
+ * @param slotIndex SIM slot id
* @param powerUp True if powering up the SIM, otherwise powering down
* @hide
* */
- void setSimPowerStateForSlot(int slotId, boolean powerUp);
+ void setSimPowerStateForSlot(int slotIndex, boolean powerUp);
/**
* Returns a list of Forbidden PLMNs from the specified SIM App
diff --git a/tests/net/java/android/net/ip/IpManagerTest.java b/tests/net/java/android/net/ip/IpManagerTest.java
new file mode 100644
index 0000000..025b017
--- /dev/null
+++ b/tests/net/java/android/net/ip/IpManagerTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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 android.net.ip;
+
+import static org.mockito.Mockito.when;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.INetworkManagementService;
+import android.provider.Settings;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
+import android.test.mock.MockContentResolver;
+
+import com.android.internal.util.test.FakeSettingsProvider;
+import com.android.internal.R;
+
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * Tests for IpManager.
+ */
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class IpManagerTest {
+ private static final int DEFAULT_AVOIDBADWIFI_CONFIG_VALUE = 1;
+
+ @Mock private Context mContext;
+ @Mock private INetworkManagementService mNMService;
+ @Mock private Resources mResources;
+ private MockContentResolver mContentResolver;
+
+ @Before public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+
+ when(mContext.getResources()).thenReturn(mResources);
+ when(mResources.getInteger(R.integer.config_networkAvoidBadWifi))
+ .thenReturn(DEFAULT_AVOIDBADWIFI_CONFIG_VALUE);
+
+ mContentResolver = new MockContentResolver();
+ mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+ when(mContext.getContentResolver()).thenReturn(mContentResolver);
+ }
+
+ @Test
+ public void testNullCallbackDoesNotThrow() throws Exception {
+ final IpManager ipm = new IpManager(mContext, "lo", null, mNMService);
+ }
+
+ @Test
+ public void testInvalidInterfaceDoesNotThrow() throws Exception {
+ final IpManager.Callback cb = new IpManager.Callback();
+ final IpManager ipm = new IpManager(mContext, "test_wlan0", cb, mNMService);
+ }
+}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 18c1245..af48d0a 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -16,7 +16,11 @@
package android.net.wifi;
+
+import android.content.pm.ParceledListSlice;
+
import android.net.wifi.hotspot2.PasspointConfiguration;
+
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.ScanSettings;
@@ -51,9 +55,9 @@
*/
oneway void requestActivityInfo(in ResultReceiver result);
- List<WifiConfiguration> getConfiguredNetworks();
+ ParceledListSlice getConfiguredNetworks();
- List<WifiConfiguration> getPrivilegedConfiguredNetworks();
+ ParceledListSlice getPrivilegedConfiguredNetworks();
WifiConfiguration getMatchingWifiConfig(in ScanResult scanResult);
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 6095c86..dac511e 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -281,7 +281,9 @@
public int apChannel = 0;
/**
- * Pre-shared key for use with WPA-PSK.
+ * Pre-shared key for use with WPA-PSK. Either an ASCII string enclosed in
+ * double quotation marks (e.g., {@code "abcdefghij"} for PSK passphrase or
+ * a string of 64 hex digits for raw PSK.
* <p/>
* When the value of this key is read, the actual key is
* not returned, just a "*" if the key has a value, or the null
@@ -305,7 +307,7 @@
/**
* Priority determines the preference given to a network by {@code wpa_supplicant}
* when choosing an access point with which to associate.
- * @deprecated Priority is no longer used.
+ * @deprecated This field does not exist anymore.
*/
@Deprecated
public int priority;
@@ -434,6 +436,13 @@
public int dtimInterval = 0;
/**
+ * Flag indicating if this configuration represents a legacy Passpoint configuration
+ * (Release N or older). This is used for migrating Passpoint configuration from N to O.
+ * This will no longer be needed after O.
+ * @hide
+ */
+ public boolean isLegacyPasspointConfig = false;
+ /**
* @hide
* Uid of app creating the configuration
*/
@@ -1951,6 +1960,7 @@
mCachedConfigKey = null; //force null configKey
selfAdded = source.selfAdded;
validatedInternetAccess = source.validatedInternetAccess;
+ isLegacyPasspointConfig = source.isLegacyPasspointConfig;
ephemeral = source.ephemeral;
meteredHint = source.meteredHint;
meteredOverride = source.meteredOverride;
@@ -2027,6 +2037,7 @@
dest.writeInt(selfAdded ? 1 : 0);
dest.writeInt(didSelfAdd ? 1 : 0);
dest.writeInt(validatedInternetAccess ? 1 : 0);
+ dest.writeInt(isLegacyPasspointConfig ? 1 : 0);
dest.writeInt(ephemeral ? 1 : 0);
dest.writeInt(meteredHint ? 1 : 0);
dest.writeInt(meteredOverride ? 1 : 0);
@@ -2093,6 +2104,7 @@
config.selfAdded = in.readInt() != 0;
config.didSelfAdd = in.readInt() != 0;
config.validatedInternetAccess = in.readInt() != 0;
+ config.isLegacyPasspointConfig = in.readInt() != 0;
config.ephemeral = in.readInt() != 0;
config.meteredHint = in.readInt() != 0;
config.meteredOverride = in.readInt() != 0;
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index ed6a166..824c436 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -21,6 +21,7 @@
import android.annotation.SystemApi;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
+import android.content.pm.ParceledListSlice;
import android.net.ConnectivityManager;
import android.net.DhcpInfo;
import android.net.Network;
@@ -46,6 +47,7 @@
import java.net.InetAddress;
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
@@ -114,166 +116,125 @@
public static final int WIFI_CREDENTIAL_FORGOT = 1;
/**
- * Broadcast intent action indicating that the a Passpoint release 2 icon has been received.
- * @hide
- */
- public static final String PASSPOINT_ICON_RECEIVED_ACTION =
- "android.net.wifi.PASSPOINT_ICON_RECEIVED";
- /** @hide */
- public static final String EXTRA_PASSPOINT_ICON_FILE = "file";
-
- /**
- * Broadcast intent action indicating that the a Passpoint release
- * 2 WNM frame has been received.
- * @hide
- */
- public static final String PASSPOINT_WNM_FRAME_RECEIVED_ACTION =
- "android.net.wifi.PASSPOINT_WNM_FRAME_RECEIVED";
- /**
- * Originating BSS
- * @hide */
- public static final String EXTRA_PASSPOINT_WNM_BSSID = "bssid";
- /**
- * SOAP-XML or OMA-DM
- * @hide */
- public static final String EXTRA_PASSPOINT_WNM_METHOD = "method";
- /**
- * Type of Passpoint match
- * @hide */
- public static final String EXTRA_PASSPOINT_WNM_PPOINT_MATCH = "match";
- /**
- * String
- * @hide */
- public static final String EXTRA_PASSPOINT_WNM_URL = "url";
- /**
- * Boolean true=ess, false=bss
- * @hide */
- public static final String EXTRA_PASSPOINT_WNM_ESS = "ess";
- /**
- * Delay in seconds
- * @hide */
- public static final String EXTRA_PASSPOINT_WNM_DELAY = "delay";
-
- /**
* Broadcast intent action indicating that a Passpoint provider icon has been received.
*
+ * Included extras:
+ * {@link #EXTRA_BSSID_LONG}
+ * {@link #EXTRA_FILENAME}
+ * {@link #EXTRA_ICON}
+ *
* Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
- */
- public static final String ACTION_PASSPOINT_ICON =
- "android.net.wifi.action.PASSPOINT_ICON";
- /**
- * BSSID of the sender.
*
- * Type: long
+ * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
+ * components will be launched.
*/
- public static final String EXTRA_PASSPOINT_ICON_BSSID =
- "android.net.wifi.extra.PASSPOINT_ICON_BSSID";
+ public static final String ACTION_PASSPOINT_ICON = "android.net.wifi.action.PASSPOINT_ICON";
/**
- * Filename of the icon.
+ * BSSID of an AP in long representation. The {@link #EXTRA_BSSID} contains BSSID in
+ * String representation.
*
- * Type: String
+ * Retrieve with {@link android.content.Intent#getLongExtra(String, long)}.
*/
- public static final String EXTRA_PASSPOINT_ICON_FILENAME =
- "android.net.wifi.extra.PASSPOINT_ICON_FILENAME";
+ public static final String EXTRA_BSSID_LONG = "android.net.wifi.extra.BSSID_LONG";
/**
- * Binary blob of the icon.
+ * Icon data.
*
- * Type: byte[]
+ * Retrieve with {@link android.content.Intent#getParcelableExtra(String)} and cast into
+ * {@link android.graphics.drawable.Icon}.
*/
- public static final String EXTRA_PASSPOINT_ICON_DATA =
- "android.net.wifi.extra.PASSPOINT_ICON_DATA";
+ public static final String EXTRA_ICON = "android.net.wifi.extra.ICON";
+ /**
+ * Name of a file.
+ *
+ * Retrieve with {@link android.content.Intent#getStringExtra(String)}.
+ */
+ public static final String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME";
/**
* Broadcast intent action indicating a Passpoint OSU Providers List element has been received.
*
+ * Included extras:
+ * {@link #EXTRA_BSSID_LONG}
+ * {@link #EXTRA_ANQP_ELEMENT_DATA}
+ *
* Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
+ *
+ * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
+ * components will be launched.
+ *
*/
public static final String ACTION_PASSPOINT_OSU_PROVIDERS_LIST =
"android.net.wifi.action.PASSPOINT_OSU_PROVIDERS_LIST";
/**
- * BSSID of the sender.
+ * Raw binary data of an ANQP (Access Network Query Protocol) element.
*
- * Type: long
+ * Retrieve with {@link android.content.Intent#getByteArrayExtra(String)}.
*/
- public static final String EXTRA_PASSPOINT_OSU_PROVIDERS_LIST_BSSID =
- "android.net.wifi.extra.PASSPOINT_OSU_PROVIDERS_LIST_BSSID";
- /**
- * Raw data of OSU Providers List ANQP element. Refer to Section 4.8 of Hotspot 2.0 Release 2
- * Technical Specification for the exact data format.
- *
- * Type: byte[]
- */
- public static final String EXTRA_PASSPOINT_OSU_PROVIDERS_LIST_DATA =
- "android.net.wifi.extra.PASSPOINT_OSU_PROVIDERS_LIST_DATA";
+ public static final String EXTRA_ANQP_ELEMENT_DATA =
+ "android.net.wifi.extra.ANQP_ELEMENT_DATA";
/**
* Broadcast intent action indicating that a Passpoint Deauth Imminent frame has been received.
*
+ * Included extras:
+ * {@link #EXTRA_BSSID_LONG}
+ * {@link #EXTRA_ESS}
+ * {@link #EXTRA_DELAY}
+ * {@link #EXTRA_URL}
+ *
* Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
+ *
+ * <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
+ * components will be launched.
+ *
*/
public static final String ACTION_PASSPOINT_DEAUTH_IMMINENT =
"android.net.wifi.action.PASSPOINT_DEAUTH_IMMINENT";
/**
- * The BSSID of the sender.
+ * Flag indicating BSS (Basic Service Set) or ESS (Extended Service Set). This will be set to
+ * {@code true} for ESS.
*
- * Type: long
+ * Retrieve with {@link android.content.Intent#getBooleanExtra(String, boolean)}.
*/
- public static final String EXTRA_PASSPOINT_DEAUTH_IMMINENT_BSSID =
- "android.net.wifi.extra.PASSPOINT_DEAUTH_IMMINENT_BSSID";
+ public static final String EXTRA_ESS = "android.net.wifi.extra.ESS";
/**
- * Flag indicating failure at BSS (Basic Service Set) or ESS (Extended Service Set) level.
+ * Delay in seconds.
*
- * Type: boolean
+ * Retrieve with {@link android.content.Intent#getIntExtra(String, int)}.
*/
- public static final String EXTRA_PASSPOINT_DEAUTH_IMMINENT_ESS =
- "android.net.wifi.extra.PASSPOINT_DEAUTH_IMMINENT_ESS";
+ public static final String EXTRA_DELAY = "android.net.wifi.extra.DELAY";
/**
- * Delay in seconds that a device shall wait before attempting re-association to the same BSS
- * or ESS (as indicated by {@link #EXTRA_PASSPOINT_DEAUTH_IMMINENT_ESS}.
+ * String representation of an URL.
*
- * Type: int
+ * Retrieve with {@link android.content.Intent#getStringExtra(String)}.
*/
- public static final String EXTRA_PASSPOINT_DEAUTH_IMMINENT_REAUTH_DELAY =
- "android.net.wifi.extra.PASSPOINT_DEAUTH_IMMINENT_REAUTH_DELAY";
- /**
- * URL that provides a webpage explaining the deauth reason.
- *
- * Type: String
- */
- public static final String EXTRA_PASSPOINT_DEAUTH_IMMINENT_REASON_URL =
- "android.net.wifi.extra.PASSPOINT_DEAUTH_IMMINENT_REASON_URL";
+ public static final String EXTRA_URL = "android.net.wifi.extra.URL";
/**
* Broadcast intent action indicating a Passpoint subscription remediation frame has been
* received.
*
+ * Included extras:
+ * {@link #EXTRA_BSSID_LONG}
+ * {@link #EXTRA_SUBSCRIPTION_REMEDIATION_METHOD}
+ * {@link #EXTRA_URL}
+ *
* Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE
+ *
+ ** <p>Note: The broadcast is only delivered to registered receivers - no manifest registered
+ * components will be launched.
*/
public static final String ACTION_PASSPOINT_SUBSCRIPTION_REMEDIATION =
"android.net.wifi.action.PASSPOINT_SUBSCRIPTION_REMEDIATION";
/**
- * The BSSID of the sender.
- *
- * Type: long
- */
- public static final String EXTRA_PASSPOINT_SUBSCRIPTION_REMEDIATION_BSSID =
- "android.net.wifi.extra.PASSPOINT_SUBSCRIPTION_REMEDIATION_BSSID";
- /**
* The protocol supported by the subscription remediation server. The possible values are:
* 0 - OMA DM
* 1 - SOAP XML SPP
*
- * Type: int
+ * Retrieve with {@link android.content.Intent#getIntExtra(String, int)}.
*/
- public static final String EXTRA_PASSPOINT_SUBSCRIPTION_REMEDIATION_SERVER_METHOD =
- "android.net.wifi.extra.PASSPOINT_SUBSCRIPTION_REMEDIATION_SERVER_METHOD";
- /**
- * URL of the subscription remediation server.
- *
- * Type: String
- */
- public static final String EXTRA_PASSPOINT_SUBSCRIPTION_REMEDIATION_SERVER_URL =
- "android.net.wifi.extra.PASSPOINT_SUBSCRIPTION_REMEDIATION_SERVER_URL";
+ public static final String EXTRA_SUBSCRIPTION_REMEDIATION_METHOD =
+ "android.net.wifi.extra.SUBSCRIPTION_REMEDIATION_METHOD";
/**
* Broadcast intent action indicating that Wi-Fi has been enabled, disabled,
@@ -859,7 +820,12 @@
*/
public List<WifiConfiguration> getConfiguredNetworks() {
try {
- return mService.getConfiguredNetworks();
+ ParceledListSlice<WifiConfiguration> parceledList =
+ mService.getConfiguredNetworks();
+ if (parceledList == null) {
+ return Collections.emptyList();
+ }
+ return parceledList.getList();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -869,7 +835,12 @@
@SystemApi
public List<WifiConfiguration> getPrivilegedConfiguredNetworks() {
try {
- return mService.getPrivilegedConfiguredNetworks();
+ ParceledListSlice<WifiConfiguration> parceledList =
+ mService.getPrivilegedConfiguredNetworks();
+ if (parceledList == null) {
+ return Collections.emptyList();
+ }
+ return parceledList.getList();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -972,12 +943,15 @@
* Name). In the case when there is an existing configuration with the same
* FQDN, the new configuration will replace the existing configuration.
*
+ * An {@link IllegalArgumentException} will be thrown on failure.
+ *
* @param config The Passpoint configuration to be added
- * @return true on success
*/
- public boolean addOrUpdatePasspointConfiguration(PasspointConfiguration config) {
+ public void addOrUpdatePasspointConfiguration(PasspointConfiguration config) {
try {
- return mService.addOrUpdatePasspointConfiguration(config);
+ if (!mService.addOrUpdatePasspointConfiguration(config)) {
+ throw new IllegalArgumentException();
+ }
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -986,12 +960,15 @@
/**
* Remove the Passpoint configuration identified by its FQDN (Fully Qualified Domain Name).
*
+ * An {@link IllegalArgumentException} will be thrown on failure.
+ *
* @param fqdn The FQDN of the passpoint configuration to be removed
- * @return true on success
*/
- public boolean removePasspointConfiguration(String fqdn) {
+ public void removePasspointConfiguration(String fqdn) {
try {
- return mService.removePasspointConfiguration(fqdn);
+ if (!mService.removePasspointConfiguration(fqdn)) {
+ throw new IllegalArgumentException();
+ }
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -1013,10 +990,13 @@
}
/**
- * Query for a Hotspot 2.0 release 2 OSU icon file.
+ * Query for a Hotspot 2.0 release 2 OSU icon file. An {@link #ACTION_PASSPOINT_ICON} intent
+ * will be broadcasted once the request is completed. The presence of the intent extra
+ * {@link #EXTRA_ICON} will indicate the result of the request.
+ * A missing intent extra {@link #EXTRA_ICON} will indicate a failure.
*
* @param bssid The BSSID of the AP
- * @param fileName File name of the icon to query
+ * @param fileName Name of the icon file (remote file) to query from the AP
*/
public void queryPasspointIcon(long bssid, String fileName) {
try {
diff --git a/wifi/java/android/net/wifi/hotspot2/ConfigParser.java b/wifi/java/android/net/wifi/hotspot2/ConfigParser.java
index 027b049a..e8e8731 100644
--- a/wifi/java/android/net/wifi/hotspot2/ConfigParser.java
+++ b/wifi/java/android/net/wifi/hotspot2/ConfigParser.java
@@ -111,6 +111,7 @@
*
* Content-Type: multipart/mixed; boundary={boundary}
* Content-Transfer-Encoding: base64
+ * [Skip uninterested headers]
*
* --{boundary}
* Content-Type: application/x-passpoint-profile
@@ -326,7 +327,8 @@
header.encodingType = entry.getValue();
break;
default:
- throw new IOException("Unexpected header: " + entry.getKey());
+ Log.d(TAG, "Ignore header: " + entry.getKey());
+ break;
}
}
return header;
@@ -344,21 +346,24 @@
* @throws IOException
*/
private static Pair<String, String> parseContentType(String contentType) throws IOException {
- String[] attributes = contentType.toString().split(";");
+ String[] attributes = contentType.split(";");
String type = null;
String boundary = null;
- if (attributes.length < 1 || attributes.length > 2) {
+ if (attributes.length < 1) {
throw new IOException("Invalid Content-Type: " + contentType);
}
+ // The type is always the first attribute.
type = attributes[0].trim();
- if (attributes.length == 2) {
- boundary = attributes[1].trim();
- if (!boundary.startsWith(BOUNDARY)) {
- throw new IOException("Invalid Content-Type: " + contentType);
+ // Look for boundary string from the rest of the attributes.
+ for (int i = 1; i < attributes.length; i++) {
+ String attribute = attributes[i].trim();
+ if (!attribute.startsWith(BOUNDARY)) {
+ Log.d(TAG, "Ignore Content-Type attribute: " + attributes[i]);
+ continue;
}
- boundary = boundary.substring(BOUNDARY.length());
+ boundary = attribute.substring(BOUNDARY.length());
// Remove the leading and trailing quote if present.
if (boundary.length() > 1 && boundary.startsWith("\"") && boundary.endsWith("\"")) {
boundary = boundary.substring(1, boundary.length()-1);
diff --git a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
index 1f661c4..333a4f7d 100644
--- a/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
+++ b/wifi/java/android/net/wifi/hotspot2/PasspointConfiguration.java
@@ -28,6 +28,7 @@
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@@ -329,10 +330,55 @@
mUsageLimitStartTimeInMs, mUsageLimitDataLimit, mUsageLimitTimeLimitInMinutes);
}
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("UpdateIdentifier: ").append(mUpdateIdentifier).append("\n");
+ builder.append("CredentialPriority: ").append(mCredentialPriority).append("\n");
+ builder.append("SubscriptionCreationTime: ").append(
+ mSubscriptionCreationTimeInMs != Long.MIN_VALUE
+ ? new Date(mSubscriptionCreationTimeInMs) : "Not specified").append("\n");
+ builder.append("SubscriptionExpirationTime: ").append(
+ mSubscriptionExpirationTimeInMs != Long.MIN_VALUE
+ ? new Date(mSubscriptionExpirationTimeInMs) : "Not specified").append("\n");
+ builder.append("UsageLimitStartTime: ").append(mUsageLimitStartTimeInMs != Long.MIN_VALUE
+ ? new Date(mUsageLimitStartTimeInMs) : "Not specified").append("\n");
+ builder.append("UsageTimePeriod: ").append(mUsageLimitUsageTimePeriodInMinutes)
+ .append("\n");
+ builder.append("UsageLimitDataLimit: ").append(mUsageLimitDataLimit).append("\n");
+ builder.append("UsageLimitTimeLimit: ").append(mUsageLimitTimeLimitInMinutes).append("\n");
+ if (mHomeSp != null) {
+ builder.append("HomeSP Begin ---\n");
+ builder.append(mHomeSp);
+ builder.append("HomeSP End ---\n");
+ }
+ if (mCredential != null) {
+ builder.append("Credential Begin ---\n");
+ builder.append(mCredential);
+ builder.append("Credential End ---\n");
+ }
+ if (mPolicy != null) {
+ builder.append("Policy Begin ---\n");
+ builder.append(mPolicy);
+ builder.append("Policy End ---\n");
+ }
+ if (mSubscriptionUpdate != null) {
+ builder.append("SubscriptionUpdate Begin ---\n");
+ builder.append(mSubscriptionUpdate);
+ builder.append("SubscriptionUpdate End ---\n");
+ }
+ if (mTrustRootCertList != null) {
+ builder.append("TrustRootCertServers: ").append(mTrustRootCertList.keySet())
+ .append("\n");
+ }
+ return builder.toString();
+ }
+
/**
* Validate the configuration data.
*
* @return true on success or false on failure
+ * @hide
*/
public boolean validate() {
if (mHomeSp == null || !mHomeSp.validate()) {
diff --git a/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java b/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java
index 2ffe428..5dc5d13 100644
--- a/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java
+++ b/wifi/java/android/net/wifi/hotspot2/omadm/PpsMoParser.java
@@ -144,6 +144,8 @@
private static final String NODE_TIME_LIMIT = "TimeLimit";
private static final String NODE_USAGE_TIME_PERIOD = "UsageTimePeriod";
private static final String NODE_CREDENTIAL_PRIORITY = "CredentialPriority";
+ private static final String NODE_EXTENSION = "Extension";
+
/**
* Fields under HomeSP subtree.
*/
@@ -629,6 +631,10 @@
case NODE_CREDENTIAL_PRIORITY:
config.setCredentialPriority(parseInteger(getPpsNodeValue(child)));
break;
+ case NODE_EXTENSION:
+ // All vendor specific information will be under this node.
+ Log.d(TAG, "Ignore Extension node for vendor specific information");
+ break;
default:
throw new ParsingException("Unknown node: " + child.getName());
}
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
index 2388841..67fa1bb 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/Credential.java
@@ -30,6 +30,7 @@
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.Arrays;
+import java.util.Date;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
@@ -282,10 +283,23 @@
mAbleToShare, mEapType, mNonEapInnerMethod);
}
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("Username: ").append(mUsername).append("\n");
+ builder.append("MachineManaged: ").append(mMachineManaged).append("\n");
+ builder.append("SoftTokenApp: ").append(mSoftTokenApp).append("\n");
+ builder.append("AbleToShare: ").append(mAbleToShare).append("\n");
+ builder.append("EAPType: ").append(mEapType).append("\n");
+ builder.append("AuthMethod: ").append(mNonEapInnerMethod).append("\n");
+ return builder.toString();
+ }
+
/**
* Validate the configuration data.
*
* @return true on success or false on failure
+ * @hide
*/
public boolean validate() {
if (TextUtils.isEmpty(mUsername)) {
@@ -439,10 +453,16 @@
return Objects.hash(mCertType, mCertSha256Fingerprint);
}
+ @Override
+ public String toString() {
+ return "CertificateType: " + mCertType + "\n";
+ }
+
/**
* Validate the configuration data.
*
* @return true on success or false on failure
+ * @hide
*/
public boolean validate() {
if (!TextUtils.equals(CERT_TYPE_X509V3, mCertType)) {
@@ -560,6 +580,14 @@
}
@Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("IMSI: ").append(mImsi).append("\n");
+ builder.append("EAPType: ").append(mEapType).append("\n");
+ return builder.toString();
+ }
+
+ @Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mImsi);
dest.writeInt(mEapType);
@@ -569,6 +597,7 @@
* Validate the configuration data.
*
* @return true on success or false on failure
+ * @hide
*/
public boolean validate() {
// Note: this only validate the format of IMSI string itself. Additional verification
@@ -764,10 +793,38 @@
mCaCertificate, mClientCertificateChain, mClientPrivateKey);
}
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("Realm: ").append(mRealm).append("\n");
+ builder.append("CreationTime: ").append(mCreationTimeInMs != Long.MIN_VALUE
+ ? new Date(mCreationTimeInMs) : "Not specified").append("\n");
+ builder.append("ExpirationTime: ").append(mExpirationTimeInMs != Long.MIN_VALUE
+ ? new Date(mExpirationTimeInMs) : "Not specified").append("\n");
+ builder.append("CheckAAAServerStatus: ").append(mCheckAaaServerCertStatus).append("\n");
+ if (mUserCredential != null) {
+ builder.append("UserCredential Begin ---\n");
+ builder.append(mUserCredential);
+ builder.append("UserCredential End ---\n");
+ }
+ if (mCertCredential != null) {
+ builder.append("CertificateCredential Begin ---\n");
+ builder.append(mCertCredential);
+ builder.append("CertificateCredential End ---\n");
+ }
+ if (mSimCredential != null) {
+ builder.append("SIMCredential Begin ---\n");
+ builder.append(mSimCredential);
+ builder.append("SIMCredential End ---\n");
+ }
+ return builder.toString();
+ }
+
/**
* Validate the configuration data.
*
* @return true on success or false on failure
+ * @hide
*/
public boolean validate() {
if (TextUtils.isEmpty(mRealm)) {
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
index 8ec40c0..9192ab0 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/HomeSp.java
@@ -241,10 +241,25 @@
mMatchAnyOis, mOtherHomePartners, mRoamingConsortiumOis);
}
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("FQDN: ").append(mFqdn).append("\n");
+ builder.append("FriendlyName: ").append(mFriendlyName).append("\n");
+ builder.append("IconURL: ").append(mIconUrl).append("\n");
+ builder.append("HomeNetworkIDs: ").append(mHomeNetworkIds).append("\n");
+ builder.append("MatchAllOIs: ").append(mMatchAllOis).append("\n");
+ builder.append("MatchAnyOIs: ").append(mMatchAnyOis).append("\n");
+ builder.append("OtherHomePartners: ").append(mOtherHomePartners).append("\n");
+ builder.append("RoamingConsortiumOIs: ").append(mRoamingConsortiumOis).append("\n");
+ return builder.toString();
+ }
+
/**
* Validate HomeSp data.
*
* @return true on success or false on failure
+ * @hide
*/
public boolean validate() {
if (TextUtils.isEmpty(mFqdn)) {
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/Policy.java b/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
index 63238e8..1df70f8 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/Policy.java
@@ -249,10 +249,21 @@
return Objects.hash(mFqdn, mFqdnExactMatch, mPriority, mCountries);
}
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("FQDN: ").append(mFqdn).append("\n");
+ builder.append("ExactMatch: ").append("mFqdnExactMatch").append("\n");
+ builder.append("Priority: ").append(mPriority).append("\n");
+ builder.append("Countries: ").append(mCountries).append("\n");
+ return builder.toString();
+ }
+
/**
* Validate RoamingParnter data.
*
* @return true on success
+ * @hide
*/
public boolean validate() {
if (TextUtils.isEmpty(mFqdn)) {
@@ -389,10 +400,34 @@
mPolicyUpdate);
}
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("MinHomeDownlinkBandwidth: ").append(mMinHomeDownlinkBandwidth)
+ .append("\n");
+ builder.append("MinHomeUplinkBandwidth: ").append(mMinHomeUplinkBandwidth).append("\n");
+ builder.append("MinRoamingDownlinkBandwidth: ").append(mMinRoamingDownlinkBandwidth)
+ .append("\n");
+ builder.append("MinRoamingUplinkBandwidth: ").append(mMinRoamingUplinkBandwidth)
+ .append("\n");
+ builder.append("ExcludedSSIDList: ").append(mExcludedSsidList).append("\n");
+ builder.append("RequiredProtoPortMap: ").append(mRequiredProtoPortMap).append("\n");
+ builder.append("MaximumBSSLoadValue: ").append(mMaximumBssLoadValue).append("\n");
+ builder.append("PreferredRoamingPartnerList: ").append(mPreferredRoamingPartnerList)
+ .append("\n");
+ if (mPolicyUpdate != null) {
+ builder.append("PolicyUpdate Begin ---\n");
+ builder.append(mPolicyUpdate);
+ builder.append("PolicyUpdate End ---\n");
+ }
+ return builder.toString();
+ }
+
/**
* Validate Policy data.
*
* @return true on success
+ * @hide
*/
public boolean validate() {
if (mPolicyUpdate == null) {
diff --git a/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java b/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java
index 70264b0e..a7adfeb 100644
--- a/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java
+++ b/wifi/java/android/net/wifi/hotspot2/pps/UpdateParameter.java
@@ -247,10 +247,23 @@
mTrustRootCertSha256Fingerprint);
}
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder();
+ builder.append("UpdateInterval: ").append(mUpdateIntervalInMinutes).append("\n");
+ builder.append("UpdateMethod: ").append(mUpdateMethod).append("\n");
+ builder.append("Restriction: ").append(mRestriction).append("\n");
+ builder.append("ServerURI: ").append(mServerUri).append("\n");
+ builder.append("Username: ").append(mUsername).append("\n");
+ builder.append("TrustRootCertURL: ").append(mTrustRootCertUrl).append("\n");
+ return builder.toString();
+ }
+
/**
* Validate UpdateParameter data.
*
* @return true on success
+ * @hide
*/
public boolean validate() {
if (mUpdateIntervalInMinutes == Long.MIN_VALUE) {
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64 b/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64
index 995963d..56919c2 100644
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64
+++ b/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.base64
@@ -1,85 +1,86 @@
-Q29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5PXtib3VuZGFyeX0KQ29udGVu
-dC1UcmFuc2Zlci1FbmNvZGluZzogYmFzZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBh
-cHBsaWNhdGlvbi94LXBhc3Nwb2ludC1wcm9maWxlCkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6
-IGJhc2U2NAoKUEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29n
-SUR4V1pYSkVWRVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVo
-YldVK1VHVnlVSEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0Fn
-UEZKVVVISnZjR1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhi
-V1UrZFhKdU9uZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZ
-M0pwY0hScGIyNDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThM
-MUpVVUhKdmNHVnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVSth
-VEF3TVR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFRt
-RnRaVDVJYjIxbFUxQTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lD
-QWdJQ0FnUEU1dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdApaVHd2VG05a1pVNWhiV1UrQ2lBZ0lD
-QWdJQ0FnSUNBOFZtRnNkV1UrUTJWdWRIVnllU0JJYjNWelpUd3ZWbUZzZFdVK0NpQWdJQ0FnCklD
-QWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcx
-bFBrWlJSRTQ4TDA1dlpHVk8KWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBtMXBOaTVqYnk1
-MWF6d3ZWbUZzZFdVK0NpQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZwpJQ0FnSUNBZ0lEeE9iMlJsUGdv
-Z0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsSnZZVzFwYm1kRGIyNXpiM0owYVhWdFQwazhMMDV2
-ClpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUGpFeE1qSXpNeXcwTkRVMU5qWThMMVpo
-YkhWbFBnb2dJQ0FnSUNBZ0lEd3YKVG05a1pUNEtJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0E4
-VG05a1pUNEtJQ0FnSUNBZ0lDQThUbTlrWlU1aGJXVStRM0psWkdWdQpkR2xoYkR3dlRtOWtaVTVo
-YldVK0NpQWdJQ0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1VtVmhi
-RzA4CkwwNXZaR1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBuTm9ZV3RsYmk1emRHbHlj
-bVZrTG1OdmJUd3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9i
-MlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsVnpaWEp1WVcxbApVR0Z6YzNkdmNtUThM
-MDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2Iy
-UmxUbUZ0ClpUNVZjMlZ5Ym1GdFpUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lX
-eDFaVDVxWVcxbGN6d3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lD
-QWdJQ0E4VG05a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxCaApjM04zYjNKa1BD
-OU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbGx0T1hWYVJFRjNUbmM5UFR3
-dlZtRnNkV1UrCkNpQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0
-S0lDQWdJQ0FnSUNBZ0lDQWdQRTV2WkdWT1lXMWwKUGtWQlVFMWxkR2h2WkR3dlRtOWtaVTVoYldV
-K0NpQWdJQ0FnSUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0FnSUR4TwpiMlJsVG1G
-dFpUNUZRVkJVZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBOFZtRnNkV1Ur
-TWpFOEwxWmhiSFZsClBnb2dJQ0FnSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lDQWdJQ0Fn
-SUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeE8KYjJSbFRtRnRaVDVKYm01bGNrMWxkR2h2
-WkR3dlRtOWtaVTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQazFUTFVOSQpRVkF0
-VmpJOEwxWmhiSFZsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThM
-MDV2WkdVK0NpQWdJQ0FnCklDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJ
-Q0FnSUNBZ1BFNXZaR1ZPWVcxbFBrUnBaMmwwWVd4RFpYSjAKYVdacFkyRjBaVHd2VG05a1pVNWhi
-V1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbApQ
-a05sY25ScFptbGpZWFJsVkhsd1pUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lX
-eDFaVDU0TlRBNWRqTThMMVpoCmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lD
-QWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEowVTBoQk1q
-VTJSbWx1WjJWeWNISnBiblE4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdV
-KwpNV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpG
-bU1XWXhaakZtTVdZeFpqRm1NV1l4ClpqRm1NV1l4Wmp3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnSUNB
-OEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWcKSUR4T2IyUmxQZ29nSUNB
-Z0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxOSlRUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4
-VG05awpaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrbE5VMGs4TDA1dlpHVk9ZVzFs
-UGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzCmRXVSthVzF6YVR3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0Fn
-SUNBOEwwNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWcKSUNBZ0lDQWdQRTV2
-WkdWT1lXMWxQa1ZCVUZSNWNHVThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBOFZtRnNk
-V1UrTWpROApMMVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEd3ZU
-bTlrWlQ0S0lDQWdJQ0FnUEM5T2IyUmxQZ29nCklDQWdQQzlPYjJSbFBnb2dJRHd2VG05a1pUNEtQ
-QzlOWjIxMFZISmxaVDRLCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94
-LXg1MDktY2EtY2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFD
-UlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtR
-VWxNYkVaa2QzcE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5U
-bFlLUWtGTlZFSXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpU
-azFxV1hkTlZFRTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5V
-VEJGZUUxSlNVSkpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMw
-TkJVVVZCQ25wdVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZY
-TldkVzFFWWxsSWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01T
-dHZSMWhhZGtoM2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJV
-RkRaV1pXYW1vd2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJo
-U1FqZzFNVEpRUWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdK
-ck1IVjVhM1JrWW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtz
-M2FFUTRjRkIyWmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxh
-CmFYQllOREY0UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVX
-TTJreGRIRXdOR3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZH
-U1hkWU5IWnpPRUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFF
-YlVGR1NYZFlOSFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJk
-MFJuCldVUldVVkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldV
-akJVUWtGVmQwRjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZ
-MDVCVVVWTVFsRkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZD
-amxIUlZBdmRXOW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNY
-ZEpWV00zCmQyazNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1Ew
-OTBhWE5rUW5FeWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JX
-MVdUQW94Y1VKS2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVF
-MXVWR3c0ZUVWWFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhw
-aFNFb3hkVlk0Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpG
-S1VDdHNlRllLYlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNS
-a1RrNTJRMWw2YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmts
-RFFWUkZMUzB0TFMwSwotLXtib3VuZGFyeX0tLQo=
+TUlNRS1WZXJzaW9uOiAxLjAKQ29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7IGJvdW5kYXJ5
+PXtib3VuZGFyeX07IGNoYXJzZXQ9VVRGLTgKQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZzogYmFz
+ZTY0CgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXBhc3Nwb2ludC1w
+cm9maWxlOyBjaGFyc2V0PVVURi04CkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IGJhc2U2NAoK
+UEUxbmJYUlVjbVZsSUhodGJHNXpQU0p6ZVc1amJXdzZaRzFrWkdZeExqSWlQZ29nSUR4V1pYSkVW
+RVErTVM0eVBDOVdaWEpFVkVRKwpDaUFnUEU1dlpHVStDaUFnSUNBOFRtOWtaVTVoYldVK1VHVnlV
+SEp2ZG1sa1pYSlRkV0p6WTNKcGNIUnBiMjQ4TDA1dlpHVk9ZVzFsClBnb2dJQ0FnUEZKVVVISnZj
+R1Z5ZEdsbGN6NEtJQ0FnSUNBZ1BGUjVjR1UrQ2lBZ0lDQWdJQ0FnUEVSRVJrNWhiV1UrZFhKdU9u
+ZG0KWVRwdGJ6cG9iM1J6Y0c5ME1tUnZkREF0Y0dWeWNISnZkbWxrWlhKemRXSnpZM0pwY0hScGIy
+NDZNUzR3UEM5RVJFWk9ZVzFsUGdvZwpJQ0FnSUNBOEwxUjVjR1UrQ2lBZ0lDQThMMUpVVUhKdmNH
+VnlkR2xsY3o0S0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBOFRtOWtaVTVoCmJXVSthVEF3TVR3dlRt
+OWtaVTVoYldVK0NpQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJRHhPYjJSbFRtRnRaVDVJYjIx
+bFUxQTgKTDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1
+dlpHVk9ZVzFsUGtaeWFXVnVaR3g1VG1GdApaVHd2VG05a1pVNWhiV1UrQ2lBZ0lDQWdJQ0FnSUNB
+OFZtRnNkV1UrUTJWdWRIVnllU0JJYjNWelpUd3ZWbUZzZFdVK0NpQWdJQ0FnCklDQWdQQzlPYjJS
+bFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrWlJSRTQ4
+TDA1dlpHVk8KWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBtMXBOaTVqYnk1MWF6d3ZWbUZz
+ZFdVK0NpQWdJQ0FnSUNBZ1BDOU9iMlJsUGdvZwpJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0Fn
+SUNBZ1BFNXZaR1ZPWVcxbFBsSnZZVzFwYm1kRGIyNXpiM0owYVhWdFQwazhMMDV2ClpHVk9ZVzFs
+UGdvZ0lDQWdJQ0FnSUNBZ1BGWmhiSFZsUGpFeE1qSXpNeXcwTkRVMU5qWThMMVpoYkhWbFBnb2dJ
+Q0FnSUNBZ0lEd3YKVG05a1pUNEtJQ0FnSUNBZ1BDOU9iMlJsUGdvZ0lDQWdJQ0E4VG05a1pUNEtJ
+Q0FnSUNBZ0lDQThUbTlrWlU1aGJXVStRM0psWkdWdQpkR2xoYkR3dlRtOWtaVTVoYldVK0NpQWdJ
+Q0FnSUNBZ1BFNXZaR1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVTVoYldVK1VtVmhiRzA4CkwwNXZa
+R1ZPWVcxbFBnb2dJQ0FnSUNBZ0lDQWdQRlpoYkhWbFBuTm9ZV3RsYmk1emRHbHljbVZrTG1OdmJU
+d3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lD
+QWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBsVnpaWEp1WVcxbApVR0Z6YzNkdmNtUThMMDV2WkdWT1lX
+MWxQZ29nSUNBZ0lDQWdJQ0FnUEU1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxUbUZ0ClpU
+NVZjMlZ5Ym1GdFpUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lXeDFaVDVxWVcx
+bGN6d3ZWbUZzZFdVK0NpQWcKSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lDQWdJQ0E4VG05
+a1pUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEU1dlpHVk9ZVzFsUGxCaApjM04zYjNKa1BDOU9iMlJsVG1G
+dFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQbGx0T1hWYVJFRjNUbmM5UFR3dlZtRnNkV1Ur
+CkNpQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThUbTlrWlQ0S0lDQWdJQ0Fn
+SUNBZ0lDQWdQRTV2WkdWT1lXMWwKUGtWQlVFMWxkR2h2WkR3dlRtOWtaVTVoYldVK0NpQWdJQ0Fn
+SUNBZ0lDQWdJRHhPYjJSbFBnb2dJQ0FnSUNBZ0lDQWdJQ0FnSUR4TwpiMlJsVG1GdFpUNUZRVkJV
+ZVhCbFBDOU9iMlJsVG1GdFpUNEtJQ0FnSUNBZ0lDQWdJQ0FnSUNBOFZtRnNkV1UrTWpFOEwxWmhi
+SFZsClBnb2dJQ0FnSUNBZ0lDQWdJQ0E4TDA1dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmxQ
+Z29nSUNBZ0lDQWdJQ0FnSUNBZ0lEeE8KYjJSbFRtRnRaVDVKYm01bGNrMWxkR2h2WkR3dlRtOWta
+VTVoYldVK0NpQWdJQ0FnSUNBZ0lDQWdJQ0FnUEZaaGJIVmxQazFUTFVOSQpRVkF0VmpJOEwxWmhi
+SFZsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0NpQWdJQ0FnSUNBZ0lDQThMMDV2WkdVK0Np
+QWdJQ0FnCklDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEeE9iMlJsUGdvZ0lDQWdJQ0FnSUNBZ1BF
+NXZaR1ZPWVcxbFBrUnBaMmwwWVd4RFpYSjAKYVdacFkyRjBaVHd2VG05a1pVNWhiV1UrQ2lBZ0lD
+QWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbApQa05sY25ScFpt
+bGpZWFJsVkhsd1pUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0FnSUR4V1lXeDFaVDU0TlRB
+NWRqTThMMVpoCmJIVmxQZ29nSUNBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWdJQ0FnUEU1
+dlpHVStDaUFnSUNBZ0lDQWdJQ0FnSUR4T2IyUmwKVG1GdFpUNURaWEowVTBoQk1qVTJSbWx1WjJW
+eWNISnBiblE4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJQ0FnSUNBZ0lDQThWbUZzZFdVKwpNV1l4WmpG
+bU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZtTVdZeFpqRm1NV1l4WmpGbU1XWXhaakZt
+TVdZeFpqRm1NV1l4ClpqRm1NV1l4Wmp3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnSUNBOEwwNXZaR1Ur
+Q2lBZ0lDQWdJQ0FnUEM5T2IyUmxQZ29nSUNBZ0lDQWcKSUR4T2IyUmxQZ29nSUNBZ0lDQWdJQ0Fn
+UEU1dlpHVk9ZVzFsUGxOSlRUd3ZUbTlrWlU1aGJXVStDaUFnSUNBZ0lDQWdJQ0E4VG05awpaVDRL
+SUNBZ0lDQWdJQ0FnSUNBZ1BFNXZaR1ZPWVcxbFBrbE5VMGs4TDA1dlpHVk9ZVzFsUGdvZ0lDQWdJ
+Q0FnSUNBZ0lDQThWbUZzCmRXVSthVzF6YVR3dlZtRnNkV1UrQ2lBZ0lDQWdJQ0FnSUNBOEwwNXZa
+R1UrQ2lBZ0lDQWdJQ0FnSUNBOFRtOWtaVDRLSUNBZ0lDQWcKSUNBZ0lDQWdQRTV2WkdWT1lXMWxQ
+a1ZCVUZSNWNHVThMMDV2WkdWT1lXMWxQZ29nSUNBZ0lDQWdJQ0FnSUNBOFZtRnNkV1UrTWpROApM
+MVpoYkhWbFBnb2dJQ0FnSUNBZ0lDQWdQQzlPYjJSbFBnb2dJQ0FnSUNBZ0lEd3ZUbTlrWlQ0S0lD
+QWdJQ0FnUEM5T2IyUmxQZ29nCklDQWdQQzlPYjJSbFBnb2dJRHd2VG05a1pUNEtQQzlOWjIxMFZI
+SmxaVDRLCgotLXtib3VuZGFyeX0KQ29udGVudC1UeXBlOiBhcHBsaWNhdGlvbi94LXg1MDktY2Et
+Y2VydApDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiBiYXNlNjQKCkxTMHRMUzFDUlVkSlRpQkRS
+VkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVVJMUkVORFFXaERaMEYzU1VKQlowbEtRVWxNYkVaa2Qz
+cE0KVm5WeVRVRXdSME5UY1VkVFNXSXpSRkZGUWtOM1ZVRk5Ra2w0UlVSQlQwSm5UbFlLUWtGTlZF
+SXdWa0pWUTBKRVVWUkZkMGhvWTA1TgpWRmwzVFZSRmVVMVVSVEZOUkVVeFYyaGpUazFxV1hkTlZF
+RTFUVlJGTVUxRVJURlhha0ZUVFZKQmR3cEVaMWxFVmxGUlJFVjNaRVpSClZrRm5VVEJGZUUxSlNV
+Skpha0ZPUW1kcmNXaHJhVWM1ZHpCQ1FWRkZSa0ZCVDBOQlVUaEJUVWxKUWtOblMwTkJVVVZCQ25w
+dVFWQlYKZWpJMlRYTmhaVFIzY3pRelkzcFNOREV2U2pKUmRISlRTVnBWUzIxV1ZYTldkVzFFWWxs
+SWNsQk9kbFJZUzFOTldFRmpaWGRQVWtSUgpXVmdLVW5GMlNIWndiamhEYzJOQ01TdHZSMWhhZGto
+M2VHbzBlbFl3VjB0dlN6SjZaVmhyWVhVemRtTjViRE5JU1V0MWNFcG1jVEpVClJVRkRaV1pXYW1v
+d2RBcEtWeXRZTXpWUVIxZHdPUzlJTlhwSlZVNVdUbFpxVXpkVmJYTTRORWwyUzJoU1FqZzFNVEpR
+UWpsVmVVaGgKWjFoWlZsZzFSMWR3UVdOV2NIbG1jbXhTQ2taSk9WRmthR2dyVUdKck1IVjVhM1Jr
+WW1ZdlEyUm1aMGhQYjJWaWNsUjBkMUpzYWswdwpiMFIwV0NzeVEzWTJhakIzUWtzM2FFUTRjRkIy
+WmpFcmRYa0tSM3BqZW1sblFWVXZORXQzTjJWYWNYbGtaamxDS3pWU2RYQlNLMGxhCmFYQllOREY0
+UldsSmNrdFNkM0ZwTlRFM1YxZDZXR05xWVVjeVkwNWlaalExTVFwNGNFZzFVRzVXTTJreGRIRXdO
+R3BOUjFGVmVrWjMKU1VSQlVVRkNielJIUVUxSU5IZElVVmxFVmxJd1QwSkNXVVZHU1hkWU5IWnpP
+RUpwUW1OVFkyOWtDalZ1YjFwSVVrMDRSVFFyYVUxRgpTVWRCTVZWa1NYZFJOMDFFYlVGR1NYZFlO
+SFp6T0VKcFFtTlRZMjlrTlc1dldraFNUVGhGTkN0cGIxSmhhMFpFUVZNS1RWSkJkMFJuCldVUldV
+VkZFUlhka1JsRldRV2RSTUVWNFoyZHJRV2QxVlZZelJFMTBWelp6ZDBSQldVUldVakJVUWtGVmQw
+RjNSVUl2ZWtGTVFtZE8KVmdwSVVUaEZRa0ZOUTBGUldYZEVVVmxLUzI5YVNXaDJZMDVCVVVWTVFs
+RkJSR2RuUlVKQlJtWlJjVTlVUVRkU2RqZExLMngxVVRkdwpibUZ6TkVKWmQwaEZDamxIUlZBdmRX
+OW9kalpMVDNrd1ZFZFJSbUp5VWxScVJtOU1WazVDT1VKYU1YbHRUVVJhTUM5VVNYZEpWV00zCmQy
+azNZVGgwTlcxRmNWbElNVFV6ZDFjS1lWZHZiMmxUYW5sTVRHaDFTVFJ6VG5KT1EwOTBhWE5rUW5F
+eWNqSk5SbGgwTm1nd2JVRlIKV1U5UWRqaFNPRXMzTDJablUzaEhSbkY2YUhsT2JXMVdUQW94Y1VK
+S2JHUjRNelJUY0hkelZFRk1VVlpRWWpSb1IzZEtlbHBtY2pGUQpZM0JGVVhnMmVFMXVWR3c0ZUVW
+WFdrVXpUWE01T1hWaFZYaGlVWEZKZDFKMUNreG5RVTlyVGtOdFdUSnRPRGxXYUhwaFNFb3hkVlk0
+Ck5VRmtUUzkwUkN0WmMyMXNibTVxZERsTVVrTmxhbUpDYVhCcVNVZHFUMWh5WnpGS1VDdHNlRllL
+YlhWTk5IWklLMUF2Yld4dGVITlEKVUhvd1pEWTFZaXRGUjIxS1duQnZUR3RQTDNSa1RrNTJRMWw2
+YWtwd1ZFVlhjRVZ6VHpaT1RXaExXVzg5Q2kwdExTMHRSVTVFSUVORgpVbFJKUmtsRFFWUkZMUzB0
+TFMwSwotLXtib3VuZGFyeX0tLQo=
diff --git a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf b/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf
index 3ddd09f..a44b542 100644
--- a/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf
+++ b/wifi/tests/assets/hsr1/HSR1ProfileWithCACert.conf
@@ -1,8 +1,9 @@
-Content-Type: multipart/mixed; boundary={boundary}
+MIME-Version: 1.0
+Content-Type: multipart/mixed; boundary={boundary}; charset=UTF-8
Content-Transfer-Encoding: base64
--{boundary}
-Content-Type: application/x-passpoint-profile
+Content-Type: application/x-passpoint-profile; charset=UTF-8
Content-Transfer-Encoding: base64
PE1nbXRUcmVlIHhtbG5zPSJzeW5jbWw6ZG1kZGYxLjIiPgogIDxWZXJEVEQ+MS4yPC9WZXJEVEQ+
diff --git a/wifi/tests/assets/pps/PerProviderSubscription.xml b/wifi/tests/assets/pps/PerProviderSubscription.xml
index 7f2d95d..1fb8309 100644
--- a/wifi/tests/assets/pps/PerProviderSubscription.xml
+++ b/wifi/tests/assets/pps/PerProviderSubscription.xml
@@ -14,6 +14,13 @@
<Node>
<NodeName>i001</NodeName>
<Node>
+ <NodeName>Extension</NodeName>
+ <Node>
+ <NodeName>VendorSpecific</NodeName>
+ <Value>Test</Value>
+ </Node>
+ </Node>
+ <Node>
<NodeName>HomeSP</NodeName>
<Node>
<NodeName>FriendlyName</NodeName>