DO NOT MERGE Revert "DO NOT MERGE Add DhcpStateMachine"

This reverts commit fe3b33d4ead06c546202753e38188db5e2eaa7fa.

Change-Id: I3a9ae1f0d17e7a154d27d4f3f3eb1efa21a34f64
diff --git a/core/java/android/net/DhcpStateMachine.java b/core/java/android/net/DhcpStateMachine.java
deleted file mode 100644
index f5cf14b..0000000
--- a/core/java/android/net/DhcpStateMachine.java
+++ /dev/null
@@ -1,353 +0,0 @@
-/*
- * 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 com.android.internal.util.Protocol;
-import com.android.internal.util.HierarchicalState;
-import com.android.internal.util.HierarchicalStateMachine;
-
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.net.DhcpInfoInternal;
-import android.net.NetworkUtils;
-import android.os.Message;
-import android.os.PowerManager;
-import android.os.SystemClock;
-import android.util.Log;
-
-/**
- * StateMachine that interacts with the native DHCP client and can talk to
- * a controller that also needs to be a StateMachine
- *
- * The Dhcp state machine provides the following features:
- * - Wakeup and renewal using the native DHCP client  (which will not renew
- *   on its own when the device is in suspend state and this can lead to device
- *   holding IP address beyond expiry)
- * - A notification right before DHCP request or renewal is started. This
- *   can be used for any additional setup before DHCP. For example, wifi sets
- *   BT-Wifi coex settings right before DHCP is initiated
- *
- * @hide
- */
-public class DhcpStateMachine extends HierarchicalStateMachine {
-
-    private static final String TAG = "DhcpStateMachine";
-    private static final boolean DBG = false;
-
-
-    /* A StateMachine that controls the DhcpStateMachine */
-    private HierarchicalStateMachine mController;
-
-    private Context mContext;
-    private BroadcastReceiver mBroadcastReceiver;
-    private AlarmManager mAlarmManager;
-    private PendingIntent mDhcpRenewalIntent;
-    private PowerManager.WakeLock mDhcpRenewWakeLock;
-    private static final String WAKELOCK_TAG = "DHCP";
-
-    private static final int DHCP_RENEW = 0;
-    private static final String ACTION_DHCP_RENEW = "android.net.wifi.DHCP_RENEW";
-
-    private enum DhcpAction {
-        START,
-        RENEW
-    };
-
-    private String mInterfaceName;
-    private boolean mRegisteredForPreDhcpNotification = false;
-
-    private static final int BASE = Protocol.BASE_DHCP;
-
-    /* Commands from controller to start/stop DHCP */
-    public static final int CMD_START_DHCP                  = BASE + 1;
-    public static final int CMD_STOP_DHCP                   = BASE + 2;
-    public static final int CMD_RENEW_DHCP                  = BASE + 3;
-
-    /* Notification from DHCP state machine prior to DHCP discovery/renewal */
-    public static final int CMD_PRE_DHCP_ACTION             = BASE + 4;
-    /* Notification from DHCP state machine post DHCP discovery/renewal. Indicates
-     * success/failure */
-    public static final int CMD_POST_DHCP_ACTION            = BASE + 5;
-
-    /* Command from controller to indicate DHCP discovery/renewal can continue
-     * after pre DHCP action is complete */
-    public static final int CMD_PRE_DHCP_ACTION_COMPLETE    = BASE + 6;
-
-    /* Message.arg1 arguments to CMD_POST_DHCP notification */
-    public static final int DHCP_SUCCESS = 1;
-    public static final int DHCP_FAILURE = 2;
-
-    private HierarchicalState mDefaultState = new DefaultState();
-    private HierarchicalState mStoppedState = new StoppedState();
-    private HierarchicalState mWaitBeforeStartState = new WaitBeforeStartState();
-    private HierarchicalState mRunningState = new RunningState();
-    private HierarchicalState mWaitBeforeRenewalState = new WaitBeforeRenewalState();
-
-    private DhcpStateMachine(Context context, HierarchicalStateMachine controller, String intf) {
-        super(TAG);
-
-        mContext = context;
-        mController = controller;
-        mInterfaceName = intf;
-
-        mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
-        Intent dhcpRenewalIntent = new Intent(ACTION_DHCP_RENEW, null);
-        mDhcpRenewalIntent = PendingIntent.getBroadcast(mContext, DHCP_RENEW, dhcpRenewalIntent, 0);
-
-        PowerManager powerManager = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
-        mDhcpRenewWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_TAG);
-
-        mBroadcastReceiver = new BroadcastReceiver() {
-            @Override
-            public void onReceive(Context context, Intent intent) {
-                //DHCP renew
-                if (DBG) Log.d(TAG, "Sending a DHCP renewal " + this);
-                //acquire a 40s wakelock to finish DHCP renewal
-                mDhcpRenewWakeLock.acquire(40000);
-                sendMessage(CMD_RENEW_DHCP);
-            }
-        };
-        mContext.registerReceiver(mBroadcastReceiver, new IntentFilter(ACTION_DHCP_RENEW));
-
-        addState(mDefaultState);
-            addState(mStoppedState, mDefaultState);
-            addState(mWaitBeforeStartState, mDefaultState);
-            addState(mRunningState, mDefaultState);
-            addState(mWaitBeforeRenewalState, mDefaultState);
-
-        setInitialState(mStoppedState);
-    }
-
-    public static DhcpStateMachine makeDhcpStateMachine(Context context, HierarchicalStateMachine controller,
-            String intf) {
-        DhcpStateMachine dsm = new DhcpStateMachine(context, controller, intf);
-        dsm.start();
-        return dsm;
-    }
-
-    /**
-     * This sends a notification right before DHCP request/renewal so that the
-     * controller can do certain actions before DHCP packets are sent out.
-     * When the controller is ready, it sends a CMD_PRE_DHCP_ACTION_COMPLETE message
-     * to indicate DHCP can continue
-     *
-     * This is used by Wifi at this time for the purpose of doing BT-Wifi coex
-     * handling during Dhcp
-     */
-    public void registerForPreDhcpNotification() {
-        mRegisteredForPreDhcpNotification = true;
-    }
-
-    class DefaultState extends HierarchicalState {
-        @Override
-        public boolean processMessage(Message message) {
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
-            switch (message.what) {
-                case CMD_RENEW_DHCP:
-                    Log.e(TAG, "Error! Failed to handle a DHCP renewal on " + mInterfaceName);
-                    break;
-                case HSM_QUIT_CMD:
-                    mContext.unregisterReceiver(mBroadcastReceiver);
-                    //let parent kill the state machine
-                    return NOT_HANDLED;
-                default:
-                    Log.e(TAG, "Error! unhandled message  " + message);
-                    break;
-            }
-            return HANDLED;
-        }
-    }
-
-
-    class StoppedState extends HierarchicalState {
-        @Override
-        public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            boolean retValue = HANDLED;
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
-            switch (message.what) {
-                case CMD_START_DHCP:
-                    if (mRegisteredForPreDhcpNotification) {
-                        /* Notify controller before starting DHCP */
-                        mController.sendMessage(CMD_PRE_DHCP_ACTION);
-                        transitionTo(mWaitBeforeStartState);
-                    } else {
-                        if (runDhcp(DhcpAction.START)) {
-                            transitionTo(mRunningState);
-                        }
-                    }
-                    break;
-                case CMD_STOP_DHCP:
-                    //ignore
-                    break;
-                default:
-                    retValue = NOT_HANDLED;
-                    break;
-            }
-            return retValue;
-        }
-    }
-
-    class WaitBeforeStartState extends HierarchicalState {
-        @Override
-        public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            boolean retValue = HANDLED;
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
-            switch (message.what) {
-                case CMD_PRE_DHCP_ACTION_COMPLETE:
-                    if (runDhcp(DhcpAction.START)) {
-                        transitionTo(mRunningState);
-                    } else {
-                        transitionTo(mStoppedState);
-                    }
-                    break;
-                case CMD_STOP_DHCP:
-                    transitionTo(mStoppedState);
-                    break;
-                case CMD_START_DHCP:
-                    //ignore
-                    break;
-                default:
-                    retValue = NOT_HANDLED;
-                    break;
-            }
-            return retValue;
-        }
-    }
-
-    class RunningState extends HierarchicalState {
-        @Override
-        public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            boolean retValue = HANDLED;
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
-            switch (message.what) {
-                case CMD_STOP_DHCP:
-                    mAlarmManager.cancel(mDhcpRenewalIntent);
-                    if (!NetworkUtils.stopDhcp(mInterfaceName)) {
-                        Log.e(TAG, "Failed to stop Dhcp on " + mInterfaceName);
-                    }
-                    transitionTo(mStoppedState);
-                    break;
-                case CMD_RENEW_DHCP:
-                    if (mRegisteredForPreDhcpNotification) {
-                        /* Notify controller before starting DHCP */
-                        mController.sendMessage(CMD_PRE_DHCP_ACTION);
-                        transitionTo(mWaitBeforeRenewalState);
-                    } else {
-                        if (!runDhcp(DhcpAction.RENEW)) {
-                            transitionTo(mStoppedState);
-                        }
-                    }
-                    break;
-                case CMD_START_DHCP:
-                    //ignore
-                    break;
-                default:
-                    retValue = NOT_HANDLED;
-            }
-            return retValue;
-        }
-    }
-
-    class WaitBeforeRenewalState extends HierarchicalState {
-        @Override
-        public void enter() {
-            if (DBG) Log.d(TAG, getName() + "\n");
-        }
-
-        @Override
-        public boolean processMessage(Message message) {
-            boolean retValue = HANDLED;
-            if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
-            switch (message.what) {
-                case CMD_STOP_DHCP:
-                    mAlarmManager.cancel(mDhcpRenewalIntent);
-                    if (!NetworkUtils.stopDhcp(mInterfaceName)) {
-                        Log.e(TAG, "Failed to stop Dhcp on " + mInterfaceName);
-                    }
-                    transitionTo(mStoppedState);
-                    break;
-                case CMD_PRE_DHCP_ACTION_COMPLETE:
-                    if (runDhcp(DhcpAction.RENEW)) {
-                       transitionTo(mRunningState);
-                    } else {
-                       transitionTo(mStoppedState);
-                    }
-                    break;
-                case CMD_START_DHCP:
-                    //ignore
-                    break;
-                default:
-                    retValue = NOT_HANDLED;
-                    break;
-            }
-            return retValue;
-        }
-    }
-
-    private boolean runDhcp(DhcpAction dhcpAction) {
-        boolean success = false;
-        DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();
-
-        if (dhcpAction == DhcpAction.START) {
-            Log.d(TAG, "DHCP request on " + mInterfaceName);
-            success = NetworkUtils.runDhcp(mInterfaceName, dhcpInfoInternal);
-        } else if (dhcpAction == DhcpAction.RENEW) {
-            Log.d(TAG, "DHCP renewal on " + mInterfaceName);
-            success = NetworkUtils.runDhcpRenew(mInterfaceName, dhcpInfoInternal);
-        }
-
-        if (success) {
-            Log.d(TAG, "DHCP succeeded on " + mInterfaceName);
-            //Do it a bit earlier than half the lease duration time
-            //to beat the native DHCP client and avoid extra packets
-            //48% for one hour lease time = 29 minutes
-            mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
-                    SystemClock.elapsedRealtime() +
-                    dhcpInfoInternal.leaseDuration * 480, //in milliseconds
-                    mDhcpRenewalIntent);
-
-            mController.obtainMessage(CMD_POST_DHCP_ACTION, DHCP_SUCCESS, 0, dhcpInfoInternal)
-                .sendToTarget();
-        } else {
-            Log.d(TAG, "DHCP failed on " + mInterfaceName + ": " +
-                    NetworkUtils.getDhcpError());
-            NetworkUtils.stopDhcp(mInterfaceName);
-            mController.obtainMessage(CMD_POST_DHCP_ACTION, DHCP_FAILURE, 0)
-                .sendToTarget();
-        }
-        return success;
-    }
-}
diff --git a/core/java/android/net/NetworkUtils.java b/core/java/android/net/NetworkUtils.java
index 823d10f..b3f3988 100644
--- a/core/java/android/net/NetworkUtils.java
+++ b/core/java/android/net/NetworkUtils.java
@@ -80,16 +80,6 @@
     public native static boolean runDhcp(String interfaceName, DhcpInfoInternal ipInfo);
 
     /**
-     * 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 ipInfo 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, DhcpInfoInternal ipInfo);
-
-    /**
      * Shut down the DHCP client daemon.
      * @param interfaceName the name of the interface for which the daemon
      * should be stopped
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetUtils.cpp
index 4becad7..3adf770 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetUtils.cpp
@@ -40,16 +40,6 @@
                     const char *dns2,
                     const char *server,
                     uint32_t  *lease);
-
-int dhcp_do_request_renew(const char *ifname,
-                    const char *ipaddr,
-                    const char *gateway,
-                    uint32_t  *prefixLength,
-                    const char *dns1,
-                    const char *dns2,
-                    const char *server,
-                    uint32_t  *lease);
-
 int dhcp_stop(const char *ifname);
 int dhcp_release_lease(const char *ifname);
 char *dhcp_get_errmsg();
@@ -156,8 +146,7 @@
     return (jint)result;
 }
 
-static jboolean android_net_utils_runDhcpCommon(JNIEnv* env, jobject clazz, jstring ifname,
-        jobject info, bool renew)
+static jboolean android_net_utils_runDhcp(JNIEnv* env, jobject clazz, jstring ifname, jobject info)
 {
     int result;
     char  ipaddr[PROPERTY_VALUE_MAX];
@@ -171,14 +160,8 @@
     const char *nameStr = env->GetStringUTFChars(ifname, NULL);
     if (nameStr == NULL) return (jboolean)false;
 
-    if (renew) {
-        result = ::dhcp_do_request_renew(nameStr, ipaddr, gateway, &prefixLength,
-                dns1, dns2, server, &lease);
-    } else {
-        result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
-                dns1, dns2, server, &lease);
-    }
-
+    result = ::dhcp_do_request(nameStr, ipaddr, gateway, &prefixLength,
+                                        dns1, dns2, server, &lease);
     env->ReleaseStringUTFChars(ifname, nameStr);
     if (result == 0 && dhcpInfoInternalFieldIds.dhcpInfoInternalClass != NULL) {
         env->SetObjectField(info, dhcpInfoInternalFieldIds.ipaddress, env->NewStringUTF(ipaddr));
@@ -193,17 +176,6 @@
     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;
@@ -247,7 +219,6 @@
     { "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/DhcpInfoInternal;)Z",  (void *)android_net_utils_runDhcp },
-    { "runDhcpRenew", "(Ljava/lang/String;Landroid/net/DhcpInfoInternal;)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 },
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 0c0e2534..4e96703 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -48,7 +48,6 @@
 import android.net.ConnectivityManager;
 import android.net.DhcpInfo;
 import android.net.DhcpInfoInternal;
-import android.net.DhcpStateMachine;
 import android.net.InterfaceConfiguration;
 import android.net.LinkAddress;
 import android.net.LinkProperties;
@@ -153,7 +152,6 @@
     private NetworkInfo mNetworkInfo;
     private SupplicantStateTracker mSupplicantStateTracker;
     private WpsStateMachine mWpsStateMachine;
-    private DhcpStateMachine mDhcpStateMachine;
 
     private AlarmManager mAlarmManager;
     private PendingIntent mScanIntent;
@@ -191,10 +189,10 @@
     static final int CMD_START_DRIVER                     = BASE + 13;
     /* Start the driver */
     static final int CMD_STOP_DRIVER                      = BASE + 14;
