diff options
-rw-r--r-- | core/java/android/net/NetworkUtils.java | 3 | ||||
-rw-r--r-- | core/jni/android_net_NetUtils.cpp | 12 | ||||
-rw-r--r-- | services/java/com/android/server/WifiService.java | 11 | ||||
-rw-r--r-- | wifi/java/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 1153648..a3ae01b 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 8383deb..feb0dad 100644 --- a/core/jni/android_net_NetUtils.cpp +++ b/core/jni/android_net_NetUtils.cpp @@ -23,6 +23,7 @@ #include <arpa/inet.h> 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 55b7a30..a561d11 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 0e2eb38..a2cdcc1 100644 --- a/wifi/java/android/net/wifi/WifiStateTracker.java +++ b/wifi/java/android/net/wifi/WifiStateTracker.java @@ -378,6 +378,14 @@ public class WifiStateTracker extends NetworkStateTracker { } /** + * 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); |