Add static IP UI

Remove the existing UI and add per network static IP config option

Change-Id: I9b8636e1559de9691144fdb54e20d40985896650
diff --git a/res/layout/wifi_dialog.xml b/res/layout/wifi_dialog.xml
index 081ab6c..8bf1fca 100644
--- a/res/layout/wifi_dialog.xml
+++ b/res/layout/wifi_dialog.xml
@@ -170,5 +170,98 @@
                     android:layout_height="wrap_content"
                     android:text="@string/wifi_show_password" />
         </LinearLayout>
+
+        <LinearLayout android:id="@+id/ipfields"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:visibility="gone">
+
+            <TextView
+                    style="?android:attr/textAppearanceSmallInverse"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="8dip"
+                    android:text="@string/wifi_ip_settings" />
+
+            <Spinner android:id="@+id/ipsettings"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:prompt="@string/wifi_ip_settings"
+                    android:entries="@array/wifi_ip_settings" />
+
+        </LinearLayout>
+
+        <LinearLayout android:id="@+id/staticip"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:visibility="gone">
+            <TextView
+                    style="?android:attr/textAppearanceSmallInverse"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="8dip"
+                    android:text="@string/wifi_ip_address" />
+
+            <EditText android:id="@+id/ipaddress"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:singleLine="true"
+                    android:inputType="textNoSuggestions" />
+
+            <TextView
+                    style="?android:attr/textAppearanceSmallInverse"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="8dip"
+                    android:text="@string/wifi_gateway" />
+
+            <EditText android:id="@+id/gateway"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:singleLine="true"
+                    android:inputType="textNoSuggestions" />
+
+            <TextView
+                    style="?android:attr/textAppearanceSmallInverse"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="8dip"
+                    android:text="@string/wifi_netmask" />
+
+            <EditText android:id="@+id/netmask"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:singleLine="true"
+                    android:inputType="textNoSuggestions" />
+
+            <TextView
+                    style="?android:attr/textAppearanceSmallInverse"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="8dip"
+                    android:text="@string/wifi_dns1" />
+
+            <EditText android:id="@+id/dns1"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:singleLine="true"
+                    android:inputType="textNoSuggestions" />
+
+            <TextView
+                    style="?android:attr/textAppearanceSmallInverse"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="8dip"
+                    android:text="@string/wifi_dns2" />
+
+            <EditText android:id="@+id/dns2"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:singleLine="true"
+                    android:inputType="textNoSuggestions" />
+
+        </LinearLayout>
     </LinearLayout>
 </ScrollView>
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index 0b44edd..e3acc10 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -341,6 +341,15 @@
         <item>GTC</item>
     </string-array>
 
+    <!-- Wi-Fi IP settings. -->
+    <string-array name="wifi_ip_settings">
+        <!-- Do not translate. -->
+        <item>DHCP</item>
+        <!-- Do not translate. -->
+        <item>Static</item>
+    </string-array>
+
+
     <!-- Sound settings for emergency tone. -->
     <string-array name="emergency_tone_entries">
         <item>Off</item>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b2a1865..84bc6cc 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -895,7 +895,9 @@
     <!-- Label for the password of the secured network -->
     <string name="wifi_password">Password</string>
     <!-- Label for the check box to show password -->
-    <string name="wifi_show_password">Show password.</string>
+    <string name="wifi_show_password">Show password</string>
+    <!-- Label for the spinner to show ip settings  -->
+    <string name="wifi_ip_settings">IP settings</string>
     <!-- Hint for unchanged fields -->
     <string name="wifi_unchanged">(unchanged)</string>
     <!-- Hint for unspecified fields -->
@@ -949,8 +951,6 @@
     <string name="wifi_ip_settings_menu_cancel">Cancel</string>
     <!-- Error message if the IP address is not valid -->
     <string name="wifi_ip_settings_invalid_ip">Please type a valid IP address.</string>