-    /* Indicates Static IP succeded */
-    static final int CMD_STATIC_IP_SUCCESS                = BASE + 15;
-    /* Indicates Static IP failed */
-    static final int CMD_STATIC_IP_FAILURE                = BASE + 16;
+    /* Indicates DHCP succeded */
+    static final int CMD_IP_CONFIG_SUCCESS                = BASE + 15;
+    /* Indicates DHCP failed */
+    static final int CMD_IP_CONFIG_FAILURE                = BASE + 16;
 
     /* Start the soft access point */
     static final int CMD_START_AP                         = BASE + 21;
@@ -344,11 +342,8 @@
      */
     private static final int DEFAULT_MAX_DHCP_RETRIES = 9;
 
-    static final int POWER_MODE_ACTIVE = 1;
-    static final int POWER_MODE_AUTO = 0;
-
-    /* Tracks the power mode for restoration after a DHCP request/renewal goes through */
-    private int mPowerMode = POWER_MODE_AUTO;
+    private static final int POWER_MODE_ACTIVE = 1;
+    private static final int POWER_MODE_AUTO = 0;
 
     /**
      * See {@link Settings.Secure#WIFI_SCAN_INTERVAL_MS}. This is the default value if a
@@ -1416,10 +1411,8 @@
          */
         NetworkUtils.resetConnections(mInterfaceName);
 
