DO NOT MERGE - Merge RQ3A.210605.005
Bug: 190855093 Merged-In: I524644366a398b34de8f659d0d0d275f3f513c0c Change-Id: I19bfd3cbd9f65d7936d9cbcbd840c96009f3a575
This commit is contained in:
commit
e7fde0c39a
37 changed files with 17838 additions and 0 deletions
2416
core/java/android/net/ConnectivityManager.java
Normal file
2416
core/java/android/net/ConnectivityManager.java
Normal file
File diff suppressed because it is too large
Load diff
105
core/java/android/net/DhcpInfo.java
Normal file
105
core/java/android/net/DhcpInfo.java
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.os.Parcelable;
|
||||
import android.os.Parcel;
|
||||
|
||||
/**
|
||||
* A simple object for retrieving the results of a DHCP request.
|
||||
*/
|
||||
public class DhcpInfo implements Parcelable {
|
||||
public int ipAddress;
|
||||
public int gateway;
|
||||
public int netmask;
|
||||
public int dns1;
|
||||
public int dns2;
|
||||
public int serverAddress;
|
||||
|
||||
public int leaseDuration;
|
||||
|
||||
public DhcpInfo() {
|
||||
super();
|
||||
}
|
||||
|
||||
/** copy constructor {@hide} */
|
||||
public DhcpInfo(DhcpInfo source) {
|
||||
if (source != null) {
|
||||
ipAddress = source.ipAddress;
|
||||
gateway = source.gateway;
|
||||
netmask = source.netmask;
|
||||
dns1 = source.dns1;
|
||||
dns2 = source.dns2;
|
||||
serverAddress = source.serverAddress;
|
||||
leaseDuration = source.leaseDuration;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer str = new StringBuffer();
|
||||
|
||||
str.append("ipaddr "); putAddress(str, ipAddress);
|
||||
str.append(" gateway "); putAddress(str, gateway);
|
||||
str.append(" netmask "); putAddress(str, netmask);
|
||||
str.append(" dns1 "); putAddress(str, dns1);
|
||||
str.append(" dns2 "); putAddress(str, dns2);
|
||||
str.append(" DHCP server "); putAddress(str, serverAddress);
|
||||
str.append(" lease ").append(leaseDuration).append(" seconds");
|
||||
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
private static void putAddress(StringBuffer buf, int addr) {
|
||||
buf.append(NetworkUtils.intToInetAddress(addr).getHostAddress());
|
||||
}
|
||||
|
||||
/** Implement the Parcelable interface {@hide} */
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Implement the Parcelable interface {@hide} */
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(ipAddress);
|
||||
dest.writeInt(gateway);
|
||||
dest.writeInt(netmask);
|
||||
dest.writeInt(dns1);
|
||||
dest.writeInt(dns2);
|
||||
dest.writeInt(serverAddress);
|
||||
dest.writeInt(leaseDuration);
|
||||
}
|
||||
|
||||
/** Implement the Parcelable interface {@hide} */
|
||||
public static final Creator<DhcpInfo> CREATOR =
|
||||
new Creator<DhcpInfo>() {
|
||||
public DhcpInfo createFromParcel(Parcel in) {
|
||||
DhcpInfo info = new DhcpInfo();
|
||||
info.ipAddress = in.readInt();
|
||||
info.gateway = in.readInt();
|
||||
info.netmask = in.readInt();
|
||||
info.dns1 = in.readInt();
|
||||
info.dns2 = in.readInt();
|
||||
info.serverAddress = in.readInt();
|
||||
info.leaseDuration = in.readInt();
|
||||
return info;
|
||||
}
|
||||
|
||||
public DhcpInfo[] newArray(int size) {
|
||||
return new DhcpInfo[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
175
core/java/android/net/IConnectivityManager.aidl
Normal file
175
core/java/android/net/IConnectivityManager.aidl
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
/**
|
||||
* Copyright (c) 2008, The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.net.LinkQualityInfo;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.Network;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.NetworkQuotaInfo;
|
||||
import android.net.NetworkRequest;
|
||||
import android.net.NetworkState;
|
||||
import android.net.ProxyInfo;
|
||||
import android.os.IBinder;
|
||||
import android.os.Messenger;
|
||||
import android.os.ParcelFileDescriptor;
|
||||
import android.os.ResultReceiver;
|
||||
|
||||
import com.android.internal.net.LegacyVpnInfo;
|
||||
import com.android.internal.net.VpnConfig;
|
||||
import com.android.internal.net.VpnProfile;
|
||||
|
||||
/**
|
||||
* Interface that answers queries about, and allows changing, the
|
||||
* state of network connectivity.
|
||||
*/
|
||||
/** {@hide} */
|
||||
interface IConnectivityManager
|
||||
{
|
||||
// Keep this in sync with framework/native/services/connectivitymanager/ConnectivityManager.h
|
||||
void markSocketAsUser(in ParcelFileDescriptor socket, int uid);
|
||||
|
||||
NetworkInfo getActiveNetworkInfo();
|
||||
NetworkInfo getActiveNetworkInfoForUid(int uid);
|
||||
NetworkInfo getNetworkInfo(int networkType);
|
||||
NetworkInfo[] getAllNetworkInfo();
|
||||
|
||||
NetworkInfo getProvisioningOrActiveNetworkInfo();
|
||||
|
||||
boolean isNetworkSupported(int networkType);
|
||||
|
||||
LinkProperties getActiveLinkProperties();
|
||||
LinkProperties getLinkPropertiesForType(int networkType);
|
||||
LinkProperties getLinkProperties(in Network network);
|
||||
|
||||
NetworkCapabilities getNetworkCapabilities(in Network network);
|
||||
|
||||
NetworkState[] getAllNetworkState();
|
||||
|
||||
NetworkQuotaInfo getActiveNetworkQuotaInfo();
|
||||
boolean isActiveNetworkMetered();
|
||||
|
||||
int startUsingNetworkFeature(int networkType, in String feature,
|
||||
in IBinder binder);
|
||||
|
||||
int stopUsingNetworkFeature(int networkType, in String feature);
|
||||
|
||||
boolean requestRouteToHost(int networkType, int hostAddress, String packageName);
|
||||
|
||||
boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress, String packageName);
|
||||
|
||||
/** Policy control over specific {@link NetworkStateTracker}. */
|
||||
void setPolicyDataEnable(int networkType, boolean enabled);
|
||||
|
||||
int tether(String iface);
|
||||
|
||||
int untether(String iface);
|
||||
|
||||
int getLastTetherError(String iface);
|
||||
|
||||
boolean isTetheringSupported();
|
||||
|
||||
String[] getTetherableIfaces();
|
||||
|
||||
String[] getTetheredIfaces();
|
||||
|
||||
String[] getTetheringErroredIfaces();
|
||||
|
||||
String[] getTetherableUsbRegexs();
|
||||
|
||||
String[] getTetherableWifiRegexs();
|
||||
|
||||
String[] getTetherableBluetoothRegexs();
|
||||
|
||||
int setUsbTethering(boolean enable);
|
||||
|
||||
void requestNetworkTransitionWakelock(in String forWhom);
|
||||
|
||||
void reportInetCondition(int networkType, int percentage);
|
||||
|
||||
void reportBadNetwork(in Network network);
|
||||
|
||||
ProxyInfo getGlobalProxy();
|
||||
|
||||
void setGlobalProxy(in ProxyInfo p);
|
||||
|
||||
ProxyInfo getProxy();
|
||||
|
||||
void setDataDependency(int networkType, boolean met);
|
||||
|
||||
boolean protectVpn(in ParcelFileDescriptor socket);
|
||||
|
||||
boolean prepareVpn(String oldPackage, String newPackage);
|
||||
|
||||
ParcelFileDescriptor establishVpn(in VpnConfig config);
|
||||
|
||||
VpnConfig getVpnConfig();
|
||||
|
||||
void startLegacyVpn(in VpnProfile profile);
|
||||
|
||||
LegacyVpnInfo getLegacyVpnInfo();
|
||||
|
||||
boolean updateLockdownVpn();
|
||||
|
||||
void captivePortalCheckCompleted(in NetworkInfo info, boolean isCaptivePortal);
|
||||
|
||||
void supplyMessenger(int networkType, in Messenger messenger);
|
||||
|
||||
int findConnectionTypeForIface(in String iface);
|
||||
|
||||
int checkMobileProvisioning(int suggestedTimeOutMs);
|
||||
|
||||
String getMobileProvisioningUrl();
|
||||
|
||||
String getMobileRedirectedProvisioningUrl();
|
||||
|
||||
LinkQualityInfo getLinkQualityInfo(int networkType);
|
||||
|
||||
LinkQualityInfo getActiveLinkQualityInfo();
|
||||
|
||||
LinkQualityInfo[] getAllLinkQualityInfo();
|
||||
|
||||
void setProvisioningNotificationVisible(boolean visible, int networkType, in String extraInfo,
|
||||
in String url);
|
||||
|
||||
void setAirplaneMode(boolean enable);
|
||||
|
||||
void registerNetworkFactory(in Messenger messenger, in String name);
|
||||
|
||||
void unregisterNetworkFactory(in Messenger messenger);
|
||||
|
||||
void registerNetworkAgent(in Messenger messenger, in NetworkInfo ni, in LinkProperties lp,
|
||||
in NetworkCapabilities nc, int score);
|
||||
|
||||
NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities,
|
||||
in Messenger messenger, int timeoutSec, in IBinder binder, int legacy);
|
||||
|
||||
NetworkRequest pendingRequestForNetwork(in NetworkCapabilities networkCapabilities,
|
||||
in PendingIntent operation);
|
||||
|
||||
NetworkRequest listenForNetwork(in NetworkCapabilities networkCapabilities,
|
||||
in Messenger messenger, in IBinder binder);
|
||||
|
||||
void pendingListenForNetwork(in NetworkCapabilities networkCapabilities,
|
||||
in PendingIntent operation);
|
||||
|
||||
void releaseNetworkRequest(in NetworkRequest networkRequest);
|
||||
|
||||
int getRestoreDefaultNetworkDelay(int networkType);
|
||||
}
|
||||
151
core/java/android/net/IpConfiguration.java
Normal file
151
core/java/android/net/IpConfiguration.java
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.net.LinkProperties;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A class representing a configured network.
|
||||
* @hide
|
||||
*/
|
||||
public class IpConfiguration implements Parcelable {
|
||||
private static final String TAG = "IpConfiguration";
|
||||
|
||||
public enum IpAssignment {
|
||||
/* Use statically configured IP settings. Configuration can be accessed
|
||||
* with linkProperties */
|
||||
STATIC,
|
||||
/* Use dynamically configured IP settigns */
|
||||
DHCP,
|
||||
/* no IP details are assigned, this is used to indicate
|
||||
* that any existing IP settings should be retained */
|
||||
UNASSIGNED
|
||||
}
|
||||
|
||||
public IpAssignment ipAssignment;
|
||||
|
||||
public enum ProxySettings {
|
||||
/* No proxy is to be used. Any existing proxy settings
|
||||
* should be cleared. */
|
||||
NONE,
|
||||
/* Use statically configured proxy. Configuration can be accessed
|
||||
* with linkProperties */
|
||||
STATIC,
|
||||
/* no proxy details are assigned, this is used to indicate
|
||||
* that any existing proxy settings should be retained */
|
||||
UNASSIGNED,
|
||||
/* Use a Pac based proxy.
|
||||
*/
|
||||
PAC
|
||||
}
|
||||
|
||||
public ProxySettings proxySettings;
|
||||
|
||||
public LinkProperties linkProperties;
|
||||
|
||||
public IpConfiguration(IpConfiguration source) {
|
||||
if (source != null) {
|
||||
ipAssignment = source.ipAssignment;
|
||||
proxySettings = source.proxySettings;
|
||||
linkProperties = new LinkProperties(source.linkProperties);
|
||||
} else {
|
||||
ipAssignment = IpAssignment.UNASSIGNED;
|
||||
proxySettings = ProxySettings.UNASSIGNED;
|
||||
linkProperties = new LinkProperties();
|
||||
}
|
||||
}
|
||||
|
||||
public IpConfiguration() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public IpConfiguration(IpAssignment ipAssignment,
|
||||
ProxySettings proxySettings,
|
||||
LinkProperties linkProperties) {
|
||||
this.ipAssignment = ipAssignment;
|
||||
this.proxySettings = proxySettings;
|
||||
this.linkProperties = new LinkProperties(linkProperties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sbuf = new StringBuilder();
|
||||
sbuf.append("IP assignment: " + ipAssignment.toString());
|
||||
sbuf.append("\n");
|
||||
sbuf.append("Proxy settings: " + proxySettings.toString());
|
||||
sbuf.append("\n");
|
||||
sbuf.append(linkProperties.toString());
|
||||
sbuf.append("\n");
|
||||
|
||||
return sbuf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(o instanceof IpConfiguration)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
IpConfiguration other = (IpConfiguration) o;
|
||||
return this.ipAssignment == other.ipAssignment &&
|
||||
this.proxySettings == other.proxySettings &&
|
||||
Objects.equals(this.linkProperties, other.linkProperties);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 13 + (linkProperties != null ? linkProperties.hashCode() : 0) +
|
||||
17 * ipAssignment.ordinal() +
|
||||
47 * proxySettings.ordinal();
|
||||
}
|
||||
|
||||
/** Implement the Parcelable interface */
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Implement the Parcelable interface */
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(ipAssignment.name());
|
||||
dest.writeString(proxySettings.name());
|
||||
dest.writeParcelable(linkProperties, flags);
|
||||
}
|
||||
|
||||
/** Implement the Parcelable interface */
|
||||
public static final Creator<IpConfiguration> CREATOR =
|
||||
new Creator<IpConfiguration>() {
|
||||
public IpConfiguration createFromParcel(Parcel in) {
|
||||
IpConfiguration config = new IpConfiguration();
|
||||
config.ipAssignment = IpAssignment.valueOf(in.readString());
|
||||
config.proxySettings = ProxySettings.valueOf(in.readString());
|
||||
config.linkProperties = in.readParcelable(null);
|
||||
return config;
|
||||
}
|
||||
|
||||
public IpConfiguration[] newArray(int size) {
|
||||
return new IpConfiguration[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
173
core/java/android/net/IpPrefix.java
Normal file
173
core/java/android/net/IpPrefix.java
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* This class represents an IP prefix, i.e., a contiguous block of IP addresses aligned on a
|
||||
* power of two boundary (also known as an "IP subnet"). A prefix is specified by two pieces of
|
||||
* information:
|
||||
*
|
||||
* <ul>
|
||||
* <li>A starting IP address (IPv4 or IPv6). This is the first IP address of the prefix.
|
||||
* <li>A prefix length. This specifies the length of the prefix by specifing the number of bits
|
||||
* in the IP address, starting from the most significant bit in network byte order, that
|
||||
* are constant for all addresses in the prefix.
|
||||
* </ul>
|
||||
*
|
||||
* For example, the prefix <code>192.0.2.0/24</code> covers the 256 IPv4 addresses from
|
||||
* <code>192.0.2.0</code> to <code>192.0.2.255</code>, inclusive, and the prefix
|
||||
* <code>2001:db8:1:2</code> covers the 2^64 IPv6 addresses from <code>2001:db8:1:2::</code> to
|
||||
* <code>2001:db8:1:2:ffff:ffff:ffff:ffff</code>, inclusive.
|
||||
*
|
||||
* Objects of this class are immutable.
|
||||
*/
|
||||
public class IpPrefix implements Parcelable {
|
||||
private final byte[] address; // network byte order
|
||||
private final int prefixLength;
|
||||
|
||||
/**
|
||||
* Constructs a new {@code IpPrefix} from a byte array containing an IPv4 or IPv6 address in
|
||||
* network byte order and a prefix length.
|
||||
*
|
||||
* @param address the IP address. Must be non-null and exactly 4 or 16 bytes long.
|
||||
* @param prefixLength the prefix length. Must be >= 0 and <= (32 or 128) (IPv4 or IPv6).
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public IpPrefix(byte[] address, int prefixLength) {
|
||||
if (address.length != 4 && address.length != 16) {
|
||||
throw new IllegalArgumentException(
|
||||
"IpPrefix has " + address.length + " bytes which is neither 4 nor 16");
|
||||
}
|
||||
if (prefixLength < 0 || prefixLength > (address.length * 8)) {
|
||||
throw new IllegalArgumentException("IpPrefix with " + address.length +
|
||||
" bytes has invalid prefix length " + prefixLength);
|
||||
}
|
||||
this.address = address.clone();
|
||||
this.prefixLength = prefixLength;
|
||||
// TODO: Validate that the non-prefix bits are zero
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public IpPrefix(InetAddress address, int prefixLength) {
|
||||
this(address.getAddress(), prefixLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this {@code IpPrefix} object against the specified object in {@code obj}. Two
|
||||
* objects are equal if they have the same startAddress and prefixLength.
|
||||
*
|
||||
* @param obj the object to be tested for equality.
|
||||
* @return {@code true} if both objects are equal, {@code false} otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof IpPrefix)) {
|
||||
return false;
|
||||
}
|
||||
IpPrefix that = (IpPrefix) obj;
|
||||
return Arrays.equals(this.address, that.address) && this.prefixLength == that.prefixLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the hashcode of the represented IP prefix.
|
||||
*
|
||||
* @return the appropriate hashcode value.
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(address) + 11 * prefixLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the first IP address in the prefix. Modifying the returned object does not
|
||||
* change this object's contents.
|
||||
*
|
||||
* @return the address in the form of a byte array.
|
||||
*/
|
||||
public InetAddress getAddress() {
|
||||
try {
|
||||
return InetAddress.getByAddress(address);
|
||||
} catch (UnknownHostException e) {
|
||||
// Cannot happen. InetAddress.getByAddress can only throw an exception if the byte
|
||||
// array is the wrong length, but we check that in the constructor.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the IP address bytes in network order (the highest order byte is the zeroth
|
||||
* element). Modifying the returned array does not change this object's contents.
|
||||
*
|
||||
* @return the address in the form of a byte array.
|
||||
*/
|
||||
public byte[] getRawAddress() {
|
||||
return address.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the prefix length of this {@code IpAddress}.
|
||||
*
|
||||
* @return the prefix length.
|
||||
*/
|
||||
public int getPrefixLength() {
|
||||
return prefixLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the Parcelable interface.
|
||||
* @hide
|
||||
*/
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the Parcelable interface.
|
||||
* @hide
|
||||
*/
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeByteArray(address);
|
||||
dest.writeInt(prefixLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the Parcelable interface.
|
||||
* @hide
|
||||
*/
|
||||
public static final Creator<IpPrefix> CREATOR =
|
||||
new Creator<IpPrefix>() {
|
||||
public IpPrefix createFromParcel(Parcel in) {
|
||||
byte[] address = in.createByteArray();
|
||||
int prefixLength = in.readInt();
|
||||
return new IpPrefix(address, prefixLength);
|
||||
}
|
||||
|
||||
public IpPrefix[] newArray(int size) {
|
||||
return new IpPrefix[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
332
core/java/android/net/LinkAddress.java
Normal file
332
core/java/android/net/LinkAddress.java
Normal file
|
|
@ -0,0 +1,332 @@
|
|||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.net.Inet4Address;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InterfaceAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import static android.system.OsConstants.IFA_F_DADFAILED;
|
||||
import static android.system.OsConstants.IFA_F_DEPRECATED;
|
||||
import static android.system.OsConstants.IFA_F_TENTATIVE;
|
||||
import static android.system.OsConstants.RT_SCOPE_HOST;
|
||||
import static android.system.OsConstants.RT_SCOPE_LINK;
|
||||
import static android.system.OsConstants.RT_SCOPE_SITE;
|
||||
import static android.system.OsConstants.RT_SCOPE_UNIVERSE;
|
||||
|
||||
/**
|
||||
* Identifies an IP address on a network link.
|
||||
*
|
||||
* A {@code LinkAddress} consists of:
|
||||
* <ul>
|
||||
* <li>An IP address and prefix length (e.g., {@code 2001:db8::1/64} or {@code 192.0.2.1/24}).
|
||||
* The address must be unicast, as multicast addresses cannot be assigned to interfaces.
|
||||
* <li>Address flags: A bitmask of {@code OsConstants.IFA_F_*} values representing properties
|
||||
* of the address (e.g., {@code android.system.OsConstants.IFA_F_OPTIMISTIC}).
|
||||
* <li>Address scope: One of the {@code OsConstants.IFA_F_*} values; defines the scope in which
|
||||
* the address is unique (e.g.,
|
||||
* {@code android.system.OsConstants.RT_SCOPE_LINK} or
|
||||
* {@code android.system.OsConstants.RT_SCOPE_UNIVERSE}).
|
||||
* </ul>
|
||||
*/
|
||||
public class LinkAddress implements Parcelable {
|
||||
/**
|
||||
* IPv4 or IPv6 address.
|
||||
*/
|
||||
private InetAddress address;
|
||||
|
||||
/**
|
||||
* Prefix length.
|
||||
*/
|
||||
private int prefixLength;
|
||||
|
||||
/**
|
||||
* Address flags. A bitmask of IFA_F_* values.
|
||||
*/
|
||||
private int flags;
|
||||
|
||||
/**
|
||||
* Address scope. One of the RT_SCOPE_* constants.
|
||||
*/
|
||||
private int scope;
|
||||
|
||||
/**
|
||||
* Utility function to determines the scope of a unicast address. Per RFC 4291 section 2.5 and
|
||||
* RFC 6724 section 3.2.
|
||||
* @hide
|
||||
*/
|
||||
static int scopeForUnicastAddress(InetAddress addr) {
|
||||
if (addr.isAnyLocalAddress()) {
|
||||
return RT_SCOPE_HOST;
|
||||
}
|
||||
|
||||
if (addr.isLoopbackAddress() || addr.isLinkLocalAddress()) {
|
||||
return RT_SCOPE_LINK;
|
||||
}
|
||||
|
||||
// isSiteLocalAddress() returns true for private IPv4 addresses, but RFC 6724 section 3.2
|
||||
// says that they are assigned global scope.
|
||||
if (!(addr instanceof Inet4Address) && addr.isSiteLocalAddress()) {
|
||||
return RT_SCOPE_SITE;
|
||||
}
|
||||
|
||||
return RT_SCOPE_UNIVERSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility function for the constructors.
|
||||
*/
|
||||
private void init(InetAddress address, int prefixLength, int flags, int scope) {
|
||||
if (address == null ||
|
||||
address.isMulticastAddress() ||
|
||||
prefixLength < 0 ||
|
||||
((address instanceof Inet4Address) && prefixLength > 32) ||
|
||||
(prefixLength > 128)) {
|
||||
throw new IllegalArgumentException("Bad LinkAddress params " + address +
|
||||
"/" + prefixLength);
|
||||
}
|
||||
this.address = address;
|
||||
this.prefixLength = prefixLength;
|
||||
this.flags = flags;
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code LinkAddress} from an {@code InetAddress} and prefix length, with
|
||||
* the specified flags and scope. Flags and scope are not checked for validity.
|
||||
* @param address The IP address.
|
||||
* @param prefixLength The prefix length.
|
||||
* @param flags A bitmask of {@code IFA_F_*} values representing properties of the address.
|
||||
* @param scope An integer defining the scope in which the address is unique (e.g.,
|
||||
* {@link OsConstants#RT_SCOPE_LINK} or {@link OsConstants#RT_SCOPE_SITE}).
|
||||
* @hide
|
||||
*/
|
||||
public LinkAddress(InetAddress address, int prefixLength, int flags, int scope) {
|
||||
init(address, prefixLength, flags, scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code LinkAddress} from an {@code InetAddress} and a prefix length.
|
||||
* The flags are set to zero and the scope is determined from the address.
|
||||
* @param address The IP address.
|
||||
* @param prefixLength The prefix length.
|
||||
* @hide
|
||||
*/
|
||||
public LinkAddress(InetAddress address, int prefixLength) {
|
||||
this(address, prefixLength, 0, 0);
|
||||
this.scope = scopeForUnicastAddress(address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code LinkAddress} from an {@code InterfaceAddress}.
|
||||
* The flags are set to zero and the scope is determined from the address.
|
||||
* @param interfaceAddress The interface address.
|
||||
* @hide
|
||||
*/
|
||||
public LinkAddress(InterfaceAddress interfaceAddress) {
|
||||
this(interfaceAddress.getAddress(),
|
||||
interfaceAddress.getNetworkPrefixLength());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code LinkAddress} from a string such as "192.0.2.5/24" or
|
||||
* "2001:db8::1/64". The flags are set to zero and the scope is determined from the address.
|
||||
* @param string The string to parse.
|
||||
* @hide
|
||||
*/
|
||||
public LinkAddress(String address) {
|
||||
this(address, 0, 0);
|
||||
this.scope = scopeForUnicastAddress(this.address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code LinkAddress} from a string such as "192.0.2.5/24" or
|
||||
* "2001:db8::1/64", with the specified flags and scope.
|
||||
* @param string The string to parse.
|
||||
* @param flags The address flags.
|
||||
* @param scope The address scope.
|
||||
* @hide
|
||||
*/
|
||||
public LinkAddress(String address, int flags, int scope) {
|
||||
InetAddress inetAddress = null;
|
||||
int prefixLength = -1;
|
||||
try {
|
||||
String [] pieces = address.split("/", 2);
|
||||
prefixLength = Integer.parseInt(pieces[1]);
|
||||
inetAddress = InetAddress.parseNumericAddress(pieces[0]);
|
||||
} catch (NullPointerException e) { // Null string.
|
||||
} catch (ArrayIndexOutOfBoundsException e) { // No prefix length.
|
||||
} catch (NumberFormatException e) { // Non-numeric prefix.
|
||||
} catch (IllegalArgumentException e) { // Invalid IP address.
|
||||
}
|
||||
|
||||
if (inetAddress == null || prefixLength == -1) {
|
||||
throw new IllegalArgumentException("Bad LinkAddress params " + address);
|
||||
}
|
||||
|
||||
init(inetAddress, prefixLength, flags, scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representation of this address, such as "192.0.2.1/24" or "2001:db8::1/64".
|
||||
* The string representation does not contain the flags and scope, just the address and prefix
|
||||
* length.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return address.getHostAddress() + "/" + prefixLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this {@code LinkAddress} instance against {@code obj}. Two addresses are equal if
|
||||
* their address, prefix length, flags and scope are equal. Thus, for example, two addresses
|
||||
* that have the same address and prefix length are not equal if one of them is deprecated and
|
||||
* the other is not.
|
||||
*
|
||||
* @param obj the object to be tested for equality.
|
||||
* @return {@code true} if both objects are equal, {@code false} otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (!(obj instanceof LinkAddress)) {
|
||||
return false;
|
||||
}
|
||||
LinkAddress linkAddress = (LinkAddress) obj;
|
||||
return this.address.equals(linkAddress.address) &&
|
||||
this.prefixLength == linkAddress.prefixLength &&
|
||||
this.flags == linkAddress.flags &&
|
||||
this.scope == linkAddress.scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashcode for this address.
|
||||
*/
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return address.hashCode() + 11 * prefixLength + 19 * flags + 43 * scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether this {@code LinkAddress} and the provided {@code LinkAddress}
|
||||
* represent the same address. Two {@code LinkAddresses} represent the same address
|
||||
* if they have the same IP address and prefix length, even if their properties are
|
||||
* different.
|
||||
*
|
||||
* @param other the {@code LinkAddress} to compare to.
|
||||
* @return {@code true} if both objects have the same address and prefix length, {@code false}
|
||||
* otherwise.
|
||||
* @hide
|
||||
*/
|
||||
public boolean isSameAddressAs(LinkAddress other) {
|
||||
return address.equals(other.address) && prefixLength == other.prefixLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link InetAddress} of this {@code LinkAddress}.
|
||||
*/
|
||||
public InetAddress getAddress() {
|
||||
return address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the prefix length of this {@code LinkAddress}.
|
||||
*/
|
||||
public int getPrefixLength() {
|
||||
return prefixLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the prefix length of this {@code LinkAddress}.
|
||||
* TODO: Delete all callers and remove in favour of getPrefixLength().
|
||||
* @hide
|
||||
*/
|
||||
public int getNetworkPrefixLength() {
|
||||
return getPrefixLength();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the flags of this {@code LinkAddress}.
|
||||
*/
|
||||
public int getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scope of this {@code LinkAddress}.
|
||||
*/
|
||||
public int getScope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this {@code LinkAddress} is global scope and preferred.
|
||||
* @hide
|
||||
*/
|
||||
public boolean isGlobalPreferred() {
|
||||
return (scope == RT_SCOPE_UNIVERSE &&
|
||||
(flags & (IFA_F_DADFAILED | IFA_F_DEPRECATED | IFA_F_TENTATIVE)) == 0L);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the Parcelable interface.
|
||||
* @hide
|
||||
*/
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the Parcelable interface.
|
||||
* @hide
|
||||
*/
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeByteArray(address.getAddress());
|
||||
dest.writeInt(prefixLength);
|
||||
dest.writeInt(this.flags);
|
||||
dest.writeInt(scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the Parcelable interface.
|
||||
* @hide
|
||||
*/
|
||||
public static final Creator<LinkAddress> CREATOR =
|
||||
new Creator<LinkAddress>() {
|
||||
public LinkAddress createFromParcel(Parcel in) {
|
||||
InetAddress address = null;
|
||||
try {
|
||||
address = InetAddress.getByAddress(in.createByteArray());
|
||||
} catch (UnknownHostException e) {
|
||||
// Nothing we can do here. When we call the constructor, we'll throw an
|
||||
// IllegalArgumentException, because a LinkAddress can't have a null
|
||||
// InetAddress.
|
||||
}
|
||||
int prefixLength = in.readInt();
|
||||
int flags = in.readInt();
|
||||
int scope = in.readInt();
|
||||
return new LinkAddress(address, prefixLength, flags, scope);
|
||||
}
|
||||
|
||||
public LinkAddress[] newArray(int size) {
|
||||
return new LinkAddress[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
880
core/java/android/net/LinkProperties.java
Normal file
880
core/java/android/net/LinkProperties.java
Normal file
|
|
@ -0,0 +1,880 @@
|
|||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.net.ProxyInfo;
|
||||
import android.os.Parcelable;
|
||||
import android.os.Parcel;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Hashtable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Describes the properties of a network link.
|
||||
*
|
||||
* A link represents a connection to a network.
|
||||
* It may have multiple addresses and multiple gateways,
|
||||
* multiple dns servers but only one http proxy and one
|
||||
* network interface.
|
||||
*
|
||||
* Note that this is just a holder of data. Modifying it
|
||||
* does not affect live networks.
|
||||
*
|
||||
*/
|
||||
public class LinkProperties implements Parcelable {
|
||||
// The interface described by the network link.
|
||||
private String mIfaceName;
|
||||
private ArrayList<LinkAddress> mLinkAddresses = new ArrayList<LinkAddress>();
|
||||
private ArrayList<InetAddress> mDnses = new ArrayList<InetAddress>();
|
||||
private String mDomains;
|
||||
private ArrayList<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
|
||||
private ProxyInfo mHttpProxy;
|
||||
private int mMtu;
|
||||
|
||||
// Stores the properties of links that are "stacked" above this link.
|
||||
// Indexed by interface name to allow modification and to prevent duplicates being added.
|
||||
private Hashtable<String, LinkProperties> mStackedLinks =
|
||||
new Hashtable<String, LinkProperties>();
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static class CompareResult<T> {
|
||||
public List<T> removed = new ArrayList<T>();
|
||||
public List<T> added = new ArrayList<T>();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String retVal = "removed=[";
|
||||
for (T addr : removed) retVal += addr.toString() + ",";
|
||||
retVal += "] added=[";
|
||||
for (T addr : added) retVal += addr.toString() + ",";
|
||||
retVal += "]";
|
||||
return retVal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public LinkProperties() {
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public LinkProperties(LinkProperties source) {
|
||||
if (source != null) {
|
||||
mIfaceName = source.getInterfaceName();
|
||||
for (LinkAddress l : source.getLinkAddresses()) mLinkAddresses.add(l);
|
||||
for (InetAddress i : source.getDnsServers()) mDnses.add(i);
|
||||
mDomains = source.getDomains();
|
||||
for (RouteInfo r : source.getRoutes()) mRoutes.add(r);
|
||||
mHttpProxy = (source.getHttpProxy() == null) ?
|
||||
null : new ProxyInfo(source.getHttpProxy());
|
||||
for (LinkProperties l: source.mStackedLinks.values()) {
|
||||
addStackedLink(l);
|
||||
}
|
||||
setMtu(source.getMtu());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the interface name for this link. All {@link RouteInfo} already set for this
|
||||
* will have their interface changed to match this new value.
|
||||
*
|
||||
* @param iface The name of the network interface used for this link.
|
||||
* @hide
|
||||
*/
|
||||
public void setInterfaceName(String iface) {
|
||||
mIfaceName = iface;
|
||||
ArrayList<RouteInfo> newRoutes = new ArrayList<RouteInfo>(mRoutes.size());
|
||||
for (RouteInfo route : mRoutes) {
|
||||
newRoutes.add(routeWithInterface(route));
|
||||
}
|
||||
mRoutes = newRoutes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the interface name for this link. May be {@code null} if not set.
|
||||
*
|
||||
* @return The interface name set for this link or {@code null}.
|
||||
*/
|
||||
public String getInterfaceName() {
|
||||
return mIfaceName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public List<String> getAllInterfaceNames() {
|
||||
List<String> interfaceNames = new ArrayList<String>(mStackedLinks.size() + 1);
|
||||
if (mIfaceName != null) interfaceNames.add(new String(mIfaceName));
|
||||
for (LinkProperties stacked: mStackedLinks.values()) {
|
||||
interfaceNames.addAll(stacked.getAllInterfaceNames());
|
||||
}
|
||||
return interfaceNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the addresses on this link. We often think of a link having a single address,
|
||||
* however, particularly with Ipv6 several addresses are typical. Note that the
|
||||
* {@code LinkProperties} actually contains {@link LinkAddress} objects which also include
|
||||
* prefix lengths for each address. This is a simplified utility alternative to
|
||||
* {@link LinkProperties#getLinkAddresses}.
|
||||
*
|
||||
* @return An umodifiable {@link List} of {@link InetAddress} for this link.
|
||||
* @hide
|
||||
*/
|
||||
public List<InetAddress> getAddresses() {
|
||||
List<InetAddress> addresses = new ArrayList<InetAddress>();
|
||||
for (LinkAddress linkAddress : mLinkAddresses) {
|
||||
addresses.add(linkAddress.getAddress());
|
||||
}
|
||||
return Collections.unmodifiableList(addresses);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the addresses on this link and all the links stacked above it.
|
||||
* @hide
|
||||
*/
|
||||
public List<InetAddress> getAllAddresses() {
|
||||
List<InetAddress> addresses = new ArrayList<InetAddress>();
|
||||
for (LinkAddress linkAddress : mLinkAddresses) {
|
||||
addresses.add(linkAddress.getAddress());
|
||||
}
|
||||
for (LinkProperties stacked: mStackedLinks.values()) {
|
||||
addresses.addAll(stacked.getAllAddresses());
|
||||
}
|
||||
return addresses;
|
||||
}
|
||||
|
||||
private int findLinkAddressIndex(LinkAddress address) {
|
||||
for (int i = 0; i < mLinkAddresses.size(); i++) {
|
||||
if (mLinkAddresses.get(i).isSameAddressAs(address)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a {@link LinkAddress} to this {@code LinkProperties} if a {@link LinkAddress} of the
|
||||
* same address/prefix does not already exist. If it does exist it is replaced.
|
||||
* @param address The {@code LinkAddress} to add.
|
||||
* @return true if {@code address} was added or updated, false otherwise.
|
||||
* @hide
|
||||
*/
|
||||
public boolean addLinkAddress(LinkAddress address) {
|
||||
if (address == null) {
|
||||
return false;
|
||||
}
|
||||
int i = findLinkAddressIndex(address);
|
||||
if (i < 0) {
|
||||
// Address was not present. Add it.
|
||||
mLinkAddresses.add(address);
|
||||
return true;
|
||||
} else if (mLinkAddresses.get(i).equals(address)) {
|
||||
// Address was present and has same properties. Do nothing.
|
||||
return false;
|
||||
} else {
|
||||
// Address was present and has different properties. Update it.
|
||||
mLinkAddresses.set(i, address);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a {@link LinkAddress} from this {@code LinkProperties}. Specifically, matches
|
||||
* and {@link LinkAddress} with the same address and prefix.
|
||||
*
|
||||
* @param toRemove A {@link LinkAddress} specifying the address to remove.
|
||||
* @return true if the address was removed, false if it did not exist.
|
||||
* @hide
|
||||
*/
|
||||
public boolean removeLinkAddress(LinkAddress toRemove) {
|
||||
int i = findLinkAddressIndex(toRemove);
|
||||
if (i >= 0) {
|
||||
mLinkAddresses.remove(i);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the {@link LinkAddress} on this link. Typically a link will have
|
||||
* one IPv4 address and one or more IPv6 addresses.
|
||||
*
|
||||
* @return An unmodifiable {@link List} of {@link LinkAddress} for this link.
|
||||
*/
|
||||
public List<LinkAddress> getLinkAddresses() {
|
||||
return Collections.unmodifiableList(mLinkAddresses);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the addresses on this link and all the links stacked above it.
|
||||
* @hide
|
||||
*/
|
||||
public List<LinkAddress> getAllLinkAddresses() {
|
||||
List<LinkAddress> addresses = new ArrayList<LinkAddress>();
|
||||
addresses.addAll(mLinkAddresses);
|
||||
for (LinkProperties stacked: mStackedLinks.values()) {
|
||||
addresses.addAll(stacked.getAllLinkAddresses());
|
||||
}
|
||||
return addresses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the {@link LinkAddress} in this {@code LinkProperties} with
|
||||
* the given {@link Collection} of {@link LinkAddress}.
|
||||
*
|
||||
* @param addresses The {@link Collection} of {@link LinkAddress} to set in this
|
||||
* object.
|
||||
* @hide
|
||||
*/
|
||||
public void setLinkAddresses(Collection<LinkAddress> addresses) {
|
||||
mLinkAddresses.clear();
|
||||
for (LinkAddress address: addresses) {
|
||||
addLinkAddress(address);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given {@link InetAddress} to the list of DNS servers.
|
||||
*
|
||||
* @param dnsServer The {@link InetAddress} to add to the list of DNS servers.
|
||||
* @hide
|
||||
*/
|
||||
public void addDnsServer(InetAddress dnsServer) {
|
||||
if (dnsServer != null) mDnses.add(dnsServer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the {@link InetAddress} for DNS servers on this link.
|
||||
*
|
||||
* @return An umodifiable {@link List} of {@link InetAddress} for DNS servers on
|
||||
* this link.
|
||||
*/
|
||||
public List<InetAddress> getDnsServers() {
|
||||
return Collections.unmodifiableList(mDnses);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the DNS domain search path used on this link.
|
||||
*
|
||||
* @param domains A {@link String} listing in priority order the comma separated
|
||||
* domains to search when resolving host names on this link.
|
||||
* @hide
|
||||
*/
|
||||
public void setDomains(String domains) {
|
||||
mDomains = domains;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DNS domains search path set for this link.
|
||||
*
|
||||
* @return A {@link String} containing the comma separated domains to search when resolving
|
||||
* host names on this link.
|
||||
*/
|
||||
public String getDomains() {
|
||||
return mDomains;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Maximum Transmission Unit size to use on this link. This should not be used
|
||||
* unless the system default (1500) is incorrect. Values less than 68 or greater than
|
||||
* 10000 will be ignored.
|
||||
*
|
||||
* @param mtu The MTU to use for this link.
|
||||
* @hide
|
||||
*/
|
||||
public void setMtu(int mtu) {
|
||||
mMtu = mtu;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets any non-default MTU size set for this link. Note that if the default is being used
|
||||
* this will return 0.
|
||||
*
|
||||
* @return The mtu value set for this link.
|
||||
* @hide
|
||||
*/
|
||||
public int getMtu() {
|
||||
return mMtu;
|
||||
}
|
||||
|
||||
private RouteInfo routeWithInterface(RouteInfo route) {
|
||||
return new RouteInfo(
|
||||
route.getDestination(),
|
||||
route.getGateway(),
|
||||
mIfaceName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a {@link RouteInfo} to this {@code LinkProperties}. If the {@link RouteInfo}
|
||||
* had an interface name set and that differs from the interface set for this
|
||||
* {@code LinkProperties} an {@link IllegalArgumentException} will be thrown. The
|
||||
* proper course is to add either un-named or properly named {@link RouteInfo}.
|
||||
*
|
||||
* @param route A {@link RouteInfo} to add to this object.
|
||||
* @hide
|
||||
*/
|
||||
public void addRoute(RouteInfo route) {
|
||||
if (route != null) {
|
||||
String routeIface = route.getInterface();
|
||||
if (routeIface != null && !routeIface.equals(mIfaceName)) {
|
||||
throw new IllegalArgumentException(
|
||||
"Route added with non-matching interface: " + routeIface +
|
||||
" vs. " + mIfaceName);
|
||||
}
|
||||
mRoutes.add(routeWithInterface(route));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the {@link RouteInfo} set on this link.
|
||||
*
|
||||
* @return An unmodifiable {@link List} of {@link RouteInfo} for this link.
|
||||
*/
|
||||
public List<RouteInfo> getRoutes() {
|
||||
return Collections.unmodifiableList(mRoutes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the routes on this link and all the links stacked above it.
|
||||
* @hide
|
||||
*/
|
||||
public List<RouteInfo> getAllRoutes() {
|
||||
List<RouteInfo> routes = new ArrayList();
|
||||
routes.addAll(mRoutes);
|
||||
for (LinkProperties stacked: mStackedLinks.values()) {
|
||||
routes.addAll(stacked.getAllRoutes());
|
||||
}
|
||||
return routes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the recommended {@link ProxyInfo} to use on this link, or {@code null} for none.
|
||||
* Note that Http Proxies are only a hint - the system recommends their use, but it does
|
||||
* not enforce it and applications may ignore them.
|
||||
*
|
||||
* @param proxy A {@link ProxyInfo} defining the Http Proxy to use on this link.
|
||||
* @hide
|
||||
*/
|
||||
public void setHttpProxy(ProxyInfo proxy) {
|
||||
mHttpProxy = proxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the recommended {@link ProxyInfo} (or {@code null}) set on this link.
|
||||
*
|
||||
* @return The {@link ProxyInfo} set on this link
|
||||
*/
|
||||
public ProxyInfo getHttpProxy() {
|
||||
return mHttpProxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a stacked link.
|
||||
*
|
||||
* If there is already a stacked link with the same interfacename as link,
|
||||
* that link is replaced with link. Otherwise, link is added to the list
|
||||
* of stacked links. If link is null, nothing changes.
|
||||
*
|
||||
* @param link The link to add.
|
||||
* @return true if the link was stacked, false otherwise.
|
||||
* @hide
|
||||
*/
|
||||
public boolean addStackedLink(LinkProperties link) {
|
||||
if (link != null && link.getInterfaceName() != null) {
|
||||
mStackedLinks.put(link.getInterfaceName(), link);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a stacked link.
|
||||
*
|
||||
* If there a stacked link with the same interfacename as link, it is
|
||||
* removed. Otherwise, nothing changes.
|
||||
*
|
||||
* @param link The link to remove.
|
||||
* @return true if the link was removed, false otherwise.
|
||||
* @hide
|
||||
*/
|
||||
public boolean removeStackedLink(LinkProperties link) {
|
||||
if (link != null && link.getInterfaceName() != null) {
|
||||
LinkProperties removed = mStackedLinks.remove(link.getInterfaceName());
|
||||
return removed != null;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the links stacked on top of this link.
|
||||
* @hide
|
||||
*/
|
||||
public List<LinkProperties> getStackedLinks() {
|
||||
List<LinkProperties> stacked = new ArrayList<LinkProperties>();
|
||||
for (LinkProperties link : mStackedLinks.values()) {
|
||||
stacked.add(new LinkProperties(link));
|
||||
}
|
||||
return Collections.unmodifiableList(stacked);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears this object to its initial state.
|
||||
* @hide
|
||||
*/
|
||||
public void clear() {
|
||||
mIfaceName = null;
|
||||
mLinkAddresses.clear();
|
||||
mDnses.clear();
|
||||
mDomains = null;
|
||||
mRoutes.clear();
|
||||
mHttpProxy = null;
|
||||
mStackedLinks.clear();
|
||||
mMtu = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the Parcelable interface
|
||||
* @hide
|
||||
*/
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String ifaceName = (mIfaceName == null ? "" : "InterfaceName: " + mIfaceName + " ");
|
||||
|
||||
String linkAddresses = "LinkAddresses: [";
|
||||
for (LinkAddress addr : mLinkAddresses) linkAddresses += addr.toString() + ",";
|
||||
linkAddresses += "] ";
|
||||
|
||||
String dns = "DnsAddresses: [";
|
||||
for (InetAddress addr : mDnses) dns += addr.getHostAddress() + ",";
|
||||
dns += "] ";
|
||||
|
||||
String domainName = "Domains: " + mDomains;
|
||||
|
||||
String mtu = " MTU: " + mMtu;
|
||||
|
||||
String routes = " Routes: [";
|
||||
for (RouteInfo route : mRoutes) routes += route.toString() + ",";
|
||||
routes += "] ";
|
||||
String proxy = (mHttpProxy == null ? "" : " HttpProxy: " + mHttpProxy.toString() + " ");
|
||||
|
||||
String stacked = "";
|
||||
if (mStackedLinks.values().size() > 0) {
|
||||
stacked += " Stacked: [";
|
||||
for (LinkProperties link: mStackedLinks.values()) {
|
||||
stacked += " [" + link.toString() + " ],";
|
||||
}
|
||||
stacked += "] ";
|
||||
}
|
||||
return "{" + ifaceName + linkAddresses + routes + dns + domainName + mtu
|
||||
+ proxy + stacked + "}";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this link has an IPv4 address.
|
||||
*
|
||||
* @return {@code true} if there is an IPv4 address, {@code false} otherwise.
|
||||
* @hide
|
||||
*/
|
||||
public boolean hasIPv4Address() {
|
||||
for (LinkAddress address : mLinkAddresses) {
|
||||
if (address.getAddress() instanceof Inet4Address) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this link has an IPv6 address.
|
||||
*
|
||||
* @return {@code true} if there is an IPv6 address, {@code false} otherwise.
|
||||
* @hide
|
||||
*/
|
||||
public boolean hasIPv6Address() {
|
||||
for (LinkAddress address : mLinkAddresses) {
|
||||
if (address.getAddress() instanceof Inet6Address) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this {@code LinkProperties} interface name against the target
|
||||
*
|
||||
* @param target LinkProperties to compare.
|
||||
* @return {@code true} if both are identical, {@code false} otherwise.
|
||||
* @hide
|
||||
*/
|
||||
public boolean isIdenticalInterfaceName(LinkProperties target) {
|
||||
return TextUtils.equals(getInterfaceName(), target.getInterfaceName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this {@code LinkProperties} interface addresses against the target
|
||||
*
|
||||
* @param target LinkProperties to compare.
|
||||
* @return {@code true} if both are identical, {@code false} otherwise.
|
||||
* @hide
|
||||
*/
|
||||
public boolean isIdenticalAddresses(LinkProperties target) {
|
||||
Collection<InetAddress> targetAddresses = target.getAddresses();
|
||||
Collection<InetAddress> sourceAddresses = getAddresses();
|
||||
return (sourceAddresses.size() == targetAddresses.size()) ?
|
||||
sourceAddresses.containsAll(targetAddresses) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this {@code LinkProperties} DNS addresses against the target
|
||||
*
|
||||
* @param target LinkProperties to compare.
|
||||
* @return {@code true} if both are identical, {@code false} otherwise.
|
||||
* @hide
|
||||
*/
|
||||
public boolean isIdenticalDnses(LinkProperties target) {
|
||||
Collection<InetAddress> targetDnses = target.getDnsServers();
|
||||
String targetDomains = target.getDomains();
|
||||
if (mDomains == null) {
|
||||
if (targetDomains != null) return false;
|
||||
} else {
|
||||
if (mDomains.equals(targetDomains) == false) return false;
|
||||
}
|
||||
return (mDnses.size() == targetDnses.size()) ?
|
||||
mDnses.containsAll(targetDnses) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this {@code LinkProperties} Routes against the target
|
||||
*
|
||||
* @param target LinkProperties to compare.
|
||||
* @return {@code true} if both are identical, {@code false} otherwise.
|
||||
* @hide
|
||||
*/
|
||||
public boolean isIdenticalRoutes(LinkProperties target) {
|
||||
Collection<RouteInfo> targetRoutes = target.getRoutes();
|
||||
return (mRoutes.size() == targetRoutes.size()) ?
|
||||
mRoutes.containsAll(targetRoutes) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this {@code LinkProperties} HttpProxy against the target
|
||||
*
|
||||
* @param target LinkProperties to compare.
|
||||
* @return {@code true} if both are identical, {@code false} otherwise.
|
||||
* @hide
|
||||
*/
|
||||
public boolean isIdenticalHttpProxy(LinkProperties target) {
|
||||
return getHttpProxy() == null ? target.getHttpProxy() == null :
|
||||
getHttpProxy().equals(target.getHttpProxy());
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this {@code LinkProperties} stacked links against the target
|
||||
*
|
||||
* @param target LinkProperties to compare.
|
||||
* @return {@code true} if both are identical, {@code false} otherwise.
|
||||
* @hide
|
||||
*/
|
||||
public boolean isIdenticalStackedLinks(LinkProperties target) {
|
||||
if (!mStackedLinks.keySet().equals(target.mStackedLinks.keySet())) {
|
||||
return false;
|
||||
}
|
||||
for (LinkProperties stacked : mStackedLinks.values()) {
|
||||
// Hashtable values can never be null.
|
||||
String iface = stacked.getInterfaceName();
|
||||
if (!stacked.equals(target.mStackedLinks.get(iface))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this {@code LinkProperties} MTU against the target
|
||||
*
|
||||
* @param target LinkProperties to compare.
|
||||
* @return {@code true} if both are identical, {@code false} otherwise.
|
||||
* @hide
|
||||
*/
|
||||
public boolean isIdenticalMtu(LinkProperties target) {
|
||||
return getMtu() == target.getMtu();
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Compares this {@code LinkProperties} instance against the target
|
||||
* LinkProperties in {@code obj}. Two LinkPropertieses are equal if
|
||||
* all their fields are equal in values.
|
||||
*
|
||||
* For collection fields, such as mDnses, containsAll() is used to check
|
||||
* if two collections contains the same elements, independent of order.
|
||||
* There are two thoughts regarding containsAll()
|
||||
* 1. Duplicated elements. eg, (A, B, B) and (A, A, B) are equal.
|
||||
* 2. Worst case performance is O(n^2).
|
||||
*
|
||||
* @param obj the object to be tested for equality.
|
||||
* @return {@code true} if both objects are equal, {@code false} otherwise.
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
|
||||
if (!(obj instanceof LinkProperties)) return false;
|
||||
|
||||
LinkProperties target = (LinkProperties) obj;
|
||||
/**
|
||||
* This method does not check that stacked interfaces are equal, because
|
||||
* stacked interfaces are not so much a property of the link as a
|
||||
* description of connections between links.
|
||||
*/
|
||||
return isIdenticalInterfaceName(target) &&
|
||||
isIdenticalAddresses(target) &&
|
||||
isIdenticalDnses(target) &&
|
||||
isIdenticalRoutes(target) &&
|
||||
isIdenticalHttpProxy(target) &&
|
||||
isIdenticalStackedLinks(target) &&
|
||||
isIdenticalMtu(target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the addresses in this LinkProperties with another
|
||||
* LinkProperties, examining only addresses on the base link.
|
||||
*
|
||||
* @param target a LinkProperties with the new list of addresses
|
||||
* @return the differences between the addresses.
|
||||
* @hide
|
||||
*/
|
||||
public CompareResult<LinkAddress> compareAddresses(LinkProperties target) {
|
||||
/*
|
||||
* Duplicate the LinkAddresses into removed, we will be removing
|
||||
* address which are common between mLinkAddresses and target
|
||||
* leaving the addresses that are different. And address which
|
||||
* are in target but not in mLinkAddresses are placed in the
|
||||
* addedAddresses.
|
||||
*/
|
||||
CompareResult<LinkAddress> result = new CompareResult<LinkAddress>();
|
||||
result.removed = new ArrayList<LinkAddress>(mLinkAddresses);
|
||||
result.added.clear();
|
||||
if (target != null) {
|
||||
for (LinkAddress newAddress : target.getLinkAddresses()) {
|
||||
if (! result.removed.remove(newAddress)) {
|
||||
result.added.add(newAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the DNS addresses in this LinkProperties with another
|
||||
* LinkProperties, examining only DNS addresses on the base link.
|
||||
*
|
||||
* @param target a LinkProperties with the new list of dns addresses
|
||||
* @return the differences between the DNS addresses.
|
||||
* @hide
|
||||
*/
|
||||
public CompareResult<InetAddress> compareDnses(LinkProperties target) {
|
||||
/*
|
||||
* Duplicate the InetAddresses into removed, we will be removing
|
||||
* dns address which are common between mDnses and target
|
||||
* leaving the addresses that are different. And dns address which
|
||||
* are in target but not in mDnses are placed in the
|
||||
* addedAddresses.
|
||||
*/
|
||||
CompareResult<InetAddress> result = new CompareResult<InetAddress>();
|
||||
|
||||
result.removed = new ArrayList<InetAddress>(mDnses);
|
||||
result.added.clear();
|
||||
if (target != null) {
|
||||
for (InetAddress newAddress : target.getDnsServers()) {
|
||||
if (! result.removed.remove(newAddress)) {
|
||||
result.added.add(newAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares all routes in this LinkProperties with another LinkProperties,
|
||||
* examining both the the base link and all stacked links.
|
||||
*
|
||||
* @param target a LinkProperties with the new list of routes
|
||||
* @return the differences between the routes.
|
||||
* @hide
|
||||
*/
|
||||
public CompareResult<RouteInfo> compareAllRoutes(LinkProperties target) {
|
||||
/*
|
||||
* Duplicate the RouteInfos into removed, we will be removing
|
||||
* routes which are common between mRoutes and target
|
||||
* leaving the routes that are different. And route address which
|
||||
* are in target but not in mRoutes are placed in added.
|
||||
*/
|
||||
CompareResult<RouteInfo> result = new CompareResult<RouteInfo>();
|
||||
|
||||
result.removed = getAllRoutes();
|
||||
result.added.clear();
|
||||
if (target != null) {
|
||||
for (RouteInfo r : target.getAllRoutes()) {
|
||||
if (! result.removed.remove(r)) {
|
||||
result.added.add(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares all interface names in this LinkProperties with another
|
||||
* LinkProperties, examining both the the base link and all stacked links.
|
||||
*
|
||||
* @param target a LinkProperties with the new list of interface names
|
||||
* @return the differences between the interface names.
|
||||
* @hide
|
||||
*/
|
||||
public CompareResult<String> compareAllInterfaceNames(LinkProperties target) {
|
||||
/*
|
||||
* Duplicate the interface names into removed, we will be removing
|
||||
* interface names which are common between this and target
|
||||
* leaving the interface names that are different. And interface names which
|
||||
* are in target but not in this are placed in added.
|
||||
*/
|
||||
CompareResult<String> result = new CompareResult<String>();
|
||||
|
||||
result.removed = getAllInterfaceNames();
|
||||
result.added.clear();
|
||||
if (target != null) {
|
||||
for (String r : target.getAllInterfaceNames()) {
|
||||
if (! result.removed.remove(r)) {
|
||||
result.added.add(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
/**
|
||||
* generate hashcode based on significant fields
|
||||
* Equal objects must produce the same hash code, while unequal objects
|
||||
* may have the same hash codes.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return ((null == mIfaceName) ? 0 : mIfaceName.hashCode()
|
||||
+ mLinkAddresses.size() * 31
|
||||
+ mDnses.size() * 37
|
||||
+ ((null == mDomains) ? 0 : mDomains.hashCode())
|
||||
+ mRoutes.size() * 41
|
||||
+ ((null == mHttpProxy) ? 0 : mHttpProxy.hashCode())
|
||||
+ mStackedLinks.hashCode() * 47)
|
||||
+ mMtu * 51;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the Parcelable interface.
|
||||
*/
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(getInterfaceName());
|
||||
dest.writeInt(mLinkAddresses.size());
|
||||
for(LinkAddress linkAddress : mLinkAddresses) {
|
||||
dest.writeParcelable(linkAddress, flags);
|
||||
}
|
||||
|
||||
dest.writeInt(mDnses.size());
|
||||
for(InetAddress d : mDnses) {
|
||||
dest.writeByteArray(d.getAddress());
|
||||
}
|
||||
dest.writeString(mDomains);
|
||||
dest.writeInt(mMtu);
|
||||
dest.writeInt(mRoutes.size());
|
||||
for(RouteInfo route : mRoutes) {
|
||||
dest.writeParcelable(route, flags);
|
||||
}
|
||||
|
||||
if (mHttpProxy != null) {
|
||||
dest.writeByte((byte)1);
|
||||
dest.writeParcelable(mHttpProxy, flags);
|
||||
} else {
|
||||
dest.writeByte((byte)0);
|
||||
}
|
||||
ArrayList<LinkProperties> stackedLinks = new ArrayList(mStackedLinks.values());
|
||||
dest.writeList(stackedLinks);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the Parcelable interface.
|
||||
*/
|
||||
public static final Creator<LinkProperties> CREATOR =
|
||||
new Creator<LinkProperties>() {
|
||||
public LinkProperties createFromParcel(Parcel in) {
|
||||
LinkProperties netProp = new LinkProperties();
|
||||
|
||||
String iface = in.readString();
|
||||
if (iface != null) {
|
||||
netProp.setInterfaceName(iface);
|
||||
}
|
||||
int addressCount = in.readInt();
|
||||
for (int i=0; i<addressCount; i++) {
|
||||
netProp.addLinkAddress((LinkAddress)in.readParcelable(null));
|
||||
}
|
||||
addressCount = in.readInt();
|
||||
for (int i=0; i<addressCount; i++) {
|
||||
try {
|
||||
netProp.addDnsServer(InetAddress.getByAddress(in.createByteArray()));
|
||||
} catch (UnknownHostException e) { }
|
||||
}
|
||||
netProp.setDomains(in.readString());
|
||||
netProp.setMtu(in.readInt());
|
||||
addressCount = in.readInt();
|
||||
for (int i=0; i<addressCount; i++) {
|
||||
netProp.addRoute((RouteInfo)in.readParcelable(null));
|
||||
}
|
||||
if (in.readByte() == 1) {
|
||||
netProp.setHttpProxy((ProxyInfo)in.readParcelable(null));
|
||||
}
|
||||
ArrayList<LinkProperties> stackedLinks = new ArrayList<LinkProperties>();
|
||||
in.readList(stackedLinks, LinkProperties.class.getClassLoader());
|
||||
for (LinkProperties stackedLink: stackedLinks) {
|
||||
netProp.addStackedLink(stackedLink);
|
||||
}
|
||||
return netProp;
|
||||
}
|
||||
|
||||
public LinkProperties[] newArray(int size) {
|
||||
return new LinkProperties[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
201
core/java/android/net/Network.java
Normal file
201
core/java/android/net/Network.java
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.net.NetworkUtils;
|
||||
import android.os.Parcelable;
|
||||
import android.os.Parcel;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
import javax.net.SocketFactory;
|
||||
|
||||
/**
|
||||
* Identifies a {@code Network}. This is supplied to applications via
|
||||
* {@link ConnectivityManager.NetworkCallbackListener} in response to
|
||||
* {@link ConnectivityManager#requestNetwork} or {@link ConnectivityManager#listenForNetwork}.
|
||||
* It is used to direct traffic to the given {@code Network}, either on a {@link Socket} basis
|
||||
* through a targeted {@link SocketFactory} or process-wide via
|
||||
* {@link ConnectivityManager#setProcessDefaultNetwork}.
|
||||
*/
|
||||
public class Network implements Parcelable {
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public final int netId;
|
||||
|
||||
private NetworkBoundSocketFactory mNetworkBoundSocketFactory = null;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public Network(int netId) {
|
||||
this.netId = netId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public Network(Network that) {
|
||||
this.netId = that.netId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Operates the same as {@code InetAddress.getAllByName} except that host
|
||||
* resolution is done on this network.
|
||||
*
|
||||
* @param host the hostname or literal IP string to be resolved.
|
||||
* @return the array of addresses associated with the specified host.
|
||||
* @throws UnknownHostException if the address lookup fails.
|
||||
*/
|
||||
public InetAddress[] getAllByName(String host) throws UnknownHostException {
|
||||
return InetAddress.getAllByNameOnNet(host, netId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Operates the same as {@code InetAddress.getByName} except that host
|
||||
* resolution is done on this network.
|
||||
*
|
||||
* @param host
|
||||
* the hostName to be resolved to an address or {@code null}.
|
||||
* @return the {@code InetAddress} instance representing the host.
|
||||
* @throws UnknownHostException
|
||||
* if the address lookup fails.
|
||||
*/
|
||||
public InetAddress getByName(String host) throws UnknownHostException {
|
||||
return InetAddress.getByNameOnNet(host, netId);
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@code SocketFactory} that produces {@code Socket}'s bound to this network.
|
||||
*/
|
||||
private class NetworkBoundSocketFactory extends SocketFactory {
|
||||
private final int mNetId;
|
||||
|
||||
public NetworkBoundSocketFactory(int netId) {
|
||||
super();
|
||||
mNetId = netId;
|
||||
}
|
||||
|
||||
private void connectToHost(Socket socket, String host, int port) throws IOException {
|
||||
// Lookup addresses only on this Network.
|
||||
InetAddress[] hostAddresses = getAllByName(host);
|
||||
// Try all but last address ignoring exceptions.
|
||||
for (int i = 0; i < hostAddresses.length - 1; i++) {
|
||||
try {
|
||||
socket.connect(new InetSocketAddress(hostAddresses[i], port));
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
// Try last address. Do throw exceptions.
|
||||
socket.connect(new InetSocketAddress(hostAddresses[hostAddresses.length - 1], port));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
|
||||
Socket socket = createSocket();
|
||||
socket.bind(new InetSocketAddress(localHost, localPort));
|
||||
connectToHost(socket, host, port);
|
||||
return socket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(InetAddress address, int port, InetAddress localAddress,
|
||||
int localPort) throws IOException {
|
||||
Socket socket = createSocket();
|
||||
socket.bind(new InetSocketAddress(localAddress, localPort));
|
||||
socket.connect(new InetSocketAddress(address, port));
|
||||
return socket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(InetAddress host, int port) throws IOException {
|
||||
Socket socket = createSocket();
|
||||
socket.connect(new InetSocketAddress(host, port));
|
||||
return socket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(String host, int port) throws IOException {
|
||||
Socket socket = createSocket();
|
||||
connectToHost(socket, host, port);
|
||||
return socket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket() throws IOException {
|
||||
Socket socket = new Socket();
|
||||
// Query a property of the underlying socket to ensure the underlying
|
||||
// socket exists so a file descriptor is available to bind to a network.
|
||||
socket.getReuseAddress();
|
||||
NetworkUtils.bindSocketToNetwork(socket.getFileDescriptor$().getInt$(), mNetId);
|
||||
return socket;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link SocketFactory} bound to this network. Any {@link Socket} created by
|
||||
* this factory will have its traffic sent over this {@code Network}. Note that if this
|
||||
* {@code Network} ever disconnects, this factory and any {@link Socket} it produced in the
|
||||
* past or future will cease to work.
|
||||
*
|
||||
* @return a {@link SocketFactory} which produces {@link Socket} instances bound to this
|
||||
* {@code Network}.
|
||||
*/
|
||||
public SocketFactory getSocketFactory() {
|
||||
if (mNetworkBoundSocketFactory == null) {
|
||||
mNetworkBoundSocketFactory = new NetworkBoundSocketFactory(netId);
|
||||
}
|
||||
return mNetworkBoundSocketFactory;
|
||||
}
|
||||
|
||||
// implement the Parcelable interface
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(netId);
|
||||
}
|
||||
|
||||
public static final Creator<Network> CREATOR =
|
||||
new Creator<Network>() {
|
||||
public Network createFromParcel(Parcel in) {
|
||||
int netId = in.readInt();
|
||||
|
||||
return new Network(netId);
|
||||
}
|
||||
|
||||
public Network[] newArray(int size) {
|
||||
return new Network[size];
|
||||
}
|
||||
};
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof Network == false) return false;
|
||||
Network other = (Network)obj;
|
||||
return this.netId == other.netId;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return netId * 11;
|
||||
}
|
||||
}
|
||||
207
core/java/android/net/NetworkAgent.java
Normal file
207
core/java/android/net/NetworkAgent.java
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
import android.os.Messenger;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.util.AsyncChannel;
|
||||
import com.android.internal.util.Protocol;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* A Utility class for handling for communicating between bearer-specific
|
||||
* code and ConnectivityService.
|
||||
*
|
||||
* A bearer may have more than one NetworkAgent if it can simultaneously
|
||||
* support separate networks (IMS / Internet / MMS Apns on cellular, or
|
||||
* perhaps connections with different SSID or P2P for Wi-Fi).
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public abstract class NetworkAgent extends Handler {
|
||||
private volatile AsyncChannel mAsyncChannel;
|
||||
private final String LOG_TAG;
|
||||
private static final boolean DBG = true;
|
||||
private static final boolean VDBG = true;
|
||||
private final Context mContext;
|
||||
private final ArrayList<Message>mPreConnectedQueue = new ArrayList<Message>();
|
||||
|
||||
private static final int BASE = Protocol.BASE_NETWORK_AGENT;
|
||||
|
||||
/**
|
||||
* Sent by ConnectivityService to the NetworkAgent to inform it of
|
||||
* suspected connectivity problems on its network. The NetworkAgent
|
||||
* should take steps to verify and correct connectivity.
|
||||
*/
|
||||
public static final int CMD_SUSPECT_BAD = BASE;
|
||||
|
||||
/**
|
||||
* Sent by the NetworkAgent (note the EVENT vs CMD prefix) to
|
||||
* ConnectivityService to pass the current NetworkInfo (connection state).
|
||||
* Sent when the NetworkInfo changes, mainly due to change of state.
|
||||
* obj = NetworkInfo
|
||||
*/
|
||||
public static final int EVENT_NETWORK_INFO_CHANGED = BASE + 1;
|
||||
|
||||
/**
|
||||
* Sent by the NetworkAgent to ConnectivityService to pass the current
|
||||
* NetworkCapabilties.
|
||||
* obj = NetworkCapabilities
|
||||
*/
|
||||
public static final int EVENT_NETWORK_CAPABILITIES_CHANGED = BASE + 2;
|
||||
|
||||
/**
|
||||
* Sent by the NetworkAgent to ConnectivityService to pass the current
|
||||
* NetworkProperties.
|
||||
* obj = NetworkProperties
|
||||
*/
|
||||
public static final int EVENT_NETWORK_PROPERTIES_CHANGED = BASE + 3;
|
||||
|
||||
/* centralize place where base network score, and network score scaling, will be
|
||||
* stored, so as we can consistently compare apple and oranges, or wifi, ethernet and LTE
|
||||
*/
|
||||
public static final int WIFI_BASE_SCORE = 60;
|
||||
|
||||
/**
|
||||
* Sent by the NetworkAgent to ConnectivityService to pass the current
|
||||
* network score.
|
||||
* obj = network score Integer
|
||||
*/
|
||||
public static final int EVENT_NETWORK_SCORE_CHANGED = BASE + 4;
|
||||
|
||||
public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
|
||||
NetworkCapabilities nc, LinkProperties lp, int score) {
|
||||
super(looper);
|
||||
LOG_TAG = logTag;
|
||||
mContext = context;
|
||||
if (ni == null || nc == null || lp == null) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
if (DBG) log("Registering NetworkAgent");
|
||||
ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(
|
||||
Context.CONNECTIVITY_SERVICE);
|
||||
cm.registerNetworkAgent(new Messenger(this), new NetworkInfo(ni),
|
||||
new LinkProperties(lp), new NetworkCapabilities(nc), score);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
switch (msg.what) {
|
||||
case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: {
|
||||
if (mAsyncChannel != null) {
|
||||
log("Received new connection while already connected!");
|
||||
} else {
|
||||
if (DBG) log("NetworkAgent fully connected");
|
||||
AsyncChannel ac = new AsyncChannel();
|
||||
ac.connected(null, this, msg.replyTo);
|
||||
ac.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,
|
||||
AsyncChannel.STATUS_SUCCESSFUL);
|
||||
synchronized (mPreConnectedQueue) {
|
||||
mAsyncChannel = ac;
|
||||
for (Message m : mPreConnectedQueue) {
|
||||
ac.sendMessage(m);
|
||||
}
|
||||
mPreConnectedQueue.clear();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AsyncChannel.CMD_CHANNEL_DISCONNECT: {
|
||||
if (DBG) log("CMD_CHANNEL_DISCONNECT");
|
||||
if (mAsyncChannel != null) mAsyncChannel.disconnect();
|
||||
break;
|
||||
}
|
||||
case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
|
||||
if (DBG) log("NetworkAgent channel lost");
|
||||
// let the client know CS is done with us.
|
||||
unwanted();
|
||||
synchronized (mPreConnectedQueue) {
|
||||
mAsyncChannel = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CMD_SUSPECT_BAD: {
|
||||
log("Unhandled Message " + msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void queueOrSendMessage(int what, Object obj) {
|
||||
synchronized (mPreConnectedQueue) {
|
||||
if (mAsyncChannel != null) {
|
||||
mAsyncChannel.sendMessage(what, obj);
|
||||
} else {
|
||||
Message msg = Message.obtain();
|
||||
msg.what = what;
|
||||
msg.obj = obj;
|
||||
mPreConnectedQueue.add(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the bearer code when it has new LinkProperties data.
|
||||
*/
|
||||
public void sendLinkProperties(LinkProperties linkProperties) {
|
||||
queueOrSendMessage(EVENT_NETWORK_PROPERTIES_CHANGED, new LinkProperties(linkProperties));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the bearer code when it has new NetworkInfo data.
|
||||
*/
|
||||
public void sendNetworkInfo(NetworkInfo networkInfo) {
|
||||
queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, new NetworkInfo(networkInfo));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the bearer code when it has new NetworkCapabilities data.
|
||||
*/
|
||||
public void sendNetworkCapabilities(NetworkCapabilities networkCapabilities) {
|
||||
queueOrSendMessage(EVENT_NETWORK_CAPABILITIES_CHANGED,
|
||||
new NetworkCapabilities(networkCapabilities));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the bearer code when it has a new score for this network.
|
||||
*/
|
||||
public void sendNetworkScore(int score) {
|
||||
queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, new Integer(score));
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when ConnectivityService has indicated they no longer want this network.
|
||||
* The parent factory should (previously) have received indication of the change
|
||||
* as well, either canceling NetworkRequests or altering their score such that this
|
||||
* network won't be immediately requested again.
|
||||
*/
|
||||
abstract protected void unwanted();
|
||||
|
||||
protected void log(String s) {
|
||||
Log.d(LOG_TAG, "NetworkAgent: " + s);
|
||||
}
|
||||
}
|
||||
526
core/java/android/net/NetworkCapabilities.java
Normal file
526
core/java/android/net/NetworkCapabilities.java
Normal file
|
|
@ -0,0 +1,526 @@
|
|||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.util.Log;
|
||||
|
||||
import java.lang.IllegalArgumentException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* This class represents the capabilities of a network. This is used both to specify
|
||||
* needs to {@link ConnectivityManager} and when inspecting a network.
|
||||
*
|
||||
* Note that this replaces the old {@link ConnectivityManager#TYPE_MOBILE} method
|
||||
* of network selection. Rather than indicate a need for Wi-Fi because an application
|
||||
* needs high bandwidth and risk obselence when a new, fast network appears (like LTE),
|
||||
* the application should specify it needs high bandwidth. Similarly if an application
|
||||
* needs an unmetered network for a bulk transfer it can specify that rather than assuming
|
||||
* all cellular based connections are metered and all Wi-Fi based connections are not.
|
||||
*/
|
||||
public final class NetworkCapabilities implements Parcelable {
|
||||
private static final String TAG = "NetworkCapabilities";
|
||||
private static final boolean DBG = false;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public NetworkCapabilities() {
|
||||
}
|
||||
|
||||
public NetworkCapabilities(NetworkCapabilities nc) {
|
||||
if (nc != null) {
|
||||
mNetworkCapabilities = nc.mNetworkCapabilities;
|
||||
mTransportTypes = nc.mTransportTypes;
|
||||
mLinkUpBandwidthKbps = nc.mLinkUpBandwidthKbps;
|
||||
mLinkDownBandwidthKbps = nc.mLinkDownBandwidthKbps;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the network's capabilities. If any are specified they will be satisfied
|
||||
* by any Network that matches all of them.
|
||||
*/
|
||||
private long mNetworkCapabilities = (1 << NET_CAPABILITY_NOT_RESTRICTED);
|
||||
|
||||
/**
|
||||
* Indicates this is a network that has the ability to reach the
|
||||
* carrier's MMSC for sending and receiving MMS messages.
|
||||
*/
|
||||
public static final int NET_CAPABILITY_MMS = 0;
|
||||
|
||||
/**
|
||||
* Indicates this is a network that has the ability to reach the carrier's
|
||||
* SUPL server, used to retrieve GPS information.
|
||||
*/
|
||||
public static final int NET_CAPABILITY_SUPL = 1;
|
||||
|
||||
/**
|
||||
* Indicates this is a network that has the ability to reach the carrier's
|
||||
* DUN or tethering gateway.
|
||||
*/
|
||||
public static final int NET_CAPABILITY_DUN = 2;
|
||||
|
||||
/**
|
||||
* Indicates this is a network that has the ability to reach the carrier's
|
||||
* FOTA portal, used for over the air updates.
|
||||
*/
|
||||
public static final int NET_CAPABILITY_FOTA = 3;
|
||||
|
||||
/**
|
||||
* Indicates this is a network that has the ability to reach the carrier's
|
||||
* IMS servers, used for network registration and signaling.
|
||||
*/
|
||||
public static final int NET_CAPABILITY_IMS = 4;
|
||||
|
||||
/**
|
||||
* Indicates this is a network that has the ability to reach the carrier's
|
||||
* CBS servers, used for carrier specific services.
|
||||
*/
|
||||
public static final int NET_CAPABILITY_CBS = 5;
|
||||
|
||||
/**
|
||||
* Indicates this is a network that has the ability to reach a Wi-Fi direct
|
||||
* peer.
|
||||
*/
|
||||
public static final int NET_CAPABILITY_WIFI_P2P = 6;
|
||||
|
||||
/**
|
||||
* Indicates this is a network that has the ability to reach a carrier's
|
||||
* Initial Attach servers.
|
||||
*/
|
||||
public static final int NET_CAPABILITY_IA = 7;
|
||||
|
||||
/**
|
||||
* Indicates this is a network that has the ability to reach a carrier's
|
||||
* RCS servers, used for Rich Communication Services.
|
||||
*/
|
||||
public static final int NET_CAPABILITY_RCS = 8;
|
||||
|
||||
/**
|
||||
* Indicates this is a network that has the ability to reach a carrier's
|
||||
* XCAP servers, used for configuration and control.
|
||||
*/
|
||||
public static final int NET_CAPABILITY_XCAP = 9;
|
||||
|
||||
/**
|
||||
* Indicates this is a network that has the ability to reach a carrier's
|
||||
* Emergency IMS servers, used for network signaling during emergency calls.
|
||||
*/
|
||||
public static final int NET_CAPABILITY_EIMS = 10;
|
||||
|
||||
/**
|
||||
* Indicates that this network is unmetered.
|
||||
*/
|
||||
public static final int NET_CAPABILITY_NOT_METERED = 11;
|
||||
|
||||
/**
|
||||
* Indicates that this network should be able to reach the internet.
|
||||
*/
|
||||
public static final int NET_CAPABILITY_INTERNET = 12;
|
||||
|
||||
/**
|
||||
* Indicates that this network is available for general use. If this is not set
|
||||
* applications should not attempt to communicate on this network. Note that this
|
||||
* is simply informative and not enforcement - enforcement is handled via other means.
|
||||
* Set by default.
|
||||
*/
|
||||
public static final int NET_CAPABILITY_NOT_RESTRICTED = 13;
|
||||
|
||||
private static final int MIN_NET_CAPABILITY = NET_CAPABILITY_MMS;
|
||||
private static final int MAX_NET_CAPABILITY = NET_CAPABILITY_NOT_RESTRICTED;
|
||||
|
||||
/**
|
||||
* Adds the given capability to this {@code NetworkCapability} instance.
|
||||
* Multiple capabilities may be applied sequentially. Note that when searching
|
||||
* for a network to satisfy a request, all capabilities requested must be satisfied.
|
||||
*
|
||||
* @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be added.
|
||||
* @return This NetworkCapability to facilitate chaining.
|
||||
* @hide
|
||||
*/
|
||||
public NetworkCapabilities addCapability(int capability) {
|
||||
if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
|
||||
throw new IllegalArgumentException("NetworkCapability out of range");
|
||||
}
|
||||
mNetworkCapabilities |= 1 << capability;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes (if found) the given capability from this {@code NetworkCapability} instance.
|
||||
*
|
||||
* @param capability the {@code NetworkCapabilities.NET_CAPABILTIY_*} to be removed.
|
||||
* @return This NetworkCapability to facilitate chaining.
|
||||
* @hide
|
||||
*/
|
||||
public NetworkCapabilities removeCapability(int capability) {
|
||||
if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
|
||||
throw new IllegalArgumentException("NetworkCapability out of range");
|
||||
}
|
||||
mNetworkCapabilities &= ~(1 << capability);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the capabilities set on this {@code NetworkCapability} instance.
|
||||
*
|
||||
* @return an array of {@code NetworkCapabilities.NET_CAPABILITY_*} values
|
||||
* for this instance.
|
||||
* @hide
|
||||
*/
|
||||
public int[] getCapabilities() {
|
||||
return enumerateBits(mNetworkCapabilities);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for the presence of a capabilitity on this instance.
|
||||
*
|
||||
* @param capability the {@code NetworkCapabilities.NET_CAPABILITY_*} to be tested for.
|
||||
* @return {@code true} if set on this instance.
|
||||
*/
|
||||
public boolean hasCapability(int capability) {
|
||||
if (capability < MIN_NET_CAPABILITY || capability > MAX_NET_CAPABILITY) {
|
||||
return false;
|
||||
}
|
||||
return ((mNetworkCapabilities & (1 << capability)) != 0);
|
||||
}
|
||||
|
||||
private int[] enumerateBits(long val) {
|
||||
int size = Long.bitCount(val);
|
||||
int[] result = new int[size];
|
||||
int index = 0;
|
||||
int resource = 0;
|
||||
while (val > 0) {
|
||||
if ((val & 1) == 1) result[index++] = resource;
|
||||
val = val >> 1;
|
||||
resource++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void combineNetCapabilities(NetworkCapabilities nc) {
|
||||
this.mNetworkCapabilities |= nc.mNetworkCapabilities;
|
||||
}
|
||||
|
||||
private boolean satisfiedByNetCapabilities(NetworkCapabilities nc) {
|
||||
return ((nc.mNetworkCapabilities & this.mNetworkCapabilities) == this.mNetworkCapabilities);
|
||||
}
|
||||
|
||||
private boolean equalsNetCapabilities(NetworkCapabilities nc) {
|
||||
return (nc.mNetworkCapabilities == this.mNetworkCapabilities);
|
||||
}
|
||||
|
||||
/**
|
||||
* Representing the transport type. Apps should generally not care about transport. A
|
||||
* request for a fast internet connection could be satisfied by a number of different
|
||||
* transports. If any are specified here it will be satisfied a Network that matches
|
||||
* any of them. If a caller doesn't care about the transport it should not specify any.
|
||||
*/
|
||||
private long mTransportTypes;
|
||||
|
||||
/**
|
||||
* Indicates this network uses a Cellular transport.
|
||||
*/
|
||||
public static final int TRANSPORT_CELLULAR = 0;
|
||||
|
||||
/**
|
||||
* Indicates this network uses a Wi-Fi transport.
|
||||
*/
|
||||
public static final int TRANSPORT_WIFI = 1;
|
||||
|
||||
/**
|
||||
* Indicates this network uses a Bluetooth transport.
|
||||
*/
|
||||
public static final int TRANSPORT_BLUETOOTH = 2;
|
||||
|
||||
/**
|
||||
* Indicates this network uses an Ethernet transport.
|
||||
*/
|
||||
public static final int TRANSPORT_ETHERNET = 3;
|
||||
|
||||
private static final int MIN_TRANSPORT = TRANSPORT_CELLULAR;
|
||||
private static final int MAX_TRANSPORT = TRANSPORT_ETHERNET;
|
||||
|
||||
/**
|
||||
* Adds the given transport type to this {@code NetworkCapability} instance.
|
||||
* Multiple transports may be applied sequentially. Note that when searching
|
||||
* for a network to satisfy a request, any listed in the request will satisfy the request.
|
||||
* For example {@code TRANSPORT_WIFI} and {@code TRANSPORT_ETHERNET} added to a
|
||||
* {@code NetworkCapabilities} would cause either a Wi-Fi network or an Ethernet network
|
||||
* to be selected. This is logically different than
|
||||
* {@code NetworkCapabilities.NET_CAPABILITY_*} listed above.
|
||||
*
|
||||
* @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be added.
|
||||
* @return This NetworkCapability to facilitate chaining.
|
||||
* @hide
|
||||
*/
|
||||
public NetworkCapabilities addTransportType(int transportType) {
|
||||
if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
|
||||
throw new IllegalArgumentException("TransportType out of range");
|
||||
}
|
||||
mTransportTypes |= 1 << transportType;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes (if found) the given transport from this {@code NetworkCapability} instance.
|
||||
*
|
||||
* @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be removed.
|
||||
* @return This NetworkCapability to facilitate chaining.
|
||||
* @hide
|
||||
*/
|
||||
public NetworkCapabilities removeTransportType(int transportType) {
|
||||
if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
|
||||
throw new IllegalArgumentException("TransportType out of range");
|
||||
}
|
||||
mTransportTypes &= ~(1 << transportType);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all the transports set on this {@code NetworkCapability} instance.
|
||||
*
|
||||
* @return an array of {@code NetworkCapabilities.TRANSPORT_*} values
|
||||
* for this instance.
|
||||
* @hide
|
||||
*/
|
||||
public int[] getTransportTypes() {
|
||||
return enumerateBits(mTransportTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests for the presence of a transport on this instance.
|
||||
*
|
||||
* @param transportType the {@code NetworkCapabilities.TRANSPORT_*} to be tested for.
|
||||
* @return {@code true} if set on this instance.
|
||||
*/
|
||||
public boolean hasTransport(int transportType) {
|
||||
if (transportType < MIN_TRANSPORT || transportType > MAX_TRANSPORT) {
|
||||
return false;
|
||||
}
|
||||
return ((mTransportTypes & (1 << transportType)) != 0);
|
||||
}
|
||||
|
||||
private void combineTransportTypes(NetworkCapabilities nc) {
|
||||
this.mTransportTypes |= nc.mTransportTypes;
|
||||
}
|
||||
private boolean satisfiedByTransportTypes(NetworkCapabilities nc) {
|
||||
return ((this.mTransportTypes == 0) ||
|
||||
((this.mTransportTypes & nc.mTransportTypes) != 0));
|
||||
}
|
||||
private boolean equalsTransportTypes(NetworkCapabilities nc) {
|
||||
return (nc.mTransportTypes == this.mTransportTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Passive link bandwidth. This is a rough guide of the expected peak bandwidth
|
||||
* for the first hop on the given transport. It is not measured, but may take into account
|
||||
* link parameters (Radio technology, allocated channels, etc).
|
||||
*/
|
||||
private int mLinkUpBandwidthKbps;
|
||||
private int mLinkDownBandwidthKbps;
|
||||
|
||||
/**
|
||||
* Sets the upstream bandwidth for this network in Kbps. This always only refers to
|
||||
* the estimated first hop transport bandwidth.
|
||||
* <p>
|
||||
* Note that when used to request a network, this specifies the minimum acceptable.
|
||||
* When received as the state of an existing network this specifies the typical
|
||||
* first hop bandwidth expected. This is never measured, but rather is inferred
|
||||
* from technology type and other link parameters. It could be used to differentiate
|
||||
* between very slow 1xRTT cellular links and other faster networks or even between
|
||||
* 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
|
||||
* fast backhauls and slow backhauls.
|
||||
*
|
||||
* @param upKbps the estimated first hop upstream (device to network) bandwidth.
|
||||
* @hide
|
||||
*/
|
||||
public void setLinkUpstreamBandwidthKbps(int upKbps) {
|
||||
mLinkUpBandwidthKbps = upKbps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the upstream bandwidth for this network in Kbps. This always only refers to
|
||||
* the estimated first hop transport bandwidth.
|
||||
*
|
||||
* @return The estimated first hop upstream (device to network) bandwidth.
|
||||
*/
|
||||
public int getLinkUpstreamBandwidthKbps() {
|
||||
return mLinkUpBandwidthKbps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the downstream bandwidth for this network in Kbps. This always only refers to
|
||||
* the estimated first hop transport bandwidth.
|
||||
* <p>
|
||||
* Note that when used to request a network, this specifies the minimum acceptable.
|
||||
* When received as the state of an existing network this specifies the typical
|
||||
* first hop bandwidth expected. This is never measured, but rather is inferred
|
||||
* from technology type and other link parameters. It could be used to differentiate
|
||||
* between very slow 1xRTT cellular links and other faster networks or even between
|
||||
* 802.11b vs 802.11AC wifi technologies. It should not be used to differentiate between
|
||||
* fast backhauls and slow backhauls.
|
||||
*
|
||||
* @param downKbps the estimated first hop downstream (network to device) bandwidth.
|
||||
* @hide
|
||||
*/
|
||||
public void setLinkDownstreamBandwidthKbps(int downKbps) {
|
||||
mLinkDownBandwidthKbps = downKbps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the downstream bandwidth for this network in Kbps. This always only refers to
|
||||
* the estimated first hop transport bandwidth.
|
||||
*
|
||||
* @return The estimated first hop downstream (network to device) bandwidth.
|
||||
*/
|
||||
public int getLinkDownstreamBandwidthKbps() {
|
||||
return mLinkDownBandwidthKbps;
|
||||
}
|
||||
|
||||
private void combineLinkBandwidths(NetworkCapabilities nc) {
|
||||
this.mLinkUpBandwidthKbps =
|
||||
Math.max(this.mLinkUpBandwidthKbps, nc.mLinkUpBandwidthKbps);
|
||||
this.mLinkDownBandwidthKbps =
|
||||
Math.max(this.mLinkDownBandwidthKbps, nc.mLinkDownBandwidthKbps);
|
||||
}
|
||||
private boolean satisfiedByLinkBandwidths(NetworkCapabilities nc) {
|
||||
return !(this.mLinkUpBandwidthKbps > nc.mLinkUpBandwidthKbps ||
|
||||
this.mLinkDownBandwidthKbps > nc.mLinkDownBandwidthKbps);
|
||||
}
|
||||
private boolean equalsLinkBandwidths(NetworkCapabilities nc) {
|
||||
return (this.mLinkUpBandwidthKbps == nc.mLinkUpBandwidthKbps &&
|
||||
this.mLinkDownBandwidthKbps == nc.mLinkDownBandwidthKbps);
|
||||
}
|
||||
|
||||
/**
|
||||
* Combine a set of Capabilities to this one. Useful for coming up with the complete set
|
||||
* {@hide}
|
||||
*/
|
||||
public void combineCapabilities(NetworkCapabilities nc) {
|
||||
combineNetCapabilities(nc);
|
||||
combineTransportTypes(nc);
|
||||
combineLinkBandwidths(nc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if our requirements are satisfied by the given Capabilities.
|
||||
* {@hide}
|
||||
*/
|
||||
public boolean satisfiedByNetworkCapabilities(NetworkCapabilities nc) {
|
||||
return (nc != null &&
|
||||
satisfiedByNetCapabilities(nc) &&
|
||||
satisfiedByTransportTypes(nc) &&
|
||||
satisfiedByLinkBandwidths(nc));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == null || (obj instanceof NetworkCapabilities == false)) return false;
|
||||
NetworkCapabilities that = (NetworkCapabilities)obj;
|
||||
return (equalsNetCapabilities(that) &&
|
||||
equalsTransportTypes(that) &&
|
||||
equalsLinkBandwidths(that));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return ((int)(mNetworkCapabilities & 0xFFFFFFFF) +
|
||||
((int)(mNetworkCapabilities >> 32) * 3) +
|
||||
((int)(mTransportTypes & 0xFFFFFFFF) * 5) +
|
||||
((int)(mTransportTypes >> 32) * 7) +
|
||||
(mLinkUpBandwidthKbps * 11) +
|
||||
(mLinkDownBandwidthKbps * 13));
|
||||
}
|
||||
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeLong(mNetworkCapabilities);
|
||||
dest.writeLong(mTransportTypes);
|
||||
dest.writeInt(mLinkUpBandwidthKbps);
|
||||
dest.writeInt(mLinkDownBandwidthKbps);
|
||||
}
|
||||
public static final Creator<NetworkCapabilities> CREATOR =
|
||||
new Creator<NetworkCapabilities>() {
|
||||
public NetworkCapabilities createFromParcel(Parcel in) {
|
||||
NetworkCapabilities netCap = new NetworkCapabilities();
|
||||
|
||||
netCap.mNetworkCapabilities = in.readLong();
|
||||
netCap.mTransportTypes = in.readLong();
|
||||
netCap.mLinkUpBandwidthKbps = in.readInt();
|
||||
netCap.mLinkDownBandwidthKbps = in.readInt();
|
||||
return netCap;
|
||||
}
|
||||
public NetworkCapabilities[] newArray(int size) {
|
||||
return new NetworkCapabilities[size];
|
||||
}
|
||||
};
|
||||
|
||||
public String toString() {
|
||||
int[] types = getTransportTypes();
|
||||
String transports = (types.length > 0 ? " Transports: " : "");
|
||||
for (int i = 0; i < types.length;) {
|
||||
switch (types[i]) {
|
||||
case TRANSPORT_CELLULAR: transports += "CELLULAR"; break;
|
||||
case TRANSPORT_WIFI: transports += "WIFI"; break;
|
||||
case TRANSPORT_BLUETOOTH: transports += "BLUETOOTH"; break;
|
||||
case TRANSPORT_ETHERNET: transports += "ETHERNET"; break;
|
||||
}
|
||||
if (++i < types.length) transports += "|";
|
||||
}
|
||||
|
||||
types = getCapabilities();
|
||||
String capabilities = (types.length > 0 ? " Capabilities: " : "");
|
||||
for (int i = 0; i < types.length; ) {
|
||||
switch (types[i]) {
|
||||
case NET_CAPABILITY_MMS: capabilities += "MMS"; break;
|
||||
case NET_CAPABILITY_SUPL: capabilities += "SUPL"; break;
|
||||
case NET_CAPABILITY_DUN: capabilities += "DUN"; break;
|
||||
case NET_CAPABILITY_FOTA: capabilities += "FOTA"; break;
|
||||
case NET_CAPABILITY_IMS: capabilities += "IMS"; break;
|
||||
case NET_CAPABILITY_CBS: capabilities += "CBS"; break;
|
||||
case NET_CAPABILITY_WIFI_P2P: capabilities += "WIFI_P2P"; break;
|
||||
case NET_CAPABILITY_IA: capabilities += "IA"; break;
|
||||
case NET_CAPABILITY_RCS: capabilities += "RCS"; break;
|
||||
case NET_CAPABILITY_XCAP: capabilities += "XCAP"; break;
|
||||
case NET_CAPABILITY_EIMS: capabilities += "EIMS"; break;
|
||||
case NET_CAPABILITY_NOT_METERED: capabilities += "NOT_METERED"; break;
|
||||
case NET_CAPABILITY_INTERNET: capabilities += "INTERNET"; break;
|
||||
case NET_CAPABILITY_NOT_RESTRICTED: capabilities += "NOT_RESTRICTED"; break;
|
||||
}
|
||||
if (++i < types.length) capabilities += "&";
|
||||
}
|
||||
|
||||
String upBand = ((mLinkUpBandwidthKbps > 0) ? " LinkUpBandwidth>=" +
|
||||
mLinkUpBandwidthKbps + "Kbps" : "");
|
||||
String dnBand = ((mLinkDownBandwidthKbps > 0) ? " LinkDnBandwidth>=" +
|
||||
mLinkDownBandwidthKbps + "Kbps" : "");
|
||||
|
||||
return "[" + transports + capabilities + upBand + dnBand + "]";
|
||||
}
|
||||
}
|
||||
80
core/java/android/net/NetworkConfig.java
Normal file
80
core/java/android/net/NetworkConfig.java
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Describes the buildtime configuration of a network.
|
||||
* Holds settings read from resources.
|
||||
* @hide
|
||||
*/
|
||||
public class NetworkConfig {
|
||||
/**
|
||||
* Human readable string
|
||||
*/
|
||||
public String name;
|
||||
|
||||
/**
|
||||
* Type from ConnectivityManager
|
||||
*/
|
||||
public int type;
|
||||
|
||||
/**
|
||||
* the radio number from radio attributes config
|
||||
*/
|
||||
public int radio;
|
||||
|
||||
/**
|
||||
* higher number == higher priority when turning off connections
|
||||
*/
|
||||
public int priority;
|
||||
|
||||
/**
|
||||
* indicates the boot time dependencyMet setting
|
||||
*/
|
||||
public boolean dependencyMet;
|
||||
|
||||
/**
|
||||
* indicates the default restoral timer in seconds
|
||||
* if the network is used as a special network feature
|
||||
* -1 indicates no restoration of default
|
||||
*/
|
||||
public int restoreTime;
|
||||
|
||||
/**
|
||||
* input string from config.xml resource. Uses the form:
|
||||
* [Connection name],[ConnectivityManager connection type],
|
||||
* [associated radio-type],[priority],[dependencyMet]
|
||||
*/
|
||||
public NetworkConfig(String init) {
|
||||
String fragments[] = init.split(",");
|
||||
name = fragments[0].trim().toLowerCase(Locale.ROOT);
|
||||
type = Integer.parseInt(fragments[1]);
|
||||
radio = Integer.parseInt(fragments[2]);
|
||||
priority = Integer.parseInt(fragments[3]);
|
||||
restoreTime = Integer.parseInt(fragments[4]);
|
||||
dependencyMet = Boolean.parseBoolean(fragments[5]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this network is supposed to be default-routable
|
||||
*/
|
||||
public boolean isDefault() {
|
||||
return (type == radio);
|
||||
}
|
||||
}
|
||||
506
core/java/android/net/NetworkInfo.java
Normal file
506
core/java/android/net/NetworkInfo.java
Normal file
|
|
@ -0,0 +1,506 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.os.Parcelable;
|
||||
import android.os.Parcel;
|
||||
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
|
||||
import java.util.EnumMap;
|
||||
|
||||
/**
|
||||
* Describes the status of a network interface.
|
||||
* <p>Use {@link ConnectivityManager#getActiveNetworkInfo()} to get an instance that represents
|
||||
* the current network connection.
|
||||
*/
|
||||
public class NetworkInfo implements Parcelable {
|
||||
|
||||
/**
|
||||
* Coarse-grained network state. This is probably what most applications should
|
||||
* use, rather than {@link android.net.NetworkInfo.DetailedState DetailedState}.
|
||||
* The mapping between the two is as follows:
|
||||
* <br/><br/>
|
||||
* <table>
|
||||
* <tr><td><b>Detailed state</b></td><td><b>Coarse-grained state</b></td></tr>
|
||||
* <tr><td><code>IDLE</code></td><td><code>DISCONNECTED</code></td></tr>
|
||||
* <tr><td><code>SCANNING</code></td><td><code>CONNECTING</code></td></tr>
|
||||
* <tr><td><code>CONNECTING</code></td><td><code>CONNECTING</code></td></tr>
|
||||
* <tr><td><code>AUTHENTICATING</code></td><td><code>CONNECTING</code></td></tr>
|
||||
* <tr><td><code>CONNECTED</code></td><td><code>CONNECTED</code></td></tr>
|
||||
* <tr><td><code>DISCONNECTING</code></td><td><code>DISCONNECTING</code></td></tr>
|
||||
* <tr><td><code>DISCONNECTED</code></td><td><code>DISCONNECTED</code></td></tr>
|
||||
* <tr><td><code>UNAVAILABLE</code></td><td><code>DISCONNECTED</code></td></tr>
|
||||
* <tr><td><code>FAILED</code></td><td><code>DISCONNECTED</code></td></tr>
|
||||
* </table>
|
||||
*/
|
||||
public enum State {
|
||||
CONNECTING, CONNECTED, SUSPENDED, DISCONNECTING, DISCONNECTED, UNKNOWN
|
||||
}
|
||||
|
||||
/**
|
||||
* The fine-grained state of a network connection. This level of detail
|
||||
* is probably of interest to few applications. Most should use
|
||||
* {@link android.net.NetworkInfo.State State} instead.
|
||||
*/
|
||||
public enum DetailedState {
|
||||
/** Ready to start data connection setup. */
|
||||
IDLE,
|
||||
/** Searching for an available access point. */
|
||||
SCANNING,
|
||||
/** Currently setting up data connection. */
|
||||
CONNECTING,
|
||||
/** Network link established, performing authentication. */
|
||||
AUTHENTICATING,
|
||||
/** Awaiting response from DHCP server in order to assign IP address information. */
|
||||
OBTAINING_IPADDR,
|
||||
/** IP traffic should be available. */
|
||||
CONNECTED,
|
||||
/** IP traffic is suspended */
|
||||
SUSPENDED,
|
||||
/** Currently tearing down data connection. */
|
||||
DISCONNECTING,
|
||||
/** IP traffic not available. */
|
||||
DISCONNECTED,
|
||||
/** Attempt to connect failed. */
|
||||
FAILED,
|
||||
/** Access to this network is blocked. */
|
||||
BLOCKED,
|
||||
/** Link has poor connectivity. */
|
||||
VERIFYING_POOR_LINK,
|
||||
/** Checking if network is a captive portal */
|
||||
CAPTIVE_PORTAL_CHECK
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the map described in the Javadoc comment above. The positions
|
||||
* of the elements of the array must correspond to the ordinal values
|
||||
* of <code>DetailedState</code>.
|
||||
*/
|
||||
private static final EnumMap<DetailedState, State> stateMap =
|
||||
new EnumMap<DetailedState, State>(DetailedState.class);
|
||||
|
||||
static {
|
||||
stateMap.put(DetailedState.IDLE, State.DISCONNECTED);
|
||||
stateMap.put(DetailedState.SCANNING, State.DISCONNECTED);
|
||||
stateMap.put(DetailedState.CONNECTING, State.CONNECTING);
|
||||
stateMap.put(DetailedState.AUTHENTICATING, State.CONNECTING);
|
||||
stateMap.put(DetailedState.OBTAINING_IPADDR, State.CONNECTING);
|
||||
stateMap.put(DetailedState.VERIFYING_POOR_LINK, State.CONNECTING);
|
||||
stateMap.put(DetailedState.CAPTIVE_PORTAL_CHECK, State.CONNECTING);
|
||||
stateMap.put(DetailedState.CONNECTED, State.CONNECTED);
|
||||
stateMap.put(DetailedState.SUSPENDED, State.SUSPENDED);
|
||||
stateMap.put(DetailedState.DISCONNECTING, State.DISCONNECTING);
|
||||
stateMap.put(DetailedState.DISCONNECTED, State.DISCONNECTED);
|
||||
stateMap.put(DetailedState.FAILED, State.DISCONNECTED);
|
||||
stateMap.put(DetailedState.BLOCKED, State.DISCONNECTED);
|
||||
}
|
||||
|
||||
private int mNetworkType;
|
||||
private int mSubtype;
|
||||
private String mTypeName;
|
||||
private String mSubtypeName;
|
||||
private State mState;
|
||||
private DetailedState mDetailedState;
|
||||
private String mReason;
|
||||
private String mExtraInfo;
|
||||
private boolean mIsFailover;
|
||||
private boolean mIsRoaming;
|
||||
private boolean mIsConnectedToProvisioningNetwork;
|
||||
|
||||
/**
|
||||
* Indicates whether network connectivity is possible:
|
||||
*/
|
||||
private boolean mIsAvailable;
|
||||
|
||||
/**
|
||||
* @param type network type
|
||||
* @deprecated
|
||||
* @hide because this constructor was only meant for internal use (and
|
||||
* has now been superseded by the package-private constructor below).
|
||||
*/
|
||||
public NetworkInfo(int type) {}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public NetworkInfo(int type, int subtype, String typeName, String subtypeName) {
|
||||
if (!ConnectivityManager.isNetworkTypeValid(type)) {
|
||||
throw new IllegalArgumentException("Invalid network type: " + type);
|
||||
}
|
||||
mNetworkType = type;
|
||||
mSubtype = subtype;
|
||||
mTypeName = typeName;
|
||||
mSubtypeName = subtypeName;
|
||||
setDetailedState(DetailedState.IDLE, null, null);
|
||||
mState = State.UNKNOWN;
|
||||
mIsAvailable = false; // until we're told otherwise, assume unavailable
|
||||
mIsRoaming = false;
|
||||
mIsConnectedToProvisioningNetwork = false;
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
public NetworkInfo(NetworkInfo source) {
|
||||
if (source != null) {
|
||||
synchronized (source) {
|
||||
mNetworkType = source.mNetworkType;
|
||||
mSubtype = source.mSubtype;
|
||||
mTypeName = source.mTypeName;
|
||||
mSubtypeName = source.mSubtypeName;
|
||||
mState = source.mState;
|
||||
mDetailedState = source.mDetailedState;
|
||||
mReason = source.mReason;
|
||||
mExtraInfo = source.mExtraInfo;
|
||||
mIsFailover = source.mIsFailover;
|
||||
mIsRoaming = source.mIsRoaming;
|
||||
mIsAvailable = source.mIsAvailable;
|
||||
mIsConnectedToProvisioningNetwork = source.mIsConnectedToProvisioningNetwork;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports the type of network to which the
|
||||
* info in this {@code NetworkInfo} pertains.
|
||||
* @return one of {@link ConnectivityManager#TYPE_MOBILE}, {@link
|
||||
* ConnectivityManager#TYPE_WIFI}, {@link ConnectivityManager#TYPE_WIMAX}, {@link
|
||||
* ConnectivityManager#TYPE_ETHERNET}, {@link ConnectivityManager#TYPE_BLUETOOTH}, or other
|
||||
* types defined by {@link ConnectivityManager}
|
||||
*/
|
||||
public int getType() {
|
||||
synchronized (this) {
|
||||
return mNetworkType;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void setType(int type) {
|
||||
synchronized (this) {
|
||||
mNetworkType = type;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a network-type-specific integer describing the subtype
|
||||
* of the network.
|
||||
* @return the network subtype
|
||||
*/
|
||||
public int getSubtype() {
|
||||
synchronized (this) {
|
||||
return mSubtype;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public void setSubtype(int subtype, String subtypeName) {
|
||||
synchronized (this) {
|
||||
mSubtype = subtype;
|
||||
mSubtypeName = subtypeName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a human-readable name describe the type of the network,
|
||||
* for example "WIFI" or "MOBILE".
|
||||
* @return the name of the network type
|
||||
*/
|
||||
public String getTypeName() {
|
||||
synchronized (this) {
|
||||
return mTypeName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a human-readable name describing the subtype of the network.
|
||||
* @return the name of the network subtype
|
||||
*/
|
||||
public String getSubtypeName() {
|
||||
synchronized (this) {
|
||||
return mSubtypeName;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether network connectivity exists or is in the process
|
||||
* of being established. This is good for applications that need to
|
||||
* do anything related to the network other than read or write data.
|
||||
* For the latter, call {@link #isConnected()} instead, which guarantees
|
||||
* that the network is fully usable.
|
||||
* @return {@code true} if network connectivity exists or is in the process
|
||||
* of being established, {@code false} otherwise.
|
||||
*/
|
||||
public boolean isConnectedOrConnecting() {
|
||||
synchronized (this) {
|
||||
return mState == State.CONNECTED || mState == State.CONNECTING;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether network connectivity exists and it is possible to establish
|
||||
* connections and pass data.
|
||||
* <p>Always call this before attempting to perform data transactions.
|
||||
* @return {@code true} if network connectivity exists, {@code false} otherwise.
|
||||
*/
|
||||
public boolean isConnected() {
|
||||
synchronized (this) {
|
||||
return mState == State.CONNECTED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether network connectivity is possible. A network is unavailable
|
||||
* when a persistent or semi-persistent condition prevents the possibility
|
||||
* of connecting to that network. Examples include
|
||||
* <ul>
|
||||
* <li>The device is out of the coverage area for any network of this type.</li>
|
||||
* <li>The device is on a network other than the home network (i.e., roaming), and
|
||||
* data roaming has been disabled.</li>
|
||||
* <li>The device's radio is turned off, e.g., because airplane mode is enabled.</li>
|
||||
* </ul>
|
||||
* @return {@code true} if the network is available, {@code false} otherwise
|
||||
*/
|
||||
public boolean isAvailable() {
|
||||
synchronized (this) {
|
||||
return mIsAvailable;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the network is available, ie, if the connectivity is possible.
|
||||
* @param isAvailable the new availability value.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void setIsAvailable(boolean isAvailable) {
|
||||
synchronized (this) {
|
||||
mIsAvailable = isAvailable;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the current attempt to connect to the network
|
||||
* resulted from the ConnectivityManager trying to fail over to this
|
||||
* network following a disconnect from another network.
|
||||
* @return {@code true} if this is a failover attempt, {@code false}
|
||||
* otherwise.
|
||||
*/
|
||||
public boolean isFailover() {
|
||||
synchronized (this) {
|
||||
return mIsFailover;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the failover boolean.
|
||||
* @param isFailover {@code true} to mark the current connection attempt
|
||||
* as a failover.
|
||||
* @hide
|
||||
*/
|
||||
public void setFailover(boolean isFailover) {
|
||||
synchronized (this) {
|
||||
mIsFailover = isFailover;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the device is currently roaming on this network.
|
||||
* When {@code true}, it suggests that use of data on this network
|
||||
* may incur extra costs.
|
||||
* @return {@code true} if roaming is in effect, {@code false} otherwise.
|
||||
*/
|
||||
public boolean isRoaming() {
|
||||
synchronized (this) {
|
||||
return mIsRoaming;
|
||||
}
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
@VisibleForTesting
|
||||
public void setRoaming(boolean isRoaming) {
|
||||
synchronized (this) {
|
||||
mIsRoaming = isRoaming;
|
||||
}
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
@VisibleForTesting
|
||||
public boolean isConnectedToProvisioningNetwork() {
|
||||
synchronized (this) {
|
||||
return mIsConnectedToProvisioningNetwork;
|
||||
}
|
||||
}
|
||||
|
||||
/** {@hide} */
|
||||
@VisibleForTesting
|
||||
public void setIsConnectedToProvisioningNetwork(boolean val) {
|
||||
synchronized (this) {
|
||||
mIsConnectedToProvisioningNetwork = val;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports the current coarse-grained state of the network.
|
||||
* @return the coarse-grained state
|
||||
*/
|
||||
public State getState() {
|
||||
synchronized (this) {
|
||||
return mState;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reports the current fine-grained state of the network.
|
||||
* @return the fine-grained state
|
||||
*/
|
||||
public DetailedState getDetailedState() {
|
||||
synchronized (this) {
|
||||
return mDetailedState;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the fine-grained state of the network.
|
||||
* @param detailedState the {@link DetailedState}.
|
||||
* @param reason a {@code String} indicating the reason for the state change,
|
||||
* if one was supplied. May be {@code null}.
|
||||
* @param extraInfo an optional {@code String} providing addditional network state
|
||||
* information passed up from the lower networking layers.
|
||||
* @hide
|
||||
*/
|
||||
public void setDetailedState(DetailedState detailedState, String reason, String extraInfo) {
|
||||
synchronized (this) {
|
||||
this.mDetailedState = detailedState;
|
||||
this.mState = stateMap.get(detailedState);
|
||||
this.mReason = reason;
|
||||
this.mExtraInfo = extraInfo;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the extraInfo field.
|
||||
* @param extraInfo an optional {@code String} providing addditional network state
|
||||
* information passed up from the lower networking layers.
|
||||
* @hide
|
||||
*/
|
||||
public void setExtraInfo(String extraInfo) {
|
||||
synchronized (this) {
|
||||
this.mExtraInfo = extraInfo;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Report the reason an attempt to establish connectivity failed,
|
||||
* if one is available.
|
||||
* @return the reason for failure, or null if not available
|
||||
*/
|
||||
public String getReason() {
|
||||
synchronized (this) {
|
||||
return mReason;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Report the extra information about the network state, if any was
|
||||
* provided by the lower networking layers.,
|
||||
* if one is available.
|
||||
* @return the extra information, or null if not available
|
||||
*/
|
||||
public String getExtraInfo() {
|
||||
synchronized (this) {
|
||||
return mExtraInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
synchronized (this) {
|
||||
StringBuilder builder = new StringBuilder("[");
|
||||
builder.append("type: ").append(getTypeName()).append("[").append(getSubtypeName()).
|
||||
append("], state: ").append(mState).append("/").append(mDetailedState).
|
||||
append(", reason: ").append(mReason == null ? "(unspecified)" : mReason).
|
||||
append(", extra: ").append(mExtraInfo == null ? "(none)" : mExtraInfo).
|
||||
append(", roaming: ").append(mIsRoaming).
|
||||
append(", failover: ").append(mIsFailover).
|
||||
append(", isAvailable: ").append(mIsAvailable).
|
||||
append(", isConnectedToProvisioningNetwork: ").
|
||||
append(mIsConnectedToProvisioningNetwork).
|
||||
append("]");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the Parcelable interface
|
||||
* @hide
|
||||
*/
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the Parcelable interface.
|
||||
* @hide
|
||||
*/
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
synchronized (this) {
|
||||
dest.writeInt(mNetworkType);
|
||||
dest.writeInt(mSubtype);
|
||||
dest.writeString(mTypeName);
|
||||
dest.writeString(mSubtypeName);
|
||||
dest.writeString(mState.name());
|
||||
dest.writeString(mDetailedState.name());
|
||||
dest.writeInt(mIsFailover ? 1 : 0);
|
||||
dest.writeInt(mIsAvailable ? 1 : 0);
|
||||
dest.writeInt(mIsRoaming ? 1 : 0);
|
||||
dest.writeInt(mIsConnectedToProvisioningNetwork ? 1 : 0);
|
||||
dest.writeString(mReason);
|
||||
dest.writeString(mExtraInfo);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the Parcelable interface.
|
||||
* @hide
|
||||
*/
|
||||
public static final Creator<NetworkInfo> CREATOR =
|
||||
new Creator<NetworkInfo>() {
|
||||
public NetworkInfo createFromParcel(Parcel in) {
|
||||
int netType = in.readInt();
|
||||
int subtype = in.readInt();
|
||||
String typeName = in.readString();
|
||||
String subtypeName = in.readString();
|
||||
NetworkInfo netInfo = new NetworkInfo(netType, subtype, typeName, subtypeName);
|
||||
netInfo.mState = State.valueOf(in.readString());
|
||||
netInfo.mDetailedState = DetailedState.valueOf(in.readString());
|
||||
netInfo.mIsFailover = in.readInt() != 0;
|
||||
netInfo.mIsAvailable = in.readInt() != 0;
|
||||
netInfo.mIsRoaming = in.readInt() != 0;
|
||||
netInfo.mIsConnectedToProvisioningNetwork = in.readInt() != 0;
|
||||
netInfo.mReason = in.readString();
|
||||
netInfo.mExtraInfo = in.readString();
|
||||
return netInfo;
|
||||
}
|
||||
|
||||
public NetworkInfo[] newArray(int size) {
|
||||
return new NetworkInfo[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
200
core/java/android/net/NetworkRequest.java
Normal file
200
core/java/android/net/NetworkRequest.java
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* Defines a request for a network, made through {@link NetworkRequest.Builder} and used
|
||||
* to request a network via {@link ConnectivityManager#requestNetwork} or listen for changes
|
||||
* via {@link ConnectivityManager#listenForNetwork}.
|
||||
*/
|
||||
public class NetworkRequest implements Parcelable {
|
||||
/**
|
||||
* The {@link NetworkCapabilities} that define this request.
|
||||
* @hide
|
||||
*/
|
||||
public final NetworkCapabilities networkCapabilities;
|
||||
|
||||
/**
|
||||
* Identifies the request. NetworkRequests should only be constructed by
|
||||
* the Framework and given out to applications as tokens to be used to identify
|
||||
* the request.
|
||||
* @hide
|
||||
*/
|
||||
public final int requestId;
|
||||
|
||||
/**
|
||||
* Set for legacy requests and the default. Set to TYPE_NONE for none.
|
||||
* Causes CONNECTIVITY_ACTION broadcasts to be sent.
|
||||
* @hide
|
||||
*/
|
||||
public final int legacyType;
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public NetworkRequest(NetworkCapabilities nc, int legacyType, int rId) {
|
||||
requestId = rId;
|
||||
networkCapabilities = nc;
|
||||
this.legacyType = legacyType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public NetworkRequest(NetworkRequest that) {
|
||||
networkCapabilities = new NetworkCapabilities(that.networkCapabilities);
|
||||
requestId = that.requestId;
|
||||
this.legacyType = that.legacyType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder used to create {@link NetworkRequest} objects. Specify the Network features
|
||||
* needed in terms of {@link NetworkCapabilities} features
|
||||
*/
|
||||
public static class Builder {
|
||||
private final NetworkCapabilities mNetworkCapabilities = new NetworkCapabilities();
|
||||
|
||||
/**
|
||||
* Default constructor for Builder.
|
||||
*/
|
||||
public Builder() {}
|
||||
|
||||
/**
|
||||
* Build {@link NetworkRequest} give the current set of capabilities.
|
||||
*/
|
||||
public NetworkRequest build() {
|
||||
return new NetworkRequest(mNetworkCapabilities, ConnectivityManager.TYPE_NONE,
|
||||
ConnectivityManager.REQUEST_ID_UNSET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the given capability requirement to this builder. These represent
|
||||
* the requested network's required capabilities. Note that when searching
|
||||
* for a network to satisfy a request, all capabilities requested must be
|
||||
* satisfied. See {@link NetworkCapabilities} for {@code NET_CAPABILITIY_*}
|
||||
* definitions.
|
||||
*
|
||||
* @param capability The {@code NetworkCapabilities.NET_CAPABILITY_*} to add.
|
||||
* @return The builder to facilitate chaining
|
||||
* {@code builder.addCapability(...).addCapability();}.
|
||||
*/
|
||||
public Builder addCapability(int capability) {
|
||||
mNetworkCapabilities.addCapability(capability);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes (if found) the given capability from this builder instance.
|
||||
*
|
||||
* @param capability The {@code NetworkCapabilities.NET_CAPABILITY_*} to remove.
|
||||
* @return The builder to facilitate chaining.
|
||||
*/
|
||||
public Builder removeCapability(int capability) {
|
||||
mNetworkCapabilities.removeCapability(capability);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given transport requirement to this builder. These represent
|
||||
* the set of allowed transports for the request. Only networks using one
|
||||
* of these transports will satisfy the request. If no particular transports
|
||||
* are required, none should be specified here. See {@link NetworkCapabilities}
|
||||
* for {@code TRANSPORT_*} definitions.
|
||||
*
|
||||
* @param transportType The {@code NetworkCapabilities.TRANSPORT_*} to add.
|
||||
* @return The builder to facilitate chaining.
|
||||
*/
|
||||
public Builder addTransportType(int transportType) {
|
||||
mNetworkCapabilities.addTransportType(transportType);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes (if found) the given transport from this builder instance.
|
||||
*
|
||||
* @param transportType The {@code NetworkCapabilities.TRANSPORT_*} to remove.
|
||||
* @return The builder to facilitate chaining.
|
||||
*/
|
||||
public Builder removeTransportType(int transportType) {
|
||||
mNetworkCapabilities.removeTransportType(transportType);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public Builder setLinkUpstreamBandwidthKbps(int upKbps) {
|
||||
mNetworkCapabilities.setLinkUpstreamBandwidthKbps(upKbps);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public Builder setLinkDownstreamBandwidthKbps(int downKbps) {
|
||||
mNetworkCapabilities.setLinkDownstreamBandwidthKbps(downKbps);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
// implement the Parcelable interface
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeParcelable(networkCapabilities, flags);
|
||||
dest.writeInt(legacyType);
|
||||
dest.writeInt(requestId);
|
||||
}
|
||||
public static final Creator<NetworkRequest> CREATOR =
|
||||
new Creator<NetworkRequest>() {
|
||||
public NetworkRequest createFromParcel(Parcel in) {
|
||||
NetworkCapabilities nc = (NetworkCapabilities)in.readParcelable(null);
|
||||
int legacyType = in.readInt();
|
||||
int requestId = in.readInt();
|
||||
NetworkRequest result = new NetworkRequest(nc, legacyType, requestId);
|
||||
return result;
|
||||
}
|
||||
public NetworkRequest[] newArray(int size) {
|
||||
return new NetworkRequest[size];
|
||||
}
|
||||
};
|
||||
|
||||
public String toString() {
|
||||
return "NetworkRequest [ id=" + requestId + ", legacyType=" + legacyType +
|
||||
", " + networkCapabilities.toString() + " ]";
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof NetworkRequest == false) return false;
|
||||
NetworkRequest that = (NetworkRequest)obj;
|
||||
return (that.legacyType == this.legacyType &&
|
||||
that.requestId == this.requestId &&
|
||||
((that.networkCapabilities == null && this.networkCapabilities == null) ||
|
||||
(that.networkCapabilities != null &&
|
||||
that.networkCapabilities.equals(this.networkCapabilities))));
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return requestId + (legacyType * 1013) +
|
||||
(networkCapabilities.hashCode() * 1051);
|
||||
}
|
||||
}
|
||||
84
core/java/android/net/NetworkState.java
Normal file
84
core/java/android/net/NetworkState.java
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
/**
|
||||
* Snapshot of network state.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public class NetworkState implements Parcelable {
|
||||
|
||||
public final NetworkInfo networkInfo;
|
||||
public final LinkProperties linkProperties;
|
||||
public final NetworkCapabilities networkCapabilities;
|
||||
/** Currently only used by testing. */
|
||||
public final String subscriberId;
|
||||
public final String networkId;
|
||||
|
||||
public NetworkState(NetworkInfo networkInfo, LinkProperties linkProperties,
|
||||
NetworkCapabilities networkCapabilities) {
|
||||
this(networkInfo, linkProperties, networkCapabilities, null, null);
|
||||
}
|
||||
|
||||
public NetworkState(NetworkInfo networkInfo, LinkProperties linkProperties,
|
||||
NetworkCapabilities networkCapabilities, String subscriberId, String networkId) {
|
||||
this.networkInfo = networkInfo;
|
||||
this.linkProperties = linkProperties;
|
||||
this.networkCapabilities = networkCapabilities;
|
||||
this.subscriberId = subscriberId;
|
||||
this.networkId = networkId;
|
||||
}
|
||||
|
||||
public NetworkState(Parcel in) {
|
||||
networkInfo = in.readParcelable(null);
|
||||
linkProperties = in.readParcelable(null);
|
||||
networkCapabilities = in.readParcelable(null);
|
||||
subscriberId = in.readString();
|
||||
networkId = in.readString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel out, int flags) {
|
||||
out.writeParcelable(networkInfo, flags);
|
||||
out.writeParcelable(linkProperties, flags);
|
||||
out.writeParcelable(networkCapabilities, flags);
|
||||
out.writeString(subscriberId);
|
||||
out.writeString(networkId);
|
||||
}
|
||||
|
||||
public static final Creator<NetworkState> CREATOR = new Creator<NetworkState>() {
|
||||
@Override
|
||||
public NetworkState createFromParcel(Parcel in) {
|
||||
return new NetworkState(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public NetworkState[] newArray(int size) {
|
||||
return new NetworkState[size];
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
328
core/java/android/net/NetworkUtils.java
Normal file
328
core/java/android/net/NetworkUtils.java
Normal file
|
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
* Copyright (C) 2008 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Collection;
|
||||
import java.util.Locale;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* Native methods for managing network interfaces.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public class NetworkUtils {
|
||||
|
||||
private static final String TAG = "NetworkUtils";
|
||||
|
||||
/** Bring the named network interface up. */
|
||||
public native static int enableInterface(String interfaceName);
|
||||
|
||||
/** Bring the named network interface down. */
|
||||
public native static int disableInterface(String interfaceName);
|
||||
|
||||
/** Setting bit 0 indicates reseting of IPv4 addresses required */
|
||||
public static final int RESET_IPV4_ADDRESSES = 0x01;
|
||||
|
||||
/** Setting bit 1 indicates reseting of IPv4 addresses required */
|
||||
public static final int RESET_IPV6_ADDRESSES = 0x02;
|
||||
|
||||
/** Reset all addresses */
|
||||
public static final int RESET_ALL_ADDRESSES = RESET_IPV4_ADDRESSES | RESET_IPV6_ADDRESSES;
|
||||
|
||||
/**
|
||||
* Reset IPv6 or IPv4 sockets that are connected via the named interface.
|
||||
*
|
||||
* @param interfaceName is the interface to reset
|
||||
* @param mask {@see #RESET_IPV4_ADDRESSES} and {@see #RESET_IPV6_ADDRESSES}
|
||||
*/
|
||||
public native static int resetConnections(String interfaceName, int mask);
|
||||
|
||||
/**
|
||||
* Start the DHCP client daemon, in order to have it request addresses
|
||||
* for the named interface, and then configure the interface with those
|
||||
* addresses. This call blocks until it obtains a result (either success
|
||||
* or failure) from the daemon.
|
||||
* @param interfaceName the name of the interface to configure
|
||||
* @param dhcpResults if the request succeeds, this object is filled in with
|
||||
* the IP address information.
|
||||
* @return {@code true} for success, {@code false} for failure
|
||||
*/
|
||||
public native static boolean runDhcp(String interfaceName, DhcpResults dhcpResults);
|
||||
|
||||
/**
|
||||
* Initiate renewal on the Dhcp client daemon. This call blocks until it obtains
|
||||
* a result (either success or failure) from the daemon.
|
||||
* @param interfaceName the name of the interface to configure
|
||||
* @param dhcpResults if the request succeeds, this object is filled in with
|
||||
* the IP address information.
|
||||
* @return {@code true} for success, {@code false} for failure
|
||||
*/
|
||||
public native static boolean runDhcpRenew(String interfaceName, DhcpResults dhcpResults);
|
||||
|
||||
/**
|
||||
* Shut down the DHCP client daemon.
|
||||
* @param interfaceName the name of the interface for which the daemon
|
||||
* should be stopped
|
||||
* @return {@code true} for success, {@code false} for failure
|
||||
*/
|
||||
public native static boolean stopDhcp(String interfaceName);
|
||||
|
||||
/**
|
||||
* Release the current DHCP lease.
|
||||
* @param interfaceName the name of the interface for which the lease should
|
||||
* be released
|
||||
* @return {@code true} for success, {@code false} for failure
|
||||
*/
|
||||
public native static boolean releaseDhcpLease(String interfaceName);
|
||||
|
||||
/**
|
||||
* Return the last DHCP-related error message that was recorded.
|
||||
* <p/>NOTE: This string is not localized, but currently it is only
|
||||
* used in logging.
|
||||
* @return the most recent error message, if any
|
||||
*/
|
||||
public native static String getDhcpError();
|
||||
|
||||
/**
|
||||
* Set the SO_MARK of {@code socketfd} to {@code mark}
|
||||
*/
|
||||
public native static void markSocket(int socketfd, int mark);
|
||||
|
||||
/**
|
||||
* Binds the current process to the network designated by {@code netId}. All sockets created
|
||||
* in the future (and not explicitly bound via a bound {@link SocketFactory} (see
|
||||
* {@link Network#getSocketFactory}) will be bound to this network. Note that if this
|
||||
* {@code Network} ever disconnects all sockets created in this way will cease to work. This
|
||||
* is by design so an application doesn't accidentally use sockets it thinks are still bound to
|
||||
* a particular {@code Network}.
|
||||
*/
|
||||
public native static void bindProcessToNetwork(int netId);
|
||||
|
||||
/**
|
||||
* Clear any process specific {@code Network} binding. This reverts a call to
|
||||
* {@link #bindProcessToNetwork}.
|
||||
*/
|
||||
public native static void unbindProcessToNetwork();
|
||||
|
||||
/**
|
||||
* Return the netId last passed to {@link #bindProcessToNetwork}, or NETID_UNSET if
|
||||
* {@link #unbindProcessToNetwork} has been called since {@link #bindProcessToNetwork}.
|
||||
*/
|
||||
public native static int getNetworkBoundToProcess();
|
||||
|
||||
/**
|
||||
* Binds host resolutions performed by this process to the network designated by {@code netId}.
|
||||
* {@link #bindProcessToNetwork} takes precedence over this setting.
|
||||
*
|
||||
* @deprecated This is strictly for legacy usage to support startUsingNetworkFeature().
|
||||
*/
|
||||
public native static void bindProcessToNetworkForHostResolution(int netId);
|
||||
|
||||
/**
|
||||
* Clears any process specific {@link Network} binding for host resolution. This does
|
||||
* not clear bindings enacted via {@link #bindProcessToNetwork}.
|
||||
*
|
||||
* @deprecated This is strictly for legacy usage to support startUsingNetworkFeature().
|
||||
*/
|
||||
public native static void unbindProcessToNetworkForHostResolution();
|
||||
|
||||
/**
|
||||
* Explicitly binds {@code socketfd} to the network designated by {@code netId}. This
|
||||
* overrides any binding via {@link #bindProcessToNetwork}.
|
||||
*/
|
||||
public native static void bindSocketToNetwork(int socketfd, int netId);
|
||||
|
||||
/**
|
||||
* Convert a IPv4 address from an integer to an InetAddress.
|
||||
* @param hostAddress an int corresponding to the IPv4 address in network byte order
|
||||
*/
|
||||
public static InetAddress intToInetAddress(int hostAddress) {
|
||||
byte[] addressBytes = { (byte)(0xff & hostAddress),
|
||||
(byte)(0xff & (hostAddress >> 8)),
|
||||
(byte)(0xff & (hostAddress >> 16)),
|
||||
(byte)(0xff & (hostAddress >> 24)) };
|
||||
|
||||
try {
|
||||
return InetAddress.getByAddress(addressBytes);
|
||||
} catch (UnknownHostException e) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a IPv4 address from an InetAddress to an integer
|
||||
* @param inetAddr is an InetAddress corresponding to the IPv4 address
|
||||
* @return the IP address as an integer in network byte order
|
||||
*/
|
||||
public static int inetAddressToInt(Inet4Address inetAddr)
|
||||
throws IllegalArgumentException {
|
||||
byte [] addr = inetAddr.getAddress();
|
||||
return ((addr[3] & 0xff) << 24) | ((addr[2] & 0xff) << 16) |
|
||||
((addr[1] & 0xff) << 8) | (addr[0] & 0xff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a network prefix length to an IPv4 netmask integer
|
||||
* @param prefixLength
|
||||
* @return the IPv4 netmask as an integer in network byte order
|
||||
*/
|
||||
public static int prefixLengthToNetmaskInt(int prefixLength)
|
||||
throws IllegalArgumentException {
|
||||
if (prefixLength < 0 || prefixLength > 32) {
|
||||
throw new IllegalArgumentException("Invalid prefix length (0 <= prefix <= 32)");
|
||||
}
|
||||
int value = 0xffffffff << (32 - prefixLength);
|
||||
return Integer.reverseBytes(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a IPv4 netmask integer to a prefix length
|
||||
* @param netmask as an integer in network byte order
|
||||
* @return the network prefix length
|
||||
*/
|
||||
public static int netmaskIntToPrefixLength(int netmask) {
|
||||
return Integer.bitCount(netmask);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an InetAddress from a string where the string must be a standard
|
||||
* representation of a V4 or V6 address. Avoids doing a DNS lookup on failure
|
||||
* but it will throw an IllegalArgumentException in that case.
|
||||
* @param addrString
|
||||
* @return the InetAddress
|
||||
* @hide
|
||||
*/
|
||||
public static InetAddress numericToInetAddress(String addrString)
|
||||
throws IllegalArgumentException {
|
||||
return InetAddress.parseNumericAddress(addrString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get InetAddress masked with prefixLength. Will never return null.
|
||||
* @param IP address which will be masked with specified prefixLength
|
||||
* @param prefixLength the prefixLength used to mask the IP
|
||||
*/
|
||||
public static InetAddress getNetworkPart(InetAddress address, int prefixLength) {
|
||||
if (address == null) {
|
||||
throw new RuntimeException("getNetworkPart doesn't accept null address");
|
||||
}
|
||||
|
||||
byte[] array = address.getAddress();
|
||||
|
||||
if (prefixLength < 0 || prefixLength > array.length * 8) {
|
||||
throw new RuntimeException("getNetworkPart - bad prefixLength");
|
||||
}
|
||||
|
||||
int offset = prefixLength / 8;
|
||||
int reminder = prefixLength % 8;
|
||||
byte mask = (byte)(0xFF << (8 - reminder));
|
||||
|
||||
if (offset < array.length) array[offset] = (byte)(array[offset] & mask);
|
||||
|
||||
offset++;
|
||||
|
||||
for (; offset < array.length; offset++) {
|
||||
array[offset] = 0;
|
||||
}
|
||||
|
||||
InetAddress netPart = null;
|
||||
try {
|
||||
netPart = InetAddress.getByAddress(array);
|
||||
} catch (UnknownHostException e) {
|
||||
throw new RuntimeException("getNetworkPart error - " + e.toString());
|
||||
}
|
||||
return netPart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if IP address type is consistent between two InetAddress.
|
||||
* @return true if both are the same type. False otherwise.
|
||||
*/
|
||||
public static boolean addressTypeMatches(InetAddress left, InetAddress right) {
|
||||
return (((left instanceof Inet4Address) && (right instanceof Inet4Address)) ||
|
||||
((left instanceof Inet6Address) && (right instanceof Inet6Address)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a 32 char hex string into a Inet6Address.
|
||||
* throws a runtime exception if the string isn't 32 chars, isn't hex or can't be
|
||||
* made into an Inet6Address
|
||||
* @param addrHexString a 32 character hex string representing an IPv6 addr
|
||||
* @return addr an InetAddress representation for the string
|
||||
*/
|
||||
public static InetAddress hexToInet6Address(String addrHexString)
|
||||
throws IllegalArgumentException {
|
||||
try {
|
||||
return numericToInetAddress(String.format(Locale.US, "%s:%s:%s:%s:%s:%s:%s:%s",
|
||||
addrHexString.substring(0,4), addrHexString.substring(4,8),
|
||||
addrHexString.substring(8,12), addrHexString.substring(12,16),
|
||||
addrHexString.substring(16,20), addrHexString.substring(20,24),
|
||||
addrHexString.substring(24,28), addrHexString.substring(28,32)));
|
||||
} catch (Exception e) {
|
||||
Log.e("NetworkUtils", "error in hexToInet6Address(" + addrHexString + "): " + e);
|
||||
throw new IllegalArgumentException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a string array of host addresses from a collection of InetAddresses
|
||||
* @param addrs a Collection of InetAddresses
|
||||
* @return an array of Strings containing their host addresses
|
||||
*/
|
||||
public static String[] makeStrings(Collection<InetAddress> addrs) {
|
||||
String[] result = new String[addrs.size()];
|
||||
int i = 0;
|
||||
for (InetAddress addr : addrs) {
|
||||
result[i++] = addr.getHostAddress();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Trim leading zeros from IPv4 address strings
|
||||
* Our base libraries will interpret that as octel..
|
||||
* Must leave non v4 addresses and host names alone.
|
||||
* For example, 192.168.000.010 -> 192.168.0.10
|
||||
* TODO - fix base libraries and remove this function
|
||||
* @param addr a string representing an ip addr
|
||||
* @return a string propertly trimmed
|
||||
*/
|
||||
public static String trimV4AddrZeros(String addr) {
|
||||
if (addr == null) return null;
|
||||
String[] octets = addr.split("\\.");
|
||||
if (octets.length != 4) return addr;
|
||||
StringBuilder builder = new StringBuilder(16);
|
||||
String result = null;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
try {
|
||||
if (octets[i].length() > 3) return addr;
|
||||
builder.append(Integer.parseInt(octets[i]));
|
||||
} catch (NumberFormatException e) {
|
||||
return addr;
|
||||
}
|
||||
if (i < 3) builder.append('.');
|
||||
}
|
||||
result = builder.toString();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
366
core/java/android/net/ProxyInfo.java
Normal file
366
core/java/android/net/ProxyInfo.java
Normal file
|
|
@ -0,0 +1,366 @@
|
|||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.apache.http.client.HttpClient;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URLConnection;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* Describes a proxy configuration.
|
||||
*
|
||||
* Proxy configurations are already integrated within the Apache HTTP stack.
|
||||
* So {@link URLConnection} and {@link HttpClient} will use them automatically.
|
||||
*
|
||||
* Other HTTP stacks will need to obtain the proxy info from
|
||||
* {@link Proxy#PROXY_CHANGE_ACTION} broadcast as the extra {@link Proxy#EXTRA_PROXY_INFO}.
|
||||
*/
|
||||
public class ProxyInfo implements Parcelable {
|
||||
|
||||
private String mHost;
|
||||
private int mPort;
|
||||
private String mExclusionList;
|
||||
private String[] mParsedExclusionList;
|
||||
|
||||
private Uri mPacFileUrl;
|
||||
/**
|
||||
*@hide
|
||||
*/
|
||||
public static final String LOCAL_EXCL_LIST = "";
|
||||
/**
|
||||
*@hide
|
||||
*/
|
||||
public static final int LOCAL_PORT = -1;
|
||||
/**
|
||||
*@hide
|
||||
*/
|
||||
public static final String LOCAL_HOST = "localhost";
|
||||
|
||||
/**
|
||||
* Constructs a {@link ProxyInfo} object that points at a Direct proxy
|
||||
* on the specified host and port.
|
||||
*/
|
||||
public static ProxyInfo buildDirectProxy(String host, int port) {
|
||||
return new ProxyInfo(host, port, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@link ProxyInfo} object that points at a Direct proxy
|
||||
* on the specified host and port.
|
||||
*
|
||||
* The proxy will not be used to access any host in exclusion list, exclList.
|
||||
*
|
||||
* @param exclList Hosts to exclude using the proxy on connections for. These
|
||||
* hosts can use wildcards such as *.example.com.
|
||||
*/
|
||||
public static ProxyInfo buildDirectProxy(String host, int port, List<String> exclList) {
|
||||
String[] array = exclList.toArray(new String[exclList.size()]);
|
||||
return new ProxyInfo(host, port, TextUtils.join(",", array), array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a {@link ProxyInfo} that will download and run the PAC script
|
||||
* at the specified URL.
|
||||
*/
|
||||
public static ProxyInfo buildPacProxy(Uri pacUri) {
|
||||
return new ProxyInfo(pacUri);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ProxyProperties that points at a HTTP Proxy.
|
||||
* @hide
|
||||
*/
|
||||
public ProxyInfo(String host, int port, String exclList) {
|
||||
mHost = host;
|
||||
mPort = port;
|
||||
setExclusionList(exclList);
|
||||
mPacFileUrl = Uri.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ProxyProperties that points at a PAC URL.
|
||||
* @hide
|
||||
*/
|
||||
public ProxyInfo(Uri pacFileUrl) {
|
||||
mHost = LOCAL_HOST;
|
||||
mPort = LOCAL_PORT;
|
||||
setExclusionList(LOCAL_EXCL_LIST);
|
||||
if (pacFileUrl == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
mPacFileUrl = pacFileUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a ProxyProperties that points at a PAC URL.
|
||||
* @hide
|
||||
*/
|
||||
public ProxyInfo(String pacFileUrl) {
|
||||
mHost = LOCAL_HOST;
|
||||
mPort = LOCAL_PORT;
|
||||
setExclusionList(LOCAL_EXCL_LIST);
|
||||
mPacFileUrl = Uri.parse(pacFileUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Only used in PacManager after Local Proxy is bound.
|
||||
* @hide
|
||||
*/
|
||||
public ProxyInfo(Uri pacFileUrl, int localProxyPort) {
|
||||
mHost = LOCAL_HOST;
|
||||
mPort = localProxyPort;
|
||||
setExclusionList(LOCAL_EXCL_LIST);
|
||||
if (pacFileUrl == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
mPacFileUrl = pacFileUrl;
|
||||
}
|
||||
|
||||
private ProxyInfo(String host, int port, String exclList, String[] parsedExclList) {
|
||||
mHost = host;
|
||||
mPort = port;
|
||||
mExclusionList = exclList;
|
||||
mParsedExclusionList = parsedExclList;
|
||||
mPacFileUrl = Uri.EMPTY;
|
||||
}
|
||||
|
||||
// copy constructor instead of clone
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public ProxyInfo(ProxyInfo source) {
|
||||
if (source != null) {
|
||||
mHost = source.getHost();
|
||||
mPort = source.getPort();
|
||||
mPacFileUrl = source.mPacFileUrl;
|
||||
mExclusionList = source.getExclusionListAsString();
|
||||
mParsedExclusionList = source.mParsedExclusionList;
|
||||
} else {
|
||||
mPacFileUrl = Uri.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public InetSocketAddress getSocketAddress() {
|
||||
InetSocketAddress inetSocketAddress = null;
|
||||
try {
|
||||
inetSocketAddress = new InetSocketAddress(mHost, mPort);
|
||||
} catch (IllegalArgumentException e) { }
|
||||
return inetSocketAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL of the current PAC script or null if there is
|
||||
* no PAC script.
|
||||
*/
|
||||
public Uri getPacFileUrl() {
|
||||
return mPacFileUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* When configured to use a Direct Proxy this returns the host
|
||||
* of the proxy.
|
||||
*/
|
||||
public String getHost() {
|
||||
return mHost;
|
||||
}
|
||||
|
||||
/**
|
||||
* When configured to use a Direct Proxy this returns the port
|
||||
* of the proxy
|
||||
*/
|
||||
public int getPort() {
|
||||
return mPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* When configured to use a Direct Proxy this returns the list
|
||||
* of hosts for which the proxy is ignored.
|
||||
*/
|
||||
public String[] getExclusionList() {
|
||||
return mParsedExclusionList;
|
||||
}
|
||||
|
||||
/**
|
||||
* comma separated
|
||||
* @hide
|
||||
*/
|
||||
public String getExclusionListAsString() {
|
||||
return mExclusionList;
|
||||
}
|
||||
|
||||
// comma separated
|
||||
private void setExclusionList(String exclusionList) {
|
||||
mExclusionList = exclusionList;
|
||||
if (mExclusionList == null) {
|
||||
mParsedExclusionList = new String[0];
|
||||
} else {
|
||||
mParsedExclusionList = exclusionList.toLowerCase(Locale.ROOT).split(",");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public boolean isValid() {
|
||||
if (!Uri.EMPTY.equals(mPacFileUrl)) return true;
|
||||
return Proxy.PROXY_VALID == Proxy.validate(mHost == null ? "" : mHost,
|
||||
mPort == 0 ? "" : Integer.toString(mPort),
|
||||
mExclusionList == null ? "" : mExclusionList);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public java.net.Proxy makeProxy() {
|
||||
java.net.Proxy proxy = java.net.Proxy.NO_PROXY;
|
||||
if (mHost != null) {
|
||||
try {
|
||||
InetSocketAddress inetSocketAddress = new InetSocketAddress(mHost, mPort);
|
||||
proxy = new java.net.Proxy(java.net.Proxy.Type.HTTP, inetSocketAddress);
|
||||
} catch (IllegalArgumentException e) {
|
||||
}
|
||||
}
|
||||
return proxy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (!Uri.EMPTY.equals(mPacFileUrl)) {
|
||||
sb.append("PAC Script: ");
|
||||
sb.append(mPacFileUrl);
|
||||
} else if (mHost != null) {
|
||||
sb.append("[");
|
||||
sb.append(mHost);
|
||||
sb.append("] ");
|
||||
sb.append(Integer.toString(mPort));
|
||||
if (mExclusionList != null) {
|
||||
sb.append(" xl=").append(mExclusionList);
|
||||
}
|
||||
} else {
|
||||
sb.append("[ProxyProperties.mHost == null]");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof ProxyInfo)) return false;
|
||||
ProxyInfo p = (ProxyInfo)o;
|
||||
// If PAC URL is present in either then they must be equal.
|
||||
// Other parameters will only be for fall back.
|
||||
if (!Uri.EMPTY.equals(mPacFileUrl)) {
|
||||
return mPacFileUrl.equals(p.getPacFileUrl()) && mPort == p.mPort;
|
||||
}
|
||||
if (!Uri.EMPTY.equals(p.mPacFileUrl)) {
|
||||
return false;
|
||||
}
|
||||
if (mExclusionList != null && !mExclusionList.equals(p.getExclusionListAsString())) {
|
||||
return false;
|
||||
}
|
||||
if (mHost != null && p.getHost() != null && mHost.equals(p.getHost()) == false) {
|
||||
return false;
|
||||
}
|
||||
if (mHost != null && p.mHost == null) return false;
|
||||
if (mHost == null && p.mHost != null) return false;
|
||||
if (mPort != p.mPort) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the Parcelable interface
|
||||
* @hide
|
||||
*/
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
/*
|
||||
* generate hashcode based on significant fields
|
||||
*/
|
||||
public int hashCode() {
|
||||
return ((null == mHost) ? 0 : mHost.hashCode())
|
||||
+ ((null == mExclusionList) ? 0 : mExclusionList.hashCode())
|
||||
+ mPort;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the Parcelable interface.
|
||||
* @hide
|
||||
*/
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
if (!Uri.EMPTY.equals(mPacFileUrl)) {
|
||||
dest.writeByte((byte)1);
|
||||
mPacFileUrl.writeToParcel(dest, 0);
|
||||
dest.writeInt(mPort);
|
||||
return;
|
||||
} else {
|
||||
dest.writeByte((byte)0);
|
||||
}
|
||||
if (mHost != null) {
|
||||
dest.writeByte((byte)1);
|
||||
dest.writeString(mHost);
|
||||
dest.writeInt(mPort);
|
||||
} else {
|
||||
dest.writeByte((byte)0);
|
||||
}
|
||||
dest.writeString(mExclusionList);
|
||||
dest.writeStringArray(mParsedExclusionList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the Parcelable interface.
|
||||
* @hide
|
||||
*/
|
||||
public static final Creator<ProxyInfo> CREATOR =
|
||||
new Creator<ProxyInfo>() {
|
||||
public ProxyInfo createFromParcel(Parcel in) {
|
||||
String host = null;
|
||||
int port = 0;
|
||||
if (in.readByte() != 0) {
|
||||
Uri url = Uri.CREATOR.createFromParcel(in);
|
||||
int localPort = in.readInt();
|
||||
return new ProxyInfo(url, localPort);
|
||||
}
|
||||
if (in.readByte() != 0) {
|
||||
host = in.readString();
|
||||
port = in.readInt();
|
||||
}
|
||||
String exclList = in.readString();
|
||||
String[] parsedExclList = in.readStringArray();
|
||||
ProxyInfo proxyProperties =
|
||||
new ProxyInfo(host, port, exclList, parsedExclList);
|
||||
return proxyProperties;
|
||||
}
|
||||
|
||||
public ProxyInfo[] newArray(int size) {
|
||||
return new ProxyInfo[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
453
core/java/android/net/RouteInfo.java
Normal file
453
core/java/android/net/RouteInfo.java
Normal file
|
|
@ -0,0 +1,453 @@
|
|||
/*
|
||||
* Copyright (C) 2011 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package android.net;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.net.UnknownHostException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Inet4Address;
|
||||
import java.net.Inet6Address;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Represents a network route.
|
||||
* <p>
|
||||
* This is used both to describe static network configuration and live network
|
||||
* configuration information.
|
||||
*
|
||||
* A route contains three pieces of information:
|
||||
* <ul>
|
||||
* <li>a destination {@link IpPrefix} specifying the network destinations covered by this route.
|
||||
* If this is {@code null} it indicates a default route of the address family (IPv4 or IPv6)
|
||||
* implied by the gateway IP address.
|
||||
* <li>a gateway {@link InetAddress} indicating the next hop to use. If this is {@code null} it
|
||||
* indicates a directly-connected route.
|
||||
* <li>an interface (which may be unspecified).
|
||||
* </ul>
|
||||
* Either the destination or the gateway may be {@code null}, but not both. If the
|
||||
* destination and gateway are both specified, they must be of the same address family
|
||||
* (IPv4 or IPv6).
|
||||
*/
|
||||
public class RouteInfo implements Parcelable {
|
||||
/**
|
||||
* The IP destination address for this route.
|
||||
* TODO: Make this an IpPrefix.
|
||||
*/
|
||||
private final LinkAddress mDestination;
|
||||
|
||||
/**
|
||||
* The gateway address for this route.
|
||||
*/
|
||||
private final InetAddress mGateway;
|
||||
|
||||
/**
|
||||
* The interface for this route.
|
||||
*/
|
||||
private final String mInterface;
|
||||
|
||||
private final boolean mIsDefault;
|
||||
private final boolean mIsHost;
|
||||
private final boolean mHasGateway;
|
||||
|
||||
/**
|
||||
* Constructs a RouteInfo object.
|
||||
*
|
||||
* If destination is null, then gateway must be specified and the
|
||||
* constructed route is either the IPv4 default route <code>0.0.0.0</code>
|
||||
* if the gateway is an instance of {@link Inet4Address}, or the IPv6 default
|
||||
* route <code>::/0</code> if gateway is an instance of
|
||||
* {@link Inet6Address}.
|
||||
* <p>
|
||||
* destination and gateway may not both be null.
|
||||
*
|
||||
* @param destination the destination prefix
|
||||
* @param gateway the IP address to route packets through
|
||||
* @param iface the interface name to send packets on
|
||||
*
|
||||
* TODO: Convert to use IpPrefix.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public RouteInfo(IpPrefix destination, InetAddress gateway, String iface) {
|
||||
this(destination == null ? null :
|
||||
new LinkAddress(destination.getAddress(), destination.getPrefixLength()),
|
||||
gateway, iface);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public RouteInfo(LinkAddress destination, InetAddress gateway, String iface) {
|
||||
if (destination == null) {
|
||||
if (gateway != null) {
|
||||
if (gateway instanceof Inet4Address) {
|
||||
destination = new LinkAddress(Inet4Address.ANY, 0);
|
||||
} else {
|
||||
destination = new LinkAddress(Inet6Address.ANY, 0);
|
||||
}
|
||||
} else {
|
||||
// no destination, no gateway. invalid.
|
||||
throw new IllegalArgumentException("Invalid arguments passed in: " + gateway + "," +
|
||||
destination);
|
||||
}
|
||||
}
|
||||
if (gateway == null) {
|
||||
if (destination.getAddress() instanceof Inet4Address) {
|
||||
gateway = Inet4Address.ANY;
|
||||
} else {
|
||||
gateway = Inet6Address.ANY;
|
||||
}
|
||||
}
|
||||
mHasGateway = (!gateway.isAnyLocalAddress());
|
||||
|
||||
mDestination = new LinkAddress(NetworkUtils.getNetworkPart(destination.getAddress(),
|
||||
destination.getPrefixLength()), destination.getPrefixLength());
|
||||
if ((destination.getAddress() instanceof Inet4Address &&
|
||||
(gateway instanceof Inet4Address == false)) ||
|
||||
(destination.getAddress() instanceof Inet6Address &&
|
||||
(gateway instanceof Inet6Address == false))) {
|
||||
throw new IllegalArgumentException("address family mismatch in RouteInfo constructor");
|
||||
}
|
||||
mGateway = gateway;
|
||||
mInterface = iface;
|
||||
mIsDefault = isDefault();
|
||||
mIsHost = isHost();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@code RouteInfo} object.
|
||||
*
|
||||
* If destination is null, then gateway must be specified and the
|
||||
* constructed route is either the IPv4 default route <code>0.0.0.0</code>
|
||||
* if the gateway is an instance of {@link Inet4Address}, or the IPv6 default
|
||||
* route <code>::/0</code> if gateway is an instance of {@link Inet6Address}.
|
||||
* <p>
|
||||
* Destination and gateway may not both be null.
|
||||
*
|
||||
* @param destination the destination address and prefix in an {@link IpPrefix}
|
||||
* @param gateway the {@link InetAddress} to route packets through
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public RouteInfo(IpPrefix destination, InetAddress gateway) {
|
||||
this(destination, gateway, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public RouteInfo(LinkAddress destination, InetAddress gateway) {
|
||||
this(destination, gateway, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a default {@code RouteInfo} object.
|
||||
*
|
||||
* @param gateway the {@link InetAddress} to route packets through
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public RouteInfo(InetAddress gateway) {
|
||||
this((LinkAddress) null, gateway, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a {@code RouteInfo} object representing a direct connected subnet.
|
||||
*
|
||||
* @param destination the {@link IpPrefix} describing the address and prefix
|
||||
* length of the subnet.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public RouteInfo(IpPrefix destination) {
|
||||
this(destination, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public RouteInfo(LinkAddress destination) {
|
||||
this(destination, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static RouteInfo makeHostRoute(InetAddress host, String iface) {
|
||||
return makeHostRoute(host, null, iface);
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static RouteInfo makeHostRoute(InetAddress host, InetAddress gateway, String iface) {
|
||||
if (host == null) return null;
|
||||
|
||||
if (host instanceof Inet4Address) {
|
||||
return new RouteInfo(new LinkAddress(host, 32), gateway, iface);
|
||||
} else {
|
||||
return new RouteInfo(new LinkAddress(host, 128), gateway, iface);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isHost() {
|
||||
return (mDestination.getAddress() instanceof Inet4Address &&
|
||||
mDestination.getPrefixLength() == 32) ||
|
||||
(mDestination.getAddress() instanceof Inet6Address &&
|
||||
mDestination.getPrefixLength() == 128);
|
||||
}
|
||||
|
||||
private boolean isDefault() {
|
||||
boolean val = false;
|
||||
if (mGateway != null) {
|
||||
if (mGateway instanceof Inet4Address) {
|
||||
val = (mDestination == null || mDestination.getPrefixLength() == 0);
|
||||
} else {
|
||||
val = (mDestination == null || mDestination.getPrefixLength() == 0);
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the destination address and prefix length in the form of an {@link IpPrefix}.
|
||||
*
|
||||
* @return {@link IpPrefix} specifying the destination. This is never {@code null}.
|
||||
*/
|
||||
public IpPrefix getDestination() {
|
||||
return new IpPrefix(mDestination.getAddress(), mDestination.getPrefixLength());
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Convert callers to use IpPrefix and then remove.
|
||||
* @hide
|
||||
*/
|
||||
public LinkAddress getDestinationLinkAddress() {
|
||||
return mDestination;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the gateway or next hop {@link InetAddress} for this route.
|
||||
*
|
||||
* @return {@link InetAddress} specifying the gateway or next hop. This may be
|
||||
& {@code null} for a directly-connected route."
|
||||
*/
|
||||
public InetAddress getGateway() {
|
||||
return mGateway;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the interface used for this route if specified, else {@code null}.
|
||||
*
|
||||
* @return The name of the interface used for this route.
|
||||
*/
|
||||
public String getInterface() {
|
||||
return mInterface;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this route is a default route (ie, has no destination specified).
|
||||
*
|
||||
* @return {@code true} if the destination has a prefix length of 0.
|
||||
*/
|
||||
public boolean isDefaultRoute() {
|
||||
return mIsDefault;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this route is a host route (ie, matches only a single host address).
|
||||
*
|
||||
* @return {@code true} if the destination has a prefix length of 32 or 128 for IPv4 or IPv6,
|
||||
* respectively.
|
||||
* @hide
|
||||
*/
|
||||
public boolean isHostRoute() {
|
||||
return mIsHost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if this route has a next hop ({@code true}) or is directly-connected
|
||||
* ({@code false}).
|
||||
*
|
||||
* @return {@code true} if a gateway is specified
|
||||
* @hide
|
||||
*/
|
||||
public boolean hasGateway() {
|
||||
return mHasGateway;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the destination and prefix of this route includes the specified
|
||||
* address.
|
||||
*
|
||||
* @param destination A {@link InetAddress} to test to see if it would match this route.
|
||||
* @return {@code true} if the destination and prefix length cover the given address.
|
||||
*/
|
||||
public boolean matches(InetAddress destination) {
|
||||
if (destination == null) return false;
|
||||
|
||||
// match the route destination and destination with prefix length
|
||||
InetAddress dstNet = NetworkUtils.getNetworkPart(destination,
|
||||
mDestination.getPrefixLength());
|
||||
|
||||
return mDestination.getAddress().equals(dstNet);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the route from a Collection of routes that best matches a given address.
|
||||
* May return null if no routes are applicable.
|
||||
* @param routes a Collection of RouteInfos to chose from
|
||||
* @param dest the InetAddress your trying to get to
|
||||
* @return the RouteInfo from the Collection that best fits the given address
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static RouteInfo selectBestRoute(Collection<RouteInfo> routes, InetAddress dest) {
|
||||
if ((routes == null) || (dest == null)) return null;
|
||||
|
||||
RouteInfo bestRoute = null;
|
||||
// pick a longest prefix match under same address type
|
||||
for (RouteInfo route : routes) {
|
||||
if (NetworkUtils.addressTypeMatches(route.mDestination.getAddress(), dest)) {
|
||||
if ((bestRoute != null) &&
|
||||
(bestRoute.mDestination.getPrefixLength() >=
|
||||
route.mDestination.getPrefixLength())) {
|
||||
continue;
|
||||
}
|
||||
if (route.matches(dest)) bestRoute = route;
|
||||
}
|
||||
}
|
||||
return bestRoute;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a human-readable description of this object.
|
||||
*/
|
||||
public String toString() {
|
||||
String val = "";
|
||||
if (mDestination != null) val = mDestination.toString();
|
||||
val += " ->";
|
||||
if (mGateway != null) val += " " + mGateway.getHostAddress();
|
||||
if (mInterface != null) val += " " + mInterface;
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares this RouteInfo object against the specified object and indicates if they are equal.
|
||||
* @return {@code true} if the objects are equal, {@code false} otherwise.
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
|
||||
if (!(obj instanceof RouteInfo)) return false;
|
||||
|
||||
RouteInfo target = (RouteInfo) obj;
|
||||
|
||||
return Objects.equals(mDestination, target.getDestinationLinkAddress()) &&
|
||||
Objects.equals(mGateway, target.getGateway()) &&
|
||||
Objects.equals(mInterface, target.getInterface());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashcode for this <code>RouteInfo</code> object.
|
||||
*/
|
||||
public int hashCode() {
|
||||
return (mDestination == null ? 0 : mDestination.hashCode() * 41)
|
||||
+ (mGateway == null ? 0 :mGateway.hashCode() * 47)
|
||||
+ (mInterface == null ? 0 :mInterface.hashCode() * 67)
|
||||
+ (mIsDefault ? 3 : 7);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the Parcelable interface
|
||||
* @hide
|
||||
*/
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the Parcelable interface
|
||||
* @hide
|
||||
*/
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
if (mDestination == null) {
|
||||
dest.writeByte((byte) 0);
|
||||
} else {
|
||||
dest.writeByte((byte) 1);
|
||||
dest.writeByteArray(mDestination.getAddress().getAddress());
|
||||
dest.writeInt(mDestination.getPrefixLength());
|
||||
}
|
||||
|
||||
if (mGateway == null) {
|
||||
dest.writeByte((byte) 0);
|
||||
} else {
|
||||
dest.writeByte((byte) 1);
|
||||
dest.writeByteArray(mGateway.getAddress());
|
||||
}
|
||||
|
||||
dest.writeString(mInterface);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement the Parcelable interface.
|
||||
* @hide
|
||||
*/
|
||||
public static final Creator<RouteInfo> CREATOR =
|
||||
new Creator<RouteInfo>() {
|
||||
public RouteInfo createFromParcel(Parcel in) {
|
||||
InetAddress destAddr = null;
|
||||
int prefix = 0;
|
||||
InetAddress gateway = null;
|
||||
|
||||
if (in.readByte() == 1) {
|
||||
byte[] addr = in.createByteArray();
|
||||
prefix = in.readInt();
|
||||
|
||||
try {
|
||||
destAddr = InetAddress.getByAddress(addr);
|
||||
} catch (UnknownHostException e) {}
|
||||
}
|
||||
|
||||
if (in.readByte() == 1) {
|
||||
byte[] addr = in.createByteArray();
|
||||
|
||||
try {
|
||||
gateway = InetAddress.getByAddress(addr);
|
||||
} catch (UnknownHostException e) {}
|
||||
}
|
||||
|
||||
String iface = in.readString();
|
||||
|
||||
LinkAddress dest = null;
|
||||
|
||||
if (destAddr != null) {
|
||||
dest = new LinkAddress(destAddr, prefix);
|
||||
}
|
||||
|
||||
return new RouteInfo(dest, gateway, iface);
|
||||
}
|
||||
|
||||
public RouteInfo[] newArray(int size) {
|
||||
return new RouteInfo[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
337
core/jni/android_net_NetUtils.cpp
Normal file
337
core/jni/android_net_NetUtils.cpp
Normal file
|
|
@ -0,0 +1,337 @@
|
|||
/*
|
||||
* Copyright 2008, 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.
|
||||
*/
|
||||
|
||||
#define LOG_TAG "NetUtils"
|
||||
|
||||
#include "jni.h"
|
||||
#include "JNIHelp.h"
|
||||
#include "NetdClient.h"
|
||||
#include "resolv_netid.h"
|
||||
#include <utils/misc.h>
|
||||
#include <android_runtime/AndroidRuntime.h>
|
||||
#include <utils/Log.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <cutils/properties.h>
|
||||
|
||||
extern "C" {
|
||||
int ifc_enable(const char *ifname);
|
||||
int ifc_disable(const char *ifname);
|
||||
int ifc_reset_connections(const char *ifname, int reset_mask);
|
||||
|
||||
int dhcp_do_request(const char * const ifname,
|
||||
const char *ipaddr,
|
||||
const char *gateway,
|
||||
uint32_t *prefixLength,
|
||||
const char *dns[],
|
||||
const char *server,
|
||||
uint32_t *lease,
|
||||
const char *vendorInfo,
|
||||
const char *domains,
|
||||
const char *mtu);
|
||||
|
||||
int dhcp_do_request_renew(const char * const ifname,
|
||||
const char *ipaddr,
|
||||
const char *gateway,
|
||||
uint32_t *prefixLength,
|
||||
const char *dns[],
|
||||
const char *server,
|
||||
uint32_t *lease,
|
||||
const char *vendorInfo,
|
||||
const char *domains,
|
||||
const char *mtu);
|
||||
|
||||
int dhcp_stop(const char *ifname);
|
||||
int dhcp_release_lease(const char *ifname);
|
||||
char *dhcp_get_errmsg();
|
||||
}
|
||||
|
||||
#define NETUTILS_PKG_NAME "android/net/NetworkUtils"
|
||||
|
||||
namespace android {
|
||||
|
||||
/*
|
||||
* The following remembers the jfieldID's of the fields
|
||||
* of the DhcpInfo Java object, so that we don't have
|
||||
* to look them up every time.
|
||||
*/
|
||||
static struct fieldIds {
|
||||
jmethodID clear;
|
||||
jmethodID setInterfaceName;
|
||||
jmethodID addLinkAddress;
|
||||
jmethodID addGateway;
|
||||
jmethodID addDns;
|
||||
jmethodID setDomains;
|
||||
jmethodID setServerAddress;
|
||||
jmethodID setLeaseDuration;
|
||||
jmethodID setVendorInfo;
|
||||
} dhcpResultsFieldIds;
|
||||
|
||||
static jint android_net_utils_enableInterface(JNIEnv* env, jobject clazz, jstring ifname)
|
||||
{
|
||||
int result;
|
||||
|
||||
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
|
||||
result = ::ifc_enable(nameStr);
|
||||
env->ReleaseStringUTFChars(ifname, nameStr);
|
||||
return (jint)result;
|
||||
}
|
||||
|
||||
static jint android_net_utils_disableInterface(JNIEnv* env, jobject clazz, jstring ifname)
|
||||
{
|
||||
int result;
|
||||
|
||||
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
|
||||
result = ::ifc_disable(nameStr);
|
||||
env->ReleaseStringUTFChars(ifname, nameStr);
|
||||
return (jint)result;
|
||||
}
|
||||
|
||||
static jint android_net_utils_resetConnections(JNIEnv* env, jobject clazz,
|
||||
jstring ifname, jint mask)
|
||||
{
|
||||
int result;
|
||||
|
||||
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
|
||||
|
||||
ALOGD("android_net_utils_resetConnections in env=%p clazz=%p iface=%s mask=0x%x\n",
|
||||
env, clazz, nameStr, mask);
|
||||
|
||||
result = ::ifc_reset_connections(nameStr, mask);
|
||||
env->ReleaseStringUTFChars(ifname, nameStr);
|
||||
return (jint)result;
|
||||
}
|
||||
|
||||
static jboolean android_net_utils_runDhcpCommon(JNIEnv* env, jobject clazz, jstring ifname,
|
||||
jobject dhcpResults, bool renew)
|
||||
{
|
||||
int result;
|
||||
char ipaddr[PROPERTY_VALUE_MAX];
|
||||
uint32_t prefixLength;
|
||||
char gateway[PROPERTY_VALUE_MAX];
|
||||
char dns1[PROPERTY_VALUE_MAX];
|
||||
char dns2[PROPERTY_VALUE_MAX];
|
||||
char dns3[PROPERTY_VALUE_MAX];
|
||||
char dns4[PROPERTY_VALUE_MAX];
|
||||
const char *dns[5] = {dns1, dns2, dns3, dns4, NULL};
|
||||
char server[PROPERTY_VALUE_MAX];
|
||||
uint32_t lease;
|
||||
char vendorInfo[PROPERTY_VALUE_MAX];
|
||||
char domains[PROPERTY_VALUE_MAX];
|
||||
char mtu[PROPERTY_VALUE_MAX];
|
||||
|
||||
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
|
||||
if (nameStr == NULL) return (jboolean)false;
|
||||
|
||||
if (renew) {
|
||||
result = ::dhcp_do_request_renew(nameStr, ipaddr, gateway, &prefixLength,
|
||||
dns, server, &lease, vendorInfo, domains, mtu);
|
||||
} else {
|
||||
result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
|
||||
dns, server, &lease, vendorInfo, domains, mtu);
|
||||
}
|
||||
if (result != 0) {
|
||||
ALOGD("dhcp_do_request failed : %s (%s)", nameStr, renew ? "renew" : "new");
|
||||
}
|
||||
|
||||
env->ReleaseStringUTFChars(ifname, nameStr);
|
||||
if (result == 0) {
|
||||
env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.clear);
|
||||
|
||||
// set mIfaceName
|
||||
// dhcpResults->setInterfaceName(ifname)
|
||||
env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setInterfaceName, ifname);
|
||||
|
||||
// set the linkAddress
|
||||
// dhcpResults->addLinkAddress(inetAddress, prefixLength)
|
||||
result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.addLinkAddress,
|
||||
env->NewStringUTF(ipaddr), prefixLength);
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
// set the gateway
|
||||
// dhcpResults->addGateway(gateway)
|
||||
result = env->CallBooleanMethod(dhcpResults,
|
||||
dhcpResultsFieldIds.addGateway, env->NewStringUTF(gateway));
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
// dhcpResults->addDns(new InetAddress(dns1))
|
||||
result = env->CallBooleanMethod(dhcpResults,
|
||||
dhcpResultsFieldIds.addDns, env->NewStringUTF(dns1));
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setDomains,
|
||||
env->NewStringUTF(domains));
|
||||
|
||||
result = env->CallBooleanMethod(dhcpResults,
|
||||
dhcpResultsFieldIds.addDns, env->NewStringUTF(dns2));
|
||||
|
||||
if (result == 0) {
|
||||
result = env->CallBooleanMethod(dhcpResults,
|
||||
dhcpResultsFieldIds.addDns, env->NewStringUTF(dns3));
|
||||
if (result == 0) {
|
||||
result = env->CallBooleanMethod(dhcpResults,
|
||||
dhcpResultsFieldIds.addDns, env->NewStringUTF(dns4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
// dhcpResults->setServerAddress(new InetAddress(server))
|
||||
result = env->CallBooleanMethod(dhcpResults, dhcpResultsFieldIds.setServerAddress,
|
||||
env->NewStringUTF(server));
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
// dhcpResults->setLeaseDuration(lease)
|
||||
env->CallVoidMethod(dhcpResults,
|
||||
dhcpResultsFieldIds.setLeaseDuration, lease);
|
||||
|
||||
// dhcpResults->setVendorInfo(vendorInfo)
|
||||
env->CallVoidMethod(dhcpResults, dhcpResultsFieldIds.setVendorInfo,
|
||||
env->NewStringUTF(vendorInfo));
|
||||
}
|
||||
return (jboolean)(result == 0);
|
||||
}
|
||||
|
||||
|
||||
static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
|
||||
{
|
||||
return android_net_utils_runDhcpCommon(env, clazz, ifname, info, false);
|
||||
}
|
||||
|
||||
static jboolean android_net_utils_runDhcpRenew(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
|
||||
{
|
||||
return android_net_utils_runDhcpCommon(env, clazz, ifname, info, true);
|
||||
}
|
||||
|
||||
|
||||
static jboolean android_net_utils_stopDhcp(JNIEnv* env, jobject clazz, jstring ifname)
|
||||
{
|
||||
int result;
|
||||
|
||||
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
|
||||
result = ::dhcp_stop(nameStr);
|
||||
env->ReleaseStringUTFChars(ifname, nameStr);
|
||||
return (jboolean)(result == 0);
|
||||
}
|
||||
|
||||
static jboolean android_net_utils_releaseDhcpLease(JNIEnv* env, jobject clazz, jstring ifname)
|
||||
{
|
||||
int result;
|
||||
|
||||
const char *nameStr = env->GetStringUTFChars(ifname, NULL);
|
||||
result = ::dhcp_release_lease(nameStr);
|
||||
env->ReleaseStringUTFChars(ifname, nameStr);
|
||||
return (jboolean)(result == 0);
|
||||
}
|
||||
|
||||
static jstring android_net_utils_getDhcpError(JNIEnv* env, jobject clazz)
|
||||
{
|
||||
return env->NewStringUTF(::dhcp_get_errmsg());
|
||||
}
|
||||
|
||||
static void android_net_utils_markSocket(JNIEnv *env, jobject thiz, jint socket, jint mark)
|
||||
{
|
||||
if (setsockopt(socket, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) < 0) {
|
||||
jniThrowException(env, "java/lang/IllegalStateException", "Error marking socket");
|
||||
}
|
||||
}
|
||||
|
||||
static void android_net_utils_bindProcessToNetwork(JNIEnv *env, jobject thiz, jint netId)
|
||||
{
|
||||
setNetworkForProcess(netId);
|
||||
}
|
||||
|
||||
static void android_net_utils_unbindProcessToNetwork(JNIEnv *env, jobject thiz)
|
||||
{
|
||||
setNetworkForProcess(NETID_UNSET);
|
||||
}
|
||||
|
||||
static jint android_net_utils_getNetworkBoundToProcess(JNIEnv *env, jobject thiz)
|
||||
{
|
||||
return getNetworkForProcess();
|
||||
}
|
||||
|
||||
static void android_net_utils_bindProcessToNetworkForHostResolution(JNIEnv *env, jobject thiz, jint netId)
|
||||
{
|
||||
setNetworkForResolv(netId);
|
||||
}
|
||||
|
||||
static void android_net_utils_unbindProcessToNetworkForHostResolution(JNIEnv *env, jobject thiz)
|
||||
{
|
||||
setNetworkForResolv(NETID_UNSET);
|
||||
}
|
||||
|
||||
static void android_net_utils_bindSocketToNetwork(JNIEnv *env, jobject thiz, jint socket, jint netId)
|
||||
{
|
||||
setNetworkForSocket(netId, socket);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* JNI registration.
|
||||
*/
|
||||
static JNINativeMethod gNetworkUtilMethods[] = {
|
||||
/* name, signature, funcPtr */
|
||||
|
||||
{ "enableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_enableInterface },
|
||||
{ "disableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_disableInterface },
|
||||
{ "resetConnections", "(Ljava/lang/String;I)I", (void *)android_net_utils_resetConnections },
|
||||
{ "runDhcp", "(Ljava/lang/String;Landroid/net/DhcpResults;)Z", (void *)android_net_utils_runDhcp },
|
||||
{ "runDhcpRenew", "(Ljava/lang/String;Landroid/net/DhcpResults;)Z", (void *)android_net_utils_runDhcpRenew },
|
||||
{ "stopDhcp", "(Ljava/lang/String;)Z", (void *)android_net_utils_stopDhcp },
|
||||
{ "releaseDhcpLease", "(Ljava/lang/String;)Z", (void *)android_net_utils_releaseDhcpLease },
|
||||
{ "getDhcpError", "()Ljava/lang/String;", (void*) android_net_utils_getDhcpError },
|
||||
{ "markSocket", "(II)V", (void*) android_net_utils_markSocket },
|
||||
{ "bindProcessToNetwork", "(I)V", (void*) android_net_utils_bindProcessToNetwork },
|
||||
{ "getNetworkBoundToProcess", "()I", (void*) android_net_utils_getNetworkBoundToProcess },
|
||||
{ "unbindProcessToNetwork", "()V", (void*) android_net_utils_unbindProcessToNetwork },
|
||||
{ "bindProcessToNetworkForHostResolution", "(I)V", (void*) android_net_utils_bindProcessToNetworkForHostResolution },
|
||||
{ "unbindProcessToNetworkForHostResolution", "()V", (void*) android_net_utils_unbindProcessToNetworkForHostResolution },
|
||||
{ "bindSocketToNetwork", "(II)V", (void*) android_net_utils_bindSocketToNetwork },
|
||||
};
|
||||
|
||||
int register_android_net_NetworkUtils(JNIEnv* env)
|
||||
{
|
||||
jclass dhcpResultsClass = env->FindClass("android/net/DhcpResults");
|
||||
LOG_FATAL_IF(dhcpResultsClass == NULL, "Unable to find class android/net/DhcpResults");
|
||||
dhcpResultsFieldIds.clear =
|
||||
env->GetMethodID(dhcpResultsClass, "clear", "()V");
|
||||
dhcpResultsFieldIds.setInterfaceName =
|
||||
env->GetMethodID(dhcpResultsClass, "setInterfaceName", "(Ljava/lang/String;)V");
|
||||
dhcpResultsFieldIds.addLinkAddress =
|
||||
env->GetMethodID(dhcpResultsClass, "addLinkAddress", "(Ljava/lang/String;I)Z");
|
||||
dhcpResultsFieldIds.addGateway =
|
||||
env->GetMethodID(dhcpResultsClass, "addGateway", "(Ljava/lang/String;)Z");
|
||||
dhcpResultsFieldIds.addDns =
|
||||
env->GetMethodID(dhcpResultsClass, "addDns", "(Ljava/lang/String;)Z");
|
||||
dhcpResultsFieldIds.setDomains =
|
||||
env->GetMethodID(dhcpResultsClass, "setDomains", "(Ljava/lang/String;)V");
|
||||
dhcpResultsFieldIds.setServerAddress =
|
||||
env->GetMethodID(dhcpResultsClass, "setServerAddress", "(Ljava/lang/String;)Z");
|
||||
dhcpResultsFieldIds.setLeaseDuration =
|
||||
env->GetMethodID(dhcpResultsClass, "setLeaseDuration", "(I)V");
|
||||
dhcpResultsFieldIds.setVendorInfo =
|
||||
env->GetMethodID(dhcpResultsClass, "setVendorInfo", "(Ljava/lang/String;)V");
|
||||
|
||||
return AndroidRuntime::registerNativeMethods(env,
|
||||
NETUTILS_PKG_NAME, gNetworkUtilMethods, NELEM(gNetworkUtilMethods));
|
||||
}
|
||||
|
||||
}; // namespace android
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
ifname total_skb_rx_bytes total_skb_rx_packets total_skb_tx_bytes total_skb_tx_packets
|
||||
rmnet2 4968 35 3081 39
|
||||
rmnet1 11153922 8051 190226 2468
|
||||
rmnet0 6824 16 5692 10
|
||||
6
core/tests/coretests/res/raw/xt_qtaguid_iface_typical
Normal file
6
core/tests/coretests/res/raw/xt_qtaguid_iface_typical
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
rmnet3 1 0 0 0 0 20822 501 1149991 815
|
||||
rmnet2 1 0 0 0 0 1594 15 1313 15
|
||||
rmnet1 1 0 0 0 0 207398 458 166918 565
|
||||
rmnet0 1 0 0 0 0 2112 24 700 10
|
||||
test1 1 1 2 3 4 5 6 7 8
|
||||
test2 0 1 2 3 4 5 6 7 8
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue