Merge "remove deprecated SIM_ACTIVATION_REQUEST intent"
diff --git a/api/current.txt b/api/current.txt
index b5a99ca..b3d9fc1 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);
@@ -7505,7 +7506,7 @@
}
public final class AdvertisingSet {
- method public void enableAdvertising(boolean);
+ method public void enableAdvertising(boolean, int);
method public void periodicAdvertisingEnable(boolean);
method public void setAdvertisingData(android.bluetooth.le.AdvertiseData);
method public void setAdvertisingParameters(android.bluetooth.le.AdvertisingSetParameters);
@@ -7538,7 +7539,6 @@
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();
@@ -7565,14 +7565,13 @@
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 setSecondaryPhy(int);
- method public android.bluetooth.le.AdvertisingSetParameters.Builder setTimeout(int);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setTxPowerLevel(int);
}
@@ -7581,6 +7580,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 +23813,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 +23824,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);
@@ -24812,6 +24817,16 @@
package android.net.wifi {
+ public final class IconInfo implements android.os.Parcelable {
+ ctor public IconInfo(java.lang.String, byte[]);
+ ctor public IconInfo(android.net.wifi.IconInfo);
+ method public int describeContents();
+ method public byte[] getData();
+ method public java.lang.String getFilename();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.IconInfo> CREATOR;
+ }
+
public class ScanResult implements android.os.Parcelable {
method public int describeContents();
method public boolean is80211mcResponder();
@@ -25011,7 +25026,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 +25055,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 +25070,21 @@
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_ICON_INFO = "android.net.wifi.extra.ICON_INFO";
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 +25303,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 +25343,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 +25355,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 +25367,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 +25389,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 +25413,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 +25439,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 +25455,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 +25479,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
diff --git a/api/system-current.txt b/api/system-current.txt
index c2338d8..55d4f4e 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -6992,6 +6992,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);
@@ -7809,7 +7810,7 @@
}
public final class AdvertisingSet {
- method public void enableAdvertising(boolean);
+ method public void enableAdvertising(boolean, int);
method public void periodicAdvertisingEnable(boolean);
method public void setAdvertisingData(android.bluetooth.le.AdvertiseData);
method public void setAdvertisingParameters(android.bluetooth.le.AdvertisingSetParameters);
@@ -7842,7 +7843,6 @@
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();
@@ -7869,14 +7869,13 @@
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 setSecondaryPhy(int);
- method public android.bluetooth.le.AdvertisingSetParameters.Builder setTimeout(int);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setTxPowerLevel(int);
}
@@ -7885,6 +7884,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 +25600,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 +25611,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);
@@ -26964,6 +26969,16 @@
field public boolean truncated;
}
+ public final class IconInfo implements android.os.Parcelable {
+ ctor public IconInfo(java.lang.String, byte[]);
+ ctor public IconInfo(android.net.wifi.IconInfo);
+ method public int describeContents();
+ method public byte[] getData();
+ method public java.lang.String getFilename();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.IconInfo> CREATOR;
+ }
+
public class RttManager {
method public void disableResponder(android.net.wifi.RttManager.ResponderCallback);
method public void enableResponder(android.net.wifi.RttManager.ResponderCallback);
@@ -27389,7 +27404,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 +27444,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 +27467,24 @@
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_ICON_INFO = "android.net.wifi.extra.ICON_INFO";
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 +27863,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 +27903,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 +27915,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 +27927,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 +27949,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 +27973,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 +27999,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 +28015,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 +28039,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
diff --git a/api/test-current.txt b/api/test-current.txt
index bc0b5b0..b383c22 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);
@@ -7514,7 +7515,7 @@
}
public final class AdvertisingSet {
- method public void enableAdvertising(boolean);
+ method public void enableAdvertising(boolean, int);
method public void periodicAdvertisingEnable(boolean);
method public void setAdvertisingData(android.bluetooth.le.AdvertiseData);
method public void setAdvertisingParameters(android.bluetooth.le.AdvertisingSetParameters);
@@ -7547,7 +7548,6 @@
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();
@@ -7574,14 +7574,13 @@
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 setSecondaryPhy(int);
- method public android.bluetooth.le.AdvertisingSetParameters.Builder setTimeout(int);
method public android.bluetooth.le.AdvertisingSetParameters.Builder setTxPowerLevel(int);
}
@@ -7590,6 +7589,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 +23886,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 +23897,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);
@@ -24885,6 +24890,16 @@
package android.net.wifi {
+ public final class IconInfo implements android.os.Parcelable {
+ ctor public IconInfo(java.lang.String, byte[]);
+ ctor public IconInfo(android.net.wifi.IconInfo);
+ method public int describeContents();
+ method public byte[] getData();
+ method public java.lang.String getFilename();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.IconInfo> CREATOR;
+ }
+
public class ScanResult implements android.os.Parcelable {
method public int describeContents();
method public boolean is80211mcResponder();
@@ -25084,7 +25099,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 +25128,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 +25143,21 @@
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_ICON_INFO = "android.net.wifi.extra.ICON_INFO";
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 +25376,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 +25416,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 +25428,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 +25440,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 +25462,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 +25486,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 +25512,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 +25528,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 +25552,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
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/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..c281c7f 100644
--- a/core/java/android/bluetooth/IBluetoothGatt.aidl
+++ b/core/java/android/bluetooth/IBluetoothGatt.aidl
@@ -50,20 +50,12 @@
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 enableAdverisingSet(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);
diff --git a/core/java/android/bluetooth/le/AdvertisingSet.java b/core/java/android/bluetooth/le/AdvertisingSet.java
index 1524022..5524a2b 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.enableAdverisingSet(this.advertiserId, enable, timeout);
} catch (RemoteException e) {
Log.e(TAG, "remote exception - ", e);
}
diff --git a/core/java/android/bluetooth/le/AdvertisingSetParameters.java b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
index 03a01e1..59fef8d 100644
--- a/core/java/android/bluetooth/le/AdvertisingSetParameters.java
+++ b/core/java/android/bluetooth/le/AdvertisingSetParameters.java
@@ -118,13 +118,11 @@
private final boolean connectable;
private final int interval;
private final int txPowerLevel;
- private final int timeoutMillis;
private AdvertisingSetParameters(boolean connectable, boolean isLegacy,
boolean isAnonymous, boolean includeTxPower,
int primaryPhy, int secondaryPhy,
- int interval, int txPowerLevel,
- int timeoutMillis) {
+ int interval, int txPowerLevel) {
this.connectable = connectable;
this.isLegacy = isLegacy;
this.isAnonymous = isAnonymous;
@@ -133,7 +131,6 @@
this.secondaryPhy = secondaryPhy;
this.interval = interval;
this.txPowerLevel = txPowerLevel;
- this.timeoutMillis = timeoutMillis;
}
private AdvertisingSetParameters(Parcel in) {
@@ -145,7 +142,6 @@
secondaryPhy = in.readInt();
interval = in.readInt();
txPowerLevel = in.readInt();
- timeoutMillis = in.readInt();
}
/**
@@ -188,11 +184,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 +193,7 @@
+ ", primaryPhy=" + primaryPhy
+ ", secondaryPhy=" + secondaryPhy
+ ", interval=" + interval
- + ", txPowerLevel=" + txPowerLevel
- + ", timeoutMillis=" + timeoutMillis + "]";
+ + ", txPowerLevel=" + txPowerLevel + "]";
}
@Override
@@ -221,7 +211,6 @@
dest.writeInt(secondaryPhy);
dest.writeInt(interval);
dest.writeInt(txPowerLevel);
- dest.writeInt(timeoutMillis);
}
public static final Parcelable.Creator<AdvertisingSetParameters> CREATOR =
@@ -250,7 +239,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
@@ -284,7 +272,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 +368,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,
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..67fd1c8 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,64 @@
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);
+ 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() {
+ public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int status) {
+ if (status != AdvertisingSetCallback.ADVERTISE_SUCCESS) {
+ postStartFailure(callback, status);
+ return;
+ }
+
+ postStartSuccess(callback, settings);
+ }
+
+ /* Legacy advertiser is disabled on timeout */
+ public void onAdvertisingEnabled(int advertiserId, 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 +189,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 +215,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 +236,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 +294,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 +317,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 +338,9 @@
* @hide
*/
public void cleanup() {
- mLeAdvertisers.clear();
+ mLegacyAdvertisers.clear();
+ mCallbackWrappers.clear();
+ mAdvertisingSets.clear();
}
// Compute the size of advertisement data or scan resp
@@ -317,13 +406,13 @@
public void run() {
if (status != AdvertisingSetCallback.ADVERTISE_SUCCESS) {
callback.onAdvertisingSetStarted(null, status);
- advertisingSetCallbackWrappers.remove(callback);
+ mCallbackWrappers.remove(callback);
return;
}
AdvertisingSet advertisingSet =
new AdvertisingSet(advertiserId, mBluetoothManager);
- advertisingSets.put(advertiserId, advertisingSet);
+ mAdvertisingSets.put(advertiserId, advertisingSet);
callback.onAdvertisingSetStarted(advertisingSet, status);
}
});
@@ -333,10 +422,10 @@
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);
}
});
}
@@ -345,7 +434,7 @@
handler.post(new Runnable() {
@Override
public void run() {
- AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
callback.onAdvertisingEnabled(advertisingSet, enabled, status);
}
});
@@ -355,7 +444,7 @@
handler.post(new Runnable() {
@Override
public void run() {
- AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
callback.onAdvertisingDataSet(advertisingSet, status);
}
});
@@ -365,7 +454,7 @@
handler.post(new Runnable() {
@Override
public void run() {
- AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
callback.onScanResponseDataSet(advertisingSet, status);
}
});
@@ -375,7 +464,7 @@
handler.post(new Runnable() {
@Override
public void run() {
- AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
callback.onAdvertisingParametersUpdated(advertisingSet, status);
}
});
@@ -385,7 +474,7 @@
handler.post(new Runnable() {
@Override
public void run() {
- AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
callback.onPeriodicAdvertisingParametersUpdated(advertisingSet, status);
}
});
@@ -395,7 +484,7 @@
handler.post(new Runnable() {
@Override
public void run() {
- AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
callback.onPeriodicAdvertisingDataSet(advertisingSet, status);
}
});
@@ -405,7 +494,7 @@
handler.post(new Runnable() {
@Override
public void run() {
- AdvertisingSet advertisingSet = advertisingSets.get(advertiserId);
+ AdvertisingSet advertisingSet = mAdvertisingSets.get(advertiserId);
callback.onPeriodicAdvertisingEnable(advertisingSet, enable, status);
}
});
@@ -413,144 +502,6 @@
};
}
- /**
- * 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/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/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/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/com/android/internal/os/WrapperInit.java b/core/java/com/android/internal/os/WrapperInit.java
index dbbebbe7..c329fd1 100644
--- a/core/java/com/android/internal/os/WrapperInit.java
+++ b/core/java/com/android/internal/os/WrapperInit.java
@@ -139,6 +139,21 @@
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);
}
}
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/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/symbols.xml b/core/res/res/values/symbols.xml
index dbeda0b..8f12484b 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" />
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/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/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 2e642ec..8df194c 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 android:label="@string/app_name" >
@@ -34,10 +33,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/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/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/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index f58cdba..7466f54 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -3087,8 +3087,7 @@
}
@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/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index dfd647c..a53d19c 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);
@@ -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/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/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java
index 76b1c90..c670782 100644
--- a/services/net/java/android/net/ip/IpManager.java
+++ b/services/net/java/android/net/ip/IpManager.java
@@ -16,6 +16,8 @@
package android.net.ip;
+import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH;
+
import com.android.internal.util.MessageUtils;
import com.android.internal.util.WakeupMessage;
@@ -23,6 +25,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,11 +37,14 @@
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.system.OsConstants;
import android.text.TextUtils;
import android.util.LocalLog;
import android.util.Log;
@@ -631,6 +637,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();
@@ -1018,16 +1031,39 @@
return true;
}
- private boolean startIPv6() {
- // Set privacy extensions.
+ private void enableInterfaceIPv6PrivacyExtensions() {
+ final String PREFER_TEMPADDRS = "2";
+ NetdService.run((INetd netd) -> {
+ netd.setProcSysNet(
+ INetd.IPV6, INetd.CONF, mInterfaceName, "use_tempaddr", PREFER_TEMPADDRS);
+ });
+ }
+
+ private void setInterfaceIPv6RaRtInfoMaxPlen(int plen) {
+ // Setting RIO max plen is best effort. Catch and ignore most exceptions.
try {
- mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true);
+ NetdService.run((INetd netd) -> {
+ netd.setProcSysNet(
+ INetd.IPV6, INetd.CONF, mInterfaceName, "accept_ra_rt_info_max_plen",
+ Integer.toString(plen));
+ });
+ } catch (ServiceSpecificException e) {
+ // Old kernel versions without support for RIOs do not export accept_ra_rt_info_max_plen
+ // in the /proc filesystem. If the kernel supports RIOs we should never see any other
+ // type of error.
+ if (e.errorCode != OsConstants.ENOENT) {
+ logError("unexpected error setting accept_ra_rt_info_max_plen %s", e);
+ }
+ }
+ }
+
+ private boolean startIPv6() {
+ try {
+ enableInterfaceIPv6PrivacyExtensions();
+ setInterfaceIPv6RaRtInfoMaxPlen(RFC7421_PREFIX_LENGTH);
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..bbd4018 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
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/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/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/IconInfo.aidl b/wifi/java/android/net/wifi/IconInfo.aidl
new file mode 100644
index 0000000..a7bb2ef
--- /dev/null
+++ b/wifi/java/android/net/wifi/IconInfo.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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.wifi;
+
+parcelable IconInfo;
diff --git a/wifi/java/android/net/wifi/IconInfo.java b/wifi/java/android/net/wifi/IconInfo.java
new file mode 100644
index 0000000..0eae363
--- /dev/null
+++ b/wifi/java/android/net/wifi/IconInfo.java
@@ -0,0 +1,111 @@
+/*
+ * 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.wifi;
+
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.os.Parcel;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * A class representing icon information.
+ */
+public final class IconInfo implements Parcelable {
+ /**
+ * Name of the icon file.
+ */
+ private final String mFilename;
+
+ /**
+ * Raw binary data of the icon.
+ */
+ private final byte[] mData;
+
+ public IconInfo(String filename, byte[] data) {
+ mFilename = filename;
+ mData = data;
+ }
+
+ public IconInfo(IconInfo source) {
+ if (source == null) {
+ mFilename = null;
+ mData = null;
+ return;
+ }
+
+ mFilename = source.mFilename;
+ if (source.mData != null) {
+ mData = Arrays.copyOf(source.mData, source.mData.length);
+ } else {
+ mData = null;
+ }
+ }
+
+ public String getFilename() {
+ return mFilename;
+ }
+
+ public byte[] getData() {
+ return mData;
+ }
+
+ @Override
+ public boolean equals(Object thatObject) {
+ if (this == thatObject) {
+ return true;
+ }
+ if (!(thatObject instanceof IconInfo)) {
+ return false;
+ }
+ IconInfo that = (IconInfo) thatObject;
+ return TextUtils.equals(mFilename, that.mFilename)
+ && Arrays.equals(mData, that.mData);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(mFilename, mData);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(mFilename);
+ dest.writeByteArray(mData);
+ }
+
+ public static final Creator<IconInfo> CREATOR =
+ new Creator<IconInfo>() {
+ @Override
+ public IconInfo createFromParcel(Parcel in) {
+ String filename = in.readString();
+ byte[] data = in.createByteArray();
+ return new IconInfo(filename, data);
+ }
+
+ @Override
+ public IconInfo[] newArray(int size) {
+ return new IconInfo[size];
+ }
+ };
+}
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..4f2881b 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,118 @@
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_ICON_INFO}
+ *
* 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 information.
*
- * Type: byte[]
+ * Retrieve with {@link android.content.Intent#getParcelableExtra(String)} and cast into
+ * {@link IconInfo}.
*/
- public static final String EXTRA_PASSPOINT_ICON_DATA =
- "android.net.wifi.extra.PASSPOINT_ICON_DATA";
+ public static final String EXTRA_ICON_INFO = "android.net.wifi.extra.ICON_INFO";
/**
* 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 +813,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 +828,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 +936,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 +953,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 +983,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 return value of
+ * {@link IconInfo#getData} from the intent extra will indicate the result of the request.
+ * A value of {@code null} 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/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/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/src/android/net/wifi/IconInfoTest.java b/wifi/tests/src/android/net/wifi/IconInfoTest.java
new file mode 100644
index 0000000..2fdb484
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/IconInfoTest.java
@@ -0,0 +1,122 @@
+/*
+ * 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.wifi;
+
+import static org.junit.Assert.assertEquals;
+
+import android.net.wifi.IconInfo;
+import android.os.Parcel;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.net.wifi.IconInfo}.
+ */
+@SmallTest
+public class IconInfoTest {
+ private static final String TEST_FILENAME = "testIcon";
+ private static final byte[] TEST_DATA = new byte[] {0x12, 0x23, 0x34, 0x45, 0x56, 0x67};
+
+ /**
+ * Verify parcel write and read consistency for the given {@link IconInfo}
+ *
+ * @param writeIcon the {@link IconInfo} to write and verify
+ * @throws Exception
+ */
+ private static void verifyParcel(IconInfo writeIcon) throws Exception {
+ Parcel parcel = Parcel.obtain();
+ writeIcon.writeToParcel(parcel, 0);
+
+ parcel.setDataPosition(0); // Rewind data position back to the beginning for read.
+ IconInfo readIcon = IconInfo.CREATOR.createFromParcel(parcel);
+ assertEquals(writeIcon, readIcon);
+ }
+
+ /**
+ * Verify parcel serialization for a {@link IconInfo} with null data.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void verifyParcelWithNullData() throws Exception {
+ verifyParcel(new IconInfo(TEST_FILENAME, (byte[]) null));
+ }
+
+ /**
+ * Verify parcel serialization for a {@link IconInfo} with zero length data.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void verifyParcelWithZeroLengthData() throws Exception {
+ verifyParcel(new IconInfo(TEST_FILENAME, new byte[0]));
+ }
+
+ /**
+ * Verify parcel serialization for a {@link IconInfo} with non-zero length data.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void verifyParcelWithNonZeroLengthData() throws Exception {
+ verifyParcel(new IconInfo(TEST_FILENAME, TEST_DATA));
+ }
+
+ /**
+ * Verify parcel serialization for a {@link IconInfo} with a null filename.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void verifyParcelWithNullFilename() throws Exception {
+ verifyParcel(new IconInfo(null, TEST_DATA));
+ }
+
+ /**
+ * Verify the copy constructor with non-null filename and data.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void verifyCopyConstructor() throws Exception {
+ IconInfo source = new IconInfo(TEST_FILENAME, TEST_DATA);
+ assertEquals(source, new IconInfo(source));
+ }
+
+ /**
+ * Verify the copy constructor with null data.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void verifyCopyConstructorWithNullData() throws Exception {
+ IconInfo source = new IconInfo(TEST_FILENAME, (byte[]) null);
+ assertEquals(source, new IconInfo(source));
+ }
+
+ /**
+ * Verify the copy constructor with null file name.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void verifyCopyConstructorWithNullFilename() throws Exception {
+ IconInfo source = new IconInfo(null, TEST_DATA);
+ assertEquals(source, new IconInfo(source));
+ }
+}