-        if (mDhcpStateMachine != null) {
-            mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
-            mDhcpStateMachine.quit();
-            mDhcpStateMachine = null;
+        if (!NetworkUtils.stopDhcp(mInterfaceName)) {
+            Log.e(TAG, "Could not stop DHCP");
         }
 
         /* Disable interface */
@@ -1445,99 +1438,6 @@
 
     }
 
-    void handlePreDhcpSetup() {
-        if (!mBluetoothConnectionActive) {
-            /*
-             * There are problems setting the Wi-Fi driver's power
-             * mode to active when bluetooth coexistence mode is
-             * enabled or sense.
-             * <p>
-             * We set Wi-Fi to active mode when
-             * obtaining an IP address because we've found
-             * compatibility issues with some routers with low power
-             * mode.
-             * <p>
-             * In order for this active power mode to properly be set,
-             * we disable coexistence mode until we're done with
-             * obtaining an IP address.  One exception is if we
-             * are currently connected to a headset, since disabling
-             * coexistence would interrupt that connection.
-             */
-            // Disable the coexistence mode
-            WifiNative.setBluetoothCoexistenceModeCommand(
-                    WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
-        }
-
-        mPowerMode =  WifiNative.getPowerModeCommand();
-        if (mPowerMode < 0) {
-            // Handle the case where supplicant driver does not support
-            // getPowerModeCommand.
-            mPowerMode = WifiStateMachine.POWER_MODE_AUTO;
-        }
-        if (mPowerMode != WifiStateMachine.POWER_MODE_ACTIVE) {
-            WifiNative.setPowerModeCommand(WifiStateMachine.POWER_MODE_ACTIVE);
-        }
-    }
-
-
-    void handlePostDhcpSetup() {
-        /* restore power mode */
-        WifiNative.setPowerModeCommand(mPowerMode);
-
-        // Set the coexistence mode back to its default value
-        WifiNative.setBluetoothCoexistenceModeCommand(
-                WifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
-    }
-
-    private void handleSuccessfulIpConfiguration(DhcpInfoInternal dhcpInfoInternal) {
-        synchronized (mDhcpInfoInternal) {
-            mDhcpInfoInternal = dhcpInfoInternal;
-        }
-        mLastSignalLevel = -1; // force update of signal strength
-        WifiConfigStore.setIpConfiguration(mLastNetworkId, dhcpInfoInternal);
-        InetAddress addr = NetworkUtils.numericToInetAddress(dhcpInfoInternal.ipAddress);
-        mWifiInfo.setInetAddress(addr);
-        if (getNetworkDetailedState() == DetailedState.CONNECTED) {
-            //DHCP renewal in connected state
-            LinkProperties linkProperties = dhcpInfoInternal.makeLinkProperties();
-            linkProperties.setHttpProxy(WifiConfigStore.getProxyProperties(mLastNetworkId));
-            linkProperties.setInterfaceName(mInterfaceName);
-            if (!linkProperties.equals(mLinkProperties)) {
-                Log.d(TAG, "Link configuration changed for netId: " + mLastNetworkId
-                    + " old: " + mLinkProperties + "new: " + linkProperties);
-                NetworkUtils.resetConnections(mInterfaceName);
-                mLinkProperties = linkProperties;
-                sendLinkConfigurationChangedBroadcast();
-            }
-        } else {
-            configureLinkProperties();
-            setNetworkDetailedState(DetailedState.CONNECTED);
-            sendNetworkStateChangeBroadcast(mLastBssid);
-        }
-    }
-
-    private void handleFailedIpConfiguration() {
-        Log.e(TAG, "IP configuration failed");
-
-        mWifiInfo.setInetAddress(null);
-        /**
-         * If we've exceeded the maximum number of retries for DHCP
-         * to a given network, disable the network
-         */
-        if (++mReconnectCount > getMaxDhcpRetries()) {
-            Log.e(TAG, "Failed " +
-                    mReconnectCount + " times, Disabling " + mLastNetworkId);
-            WifiConfigStore.disableNetwork(mLastNetworkId);
-            mReconnectCount = 0;
-        }
-
-        /* DHCP times out after about 30 seconds, we do a
-         * disconnect and an immediate reconnect to try again
-         */
-        WifiNative.disconnectCommand();
-        WifiNative.reconnectCommand();
-    }
-
     private boolean startSoftApWithConfig(WifiConfiguration config, int currentStatus) {
         if (config == null) {
             config = WifiApConfigStore.getApConfiguration();
@@ -1563,7 +1463,6 @@
         return true;
     }
 
-
     /*********************************************************
      * Notifications from WifiMonitor
      ********************************************************/
@@ -1741,8 +1640,6 @@
                 case CMD_FORGET_NETWORK:
                 case CMD_RSSI_POLL:
                 case CMD_ENABLE_ALL_NETWORKS:
-                case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
-                case DhcpStateMachine.CMD_POST_DHCP_ACTION:
                     break;
                 case CMD_START_WPS:
                     /* Return failure when the state machine cannot handle WPS initiation*/
@@ -2605,18 +2502,74 @@
     }
 
     class ConnectingState extends HierarchicalState {
+        boolean mModifiedBluetoothCoexistenceMode;
+        int mPowerMode;
+        boolean mUseStaticIp;
+        Thread mDhcpThread;
 
         @Override
         public void enter() {
             if (DBG) Log.d(TAG, getName() + "\n");
             EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName());
+            mUseStaticIp = WifiConfigStore.isUsingStaticIp(mLastNetworkId);
+            if (!mUseStaticIp) {
+                mDhcpThread = null;
+                mModifiedBluetoothCoexistenceMode = false;
+                mPowerMode = POWER_MODE_AUTO;
 
-             if (!WifiConfigStore.isUsingStaticIp(mLastNetworkId)) {
-                //start DHCP
-                mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(
-                        mContext, WifiStateMachine.this, mInterfaceName);
-                mDhcpStateMachine.registerForPreDhcpNotification();
-                mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
+                if (!mBluetoothConnectionActive) {
+                    /*
+                     * There are problems setting the Wi-Fi driver's power
+                     * mode to active when bluetooth coexistence mode is
+                     * enabled or sense.
+                     * <p>
+                     * We set Wi-Fi to active mode when
+                     * obtaining an IP address because we've found
+                     * compatibility issues with some routers with low power
+                     * mode.
+                     * <p>
+                     * In order for this active power mode to properly be set,
+                     * we disable coexistence mode until we're done with
+                     * obtaining an IP address.  One exception is if we
+                     * are currently connected to a headset, since disabling
+                     * coexistence would interrupt that connection.
+                     */
+                    mModifiedBluetoothCoexistenceMode = true;
+
+                    // Disable the coexistence mode
+                    WifiNative.setBluetoothCoexistenceModeCommand(
+                            WifiNative.BLUETOOTH_COEXISTENCE_MODE_DISABLED);
+                }
+
+                mPowerMode =  WifiNative.getPowerModeCommand();
+                if (mPowerMode < 0) {
+                  // Handle the case where supplicant driver does not support
+                  // getPowerModeCommand.
+                    mPowerMode = POWER_MODE_AUTO;
+                }
+                if (mPowerMode != POWER_MODE_ACTIVE) {
+                    WifiNative.setPowerModeCommand(POWER_MODE_ACTIVE);
+                }
+
+                Log.d(TAG, "DHCP request started");
+                mDhcpThread = new Thread(new Runnable() {
+                    public void run() {
+                        DhcpInfoInternal dhcpInfoInternal = new DhcpInfoInternal();
+                        if (NetworkUtils.runDhcp(mInterfaceName, dhcpInfoInternal)) {
+                            Log.d(TAG, "DHCP request succeeded");
+                            synchronized (mDhcpInfoInternal) {
+                                mDhcpInfoInternal = dhcpInfoInternal;
+                            }
+                            WifiConfigStore.setIpConfiguration(mLastNetworkId, dhcpInfoInternal);
+                            sendMessage(CMD_IP_CONFIG_SUCCESS);
+                        } else {
+                            Log.d(TAG, "DHCP request failed: " +
+                                    NetworkUtils.getDhcpError());
+                            sendMessage(CMD_IP_CONFIG_FAILURE);
+                        }
+                    }
+                });
+                mDhcpThread.start();
             } else {
                 DhcpInfoInternal dhcpInfoInternal = WifiConfigStore.getIpConfiguration(
                         mLastNetworkId);
@@ -2628,13 +2581,16 @@
                 try {
                     netd.setInterfaceConfig(mInterfaceName, ifcg);
                     Log.v(TAG, "Static IP configuration succeeded");
-                    sendMessage(CMD_STATIC_IP_SUCCESS, dhcpInfoInternal);
+                    synchronized (mDhcpInfoInternal) {
+                        mDhcpInfoInternal = dhcpInfoInternal;
+                    }
+                    sendMessage(CMD_IP_CONFIG_SUCCESS);
                 } catch (RemoteException re) {
                     Log.v(TAG, "Static IP configuration failed: " + re);
-                    sendMessage(CMD_STATIC_IP_FAILURE);
+                    sendMessage(CMD_IP_CONFIG_FAILURE);
                 } catch (IllegalStateException e) {
                     Log.v(TAG, "Static IP configuration failed: " + e);
-                    sendMessage(CMD_STATIC_IP_FAILURE);
+                    sendMessage(CMD_IP_CONFIG_FAILURE);
                 }
             }
          }
@@ -2643,26 +2599,44 @@
           if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
 
           switch(message.what) {
-              case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
-                  handlePreDhcpSetup();
-                  mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE);
-                  break;
-              case DhcpStateMachine.CMD_POST_DHCP_ACTION:
-                  handlePostDhcpSetup();
-                  if (message.arg1 == DhcpStateMachine.DHCP_SUCCESS) {
-                      handleSuccessfulIpConfiguration((DhcpInfoInternal) message.obj);
-                      transitionTo(mConnectedState);
-                  } else if (message.arg1 == DhcpStateMachine.DHCP_FAILURE) {
-                      handleFailedIpConfiguration();
-                      transitionTo(mDisconnectingState);
+              case CMD_IP_CONFIG_SUCCESS:
+                  mLastSignalLevel = -1; // force update of signal strength
+                  InetAddress addr;
+                  synchronized (mDhcpInfoInternal) {
+                      addr = NetworkUtils.numericToInetAddress(mDhcpInfoInternal.ipAddress);
                   }
-                  break;
-              case CMD_STATIC_IP_SUCCESS:
-                  handleSuccessfulIpConfiguration((DhcpInfoInternal) message.obj);
+                  mWifiInfo.setInetAddress(addr);
+                  configureLinkProperties();
+                  if (getNetworkDetailedState() == DetailedState.CONNECTED) {
+                      sendLinkConfigurationChangedBroadcast();
+                  } else {
+                      setNetworkDetailedState(DetailedState.CONNECTED);
+                      sendNetworkStateChangeBroadcast(mLastBssid);
+                  }
+                  //TODO: The framework is not detecting a DHCP renewal and a possible
+                  //IP change. we should detect this and send out a config change broadcast
                   transitionTo(mConnectedState);
                   break;
-              case CMD_STATIC_IP_FAILURE:
-                  handleFailedIpConfiguration();
+              case CMD_IP_CONFIG_FAILURE:
+                  mWifiInfo.setInetAddress(null);
+
+                  Log.e(TAG, "IP configuration failed");
+                  /**
+                   * If we've exceeded the maximum number of retries for DHCP
+                   * to a given network, disable the network
+                   */
+                  if (++mReconnectCount > getMaxDhcpRetries()) {
+                      Log.e(TAG, "Failed " +
+                              mReconnectCount + " times, Disabling " + mLastNetworkId);
+                      WifiConfigStore.disableNetwork(mLastNetworkId);
+                      mReconnectCount = 0;
+                  }
+
+                  /* DHCP times out after about 30 seconds, we do a
+                   * disconnect and an immediate reconnect to try again
+                   */
+                  WifiNative.disconnectCommand();
+                  WifiNative.reconnectCommand();
                   transitionTo(mDisconnectingState);
                   break;
               case CMD_DISCONNECT:
@@ -2706,6 +2680,23 @@
           EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what);
           return HANDLED;
       }
+
+      @Override
+      public void exit() {
+          /* reset power state & bluetooth coexistence if on DHCP */
+          if (!mUseStaticIp) {
+              if (mPowerMode != POWER_MODE_ACTIVE) {
+                  WifiNative.setPowerModeCommand(mPowerMode);
+              }
+
+              if (mModifiedBluetoothCoexistenceMode) {
+                  // Set the coexistence mode back to its default value
+                  WifiNative.setBluetoothCoexistenceModeCommand(
+                          WifiNative.BLUETOOTH_COEXISTENCE_MODE_SENSE);
+              }
+          }
+
+      }
     }
 
     class ConnectedState extends HierarchicalState {
@@ -2723,19 +2714,6 @@
             if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
             boolean eventLoggingEnabled = true;
             switch (message.what) {
-              case DhcpStateMachine.CMD_PRE_DHCP_ACTION:
-                  handlePreDhcpSetup();
-                  mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_PRE_DHCP_ACTION_COMPLETE);
-                  break;
-              case DhcpStateMachine.CMD_POST_DHCP_ACTION:
-                  handlePostDhcpSetup();
-                  if (message.arg1 == DhcpStateMachine.DHCP_SUCCESS) {
-                      handleSuccessfulIpConfiguration((DhcpInfoInternal) message.obj);
-                  } else if (message.arg1 == DhcpStateMachine.DHCP_FAILURE) {
-                      handleFailedIpConfiguration();
-                      transitionTo(mDisconnectingState);
-                  }
-                  break;
                 case CMD_DISCONNECT:
                     WifiNative.disconnectCommand();
                     transitionTo(mDisconnectingState);