-    <!-- Checkbox for whether to use a static IP address -->
-    <string name="wifi_use_static_ip">Use static IP</string>
     <!-- Label for the DNS (first one) -->
     <string name="wifi_dns1">DNS 1</string>
     <!-- Label for the DNS (second one)-->
diff --git a/res/xml/wifi_advanced_settings.xml b/res/xml/wifi_advanced_settings.xml
index e603be9..8496428 100644
--- a/res/xml/wifi_advanced_settings.xml
+++ b/res/xml/wifi_advanced_settings.xml
@@ -43,54 +43,4 @@
         android:title="@string/wifi_advanced_ip_address_title"
         />
 
-    <PreferenceCategory
-            android:title="@string/wifi_ip_settings_titlebar"
-            />
-    
-    <CheckBoxPreference
-            android:key="use_static_ip"
-            android:title="@string/wifi_use_static_ip"
-            android:persistent="false"
-            />    
-    
-    <EditTextPreference
-            android:dependency="use_static_ip"
-            android:key="ip_address"
-            android:title="@string/wifi_ip_address"
-            android:persistent="false"
-            android:singleLine="true"
-            />    
-    
-    <EditTextPreference
-            android:dependency="use_static_ip"
-            android:key="gateway"
-            android:title="@string/wifi_gateway"
-            android:persistent="false"
-            android:singleLine="true"
-            />    
-    
-    <EditTextPreference
-            android:dependency="use_static_ip"
-            android:key="netmask"
-            android:title="@string/wifi_netmask"
-            android:persistent="false"
-            android:singleLine="true"
-            />    
-
-    <EditTextPreference
-            android:dependency="use_static_ip"
-            android:key="dns1"
-            android:title="@string/wifi_dns1"
-            android:persistent="false"
-            android:singleLine="true"
-            />    
-    
-    <EditTextPreference
-            android:dependency="use_static_ip"
-            android:key="dns2"
-            android:title="@string/wifi_dns2"
-            android:persistent="false"
-            android:singleLine="true"
-            />    
-    
 </PreferenceScreen>   
diff --git a/src/com/android/settings/wifi/AdvancedSettings.java b/src/com/android/settings/wifi/AdvancedSettings.java
index 636e1df..4b33fdc 100644
--- a/src/com/android/settings/wifi/AdvancedSettings.java
+++ b/src/com/android/settings/wifi/AdvancedSettings.java
@@ -18,21 +18,14 @@
 
 import com.android.settings.R;
 
-import android.content.ContentResolver;
 import android.net.wifi.WifiInfo;
 import android.net.wifi.WifiManager;
 import android.os.Bundle;
-import android.preference.CheckBoxPreference;
-import android.preference.EditTextPreference;
 import android.preference.ListPreference;
 import android.preference.Preference;
 import android.preference.PreferenceActivity;
 import android.provider.Settings;
-import android.provider.Settings.System;
 import android.text.TextUtils;
-import android.view.KeyEvent;
-import android.view.Menu;
-import android.view.MenuItem;
 import android.widget.Toast;
 import android.os.SystemProperties;
 
@@ -41,24 +34,9 @@
 
     private static final String KEY_MAC_ADDRESS = "mac_address";
     private static final String KEY_CURRENT_IP_ADDRESS = "current_ip_address";
-    private static final String KEY_USE_STATIC_IP = "use_static_ip";
     private static final String KEY_NUM_CHANNELS = "num_channels";
     private static final String KEY_SLEEP_POLICY = "sleep_policy";
     
-    private String[] mSettingNames = {
-            System.WIFI_STATIC_IP, System.WIFI_STATIC_GATEWAY, System.WIFI_STATIC_NETMASK,
-            System.WIFI_STATIC_DNS1, System.WIFI_STATIC_DNS2
-    };
-    
-    private String[] mPreferenceKeys = {
-            "ip_address", "gateway", "netmask", "dns1", "dns2"
-    };
-    
-    private CheckBoxPreference mUseStaticIpCheckBox;
-    
-    private static final int MENU_ITEM_SAVE = Menu.FIRST;
-    private static final int MENU_ITEM_CANCEL = Menu.FIRST + 1;
-    
     //Tracks ro.debuggable (1 on userdebug builds)
     private static int DEBUGGABLE;
 
