diff --git a/core/java/android/net/LinkAddress.java b/core/java/android/net/LinkAddress.java new file mode 100644 index 0000000000..cb302da56b --- /dev/null +++ b/core/java/android/net/LinkAddress.java @@ -0,0 +1,149 @@ +/* + * 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.InetAddress; +import java.net.InterfaceAddress; +import java.net.UnknownHostException; + +/** + * Identifies an address of a network link + * @hide + */ +public class LinkAddress implements Parcelable { + /** + * IPv4 or IPv6 address. + */ + private final InetAddress address; + + /** + * Network prefix + */ + private final int prefix; + + public LinkAddress(InetAddress address, InetAddress mask) { + this.address = address; + this.prefix = computeprefix(mask); + } + + public LinkAddress(InetAddress address, int prefix) { + this.address = address; + this.prefix = prefix; + } + + public LinkAddress(InterfaceAddress interfaceAddress) { + this.address = interfaceAddress.getAddress(); + this.prefix = interfaceAddress.getNetworkPrefixLength(); + } + + private static int computeprefix(InetAddress mask) { + int count = 0; + for (byte b : mask.getAddress()) { + for (int i = 0; i < 8; ++i) { + if ((b & (1 << i)) != 0) { + ++count; + } + } + } + return count; + } + + @Override + public String toString() { + return (address == null ? "" : (address.getHostAddress() + "/" + prefix)); + } + + /** + * Compares this {@code LinkAddress} instance against the specified address + * in {@code obj}. Two addresses are equal if their InetAddress and prefix + * are equal + * + * @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.prefix == linkAddress.prefix; + } + + /** + * Returns the InetAddress for this address. + */ + public InetAddress getAddress() { + return address; + } + + /** + * Get network prefix length + */ + public int getNetworkPrefix() { + return prefix; + } + + /** + * Implement the Parcelable interface + * @hide + */ + public int describeContents() { + return 0; + } + + /** + * Implement the Parcelable interface. + * @hide + */ + public void writeToParcel(Parcel dest, int flags) { + if (address != null) { + dest.writeByte((byte)1); + dest.writeByteArray(address.getAddress()); + dest.writeInt(prefix); + } else { + dest.writeByte((byte)0); + } + } + + /** + * Implement the Parcelable interface. + * @hide + */ + public static final Creator CREATOR = + new Creator() { + public LinkAddress createFromParcel(Parcel in) { + InetAddress address = null; + int prefix = 0; + if (in.readByte() == 1) { + try { + address = InetAddress.getByAddress(in.createByteArray()); + prefix = in.readInt(); + } catch (UnknownHostException e) { } + } + return new LinkAddress(address, prefix); + } + + public LinkAddress[] newArray(int size) { + return new LinkAddress[size]; + } + }; +} diff --git a/core/java/android/net/LinkProperties.java b/core/java/android/net/LinkProperties.java index f411eac1b2..f1545eab46 100644 --- a/core/java/android/net/LinkProperties.java +++ b/core/java/android/net/LinkProperties.java @@ -36,8 +36,8 @@ import java.util.Collections; */ public class LinkProperties implements Parcelable { - private NetworkInterface mIface; - private Collection mAddresses; + String mIfaceName; + private Collection mLinkAddresses; private Collection mDnses; private InetAddress mGateway; private ProxyProperties mHttpProxy; @@ -49,34 +49,42 @@ public class LinkProperties implements Parcelable { // copy constructor instead of clone public LinkProperties(LinkProperties source) { if (source != null) { - mIface = source.getInterface(); - mAddresses = source.getAddresses(); + mIfaceName = source.getInterfaceName(); + mLinkAddresses = source.getLinkAddresses(); mDnses = source.getDnses(); mGateway = source.getGateway(); mHttpProxy = new ProxyProperties(source.getHttpProxy()); } } - public void setInterface(NetworkInterface iface) { - mIface = iface; - } - public NetworkInterface getInterface() { - return mIface; - } - public String getInterfaceName() { - return (mIface == null ? null : mIface.getName()); + public void setInterfaceName(String iface) { + mIfaceName = iface; } - public void addAddress(InetAddress address) { - mAddresses.add(address); + public String getInterfaceName() { + return mIfaceName; } + public Collection getAddresses() { - return Collections.unmodifiableCollection(mAddresses); + Collection addresses = new ArrayList(); + for (LinkAddress linkAddress : mLinkAddresses) { + addresses.add(linkAddress.getAddress()); + } + return Collections.unmodifiableCollection(addresses); + } + + public void addLinkAddress(LinkAddress address) { + mLinkAddresses.add(address); + } + + public Collection getLinkAddresses() { + return Collections.unmodifiableCollection(mLinkAddresses); } public void addDns(InetAddress dns) { mDnses.add(dns); } + public Collection getDnses() { return Collections.unmodifiableCollection(mDnses); } @@ -96,8 +104,8 @@ public class LinkProperties implements Parcelable { } public void clear() { - mIface = null; - mAddresses = new ArrayList(); + mIfaceName = null; + mLinkAddresses = new ArrayList(); mDnses = new ArrayList(); mGateway = null; mHttpProxy = null; @@ -113,11 +121,11 @@ public class LinkProperties implements Parcelable { @Override public String toString() { - String ifaceName = (mIface == null ? "" : "InterfaceName: " + mIface.getName() + " "); + String ifaceName = (mIfaceName == null ? "" : "InterfaceName: " + mIfaceName + " "); - String ip = "IpAddresses: ["; - for (InetAddress addr : mAddresses) ip += addr.getHostAddress() + ","; - ip += "] "; + String linkAddresses = "LinkAddresses: ["; + for (LinkAddress addr : mLinkAddresses) linkAddresses += addr.toString(); + linkAddresses += "] "; String dns = "DnsAddresses: ["; for (InetAddress addr : mDnses) dns += addr.getHostAddress() + ","; @@ -126,7 +134,7 @@ public class LinkProperties implements Parcelable { String proxy = (mHttpProxy == null ? "" : "HttpProxy: " + mHttpProxy.toString() + " "); String gateway = (mGateway == null ? "" : "Gateway: " + mGateway.getHostAddress() + " "); - return ifaceName + ip + gateway + dns + proxy; + return ifaceName + linkAddresses + gateway + dns + proxy; } /** @@ -135,12 +143,11 @@ public class LinkProperties implements Parcelable { */ public void writeToParcel(Parcel dest, int flags) { dest.writeString(getInterfaceName()); - dest.writeInt(mAddresses.size()); - //TODO: explore an easy alternative to preserve hostname - // without doing a lookup - for(InetAddress a : mAddresses) { - dest.writeByteArray(a.getAddress()); + dest.writeInt(mLinkAddresses.size()); + for(LinkAddress linkAddress : mLinkAddresses) { + dest.writeParcelable(linkAddress, flags); } + dest.writeInt(mDnses.size()); for(InetAddress d : mDnses) { dest.writeByteArray(d.getAddress()); @@ -170,16 +177,14 @@ public class LinkProperties implements Parcelable { String iface = in.readString(); if (iface != null) { try { - netProp.setInterface(NetworkInterface.getByName(iface)); + netProp.setInterfaceName(iface); } catch (Exception e) { return null; } } int addressCount = in.readInt(); for (int i=0; i