diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java index 5fd5315fe888e..e74db67023667 100644 --- a/core/java/android/net/MobileDataStateTracker.java +++ b/core/java/android/net/MobileDataStateTracker.java @@ -29,6 +29,7 @@ import com.android.internal.telephony.Phone; import com.android.internal.telephony.TelephonyIntents; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo; +import android.net.NetworkProperties; import android.telephony.TelephonyManager; import android.util.Log; import android.text.TextUtils; @@ -55,7 +56,7 @@ public class MobileDataStateTracker implements NetworkStateTracker { private boolean mTeardownRequested = false; private Handler mTarget; private Context mContext; - private String mInterfaceName; + private NetworkProperties mNetworkProperties; private boolean mPrivateDnsRouteSet = false; private int mDefaultGatewayAddr = 0; private boolean mDefaultRouteSet = false; @@ -101,14 +102,6 @@ public class MobileDataStateTracker implements NetworkStateTracker { return sDnsPropNames; } - /** - * Return the name of our network interface. - * @return the name of our interface. - */ - public String getInterfaceName() { - return mInterfaceName; - } - public boolean isPrivateDnsRouteSet() { return mPrivateDnsRouteSet; } @@ -211,9 +204,11 @@ public class MobileDataStateTracker implements NetworkStateTracker { } setDetailedState(DetailedState.DISCONNECTED, reason, apnName); - if (mInterfaceName != null) { - NetworkUtils.resetConnections(mInterfaceName); + if (mNetworkProperties != null) { + NetworkUtils.resetConnections(mNetworkProperties.getInterface(). + getName()); } + // TODO - check this // can't do this here - ConnectivityService needs it to clear stuff // it's ok though - just leave it to be refreshed next time // we connect. @@ -229,9 +224,11 @@ public class MobileDataStateTracker implements NetworkStateTracker { setDetailedState(DetailedState.SUSPENDED, reason, apnName); break; case CONNECTED: - mInterfaceName = intent.getStringExtra(Phone.DATA_IFACE_NAME_KEY); - if (mInterfaceName == null) { - Log.d(TAG, "CONNECTED event did not supply interface name."); + mNetworkProperties = intent.getParcelableExtra( + Phone.DATA_NETWORK_PROPERTIES_KEY); + if (mNetworkProperties == null) { + Log.d(TAG, + "CONNECTED event did not supply network properties."); } setDetailedState(DetailedState.CONNECTED, reason, apnName); break; @@ -565,4 +562,8 @@ public class MobileDataStateTracker implements NetworkStateTracker { return null; } } + + public NetworkProperties getNetworkProperties() { + return mNetworkProperties; + } } diff --git a/core/java/android/net/NetworkProperties.aidl b/core/java/android/net/NetworkProperties.aidl new file mode 100644 index 0000000000000..07aac6ec101f3 --- /dev/null +++ b/core/java/android/net/NetworkProperties.aidl @@ -0,0 +1,22 @@ +/* +** +** Copyright (C) 2009 Qualcomm Innovation Center, Inc. All Rights Reserved. +** Copyright (C) 2009 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; + +parcelable NetworkProperties; + diff --git a/core/java/android/net/NetworkProperties.java b/core/java/android/net/NetworkProperties.java new file mode 100644 index 0000000000000..56e1f1a485b01 --- /dev/null +++ b/core/java/android/net/NetworkProperties.java @@ -0,0 +1,196 @@ +/* + * 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 android.util.Log; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Collection; + +/** + * Describes the properties of a network interface or single address + * of an interface. + * TODO - consider adding optional fields like Apn and ApnType + * @hide + */ +public class NetworkProperties implements Parcelable { + + private NetworkInterface mIface; + private Collection mAddresses; + private Collection mDnses; + private InetAddress mGateway; + private ProxyProperties mHttpProxy; + + public NetworkProperties() { + clear(); + } + + public synchronized void setInterface(NetworkInterface iface) { + mIface = iface; + } + public synchronized NetworkInterface getInterface() { + return mIface; + } + public synchronized String getInterfaceName() { + return (mIface == null ? null : mIface.getName()); + } + + public synchronized void addAddress(InetAddress address) { + mAddresses.add(address); + } + public synchronized Collection getAddresses() { + return mAddresses; + } + + public synchronized void addDns(InetAddress dns) { + mDnses.add(dns); + } + public synchronized Collection getDnses() { + return mDnses; + } + + public synchronized void setGateway(InetAddress gateway) { + mGateway = gateway; + } + public synchronized InetAddress getGateway() { + return mGateway; + } + + public synchronized void setHttpProxy(ProxyProperties proxy) { + mHttpProxy = proxy; + } + public synchronized ProxyProperties getHttpProxy() { + return mHttpProxy; + } + + public synchronized void clear() { + mIface = null; + mAddresses = new ArrayList(); + mDnses = new ArrayList(); + mGateway = null; + mHttpProxy = null; + } + + /** + * Implement the Parcelable interface + * @hide + */ + public int describeContents() { + return 0; + } + + public synchronized String toString() { + String ifaceName = (mIface == null ? "" : "InterfaceName: " + mIface.getName() + " "); + + String ip = "IpAddresses: ["; + for (InetAddress addr : mAddresses) ip += addr.toString() + ","; + ip += "] "; + + String dns = "DnsAddresses: ["; + for (InetAddress addr : mDnses) dns += addr.toString() + ","; + dns += "] "; + + String proxy = (mHttpProxy == null ? "" : "HttpProxy: " + mHttpProxy.toString() + " "); + String gateway = (mGateway == null ? "" : "Gateway: " + mGateway.toString() + " "); + + return ifaceName + ip + gateway + dns + proxy; + } + + /** + * Implement the Parcelable interface. + * @hide + */ + public synchronized void writeToParcel(Parcel dest, int flags) { + dest.writeString(getInterfaceName()); + dest.writeInt(mAddresses.size()); + for(InetAddress a : mAddresses) { + dest.writeString(a.getHostName()); + dest.writeByteArray(a.getAddress()); + } + dest.writeInt(mDnses.size()); + for(InetAddress d : mDnses) { + dest.writeString(d.getHostName()); + dest.writeByteArray(d.getAddress()); + } + if (mGateway != null) { + dest.writeByte((byte)1); + dest.writeString(mGateway.getHostName()); + dest.writeByteArray(mGateway.getAddress()); + } else { + dest.writeByte((byte)0); + } + if (mHttpProxy != null) { + dest.writeByte((byte)1); + dest.writeParcelable(mHttpProxy, flags); + } else { + dest.writeByte((byte)0); + } + } + + /** + * Implement the Parcelable interface. + * @hide + */ + public static final Creator CREATOR = + new Creator() { + public NetworkProperties createFromParcel(Parcel in) { + NetworkProperties netProp = new NetworkProperties(); + String iface = in.readString(); + if (iface != null) { + try { + netProp.setInterface(NetworkInterface.getByName(iface)); + } catch (Exception e) { + return null; + } + } + int addressCount = in.readInt(); + for (int i=0; i> 8) & 0xff); + addrBytes[2] = (byte)((addr >> 16) & 0xff); + addrBytes[3] = (byte)((addr >> 24) & 0xff); + return addrBytes; + } + + public static int v4StringToInt(String str) { + int result = 0; + String[] array = str.split("\\."); + if (array.length != 4) return 0; try { - inetAddress = InetAddress.getByName(hostname); - } catch (UnknownHostException e) { - return -1; + result = Integer.parseInt(array[3]); + result = (result << 8) + Integer.parseInt(array[2]); + result = (result << 8) + Integer.parseInt(array[1]); + result = (result << 8) + Integer.parseInt(array[0]); + } catch (NumberFormatException e) { + return 0; } - byte[] addrBytes; - int addr; - addrBytes = inetAddress.getAddress(); - addr = ((addrBytes[3] & 0xff) << 24) - | ((addrBytes[2] & 0xff) << 16) - | ((addrBytes[1] & 0xff) << 8) - | (addrBytes[0] & 0xff); - return addr; + return result; } } diff --git a/core/java/android/net/ProxyProperties.java b/core/java/android/net/ProxyProperties.java new file mode 100644 index 0000000000000..6828dd4fac637 --- /dev/null +++ b/core/java/android/net/ProxyProperties.java @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2007 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.net; + + +import android.os.Parcel; +import android.os.Parcelable; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +/** + * A container class for the http proxy info + * @hide + */ +public class ProxyProperties implements Parcelable { + + private InetAddress mProxy; + private int mPort; + private String mExclusionList; + + public ProxyProperties() { + } + + public synchronized InetAddress getAddress() { + return mProxy; + } + public synchronized void setAddress(InetAddress proxy) { + mProxy = proxy; + } + + public synchronized int getPort() { + return mPort; + } + public synchronized void setPort(int port) { + mPort = port; + } + + public synchronized String getExclusionList() { + return mExclusionList; + } + public synchronized void setExclusionList(String exclusionList) { + mExclusionList = exclusionList; + } + + /** + * Implement the Parcelable interface + * @hide + */ + public int describeContents() { + return 0; + } + + /** + * Implement the Parcelable interface. + * @hide + */ + public synchronized void writeToParcel(Parcel dest, int flags) { + if (mProxy != null) { + dest.writeByte((byte)1); + dest.writeString(mProxy.getHostName()); + dest.writeByteArray(mProxy.getAddress()); + } else { + dest.writeByte((byte)0); + } + dest.writeInt(mPort); + dest.writeString(mExclusionList); + } + + /** + * Implement the Parcelable interface. + * @hide + */ + public static final Creator CREATOR = + new Creator() { + public ProxyProperties createFromParcel(Parcel in) { + ProxyProperties proxyProperties = new ProxyProperties(); + if (in.readByte() == 1) { + try { + proxyProperties.setAddress(InetAddress.getByAddress(in.readString(), + in.createByteArray())); + } catch (UnknownHostException e) {} + } + proxyProperties.setPort(in.readInt()); + proxyProperties.setExclusionList(in.readString()); + return proxyProperties; + } + + public ProxyProperties[] newArray(int size) { + return new ProxyProperties[size]; + } + }; + +}; diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp index feb0dadc15b1d..3cde9d63ed6d5 100644 --- a/core/jni/android_net_NetUtils.cpp +++ b/core/jni/android_net_NetUtils.cpp @@ -222,10 +222,10 @@ static JNINativeMethod gNetworkUtilMethods[] = { { "enableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_enableInterface }, { "disableInterface", "(Ljava/lang/String;)I", (void *)android_net_utils_disableInterface }, - { "addHostRoute", "(Ljava/lang/String;I)I", (void *)android_net_utils_addHostRoute }, + { "addHostRouteNative", "(Ljava/lang/String;I)I", (void *)android_net_utils_addHostRoute }, { "removeHostRoutes", "(Ljava/lang/String;)I", (void *)android_net_utils_removeHostRoutes }, - { "setDefaultRoute", "(Ljava/lang/String;I)I", (void *)android_net_utils_setDefaultRoute }, - { "getDefaultRoute", "(Ljava/lang/String;)I", (void *)android_net_utils_getDefaultRoute }, + { "setDefaultRouteNative", "(Ljava/lang/String;I)I", (void *)android_net_utils_setDefaultRoute }, + { "getDefaultRouteNative", "(Ljava/lang/String;)I", (void *)android_net_utils_getDefaultRoute }, { "removeDefaultRoute", "(Ljava/lang/String;)I", (void *)android_net_utils_removeDefaultRoute }, { "resetConnections", "(Ljava/lang/String;)I", (void *)android_net_utils_resetConnections }, { "runDhcp", "(Ljava/lang/String;Landroid/net/DhcpInfo;)Z", (void *)android_net_utils_runDhcp }, diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java index 9ff7de6152783..9c504feac92bd 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -26,6 +26,7 @@ import android.net.ConnectivityManager; import android.net.IConnectivityManager; import android.net.MobileDataStateTracker; import android.net.NetworkInfo; +import android.net.NetworkProperties; import android.net.NetworkStateTracker; import android.net.wifi.WifiStateTracker; import android.net.NetworkUtils; @@ -51,7 +52,10 @@ import java.io.FileDescriptor; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; +import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.ArrayList; +import java.util.Collection; import java.util.List; /** @@ -741,6 +745,7 @@ public class ConnectivityService extends IConnectivityManager.Stub { * specified host is to be routed * @param hostAddress the IP address of the host to which the route is * desired + * todo - deprecate (only v4!) * @return {@code true} on success, {@code false} on failure */ public boolean requestRouteToHost(int networkType, int hostAddress) { @@ -757,7 +762,11 @@ public class ConnectivityService extends IConnectivityManager.Stub { } return false; } - return addHostRoute(tracker, hostAddress); + try { + InetAddress addr = InetAddress.getByAddress(NetworkUtils.v4IntToArray(hostAddress)); + return addHostRoute(tracker, addr); + } catch (UnknownHostException e) {} + return false; } /** @@ -765,22 +774,25 @@ public class ConnectivityService extends IConnectivityManager.Stub { * host via the mobile data network. * @param hostAddress the IP address of the host to which the route is desired, * in network byte order. + * TODO - deprecate * @return {@code true} on success, {@code false} on failure */ - private boolean addHostRoute(NetworkStateTracker nt, int hostAddress) { + private boolean addHostRoute(NetworkStateTracker nt, InetAddress hostAddress) { if (nt.getNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI) { return false; } - String interfaceName = nt.getInterfaceName(); + NetworkProperties p = nt.getNetworkProperties(); + if (p == null) return false; + String interfaceName = p.getInterfaceName(); if (DBG) { - Slog.d(TAG, "Requested host route to " + Integer.toHexString(hostAddress) + - "(" + interfaceName + ")"); + Slog.d(TAG, "Requested host route to " + hostAddress + "(" + interfaceName + ")"); } - if (interfaceName != null && hostAddress != -1) { + if (interfaceName != null) { return NetworkUtils.addHostRoute(interfaceName, hostAddress) == 0; } else { + if (DBG) Slog.e(TAG, "addHostRoute failed due to null interface name"); return false; } } @@ -1251,21 +1263,20 @@ public class ConnectivityService extends IConnectivityManager.Stub { } private void addPrivateDnsRoutes(NetworkStateTracker nt) { - String interfaceName = nt.getInterfaceName(); boolean privateDnsRouteSet = nt.isPrivateDnsRouteSet(); + NetworkProperties p = nt.getNetworkProperties(); + if (p == null) return; + String interfaceName = p.getInterfaceName(); if (DBG) { Slog.d(TAG, "addPrivateDnsRoutes for " + nt + "(" + interfaceName + ") - mPrivateDnsRouteSet = " + privateDnsRouteSet); } - String[] dnsList = getNameServerList(nt.getDnsPropNames()); if (interfaceName != null && !privateDnsRouteSet) { - for (String addrString : dnsList) { - int addr = NetworkUtils.lookupHost(addrString); - if (addr != -1 && addr != 0) { - if (DBG) Slog.d(TAG, " adding "+addrString+" ("+addr+")"); - NetworkUtils.addHostRoute(interfaceName, addr); - } + Collection dnsList = p.getDnses(); + for (InetAddress dns : dnsList) { + if (DBG) Slog.d(TAG, " adding " + dns); + NetworkUtils.addHostRoute(interfaceName, dns); } nt.privateDnsRouteSet(true); } @@ -1274,7 +1285,9 @@ public class ConnectivityService extends IConnectivityManager.Stub { private void removePrivateDnsRoutes(NetworkStateTracker nt) { // TODO - we should do this explicitly but the NetUtils api doesnt // support this yet - must remove all. No worse than before - String interfaceName = nt.getInterfaceName(); + NetworkProperties p = nt.getNetworkProperties(); + if (p == null) return; + String interfaceName = p.getInterfaceName(); boolean privateDnsRouteSet = nt.isPrivateDnsRouteSet(); if (interfaceName != null && privateDnsRouteSet) { if (DBG) { @@ -1286,61 +1299,42 @@ public class ConnectivityService extends IConnectivityManager.Stub { } } - /** - * Return the IP addresses of the DNS servers available for this - * network interface. - * @param propertyNames the names of the system properties whose values - * give the IP addresses. Properties with no values are skipped. - * @return an array of {@code String}s containing the IP addresses - * of the DNS servers, in dot-notation. This may have fewer - * non-null entries than the list of names passed in, since - * some of the passed-in names may have empty values. - */ - String[] getNameServerList(String[] propertyNames) { - String[] dnsAddresses = new String[propertyNames.length]; - int i, j; - - for (i = 0, j = 0; i < propertyNames.length; i++) { - String value = SystemProperties.get(propertyNames[i]); - // The GSM layer sometimes sets a bogus DNS server address of - // 0.0.0.0 - if (!TextUtils.isEmpty(value) && !TextUtils.equals(value, "0.0.0.0")) { - dnsAddresses[j++] = value; - } - } - return dnsAddresses; - } private void addDefaultRoute(NetworkStateTracker nt) { - String interfaceName = nt.getInterfaceName(); - int defaultGatewayAddr = nt.getDefaultGatewayAddr(); + NetworkProperties p = nt.getNetworkProperties(); + if (p == null) return; + String interfaceName = p.getInterfaceName(); + InetAddress defaultGatewayAddr = p.getGateway(); boolean defaultRouteSet = nt.isDefaultRouteSet(); - NetworkInfo networkInfo = nt.getNetworkInfo(); - if ((interfaceName != null) && (defaultGatewayAddr != 0) && - defaultRouteSet == false) { - if (DBG) { + if ((interfaceName != null) && (defaultGatewayAddr != null ) && + (defaultRouteSet == false)) { + boolean error = (NetworkUtils.setDefaultRoute(interfaceName, defaultGatewayAddr) < 0); + + if (DBG && !error) { + NetworkInfo networkInfo = nt.getNetworkInfo(); Slog.d(TAG, "addDefaultRoute for " + networkInfo.getTypeName() + " (" + interfaceName + "), GatewayAddr=" + defaultGatewayAddr); } - NetworkUtils.setDefaultRoute(interfaceName, defaultGatewayAddr); - nt.defaultRouteSet(true); + nt.defaultRouteSet(!error); } } public void removeDefaultRoute(NetworkStateTracker nt) { - String interfaceName = nt.getInterfaceName(); + NetworkProperties p = nt.getNetworkProperties(); + if (p == null) return; + String interfaceName = p.getInterfaceName(); boolean defaultRouteSet = nt.isDefaultRouteSet(); - NetworkInfo networkInfo = nt.getNetworkInfo(); if (interfaceName != null && defaultRouteSet == true) { - if (DBG) { + boolean error = (NetworkUtils.removeDefaultRoute(interfaceName) < 0); + if (DBG && !error) { + NetworkInfo networkInfo = nt.getNetworkInfo(); Slog.d(TAG, "removeDefaultRoute for " + networkInfo.getTypeName() + " (" + interfaceName + ")"); } - NetworkUtils.removeDefaultRoute(interfaceName); - nt.defaultRouteSet(false); + nt.defaultRouteSet(error); } } @@ -1430,12 +1424,14 @@ public class ConnectivityService extends IConnectivityManager.Stub { NetworkStateTracker nt = mNetTrackers[i]; if (nt.getNetworkInfo().isConnected() && !nt.isTeardownRequested()) { + NetworkProperties p = nt.getNetworkProperties(); + if (p == null) continue; List pids = mNetRequestersPids[i]; for (int j=0; j dnses = p.getDnses(); + writePidDns(dnses, myPid); if (doBump) { bumpDns(); } @@ -1457,12 +1453,10 @@ public class ConnectivityService extends IConnectivityManager.Stub { } } - private void writePidDns(String[] dnsList, int pid) { + private void writePidDns(Collection dnses, int pid) { int j = 1; - for (String dns : dnsList) { - if (dns != null && !TextUtils.equals(dns, "0.0.0.0")) { - SystemProperties.set("net.dns" + j++ + "." + pid, dns); - } + for (InetAddress dns : dnses) { + SystemProperties.set("net.dns" + j++ + "." + pid, dns.getHostAddress()); } } @@ -1488,17 +1482,17 @@ public class ConnectivityService extends IConnectivityManager.Stub { NetworkStateTracker nt = mNetTrackers[netType]; if (nt != null && nt.getNetworkInfo().isConnected() && !nt.isTeardownRequested()) { - String[] dnsList = getNameServerList(nt.getDnsPropNames()); + NetworkProperties p = nt.getNetworkProperties(); + if (p == null) continue; + Collection dnses = p.getDnses(); if (mNetAttributes[netType].isDefault()) { int j = 1; - for (String dns : dnsList) { - if (dns != null && !TextUtils.equals(dns, "0.0.0.0")) { - if (DBG) { - Slog.d(TAG, "adding dns " + dns + " for " + - nt.getNetworkInfo().getTypeName()); - } - SystemProperties.set("net.dns" + j++, dns); + for (InetAddress dns : dnses) { + if (DBG) { + Slog.d(TAG, "adding dns " + dns + " for " + + nt.getNetworkInfo().getTypeName()); } + SystemProperties.set("net.dns" + j++, dns.getHostAddress()); } for (int k=j ; k mConnectedApns; - private String mDataConnectionInterfaceName = ""; + private NetworkProperties mDataConnectionProperties; private Bundle mCellLocation = new Bundle(); @@ -353,7 +355,8 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } public void notifyDataConnection(int state, boolean isDataConnectivityPossible, - String reason, String apn, String apnType, String interfaceName, int networkType) { + String reason, String apn, String apnType, NetworkProperties networkProperties, + int networkType) { if (!checkNotifyPermission("notifyDataConnection()" )) { return; } @@ -380,7 +383,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { mDataConnectionPossible = isDataConnectivityPossible; mDataConnectionReason = reason; mDataConnectionApn = apn; - mDataConnectionInterfaceName = interfaceName; + mDataConnectionProperties = networkProperties; if (mDataConnectionNetworkType != networkType) { mDataConnectionNetworkType = networkType; modified = true; @@ -400,7 +403,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } } broadcastDataConnectionStateChanged(state, isDataConnectivityPossible, reason, apn, - apnType, interfaceName); + apnType, networkProperties); } public void notifyDataConnectionFailed(String reason, String apnType) { @@ -487,7 +490,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { pw.println(" mDataConnectionPossible=" + mDataConnectionPossible); pw.println(" mDataConnectionReason=" + mDataConnectionReason); pw.println(" mDataConnectionApn=" + mDataConnectionApn); - pw.println(" mDataConnectionInterfaceName=" + mDataConnectionInterfaceName); + pw.println(" mDataConnectionProperties=" + mDataConnectionProperties); pw.println(" mCellLocation=" + mCellLocation); pw.println("registrations: count=" + recordCount); for (Record r : mRecords) { @@ -561,7 +564,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { private void broadcastDataConnectionStateChanged(int state, boolean isDataConnectivityPossible, - String reason, String apn, String apnType, String interfaceName) { + String reason, String apn, String apnType, NetworkProperties networkProperties) { // Note: not reporting to the battery stats service here, because the // status bar takes care of that after taking into account all of the // required info. @@ -574,9 +577,15 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { if (reason != null) { intent.putExtra(Phone.STATE_CHANGE_REASON_KEY, reason); } + if (networkProperties != null) { + intent.putExtra(Phone.DATA_NETWORK_PROPERTIES_KEY, networkProperties); + NetworkInterface iface = networkProperties.getInterface(); + if (iface != null) { + intent.putExtra(Phone.DATA_IFACE_NAME_KEY, iface.getName()); + } + } intent.putExtra(Phone.DATA_APN_KEY, apn); intent.putExtra(Phone.DATA_APN_TYPE_KEY, apnType); - intent.putExtra(Phone.DATA_IFACE_NAME_KEY, interfaceName); mContext.sendStickyBroadcast(intent); } diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java index e71fe2e5b02bd..06807c6542189 100644 --- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java @@ -17,6 +17,7 @@ package com.android.internal.telephony; import android.app.PendingIntent; +import android.net.NetworkProperties; import android.os.AsyncResult; import android.os.Handler; import android.os.Message; @@ -26,6 +27,10 @@ import android.provider.Settings.SettingNotFoundException; import android.text.TextUtils; import android.util.Log; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.net.UnknownHostException; import java.util.ArrayList; /** @@ -191,6 +196,9 @@ public abstract class DataConnectionTracker extends Handler { /** indication of our availability (preconditions to trysetupData are met) **/ protected boolean mAvailability = false; + /** all our network properties (dns, gateway, ip, etc) */ + protected NetworkProperties mNetworkProperties; + /** * Default constructor */ @@ -424,6 +432,15 @@ public abstract class DataConnectionTracker extends Handler { protected abstract void setState(State s); + protected NetworkProperties getNetworkProperties(String apnType) { + int id = apnTypeToId(apnType); + if (isApnIdEnabled(id)) { + return mNetworkProperties; + } else { + return null; + } + } + // tell all active apns of the current condition protected void notifyDataConnection(String reason) { for (int id = 0; id < APN_NUM_TYPES; id++) { @@ -668,5 +685,43 @@ public abstract class DataConnectionTracker extends Handler { } } + protected NetworkProperties makeNetworkProperties(DataConnection connection) { + NetworkProperties properties = new NetworkProperties(); + try { + properties.setInterface(NetworkInterface.getByName(connection.getInterface())); + } catch (SocketException e) { + Log.e(LOG_TAG, "SocketException creating NetworkInterface: " + e); + } catch (NullPointerException e) { + Log.e(LOG_TAG, "NPE trying to makeNetworkProperties: " + e); + } + try { + properties.addAddress(InetAddress.getByName(connection.getIpAddress())); + } catch (UnknownHostException e) { + Log.e(LOG_TAG, "UnknownHostException setting IpAddress: " + e); + } catch (SecurityException e) { + Log.e(LOG_TAG, "SecurityException setting IpAddress: " + e); + } + + try { + properties.setGateway(InetAddress.getByName(connection.getGatewayAddress())); + } catch (UnknownHostException e) { + Log.e(LOG_TAG, "UnknownHostException setting GatewayAddress: " + e); + } catch (SecurityException e) { + Log.e(LOG_TAG, "SecurityException setting GatewayAddress: " + e); + } + + try { + String[] dnsStrings = connection.getDnsServers(); + for (int i = 0; iPhoneStateNotifier or an equivalent. diff --git a/telephony/java/com/android/internal/telephony/PhoneBase.java b/telephony/java/com/android/internal/telephony/PhoneBase.java index cf80691f96ceb..e5968a7d298ea 100644 --- a/telephony/java/com/android/internal/telephony/PhoneBase.java +++ b/telephony/java/com/android/internal/telephony/PhoneBase.java @@ -21,6 +21,7 @@ import android.app.IActivityManager; import android.content.Context; import android.content.res.Configuration; import android.content.SharedPreferences; +import android.net.NetworkProperties; import android.net.wifi.WifiManager; import android.os.AsyncResult; import android.os.Handler; @@ -955,6 +956,10 @@ public abstract class PhoneBase extends Handler implements Phone { return mDataConnection.getActiveApnTypes(); } + public NetworkProperties getNetworkProperties(String apnType) { + return mDataConnection.getNetworkProperties(apnType); + } + public String getActiveApn() { return mDataConnection.getActiveApnString(); } diff --git a/telephony/java/com/android/internal/telephony/PhoneProxy.java b/telephony/java/com/android/internal/telephony/PhoneProxy.java index fb2a938c85ab6..d84859cff40c9 100644 --- a/telephony/java/com/android/internal/telephony/PhoneProxy.java +++ b/telephony/java/com/android/internal/telephony/PhoneProxy.java @@ -21,6 +21,7 @@ import android.app.ActivityManagerNative; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.net.NetworkProperties; import android.os.Handler; import android.os.Message; import android.os.SystemProperties; @@ -211,6 +212,10 @@ public class PhoneProxy extends Handler implements Phone { return mActivePhone.getActiveApnTypes(); } + public NetworkProperties getNetworkProperties(String apnType) { + return mActivePhone.getNetworkProperties(apnType); + } + public String getActiveApn() { return mActivePhone.getActiveApn(); } diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java index bd103d4975676..8a3af3be4104a 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java @@ -53,6 +53,7 @@ import com.android.internal.telephony.Phone; import com.android.internal.telephony.RetryManager; import com.android.internal.telephony.ServiceStateTracker; +import java.net.NetworkInterface; import java.util.ArrayList; /** @@ -736,6 +737,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { } if (ar.exception == null) { + mNetworkProperties = makeNetworkProperties(mActiveDataConnection); + // everything is setup notifyDefaultData(reason); } else { diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index 6826fa8e2d41c..c76da80e5653a 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -30,6 +30,8 @@ import android.database.Cursor; import android.net.ConnectivityManager; import android.net.IConnectivityManager; import android.net.NetworkInfo; +import android.net.NetworkProperties; +import android.net.ProxyProperties; import android.net.TrafficStats; import android.net.Uri; import android.net.wifi.WifiManager; @@ -58,6 +60,9 @@ import com.android.internal.telephony.EventLogTags; import com.android.internal.telephony.DataConnection.FailCause; import java.io.IOException; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.UnknownHostException; import java.util.ArrayList; /** @@ -1133,6 +1138,25 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { } if (ar.exception == null) { + mNetworkProperties = makeNetworkProperties(mActivePdp); + + ApnSetting apn = mActivePdp.getApn(); + if (apn.proxy != null && apn.proxy.length() != 0) { + try { + ProxyProperties proxy = new ProxyProperties(); + proxy.setAddress(InetAddress.getByName(apn.proxy)); + proxy.setPort(Integer.parseInt(apn.port)); + mNetworkProperties.setHttpProxy(proxy); + } catch (UnknownHostException e) { + Log.e(LOG_TAG, "UnknownHostException making ProxyProperties: " + e); + } catch (SecurityException e) { + Log.e(LOG_TAG, "SecurityException making ProxyProperties: " + e); + } catch (NumberFormatException e) { + Log.e(LOG_TAG, "NumberFormatException making ProxyProperties (" + apn.port + + "): " + e); + } + } + // everything is setup if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) { SystemProperties.set("gsm.defaultpdpcontext.active", "true"); diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java index 5b4faf97c4af7..5780a04c0c35e 100644 --- a/wifi/java/android/net/wifi/WifiStateTracker.java +++ b/wifi/java/android/net/wifi/WifiStateTracker.java @@ -30,6 +30,7 @@ import android.net.NetworkUtils; import android.net.ConnectivityManager; import android.net.NetworkInfo.DetailedState; import android.net.NetworkInfo.State; +import android.net.NetworkProperties; import android.os.Message; import android.os.Parcelable; import android.os.Handler; @@ -54,6 +55,9 @@ import android.content.Context; import android.database.ContentObserver; import com.android.internal.app.IBatteryStats; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.List; @@ -211,6 +215,7 @@ public class WifiStateTracker extends Handler implements NetworkStateTracker { private boolean mDisconnectExpected; private DhcpHandler mDhcpTarget; private DhcpInfo mDhcpInfo; + private NetworkProperties mNetworkProperties; private int mLastSignalLevel = -1; private String mLastBssid; private String mLastSsid; @@ -315,7 +320,6 @@ public class WifiStateTracker extends Handler implements NetworkStateTracker { private String mInterfaceName; private static String LS = System.getProperty("line.separator"); - private static String[] sDnsPropNames; private Handler mTarget; private Context mContext; private boolean mPrivateDnsRouteSet = false; @@ -379,10 +383,7 @@ public class WifiStateTracker extends Handler implements NetworkStateTracker { mSettingsObserver = new SettingsObserver(new Handler()); mInterfaceName = SystemProperties.get("wifi.interface", "tiwlan0"); - sDnsPropNames = new String[] { - "dhcp." + mInterfaceName + ".dns1", - "dhcp." + mInterfaceName + ".dns2" - }; + mNetworkProperties = new NetworkProperties(); mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo")); } @@ -476,15 +477,6 @@ public class WifiStateTracker extends Handler implements NetworkStateTracker { updateNetworkInfo(); } - /** - * Return the IP addresses of the DNS servers available for the WLAN - * network interface. - * @return a list of DNS addresses, with no holes. - */ - public String[] getDnsPropNames() { - return sDnsPropNames; - } - /** * Return the name of our WLAN network interface. * @return the name of our interface. @@ -901,6 +893,7 @@ public class WifiStateTracker extends Handler implements NetworkStateTracker { } setDetailedState(DetailedState.DISCONNECTED); setSupplicantState(SupplicantState.UNINITIALIZED); + mNetworkProperties.clear(); mHaveIpAddress = false; mObtainingIpAddress = false; if (died) { @@ -1008,6 +1001,7 @@ public class WifiStateTracker extends Handler implements NetworkStateTracker { reconnectCommand(); } } else if (newState == SupplicantState.DISCONNECTED) { + mNetworkProperties.clear(); mHaveIpAddress = false; if (isDriverStopped() || mDisconnectExpected) { handleDisconnectedState(DetailedState.DISCONNECTED, true); @@ -1192,6 +1186,7 @@ public class WifiStateTracker extends Handler implements NetworkStateTracker { } mReconnectCount = 0; mHaveIpAddress = true; + configureNetworkProperties(); mObtainingIpAddress = false; mWifiInfo.setIpAddress(mDhcpInfo.ipAddress); mLastSignalLevel = -1; // force update of signal strength @@ -1217,6 +1212,7 @@ public class WifiStateTracker extends Handler implements NetworkStateTracker { // [31- 1] Reserved for future use // [ 0- 0] Interface configuration succeeded (1) or failed (0) EventLog.writeEvent(EVENTLOG_INTERFACE_CONFIGURATION_STATE_CHANGED, 0); + mNetworkProperties.clear(); mHaveIpAddress = false; mWifiInfo.setIpAddress(0); mObtainingIpAddress = false; @@ -1289,6 +1285,49 @@ public class WifiStateTracker extends Handler implements NetworkStateTracker { return disabledNetwork; } + + private void configureNetworkProperties() { + try { + mNetworkProperties.setInterface(NetworkInterface.getByName(mInterfaceName)); + } catch (SocketException e) { + Log.e(TAG, "SocketException creating NetworkInterface from " + mInterfaceName + + ". e=" + e); + return; + } catch (NullPointerException e) { + Log.e(TAG, "NPE creating NetworkInterface. e=" + e); + return; + } + // TODO - fix this for v6 + try { + mNetworkProperties.addAddress(InetAddress.getByAddress( + NetworkUtils.v4IntToArray(mDhcpInfo.ipAddress))); + } catch (UnknownHostException e) { + Log.e(TAG, "Exception setting IpAddress using " + mDhcpInfo + ", e=" + e); + } + + try { + mNetworkProperties.setGateway(InetAddress.getByAddress(NetworkUtils.v4IntToArray( + mDhcpInfo.gateway))); + } catch (UnknownHostException e) { + Log.e(TAG, "Exception setting Gateway using " + mDhcpInfo + ", e=" + e); + } + + try { + mNetworkProperties.addDns(InetAddress.getByAddress( + NetworkUtils.v4IntToArray(mDhcpInfo.dns1))); + } catch (UnknownHostException e) { + Log.e(TAG, "Exception setting Dns1 using " + mDhcpInfo + ", e=" + e); + } + try { + mNetworkProperties.addDns(InetAddress.getByAddress( + NetworkUtils.v4IntToArray(mDhcpInfo.dns2))); + + } catch (UnknownHostException e) { + Log.e(TAG, "Exception setting Dns2 using " + mDhcpInfo + ", e=" + e); + } + // TODO - add proxy info + } + private void configureInterface() { checkPollTimer(); mLastSignalLevel = -1; @@ -1300,11 +1339,9 @@ public class WifiStateTracker extends Handler implements NetworkStateTracker { } else { int event; if (NetworkUtils.configureInterface(mInterfaceName, mDhcpInfo)) { - mHaveIpAddress = true; event = EVENT_INTERFACE_CONFIGURATION_SUCCEEDED; if (LOCAL_LOGD) Log.v(TAG, "Static IP configuration succeeded"); } else { - mHaveIpAddress = false; event = EVENT_INTERFACE_CONFIGURATION_FAILED; if (LOCAL_LOGD) Log.v(TAG, "Static IP configuration failed"); } @@ -1339,6 +1376,7 @@ public class WifiStateTracker extends Handler implements NetworkStateTracker { */ public void resetConnections(boolean disableInterface) { if (LOCAL_LOGD) Log.d(TAG, "Reset connections and stopping DHCP"); + mNetworkProperties.clear(); mHaveIpAddress = false; mObtainingIpAddress = false; mWifiInfo.setIpAddress(0); @@ -2282,11 +2320,12 @@ public class WifiStateTracker extends Handler implements NetworkStateTracker { mNotificationRepeatTime = 0; mNumScansSinceNetworkStateChange = 0; } - + @Override public String toString() { StringBuffer sb = new StringBuffer(); - sb.append("interface ").append(mInterfaceName); + + sb.append(mNetworkProperties.toString()); sb.append(" runState="); if (mRunState >= 1 && mRunState <= mRunStateNames.length) { sb.append(mRunStateNames[mRunState-1]); @@ -2366,7 +2405,7 @@ public class WifiStateTracker extends Handler implements NetworkStateTracker { setBluetoothCoexistenceMode( WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED); } - + powerMode = getPowerMode(); if (powerMode < 0) { // Handle the case where supplicant driver does not support @@ -2588,4 +2627,8 @@ public class WifiStateTracker extends Handler implements NetworkStateTracker { Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 1) == 1; } } + + public NetworkProperties getNetworkProperties() { + return mNetworkProperties; + } }