@@ -68,14 +46,6 @@
         
         addPreferencesFromResource(R.xml.wifi_advanced_settings);
         
-        mUseStaticIpCheckBox = (CheckBoxPreference) findPreference(KEY_USE_STATIC_IP);
-        mUseStaticIpCheckBox.setOnPreferenceChangeListener(this);
-
-        for (int i = 0; i < mPreferenceKeys.length; i++) {
-            Preference preference = findPreference(mPreferenceKeys[i]);
-            preference.setOnPreferenceChangeListener(this);
-        }
-
         DEBUGGABLE = SystemProperties.getInt("ro.debuggable", 0);
 
         /**
@@ -101,7 +71,6 @@
     protected void onResume() {
         super.onResume();
         
-        updateUi();
         /**
          * Remove user control of regulatory domain
          * channel count settings in non userdebug builds
@@ -155,16 +124,6 @@
         pref.setValue(String.valueOf(value));
     }
 
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-    
-        if (keyCode == KeyEvent.KEYCODE_BACK) {
-            updateSettingsProvider();
-        }
-    
-        return super.onKeyDown(keyCode, event);
-    }
-
     public boolean onPreferenceChange(Preference preference, Object newValue) {
         String key = preference.getKey();
         if (key == null) return true;
@@ -193,121 +152,11 @@
                 return false;
             }
 
-        } else if (key.equals(KEY_USE_STATIC_IP)) {
-            boolean value = ((Boolean) newValue).booleanValue();
-
-            try {
-                Settings.System.putInt(getContentResolver(),
-                        Settings.System.WIFI_USE_STATIC_IP, value ? 1 : 0);
-            } catch (NumberFormatException e) {
-                return false;
-            }
-        } else {
-            String value = (String) newValue;
-            
-            if (!isIpAddress(value)) {
-                Toast.makeText(this, R.string.wifi_ip_settings_invalid_ip, Toast.LENGTH_LONG).show();
-                return false;
-            }
-            
-            preference.setSummary(value);
-            for (int i = 0; i < mSettingNames.length; i++) {
-                if (key.equals(mPreferenceKeys[i])) {
-                    Settings.System.putString(getContentResolver(), mSettingNames[i], value);
-                    break;
-                }
-            }
         }
         
         return true;
     }
 
-    private boolean isIpAddress(String value) {
-        
-        int start = 0;
-        int end = value.indexOf('.');
-        int numBlocks = 0;
-        
-        while (start < value.length()) {
-            
-            if (end == -1) {
-                end = value.length();
-            }
-
-            try {
-                int block = Integer.parseInt(value.substring(start, end));
-                if ((block > 255) || (block < 0)) {
-                    return false;
-                }
-            } catch (NumberFormatException e) {
-                return false;
-            }
-            
-            numBlocks++;
-            
-            start = end + 1;
-            end = value.indexOf('.', start);
-        }
-        
-        return numBlocks == 4;
-    }
-    
-    @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        
-        menu.add(0, MENU_ITEM_SAVE, 0, R.string.wifi_ip_settings_menu_save)
-                .setIcon(android.R.drawable.ic_menu_save);
-
-        menu.add(0, MENU_ITEM_CANCEL, 0, R.string.wifi_ip_settings_menu_cancel)
-                .setIcon(android.R.drawable.ic_menu_close_clear_cancel);
-
-        return super.onCreateOptionsMenu(menu);
-    }
-
-    @Override
-    public boolean onOptionsItemSelected(MenuItem item) {
-
-        switch (item.getItemId()) {
-        
-            case MENU_ITEM_SAVE:
-                updateSettingsProvider();
-                finish();
-                return true;
-                
-            case MENU_ITEM_CANCEL:
-                finish();
-                return true;
-        }
-        
-        return super.onOptionsItemSelected(item);
-    }
-
-    private void updateUi() {
-        ContentResolver contentResolver = getContentResolver();
-        
-        mUseStaticIpCheckBox.setChecked(System.getInt(contentResolver,
-                System.WIFI_USE_STATIC_IP, 0) != 0);
-        
-        for (int i = 0; i < mSettingNames.length; i++) {
-            EditTextPreference preference = (EditTextPreference) findPreference(mPreferenceKeys[i]);
-            String settingValue = System.getString(contentResolver, mSettingNames[i]);
-            preference.setText(settingValue);
-            preference.setSummary(settingValue);
-        }
-    }
-    
-    private void updateSettingsProvider() {
-        ContentResolver contentResolver = getContentResolver();
-
-        System.putInt(contentResolver, System.WIFI_USE_STATIC_IP,
-                mUseStaticIpCheckBox.isChecked() ? 1 : 0);
-        
-        for (int i = 0; i < mSettingNames.length; i++) {
-            EditTextPreference preference = (EditTextPreference) findPreference(mPreferenceKeys[i]);
-            System.putString(contentResolver, mSettingNames[i], preference.getText());
-        }
-    }
-    
     private void refreshWifiInfo() {
         WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
         WifiInfo wifiInfo = wifiManager.getConnectionInfo();
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index f662acb..a09bfa3 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -19,8 +19,10 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.res.Resources;
+import android.net.DhcpInfo;
 import android.net.NetworkInfo.DetailedState;
 import android.net.wifi.WifiConfiguration;
+import android.net.wifi.WifiConfiguration.IpAssignment;
 import android.net.wifi.WifiConfiguration.AuthAlgorithm;
 import android.net.wifi.WifiConfiguration.KeyMgmt;
 import android.net.wifi.WifiInfo;
@@ -37,8 +39,10 @@
 import android.widget.CheckBox;
 import android.widget.Spinner;
 import android.widget.TextView;
+import android.widget.Toast;
 
 import com.android.settings.R;
+import java.net.UnknownHostException;
 
 /**
  * The class for allowing UIs like {@link WifiDialog} and {@link WifiConfigPreference} to
@@ -54,18 +58,27 @@
 
     private boolean mEdit;
 
-    private TextView mSsid;
+    private TextView mSsidView;
 
     // e.g. AccessPoint.SECURITY_NONE
-    private int mSecurityType;
+    private int mAccessPointSecurity;
     private TextView mPasswordView;
 
-    private Spinner mEapMethod;
-    private Spinner mEapCaCert;
-    private Spinner mPhase2;
-    private Spinner mEapUserCert;
-    private TextView mEapIdentity;
-    private TextView mEapAnonymous;
+    private Spinner mSecuritySpinner;
+    private Spinner mEapMethodSpinner;
+    private Spinner mEapCaCertSpinner;
+    private Spinner mPhase2Spinner;
+    private Spinner mEapUserCertSpinner;
+    private TextView mEapIdentityView;
+    private TextView mEapAnonymousView;
+
+    private static final String STATIC_IP = "Static";
+    private Spinner mIpSettingsSpinner;
+    private TextView mIpAddressView;
+    private TextView mGatewayView;
+    private TextView mNetmaskView;
+    private TextView mDns1View;
+    private TextView mDns2View;
 
     static boolean requireKeyStore(WifiConfiguration config) {
         String values[] = {config.ca_cert.value(), config.client_cert.value(),
@@ -84,7 +97,8 @@
 
         mView = view;
         mAccessPoint = accessPoint;
-        mSecurityType = (accessPoint == null) ? AccessPoint.SECURITY_NONE : accessPoint.security;
+        mAccessPointSecurity = (accessPoint == null) ? AccessPoint.SECURITY_NONE :
+                accessPoint.security;
         mEdit = edit;
 
         final Context context = mConfigUi.getContext();
@@ -93,10 +107,10 @@
         if (mAccessPoint == null) {
             mConfigUi.setTitle(R.string.wifi_add_network);
             mView.findViewById(R.id.type).setVisibility(View.VISIBLE);
-            mSsid = (TextView) mView.findViewById(R.id.ssid);
-            mSsid.addTextChangedListener(this);
-            ((Spinner) mView.findViewById(R.id.security)).setOnItemSelectedListener(this);
-
+            mSsidView = (TextView) mView.findViewById(R.id.ssid);
+            mSsidView.addTextChangedListener(this);
+            mSecuritySpinner = ((Spinner) mView.findViewById(R.id.security));
+            mSecuritySpinner.setOnItemSelectedListener(this);
             mConfigUi.setSubmitButton(context.getString(R.string.wifi_save));
         } else {
             mConfigUi.setTitle(mAccessPoint.ssid);
@@ -128,6 +142,7 @@
 
             if (mAccessPoint.networkId == -1 || mEdit) {
                 showSecurityFields();
+                showIpConfigFields();
             }
 
             if (mEdit) {
@@ -135,6 +150,8 @@
             } else {
                 if (state == null && level != -1) {
                     mConfigUi.setSubmitButton(context.getString(R.string.wifi_connect));
+                } else {
+                    mView.findViewById(R.id.ipfields).setVisibility(View.GONE);
                 }
                 if (mAccessPoint.networkId != -1) {
                     mConfigUi.setForgetButton(context.getString(R.string.wifi_forget));
@@ -142,6 +159,15 @@
             }
         }
 
+        mIpSettingsSpinner = ((Spinner) mView.findViewById(R.id.ipsettings));
+        if (mAccessPoint != null && mAccessPoint.networkId != -1) {
+            WifiConfiguration config = mAccessPoint.getConfig();
+            if (config.ipAssignment == IpAssignment.STATIC) {
+                setSelection(mIpSettingsSpinner, STATIC_IP);
+            }
+        }
+        mIpSettingsSpinner.setOnItemSelectedListener(this);
+
         mConfigUi.setCancelButton(context.getString(R.string.wifi_cancel));
         if (mConfigUi.getSubmitButton() != null) {
             enableSubmitIfAppropriate();
@@ -155,12 +181,12 @@
         group.addView(row);
     }
 
+    /* show submit button if the password is valid */
     private void enableSubmitIfAppropriate() {
-        // TODO: make sure this is complete.
-        if ((mSsid != null && mSsid.length() == 0) ||
-                ((mAccessPoint == null || mAccessPoint.networkId == -1) &&
-                ((mSecurityType == AccessPoint.SECURITY_WEP && mPasswordView.length() == 0) ||
-                (mSecurityType == AccessPoint.SECURITY_PSK && mPasswordView.length() < 8)))) {
+        if ((mSsidView != null && mSsidView.length() == 0) ||
+            ((mAccessPoint == null || mAccessPoint.networkId == -1) &&
+            ((mAccessPointSecurity == AccessPoint.SECURITY_WEP && mPasswordView.length() == 0) ||
+            (mAccessPointSecurity == AccessPoint.SECURITY_PSK && mPasswordView.length() < 8)))) {
             mConfigUi.getSubmitButton().setEnabled(false);
         } else {
             mConfigUi.getSubmitButton().setEnabled(true);
@@ -176,7 +202,7 @@
 
         if (mAccessPoint == null) {
             config.SSID = AccessPoint.convertToQuotedString(
-                    mSsid.getText().toString());
+                    mSsidView.getText().toString());
             // If the user adds a network manually, assume that it is hidden.
             config.hiddenSSID = true;
         } else if (mAccessPoint.networkId == -1) {
@@ -186,10 +212,10 @@
             config.networkId = mAccessPoint.networkId;
         }
 
-        switch (mSecurityType) {
+        switch (mAccessPointSecurity) {
             case AccessPoint.SECURITY_NONE:
                 config.allowedKeyManagement.set(KeyMgmt.NONE);
-                return config;
+                break;
 
             case AccessPoint.SECURITY_WEP:
                 config.allowedKeyManagement.set(KeyMgmt.NONE);
@@ -206,7 +232,7 @@
                         config.wepKeys[0] = '"' + password + '"';
                     }
                 }
-                return config;
+                break;
 
             case AccessPoint.SECURITY_PSK:
                 config.allowedKeyManagement.set(KeyMgmt.WPA_PSK);
@@ -218,38 +244,63 @@
                         config.preSharedKey = '"' + password + '"';
                     }
                 }
