From 0900f3657664d9046e6723825fd32b244eef2b6c Mon Sep 17 00:00:00 2001 From: Mike Lockwood Date: Fri, 10 Jul 2009 17:24:07 -0400 Subject: [PATCH] wifi: Keep the WLAN network interface up whenever wifi is enabled. We now only bring it down briefly and bring it back up again when we want to reset the interface. Signed-off-by: Mike Lockwood --- core/java/android/net/NetworkUtils.java | 3 +++ core/jni/android_net_NetUtils.cpp | 12 ++++++++++++ .../java/com/android/server/WifiService.java | 11 +++++++++-- .../android/net/wifi/WifiStateTracker.java | 19 +++++++++++++++---- 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java index 115364872955d..a3ae01b5597b6 100644 --- a/core/java/android/net/NetworkUtils.java +++ b/core/java/android/net/NetworkUtils.java @@ -25,6 +25,9 @@ import java.net.UnknownHostException; * {@hide} */ public class 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); diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp index 8383deb59a725..feb0dadc15b1d 100644 --- a/core/jni/android_net_NetUtils.cpp +++ b/core/jni/android_net_NetUtils.cpp @@ -23,6 +23,7 @@ #include extern "C" { +int ifc_enable(const char *ifname); int ifc_disable(const char *ifname); int ifc_add_host_route(const char *ifname, uint32_t addr); int ifc_remove_host_routes(const char *ifname); @@ -66,6 +67,16 @@ static struct fieldIds { jfieldID leaseDuration; } dhcpInfoFieldIds; +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; @@ -209,6 +220,7 @@ static jboolean android_net_utils_configureInterface(JNIEnv* env, 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 }, { "addHostRoute", "(Ljava/lang/String;I)I", (void *)android_net_utils_addHostRoute }, { "removeHostRoutes", "(Ljava/lang/String;)I", (void *)android_net_utils_removeHostRoutes }, diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java index 55b7a30a7b165..a561d119cd795 100644 --- a/services/java/com/android/server/WifiService.java +++ b/services/java/com/android/server/WifiService.java @@ -41,6 +41,7 @@ import android.net.wifi.WifiConfiguration; import android.net.wifi.SupplicantState; import android.net.NetworkStateTracker; import android.net.DhcpInfo; +import android.net.NetworkUtils; import android.os.Binder; import android.os.Handler; import android.os.HandlerThread; @@ -344,7 +345,7 @@ public class WifiService extends IWifiManager.Stub { } // We must reset the interface before we unload the driver - mWifiStateTracker.resetInterface(); + mWifiStateTracker.resetInterface(false); if (!WifiNative.unloadDriver()) { Log.e(TAG, "Failed to unload Wi-Fi driver."); @@ -1045,7 +1046,13 @@ public class WifiService extends IWifiManager.Stub { enforceChangePermission(); synchronized (mWifiStateTracker) { - return WifiNative.enableNetworkCommand(netId, disableOthers); + String ifname = mWifiStateTracker.getInterfaceName(); + NetworkUtils.enableInterface(ifname); + boolean result = WifiNative.enableNetworkCommand(netId, disableOthers); + if (!result) { + NetworkUtils.disableInterface(ifname); + } + return result; } } diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java index 0e2eb38b56270..a2cdcc1d600dc 100644 --- a/wifi/java/android/net/wifi/WifiStateTracker.java +++ b/wifi/java/android/net/wifi/WifiStateTracker.java @@ -377,6 +377,14 @@ public class WifiStateTracker extends NetworkStateTracker { return getNameServerList(sDnsPropNames); } + /** + * Return the name of our WLAN network interface. + * @return the name of our interface. + */ + public String getInterfaceName() { + return mInterfaceName; + } + /** * Return the system properties name associated with the tcp buffer sizes * for this network. @@ -784,7 +792,7 @@ public class WifiStateTracker extends NetworkStateTracker { WifiNative.closeSupplicantConnection(); } if (died) { - resetInterface(); + resetInterface(false); } // When supplicant dies, kill the DHCP thread if (mDhcpTarget != null) { @@ -1195,7 +1203,7 @@ public class WifiStateTracker extends NetworkStateTracker { cancelDisconnect(); } mDisconnectExpected = false; - resetInterface(); + resetInterface(true); setDetailedState(newState); sendNetworkStateChangeBroadcast(mLastBssid); mWifiInfo.setBSSID(null); @@ -1208,7 +1216,7 @@ public class WifiStateTracker extends NetworkStateTracker { * Resets the Wi-Fi interface by clearing any state, resetting any sockets * using the interface, stopping DHCP, and disabling the interface. */ - public void resetInterface() { + public void resetInterface(boolean reenable) { mHaveIpAddress = false; mObtainingIpAddress = false; mWifiInfo.setIpAddress(0); @@ -1229,6 +1237,9 @@ public class WifiStateTracker extends NetworkStateTracker { } NetworkUtils.disableInterface(mInterfaceName); + if (reenable) { + NetworkUtils.enableInterface(mInterfaceName); + } } /** @@ -1872,7 +1883,7 @@ public class WifiStateTracker extends NetworkStateTracker { oDns2 != mDhcpInfo.dns2)); if (changed) { - resetInterface(); + resetInterface(true); configureInterface(); if (mUseStaticIp) { mTarget.sendEmptyMessage(EVENT_CONFIGURATION_CHANGED);