-                return config;
+                break;
 
             case AccessPoint.SECURITY_EAP:
                 config.allowedKeyManagement.set(KeyMgmt.WPA_EAP);
                 config.allowedKeyManagement.set(KeyMgmt.IEEE8021X);
-                config.eap.setValue((String) mEapMethod.getSelectedItem());
+                config.eap.setValue((String) mEapMethodSpinner.getSelectedItem());
 
-                config.phase2.setValue((mPhase2.getSelectedItemPosition() == 0) ? "" :
-                        "auth=" + mPhase2.getSelectedItem());
-                config.ca_cert.setValue((mEapCaCert.getSelectedItemPosition() == 0) ? "" :
+                config.phase2.setValue((mPhase2Spinner.getSelectedItemPosition() == 0) ? "" :
+                        "auth=" + mPhase2Spinner.getSelectedItem());
+                config.ca_cert.setValue((mEapCaCertSpinner.getSelectedItemPosition() == 0) ? "" :
                         KEYSTORE_SPACE + Credentials.CA_CERTIFICATE +
-                        (String) mEapCaCert.getSelectedItem());
-                config.client_cert.setValue((mEapUserCert.getSelectedItemPosition() == 0) ? "" :
-                        KEYSTORE_SPACE + Credentials.USER_CERTIFICATE +
-                        (String) mEapUserCert.getSelectedItem());
-                config.private_key.setValue((mEapUserCert.getSelectedItemPosition() == 0) ? "" :
-                        KEYSTORE_SPACE + Credentials.USER_PRIVATE_KEY +
-                        (String) mEapUserCert.getSelectedItem());
-                config.identity.setValue((mEapIdentity.length() == 0) ? "" :
-                        mEapIdentity.getText().toString());
-                config.anonymous_identity.setValue((mEapAnonymous.length() == 0) ? "" :
-                        mEapAnonymous.getText().toString());
+                        (String) mEapCaCertSpinner.getSelectedItem());
+                config.client_cert.setValue((mEapUserCertSpinner.getSelectedItemPosition() == 0) ?
+                        "" : KEYSTORE_SPACE + Credentials.USER_CERTIFICATE +
+                        (String) mEapUserCertSpinner.getSelectedItem());
+                config.private_key.setValue((mEapUserCertSpinner.getSelectedItemPosition() == 0) ?
+                        "" : KEYSTORE_SPACE + Credentials.USER_PRIVATE_KEY +
+                        (String) mEapUserCertSpinner.getSelectedItem());
+                config.identity.setValue((mEapIdentityView.length() == 0) ? "" :
+                        mEapIdentityView.getText().toString());
+                config.anonymous_identity.setValue((mEapAnonymousView.length() == 0) ? "" :
+                        mEapAnonymousView.getText().toString());
                 if (mPasswordView.length() != 0) {
                     config.password.setValue(mPasswordView.getText().toString());
                 }
-                return config;
+                break;
+
+            default:
+                    return null;
         }
-        return null;
+
+        config.ipAssignment = mIpSettingsSpinner.getSelectedItem().toString().equals(STATIC_IP) ?
+                IpAssignment.STATIC : IpAssignment.DHCP;
+
+        if (config.ipAssignment == IpAssignment.STATIC) {
+            //TODO: A better way to do this is to not dismiss the
+            //dialog as long as one of the fields is invalid
+            try {
+                config.ipConfig.ipAddress = stringToIpAddr(mIpAddressView.getText().toString());
+                config.ipConfig.gateway = stringToIpAddr(mGatewayView.getText().toString());
+                config.ipConfig.netmask = stringToIpAddr(mNetmaskView.getText().toString());
+                config.ipConfig.dns1 = stringToIpAddr(mDns1View.getText().toString());
+                if (mDns2View.getText() != null && mDns2View.getText().length() > 0) {
+                    config.ipConfig.dns2 = stringToIpAddr(mDns2View.getText().toString());
+                }
+            } catch (UnknownHostException e) {
+                Toast.makeText(mConfigUi.getContext(), R.string.wifi_ip_settings_invalid_ip,
+                        Toast.LENGTH_LONG).show();
+                return null;
+            }
+        }
+
+        return config;
     }
 
     private void showSecurityFields() {
-        if (mSecurityType == AccessPoint.SECURITY_NONE) {
+        if (mAccessPointSecurity == AccessPoint.SECURITY_NONE) {
             mView.findViewById(R.id.fields).setVisibility(View.GONE);
             return;
         }
@@ -265,37 +316,75 @@
             }
         }
 
-        if (mSecurityType != AccessPoint.SECURITY_EAP) {
+        if (mAccessPointSecurity != AccessPoint.SECURITY_EAP) {
             mView.findViewById(R.id.eap).setVisibility(View.GONE);
             return;
         }
         mView.findViewById(R.id.eap).setVisibility(View.VISIBLE);
 
-        if (mEapMethod == null) {
-            mEapMethod = (Spinner) mView.findViewById(R.id.method);
-            mPhase2 = (Spinner) mView.findViewById(R.id.phase2);
-            mEapCaCert = (Spinner) mView.findViewById(R.id.ca_cert);
-            mEapUserCert = (Spinner) mView.findViewById(R.id.user_cert);
-            mEapIdentity = (TextView) mView.findViewById(R.id.identity);
-            mEapAnonymous = (TextView) mView.findViewById(R.id.anonymous);
+        if (mEapMethodSpinner == null) {
+            mEapMethodSpinner = (Spinner) mView.findViewById(R.id.method);
+            mPhase2Spinner = (Spinner) mView.findViewById(R.id.phase2);
+            mEapCaCertSpinner = (Spinner) mView.findViewById(R.id.ca_cert);
+            mEapUserCertSpinner = (Spinner) mView.findViewById(R.id.user_cert);
+            mEapIdentityView = (TextView) mView.findViewById(R.id.identity);
+            mEapAnonymousView = (TextView) mView.findViewById(R.id.anonymous);
 
-            loadCertificates(mEapCaCert, Credentials.CA_CERTIFICATE);
-            loadCertificates(mEapUserCert, Credentials.USER_PRIVATE_KEY);
+            loadCertificates(mEapCaCertSpinner, Credentials.CA_CERTIFICATE);
+            loadCertificates(mEapUserCertSpinner, Credentials.USER_PRIVATE_KEY);
 
             if (mAccessPoint != null && mAccessPoint.networkId != -1) {
                 WifiConfiguration config = mAccessPoint.getConfig();
-                setSelection(mEapMethod, config.eap.value());
-                setSelection(mPhase2, config.phase2.value());
-                setCertificate(mEapCaCert, Credentials.CA_CERTIFICATE,
+                setSelection(mEapMethodSpinner, config.eap.value());
+                setSelection(mPhase2Spinner, config.phase2.value());
+                setCertificate(mEapCaCertSpinner, Credentials.CA_CERTIFICATE,
                         config.ca_cert.value());
-                setCertificate(mEapUserCert, Credentials.USER_PRIVATE_KEY,
+                setCertificate(mEapUserCertSpinner, Credentials.USER_PRIVATE_KEY,
                         config.private_key.value());
-                mEapIdentity.setText(config.identity.value());
-                mEapAnonymous.setText(config.anonymous_identity.value());
+                mEapIdentityView.setText(config.identity.value());
+                mEapAnonymousView.setText(config.anonymous_identity.value());
             }
         }
     }
 
+    private void showIpConfigFields() {
+        WifiConfiguration config = null;
+
+        mView.findViewById(R.id.ipfields).setVisibility(View.VISIBLE);
+
+        if (mIpSettingsSpinner == null) {
+            mIpSettingsSpinner = (Spinner) mView.findViewById(R.id.ipsettings);
+        }
+
+        if (mAccessPoint != null && mAccessPoint.networkId != -1) {
+            config = mAccessPoint.getConfig();
+        }
+
+        if (mIpSettingsSpinner.getSelectedItem().equals(STATIC_IP)) {
+            mView.findViewById(R.id.staticip).setVisibility(View.VISIBLE);
+            if (mIpAddressView == null) {
+                mIpAddressView = (TextView) mView.findViewById(R.id.ipaddress);
+                mGatewayView = (TextView) mView.findViewById(R.id.gateway);
+                mNetmaskView = (TextView) mView.findViewById(R.id.netmask);
+                mDns1View = (TextView) mView.findViewById(R.id.dns1);
+                mDns2View = (TextView) mView.findViewById(R.id.dns2);
+            }
+            if (config != null) {
+                DhcpInfo ipConfig = config.ipConfig;
+                if (ipConfig != null && ipConfig.ipAddress != 0) {
+                    mIpAddressView.setText(intToIpString(ipConfig.ipAddress));
+                    mGatewayView.setText(intToIpString(ipConfig.gateway));
+                    mNetmaskView.setText(intToIpString(ipConfig.netmask));
+                    mDns1View.setText(intToIpString(ipConfig.dns1));
+                    mDns2View.setText(intToIpString(ipConfig.dns2));
+                }
+            }
+        } else {
+            mView.findViewById(R.id.staticip).setVisibility(View.GONE);
+        }
+    }
+
+
     private void loadCertificates(Spinner spinner, String prefix) {
         final Context context = mConfigUi.getContext();
         final String unspecified = context.getString(R.string.wifi_unspecified);
@@ -358,12 +447,41 @@
 
     @Override
     public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
-        mSecurityType = position;
-        showSecurityFields();
-        enableSubmitIfAppropriate();
+        if (view == mSecuritySpinner) {
+            mAccessPointSecurity = position;
+            showSecurityFields();
+            enableSubmitIfAppropriate();
+        } else {
+            showIpConfigFields();
+        }
     }
 
     @Override
     public void onNothingSelected(AdapterView<?> parent) {
     }
+
+    /* TODO: should go away when we move to IPv6 based config storage */
+    private static int stringToIpAddr(String addrString) throws UnknownHostException {
+        try {
+            String[] parts = addrString.split("\\.");
+            if (parts.length != 4) {
+                throw new UnknownHostException(addrString);
+            }
+
+            int a = Integer.parseInt(parts[0]);
+            int b = Integer.parseInt(parts[1]) << 8;
+            int c = Integer.parseInt(parts[2]) << 16;
+            int d = Integer.parseInt(parts[3]) << 24;
+
+            return a | b | c | d;
+        } catch (NumberFormatException e) {
+            throw new UnknownHostException(addrString);
+        }
+    }
+
+    private static String intToIpString(int i) {
+        return (i & 0xFF) + "." + ((i >>  8 ) & 0xFF) + "." +((i >> 16 ) & 0xFF) + "." +
+            ((i >> 24 ) & 0xFF);
+    }
+
 }
\ No newline at end of file
diff --git a/src/com/android/settings/wifi/WifiSettings.java b/src/com/android/settings/wifi/WifiSettings.java
index 4bf11e4..acb9ad3 100644
--- a/src/com/android/settings/wifi/WifiSettings.java
+++ b/src/com/android/settings/wifi/WifiSettings.java
@@ -288,9 +288,7 @@
                 }
                 if (mSelectedAccessPoint.networkId != -1) {
                     menu.add(Menu.NONE, MENU_ID_FORGET, 0, R.string.wifi_menu_forget);
-                    if (mSelectedAccessPoint.security != AccessPoint.SECURITY_NONE) {
-                        menu.add(Menu.NONE, MENU_ID_MODIFY, 0, R.string.wifi_menu_modify);
-                    }
+                    menu.add(Menu.NONE, MENU_ID_MODIFY, 0, R.string.wifi_menu_modify);
                 }
             }
         }