Merge "Check null of getActivity() when needed."
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 405acaa..130674e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -100,6 +100,7 @@
         </activity-alias>
 
         <activity android:name=".wifi.WifiSettingsForSetupWizardXL"
+                  android:theme="@android:style/Theme.NoTitleBar"
                   android:clearTaskOnLaunch="true"
                   android:screenOrientation="landscape"
                   android:exported="true" />
@@ -196,10 +197,10 @@
             </intent-filter>
         </activity-alias>
 
-        <activity android:name=".vpn.VpnSettings"
-                android:label="@string/vpn_settings_title"
+        <activity-alias android:name=".vpn.VpnSettings"
                 android:configChanges="orientation|keyboardHidden"
-                android:clearTaskOnLaunch="true">
+                android:clearTaskOnLaunch="true"
+                android:targetActivity="Settings">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <action android:name="android.net.vpn.SETTINGS" />
@@ -207,14 +208,7 @@
                 <category android:name="android.intent.category.VOICE_LAUNCH" />
                 <category android:name="com.android.settings.SHORTCUT" />
             </intent-filter>
-        </activity>
-
-        <activity android:name=".vpn.VpnTypeSelection"
-                android:configChanges="orientation|keyboardHidden">
-        </activity>
-        <activity android:name=".vpn.VpnEditor"
-                android:configChanges="orientation|keyboardHidden">
-        </activity>
+        </activity-alias>
 
         <activity-alias android:name="DateTimeSettings"
                 android:label="@string/date_and_time"
@@ -228,8 +222,10 @@
             </intent-filter>
         </activity-alias>
 
-        <activity android:name="DateTimeSettingsSetupWizard" android:label="@string/date_and_time"
-            android:screenOrientation="behind">
+        <activity android:name="DateTimeSettingsSetupWizard"
+                  android:label="@string/date_and_time"
+                  android:theme="@android:style/Theme.NoTitleBar"
+                  android:screenOrientation="behind">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
             </intent-filter>
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/res/xml/wireless_settings.xml b/res/xml/wireless_settings.xml
index 8e05e60..f6d0012 100644
--- a/res/xml/wireless_settings.xml
+++ b/res/xml/wireless_settings.xml
@@ -59,13 +59,10 @@
     </PreferenceScreen>
 
     <PreferenceScreen
+        android:fragment="com.android.settings.vpn.VpnSettings"
         android:key="vpn_settings"
         android:title="@string/vpn_settings_title"
         android:summary="@string/vpn_settings_summary" >
-        <intent
-            android:action="android.intent.action.MAIN"
-            android:targetPackage="com.android.settings"
-            android:targetClass="com.android.settings.vpn.VpnSettings" />
     </PreferenceScreen>
 
     <PreferenceScreen
diff --git a/src/com/android/settings/DateTimeSettingsSetupWizard.java b/src/com/android/settings/DateTimeSettingsSetupWizard.java
index 5da17da..016a7f2 100644
--- a/src/com/android/settings/DateTimeSettingsSetupWizard.java
+++ b/src/com/android/settings/DateTimeSettingsSetupWizard.java
@@ -19,6 +19,7 @@
 import com.android.settings.ZonePicker.ZoneSelectionListener;
 
 import android.app.Activity;
+import android.content.Context;
 import android.content.res.Configuration;
 import android.os.Bundle;
 import android.provider.Settings;
@@ -26,6 +27,7 @@
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.view.Window;
+import android.view.inputmethod.InputMethodManager;
 import android.widget.Button;
 import android.widget.CompoundButton;
 import android.widget.CompoundButton.OnCheckedChangeListener;
@@ -44,6 +46,7 @@
     private Button mTimeZone;
     private TimePicker mTimePicker;
     private DatePicker mDatePicker;
+    private InputMethodManager mInputMethodManager;
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
@@ -90,6 +93,8 @@
         mDatePicker = (DatePicker)findViewById(R.id.date_picker);
         mDatePicker.setEnabled(!autoDateTimeEnabled);
 
+        mInputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
+
         ((ZonePicker)getFragmentManager().findFragmentById(R.id.zone_picker_fragment))
                 .setZoneSelectionListener(this);
 
@@ -123,6 +128,7 @@
 
     @Override
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+        final boolean autoEnabled = isChecked;  // just for readibility.
         Settings.System.putInt(getContentResolver(),
                 Settings.System.AUTO_TIME,
                 isChecked ? 1 : 0);
@@ -130,9 +136,16 @@
             findViewById(R.id.current_time_zone).setVisibility(View.VISIBLE);
             findViewById(R.id.zone_picker).setVisibility(View.GONE);
         }
-        mTimeZone.setEnabled(!isChecked);
-        mTimePicker.setEnabled(!isChecked);
-        mDatePicker.setEnabled(!isChecked);
+        mTimeZone.setEnabled(!autoEnabled);
+        mTimePicker.setEnabled(!autoEnabled);
+        mDatePicker.setEnabled(!autoEnabled);
+        if (autoEnabled) {
+            final View focusedView = getCurrentFocus();
+            if (focusedView != null) {
+                mInputMethodManager.hideSoftInputFromWindow(focusedView.getWindowToken(), 0);
+                focusedView.clearFocus();
+            }
+        }
     }
 
     @Override
diff --git a/src/com/android/settings/LocalePicker.java b/src/com/android/settings/LocalePicker.java
index 2030e95..8b94ccb 100644
--- a/src/com/android/settings/LocalePicker.java
+++ b/src/com/android/settings/LocalePicker.java
@@ -16,6 +16,8 @@
 
 package com.android.settings;
 
+import java.util.Locale;
+
 public class LocalePicker extends com.android.internal.app.LocalePicker
         implements com.android.internal.app.LocalePicker.LocaleSelectionListener {
     public LocalePicker() {
@@ -24,7 +26,8 @@
     }
 
     @Override
-    public void onLocaleSelected() {
+    public void onLocaleSelected(Locale locale) {
         getActivity().onBackPressed();
+        LocalePicker.updateLocale(locale);
     }
 }
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index 50aa1df..cc3f7ea 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -41,7 +41,8 @@
  */
 public class Settings extends Activity
         implements PreferenceFragment.OnPreferenceStartFragmentCallback,
-        SettingsPreferenceFragment.OnStateListener {
+        SettingsPreferenceFragment.OnStateListener,
+        SettingsPreferenceFragment.FragmentStarter {
 
     private static final boolean DBG = false;
 
@@ -143,7 +144,9 @@
         if (DBG) Log.d(TAG, "showFragment");
        Fragment f = Fragment.instantiate(this, fragmentClass, extras);
         if (f instanceof SettingsPreferenceFragment) {
-            ((SettingsPreferenceFragment) f).setOnStateListener(this);
+            SettingsPreferenceFragment spf = (SettingsPreferenceFragment) f;
+            spf.setOnStateListener(this);
+            spf.setFragmentStarter(this);
         }
         mBreadCrumbs.clear();
         getFragmentManager().popBackStack(BACK_STACK_PREFS, POP_BACK_STACK_INCLUSIVE);
@@ -176,9 +179,17 @@
 
     public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
         if (DBG) Log.d(TAG, "onPreferenceStartFragment");
-        Fragment f = Fragment.instantiate(this, pref.getFragment(), pref.getExtras());
+        return startFragment(caller, pref.getFragment(), -1, pref.getExtras());
+    }
+
+    public boolean startFragment(
+            Fragment caller, String fragmentClass, int requestCode, Bundle extras) {
+        Fragment f = Fragment.instantiate(this, fragmentClass, extras);
+        caller.setTargetFragment(f, requestCode);
         if (f instanceof SettingsPreferenceFragment) {
-            ((SettingsPreferenceFragment) f).setOnStateListener(this);
+            SettingsPreferenceFragment spf = (SettingsPreferenceFragment) f;
+            spf.setOnStateListener(this);
+            spf.setFragmentStarter(this);
         }
         getFragmentManager().openTransaction().replace(R.id.prefs, f)
                 .addToBackStack(BACK_STACK_PREFS).commit();
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index 935c72a..f41561e 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -19,6 +19,7 @@
 import android.app.Activity;
 import android.app.Dialog;
 import android.app.DialogFragment;
+import android.app.Fragment;
 import android.content.ContentResolver;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -58,6 +59,10 @@
     private SettingsDialogFragment mDialogFragment;
 
     private OnStateListener mOnStateListener;
+    private FragmentStarter mFragmentStarter;
+
+    private int mResultCode = Activity.RESULT_CANCELED;
+    private Intent mResultData;
 
     private Button mNextButton;
 
@@ -74,6 +79,43 @@
         mOnStateListener = listener;
     }
 
+    /**
+     * Letting the class, assumed to be Fragment, start another Fragment object.
+     * The target Fragment object is stored in the caller Fragment using
+     * {@link Fragment#setTargetFragment(Fragment, int)}. The caller
+     * is able to obtain result code and result data via
+     * {@link SettingsPreferenceFragment#getResultCode()} and
+     * {@link SettingsPreferenceFragment#getResultData()} accordingly.
+     */
+    interface FragmentStarter {
+        public boolean startFragment(
+                Fragment caller, String fragmentClass, int requestCode, Bundle extras);
+    }
+
+    public void setFragmentStarter(FragmentStarter starter) {
+        mFragmentStarter = starter;
+    }
+
+    @Override
+    public void onResume() {
+        super.onResume();
+
+        final Fragment f = getTargetFragment();
+        final int requestCode = getTargetRequestCode();
+
+        // TargetFragment becomes invalid when this object is resumed. Notify it to
+        // FragmentManager. Without this code, FragmentManager wrongly take the TargetFragment
+        // as live, and throws IllegalStateException.
+        setTargetFragment(null, -1);
+
+        if (f != null && (f instanceof SettingsPreferenceFragment)) {
+            final SettingsPreferenceFragment spf = (SettingsPreferenceFragment)f;
+            final int resultCode = spf.getResultCode();
+            final Intent resultData = spf.getResultData();
+            onActivityResult(requestCode, resultCode, resultData);
+        }
+    }
+
     @Override
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
@@ -86,6 +128,32 @@
         setupButtonBar();
     }
 
+    public final void setResult(int resultCode) {
+        mResultCode = resultCode;
+        mResultData = null;
+    }
+
+    public final void setResult(int resultCode, Intent data) {
+        mResultCode = resultCode;
+        mResultData = data;
+    }
+
+    public final int getResultCode() {
+        return mResultCode;
+    }
+
+    public final Intent getResultData() {
+        return mResultData;
+    }
+
+    /*
+     * The name is intentionally made different from Activity#finish(), so that
+     * users won't misunderstand its meaning.
+     */
+    public final void finishFragment() {
+        getActivity().onBackPressed();
+    }
+
     @Override
     public void onDestroy() {
         super.onDestroy();
@@ -179,6 +247,16 @@
         getActivity().onBackPressed();
     }
 
+    public boolean startFragment(
+            Fragment caller, String fragmentClass, int requestCode, Bundle extras) {
+        if (mFragmentStarter != null) {
+            return mFragmentStarter.startFragment(caller, fragmentClass, requestCode, extras);
+        } else {
+            Log.w(TAG, "FragmentStarter is not set.");
+            return false;
+        }
+    }
+
     /**
      * Sets up Button Bar possibly required in the Fragment. Probably available only in
      * phones.
diff --git a/src/com/android/settings/applications/InstalledAppDetails.java b/src/com/android/settings/applications/InstalledAppDetails.java
index 8765dfb..af03549 100644
--- a/src/com/android/settings/applications/InstalledAppDetails.java
+++ b/src/com/android/settings/applications/InstalledAppDetails.java
@@ -69,6 +69,7 @@
 public class InstalledAppDetails extends Activity
         implements View.OnClickListener, ApplicationsState.Callbacks {
     private static final String TAG="InstalledAppDetails";
+    static final boolean SUPPORT_DISABLE_APPS = false;
     
     private PackageManager mPm;
     private ApplicationsState mState;
@@ -259,30 +260,32 @@
         } else {
             if ((mAppEntry.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                 enabled = false;
-                try {
-                    // Try to prevent the user from bricking their phone
-                    // by not allowing disabling of apps signed with the
-                    // system cert and any launcher app in the system.
-                    PackageInfo sys = mPm.getPackageInfo("android",
-                            PackageManager.GET_SIGNATURES);
-                    Intent intent = new Intent(Intent.ACTION_MAIN);
-                    intent.addCategory(Intent.CATEGORY_HOME);
-                    intent.setPackage(mAppEntry.info.packageName);
-                    List<ResolveInfo> homes = mPm.queryIntentActivities(intent, 0);
-                    if ((homes != null && homes.size() > 0) ||
-                            (mPackageInfo != null &&
-                                    sys.signatures[0].equals(mPackageInfo.signatures[0]))) {
-                        // Disable button for core system applications.
-                        mUninstallButton.setText(R.string.disable_text);
-                    } else if (mAppEntry.info.enabled) {
-                        mUninstallButton.setText(R.string.disable_text);
-                        enabled = true;
-                    } else {
-                        mUninstallButton.setText(R.string.enable_text);
-                        enabled = true;
+                if (SUPPORT_DISABLE_APPS) {
+                    try {
+                        // Try to prevent the user from bricking their phone
+                        // by not allowing disabling of apps signed with the
+                        // system cert and any launcher app in the system.
+                        PackageInfo sys = mPm.getPackageInfo("android",
+                                PackageManager.GET_SIGNATURES);
+                        Intent intent = new Intent(Intent.ACTION_MAIN);
+                        intent.addCategory(Intent.CATEGORY_HOME);
+                        intent.setPackage(mAppEntry.info.packageName);
+                        List<ResolveInfo> homes = mPm.queryIntentActivities(intent, 0);
+                        if ((homes != null && homes.size() > 0) ||
+                                (mPackageInfo != null &&
+                                        sys.signatures[0].equals(mPackageInfo.signatures[0]))) {
+                            // Disable button for core system applications.
+                            mUninstallButton.setText(R.string.disable_text);
+                        } else if (mAppEntry.info.enabled) {
+                            mUninstallButton.setText(R.string.disable_text);
+                            enabled = true;
+                        } else {
+                            mUninstallButton.setText(R.string.enable_text);
+                            enabled = true;
+                        }
+                    } catch (PackageManager.NameNotFoundException e) {
+                        Log.w(TAG, "Unable to get package info", e);
                     }
-                } catch (PackageManager.NameNotFoundException e) {
-                    Log.w(TAG, "Unable to get package info", e);
                 }
             } else {
                 mUninstallButton.setText(R.string.uninstall_text);
diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java
index 772e48d..34e0e8e 100644
--- a/src/com/android/settings/applications/ManageApplications.java
+++ b/src/com/android/settings/applications/ManageApplications.java
@@ -354,7 +354,11 @@
                     holder.appIcon.setImageDrawable(entry.icon);
                 }
                 holder.updateSizeText(ManageApplications.this);
-                holder.disabled.setVisibility(entry.info.enabled ? View.GONE : View.VISIBLE);
+                if (InstalledAppDetails.SUPPORT_DISABLE_APPS) {
+                    holder.disabled.setVisibility(entry.info.enabled ? View.GONE : View.VISIBLE);
+                } else {
+                    holder.disabled.setVisibility(View.GONE);
+                }
             }
             mActive.remove(convertView);
             mActive.add(convertView);
diff --git a/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java b/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
index eec0ad8..37e48ff 100644
--- a/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
+++ b/src/com/android/settings/bluetooth/BluetoothDiscoverableEnabler.java
@@ -144,7 +144,7 @@
     private void persistDiscoverableEndTimestamp(long endTimestamp) {
         SharedPreferences.Editor editor = mLocalManager.getSharedPreferences().edit();
         editor.putLong(SHARED_PREFERENCES_KEY_DISCOVERABLE_END_TIMESTAMP, endTimestamp);
-        editor.commit();
+        editor.apply();
     }
 
     private void handleModeChanged(int mode) {
diff --git a/src/com/android/settings/bluetooth/BluetoothEventRedirector.java b/src/com/android/settings/bluetooth/BluetoothEventRedirector.java
index f3a404f..54fde9d 100644
--- a/src/com/android/settings/bluetooth/BluetoothEventRedirector.java
+++ b/src/com/android/settings/bluetooth/BluetoothEventRedirector.java
@@ -227,6 +227,6 @@
         SharedPreferences.Editor editor = mManager.getSharedPreferences().edit();
         editor.putLong(LocalBluetoothManager.SHARED_PREFERENCES_KEY_DISCOVERING_TIMESTAMP,
                 System.currentTimeMillis());
-        editor.commit();
+        editor.apply();
     }
 }
diff --git a/src/com/android/settings/bluetooth/DockService.java b/src/com/android/settings/bluetooth/DockService.java
index d0f8099..db24554 100644
--- a/src/com/android/settings/bluetooth/DockService.java
+++ b/src/com/android/settings/bluetooth/DockService.java
@@ -788,14 +788,14 @@
         SharedPreferences.Editor editor = getSharedPreferences(SHARED_PREFERENCES_NAME,
                 Context.MODE_PRIVATE).edit();
         editor.putBoolean(key, bool);
-        editor.commit();
+        editor.apply();
     }
 
     private void setSettingInt(String key, int value) {
         SharedPreferences.Editor editor = getSharedPreferences(SHARED_PREFERENCES_NAME,
                 Context.MODE_PRIVATE).edit();
         editor.putInt(key, value);
-        editor.commit();
+        editor.apply();
     }
 
     private void removeSetting(String key) {
@@ -803,8 +803,7 @@
                 Context.MODE_PRIVATE);
         SharedPreferences.Editor editor = sharedPref.edit();
         editor.remove(key);
-        editor.commit();
-        return;
+        editor.apply();
     }
 
     public synchronized void onServiceConnected() {
diff --git a/src/com/android/settings/bluetooth/LocalBluetoothManager.java b/src/com/android/settings/bluetooth/LocalBluetoothManager.java
index 2ffb139..97e823e 100644
--- a/src/com/android/settings/bluetooth/LocalBluetoothManager.java
+++ b/src/com/android/settings/bluetooth/LocalBluetoothManager.java
@@ -356,7 +356,7 @@
                 deviceAddress);
         editor.putLong(LocalBluetoothManager.SHARED_PREFERENCES_KEY_LAST_SELECTED_DEVICE_TIME,
                 System.currentTimeMillis());
-        editor.commit();
+        editor.apply();
     }
 
     public boolean hasDockAutoConnectSetting(String addr) {
@@ -371,12 +371,12 @@
     public void saveDockAutoConnectSetting(String addr, boolean autoConnect) {
         SharedPreferences.Editor editor = getSharedPreferences().edit();
         editor.putBoolean(SHARED_PREFERENCES_KEY_DOCK_AUTO_CONNECT + addr, autoConnect);
-        editor.commit();
+        editor.apply();
     }
 
     public void removeDockAutoConnectSetting(String addr) {
         SharedPreferences.Editor editor = getSharedPreferences().edit();
         editor.remove(SHARED_PREFERENCES_KEY_DOCK_AUTO_CONNECT + addr);
-        editor.commit();
+        editor.apply();
     }
 }
diff --git a/src/com/android/settings/bluetooth/RequestPermissionActivity.java b/src/com/android/settings/bluetooth/RequestPermissionActivity.java
index eca233c..dd802f3 100644
--- a/src/com/android/settings/bluetooth/RequestPermissionActivity.java
+++ b/src/com/android/settings/bluetooth/RequestPermissionActivity.java
@@ -277,7 +277,7 @@
         editor.putLong(
                 BluetoothDiscoverableEnabler.SHARED_PREFERENCES_KEY_DISCOVERABLE_END_TIMESTAMP,
                 endTimestamp);
-        editor.commit();
+        editor.apply();
     }
 
     @Override
diff --git a/src/com/android/settings/vpn/VpnEditor.java b/src/com/android/settings/vpn/VpnEditor.java
index 349befb..3ab0b90 100644
--- a/src/com/android/settings/vpn/VpnEditor.java
+++ b/src/com/android/settings/vpn/VpnEditor.java
@@ -17,7 +17,9 @@
 package com.android.settings.vpn;
 
 import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
 
+import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.content.DialogInterface;
@@ -27,22 +29,19 @@
 import android.net.vpn.L2tpProfile;
 import android.net.vpn.PptpProfile;
 import android.net.vpn.VpnProfile;
-import android.net.vpn.VpnType;
 import android.os.Bundle;
 import android.os.Parcel;
 import android.os.Parcelable;
-import android.preference.PreferenceActivity;
-import android.preference.PreferenceGroup;
 import android.text.TextUtils;
-import android.view.KeyEvent;
+import android.util.Log;
 import android.view.Menu;
+import android.view.MenuInflater;
 import android.view.MenuItem;
-import android.view.View;
 
 /**
  * The activity class for editing a new or existing VPN profile.
  */
-public class VpnEditor extends PreferenceActivity {
+public class VpnEditor extends SettingsPreferenceFragment {
     private static final int MENU_SAVE = Menu.FIRST;
     private static final int MENU_CANCEL = Menu.FIRST + 1;
     private static final int CONFIRM_DIALOG_ID = 0;
@@ -56,59 +55,75 @@
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        VpnProfile p = (VpnProfile) ((savedInstanceState == null)
-                ? getIntent().getParcelableExtra(VpnSettings.KEY_VPN_PROFILE)
-                : savedInstanceState.getParcelable(KEY_PROFILE));
-        mProfileEditor = getEditor(p);
-        mAddingProfile = TextUtils.isEmpty(p.getName());
 
         // Loads the XML preferences file
         addPreferencesFromResource(R.xml.vpn_edit);
+    }
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        VpnProfile p;
+        if (savedInstanceState != null) {
+            p = (VpnProfile)savedInstanceState.getParcelable(KEY_PROFILE);
+        } else {
+            p = (VpnProfile)getArguments().getParcelable(VpnSettings.KEY_VPN_PROFILE);
+            if (p == null) {
+                p = getActivity().getIntent().getParcelableExtra(VpnSettings.KEY_VPN_PROFILE);
+            }
+        }
+
+        mProfileEditor = getEditor(p);
+        mAddingProfile = TextUtils.isEmpty(p.getName());
 
         initViewFor(p);
 
         Parcel parcel = Parcel.obtain();
         p.writeToParcel(parcel, 0);
         mOriginalProfileData = parcel.marshall();
+
+        registerForContextMenu(getListView());
+        setHasOptionsMenu(true);
     }
 
     @Override
-    protected synchronized void onSaveInstanceState(Bundle outState) {
+    public synchronized void onSaveInstanceState(Bundle outState) {
         if (mProfileEditor == null) return;
 
         outState.putParcelable(KEY_PROFILE, getProfile());
     }
 
     @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        super.onCreateOptionsMenu(menu);
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        super.onCreateOptionsMenu(menu, inflater);
         menu.add(0, MENU_SAVE, 0, R.string.vpn_menu_done)
             .setIcon(android.R.drawable.ic_menu_save);
         menu.add(0, MENU_CANCEL, 0,
                 mAddingProfile ? R.string.vpn_menu_cancel
                                : R.string.vpn_menu_revert)
             .setIcon(android.R.drawable.ic_menu_close_clear_cancel);
-        return true;
     }
 
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId()) {
             case MENU_SAVE:
-                if (validateAndSetResult()) finish();
+                if (validateAndSetResult()) finishFragment();
                 return true;
 
             case MENU_CANCEL:
                 if (profileChanged()) {
                     showDialog(CONFIRM_DIALOG_ID);
                 } else {
-                    finish();
+                    finishFragment();
                 }
                 return true;
         }
         return super.onOptionsItemSelected(item);
     }
 
+    /*
     @Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
         switch (keyCode) {
@@ -117,7 +132,7 @@
                 return true;
         }
         return super.onKeyDown(keyCode, event);
-    }
+    }*/
 
     private void initViewFor(VpnProfile profile) {
         setTitle(profile);
@@ -125,10 +140,11 @@
     }
 
     private void setTitle(VpnProfile profile) {
+        final Activity activity = getActivity();
         String formatString = mAddingProfile
-                ? getString(R.string.vpn_edit_title_add)
-                : getString(R.string.vpn_edit_title_edit);
-        setTitle(String.format(formatString,
+                ? activity.getString(R.string.vpn_edit_title_add)
+                : activity.getString(R.string.vpn_edit_title_edit);
+        activity.setTitle(String.format(formatString,
                 profile.getType().getDisplayName()));
     }
 
@@ -140,7 +156,7 @@
         String errorMsg = mProfileEditor.validate();
 
         if (errorMsg != null) {
-            Util.showErrorMessage(this, errorMsg);
+            Util.showErrorMessage(getActivity(), errorMsg);
             return false;
         }
 
@@ -149,9 +165,9 @@
     }
 
     private void setResult(VpnProfile p) {
-        Intent intent = new Intent(this, VpnSettings.class);
+        Intent intent = new Intent(getActivity(), VpnSettings.class);
         intent.putExtra(VpnSettings.KEY_VPN_PROFILE, (Parcelable) p);
-        setResult(RESULT_OK, intent);
+        setResult(Activity.RESULT_OK, intent);
     }
 
     private VpnProfileEditor getEditor(VpnProfile p) {
@@ -175,10 +191,9 @@
 
 
     @Override
-    protected Dialog onCreateDialog(int id) {
-
+    public Dialog onCreateDialog(int id) {
         if (id == CONFIRM_DIALOG_ID) {
-            return new AlertDialog.Builder(this)
+            return new AlertDialog.Builder(getActivity())
                     .setTitle(android.R.string.dialog_alert_title)
                     .setIcon(android.R.drawable.ic_dialog_alert)
                     .setMessage(mAddingProfile
@@ -187,7 +202,7 @@
                     .setPositiveButton(R.string.vpn_yes_button,
                             new DialogInterface.OnClickListener() {
                                 public void onClick(DialogInterface dialog, int w) {
-                                    finish();
+                                    finishFragment();
                                 }
                             })
                     .setNegativeButton(R.string.vpn_mistake_button, null)
@@ -197,8 +212,9 @@
         return super.onCreateDialog(id);
     }
 
+    /*
     @Override
-    protected void onPrepareDialog(int id, Dialog dialog) {
+    public void onPrepareDialog(int id, Dialog dialog) {
         super.onPrepareDialog(id, dialog);
 
         if (id == CONFIRM_DIALOG_ID) {
@@ -206,7 +222,7 @@
                     ? getString(R.string.vpn_confirm_add_profile_cancellation)
                     : getString(R.string.vpn_confirm_edit_profile_cancellation));
         }
-    }
+    }*/
 
     private VpnProfile getProfile() {
         return mProfileEditor.getProfile();
diff --git a/src/com/android/settings/vpn/VpnSettings.java b/src/com/android/settings/vpn/VpnSettings.java
index 7b8d433..e9a4c3d 100644
--- a/src/com/android/settings/vpn/VpnSettings.java
+++ b/src/com/android/settings/vpn/VpnSettings.java
@@ -17,11 +17,14 @@
 package com.android.settings.vpn;
 
 import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
 
+import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
-import android.content.ComponentName;
+import android.app.Fragment;
 import android.content.BroadcastReceiver;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
@@ -37,12 +40,10 @@
 import android.os.Bundle;
 import android.os.ConditionVariable;
 import android.os.IBinder;
-import android.os.Parcelable;
 import android.preference.Preference;
-import android.preference.PreferenceActivity;
+import android.preference.Preference.OnPreferenceClickListener;
 import android.preference.PreferenceCategory;
 import android.preference.PreferenceScreen;
-import android.preference.Preference.OnPreferenceClickListener;
 import android.security.Credentials;
 import android.security.KeyStore;
 import android.text.TextUtils;
@@ -69,8 +70,8 @@
 /**
  * The preference activity for configuring VPN settings.
  */
-public class VpnSettings extends PreferenceActivity implements
-        DialogInterface.OnClickListener {
+public class VpnSettings extends SettingsPreferenceFragment
+        implements DialogInterface.OnClickListener {
     // Key to the field exchanged for profile editing.
     static final String KEY_VPN_PROFILE = "vpn_profile";
 
@@ -122,7 +123,7 @@
 
     private KeyStore mKeyStore = KeyStore.getInstance();
 
-    private VpnManager mVpnManager = new VpnManager(this);
+    private VpnManager mVpnManager;
 
     private ConnectivityReceiver mConnectivityReceiver =
             new ConnectivityReceiver();
@@ -137,7 +138,13 @@
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         addPreferencesFromResource(R.xml.vpn_settings);
+    }
 
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        mVpnManager = new VpnManager(getActivity());
         // restore VpnProfile list and construct VpnPreference map
         mVpnListContainer = (PreferenceCategory) findPreference(PREF_VPN_LIST);
 
@@ -168,22 +175,24 @@
         if ((mUnlockAction != null) && isKeyStoreUnlocked()) {
             Runnable action = mUnlockAction;
             mUnlockAction = null;
-            runOnUiThread(action);
+            getActivity().runOnUiThread(action);
         }
     }
 
     @Override
-    protected void onDestroy() {
-        super.onDestroy();
+    public void onDestroyView() {
         unregisterForContextMenu(getListView());
         mVpnManager.unregisterConnectivityReceiver(mConnectivityReceiver);
         if ((mShowingDialog != null) && mShowingDialog.isShowing()) {
             mShowingDialog.dismiss();
         }
+        // This should be called after the procedure above as ListView inside this Fragment
+        // will be deleted here.
+        super.onDestroyView();
     }
 
     @Override
-    protected Dialog onCreateDialog (int id) {
+    public Dialog onCreateDialog (int id) {
         switch (id) {
             case DIALOG_CONNECT:
                 return createConnectDialog();
@@ -203,13 +212,14 @@
     }
 
     private Dialog createConnectDialog() {
-        return new AlertDialog.Builder(this)
+        final Activity activity = getActivity();
+        return new AlertDialog.Builder(activity)
                 .setView(mConnectingActor.createConnectView())
-                .setTitle(String.format(getString(R.string.vpn_connect_to),
+                .setTitle(String.format(activity.getString(R.string.vpn_connect_to),
                         mActiveProfile.getName()))
-                .setPositiveButton(getString(R.string.vpn_connect_button),
+                .setPositiveButton(activity.getString(R.string.vpn_connect_button),
                         this)
-                .setNegativeButton(getString(android.R.string.cancel),
+                .setNegativeButton(activity.getString(android.R.string.cancel),
                         this)
                 .setOnCancelListener(new DialogInterface.OnCancelListener() {
                             public void onCancel(DialogInterface dialog) {
@@ -291,7 +301,7 @@
     }
 
     private AlertDialog.Builder createCommonDialogBuilder() {
-        return new AlertDialog.Builder(this)
+        return new AlertDialog.Builder(getActivity())
                 .setTitle(android.R.string.dialog_alert_title)
                 .setIcon(android.R.drawable.ic_dialog_alert)
                 .setPositiveButton(R.string.vpn_yes_button,
@@ -364,9 +374,9 @@
     }
 
     @Override
-    protected void onActivityResult(final int requestCode, final int resultCode,
+    public void onActivityResult(final int requestCode, final int resultCode,
             final Intent data) {
-        if ((resultCode == RESULT_CANCELED) || (data == null)) {
+        if ((resultCode == Activity.RESULT_CANCELED) || (data == null)) {
             Log.d(TAG, "no result returned by editor");
             return;
         }
@@ -381,11 +391,12 @@
                 return;
             }
 
+            final Activity activity = getActivity();
             int index = getProfileIndexFromId(p.getId());
             if (checkDuplicateName(p, index)) {
                 final VpnProfile profile = p;
-                Util.showErrorMessage(this, String.format(
-                        getString(R.string.vpn_error_duplicate_name),
+                Util.showErrorMessage(activity, String.format(
+                        activity.getString(R.string.vpn_error_duplicate_name),
                         p.getName()),
                         new DialogInterface.OnClickListener() {
                             public void onClick(DialogInterface dialog, int w) {
@@ -407,30 +418,32 @@
             try {
                 if (index < 0) {
                     addProfile(p);
-                    Util.showShortToastMessage(this, String.format(
-                            getString(R.string.vpn_profile_added), p.getName()));
+                    Util.showShortToastMessage(activity, String.format(
+                            activity.getString(R.string.vpn_profile_added), p.getName()));
                 } else {
                     replaceProfile(index, p);
-                    Util.showShortToastMessage(this, String.format(
-                            getString(R.string.vpn_profile_replaced),
+                    Util.showShortToastMessage(activity, String.format(
+                            activity.getString(R.string.vpn_profile_replaced),
                             p.getName()));
                 }
             } catch (IOException e) {
                 final VpnProfile profile = p;
-                Util.showErrorMessage(this, e + ": " + e.getMessage(),
+                Util.showErrorMessage(activity, e + ": " + e.getMessage(),
                         new DialogInterface.OnClickListener() {
                             public void onClick(DialogInterface dialog, int w) {
                                 startVpnEditor(profile);
                             }
                         });
             }
+
+            // Remove cached VpnEditor as it is needless anymore.
         } else {
             throw new RuntimeException("unknown request code: " + requestCode);
         }
     }
 
     // Called when the buttons on the connect dialog are clicked.
-    //@Override
+    @Override
     public synchronized void onClick(DialogInterface dialog, int which) {
         if (which == CONNECT_BUTTON) {
             Dialog d = (Dialog) dialog;
@@ -440,12 +453,15 @@
                 removeDialog(DIALOG_CONNECT);
                 return;
             } else {
-                dismissDialog(DIALOG_CONNECT);
+                // dismissDialog(DIALOG_CONNECT);
+                removeDialog(DIALOG_CONNECT);
+
+                final Activity activity = getActivity();
                 // show error dialog
-                mShowingDialog = new AlertDialog.Builder(this)
+                mShowingDialog = new AlertDialog.Builder(activity)
                         .setTitle(android.R.string.dialog_alert_title)
                         .setIcon(android.R.drawable.ic_dialog_alert)
-                        .setMessage(String.format(getString(
+                        .setMessage(String.format(activity.getString(
                                 R.string.vpn_error_miss_entering), error))
                         .setPositiveButton(R.string.vpn_back_button,
                                 new DialogInterface.OnClickListener() {
@@ -513,7 +529,7 @@
                         }
                     }
                 };
-        mShowingDialog = new AlertDialog.Builder(this)
+        mShowingDialog = new AlertDialog.Builder(getActivity())
                 .setTitle(android.R.string.dialog_alert_title)
                 .setIcon(android.R.drawable.ic_dialog_alert)
                 .setMessage(R.string.vpn_confirm_profile_deletion)
@@ -559,7 +575,7 @@
     // Adds a preference in mVpnListContainer
     private VpnPreference addPreferenceFor(
             VpnProfile p, boolean addToContainer) {
-        VpnPreference pref = new VpnPreference(this, p);
+        VpnPreference pref = new VpnPreference(getActivity(), p);
         mVpnPreferenceMap.put(p.getName(), pref);
         if (addToContainer) mVpnListContainer.addPreference(pref);
 
@@ -599,8 +615,8 @@
     }
 
     private void startVpnTypeSelection() {
-        Intent intent = new Intent(this, VpnTypeSelection.class);
-        startActivityForResult(intent, REQUEST_SELECT_VPN_TYPE);
+        startFragment(this, VpnTypeSelection.class.getCanonicalName(),
+                REQUEST_SELECT_VPN_TYPE, null);
     }
 
     private boolean isKeyStoreUnlocked() {
@@ -614,16 +630,14 @@
                 L2tpIpsecPskProfile pskProfile = (L2tpIpsecPskProfile) p;
                 String presharedKey = pskProfile.getPresharedKey();
                 if (!TextUtils.isEmpty(presharedKey)) return true;
-                // pass through
-
+                // $FALL-THROUGH$
             case L2TP:
                 L2tpProfile l2tpProfile = (L2tpProfile) p;
                 if (l2tpProfile.isSecretEnabled() &&
                         !TextUtils.isEmpty(l2tpProfile.getSecretString())) {
                     return true;
                 }
-                // pass through
-
+                // $FALL-THROUGH$
             default:
                 return false;
         }
@@ -648,14 +662,15 @@
     private boolean unlockKeyStore(VpnProfile p, Runnable action) {
         if (isKeyStoreUnlocked()) return true;
         mUnlockAction = action;
-        Credentials.getInstance().unlock(this);
+        Credentials.getInstance().unlock(getActivity());
         return false;
     }
 
     private void startVpnEditor(final VpnProfile profile) {
-        Intent intent = new Intent(this, VpnEditor.class);
-        intent.putExtra(KEY_VPN_PROFILE, (Parcelable) profile);
-        startActivityForResult(intent, REQUEST_ADD_OR_EDIT_PROFILE);
+        Bundle args = new Bundle();
+        args.putParcelable(KEY_VPN_PROFILE, profile);
+        startFragment(this, VpnEditor.class.getCanonicalName(),
+                REQUEST_ADD_OR_EDIT_PROFILE, args);
     }
 
     private synchronized void connect(final VpnProfile p) {
@@ -714,7 +729,7 @@
 
         case CONNECTING:
             mConnectingActor = getActor(p);
-            // pass through
+            // $FALL-THROUGH$
         case DISCONNECTING:
             mActiveProfile = p;
             disableProfilePreferencesIfOneActive();
@@ -810,11 +825,6 @@
             public int compare(VpnProfile p1, VpnProfile p2) {
                 return p1.getName().compareTo(p2.getName());
             }
-
-            public boolean equals(VpnProfile p) {
-                // not used
-                return false;
-            }
         });
         for (VpnProfile p : mVpnProfileList) {
             Preference pref = addPreferenceFor(p, false);
@@ -855,20 +865,21 @@
     }
 
     private String getProfileSummaryString(VpnProfile p) {
+        final Activity activity = getActivity();
         switch (p.getState()) {
         case CONNECTING:
-            return getString(R.string.vpn_connecting);
+            return activity.getString(R.string.vpn_connecting);
         case DISCONNECTING:
-            return getString(R.string.vpn_disconnecting);
+            return activity.getString(R.string.vpn_disconnecting);
         case CONNECTED:
-            return getString(R.string.vpn_connected);
+            return activity.getString(R.string.vpn_connected);
         default:
-            return getString(R.string.vpn_connect_hint);
+            return activity.getString(R.string.vpn_connect_hint);
         }
     }
 
     private VpnProfileActor getActor(VpnProfile p) {
-        return new AuthenticationActor(this, p);
+        return new AuthenticationActor(getActivity(), p);
     }
 
     private VpnProfile createVpnProfile(String type) {
@@ -938,8 +949,7 @@
                     Log.e(TAG, "keystore write failed: key=" + key);
                 }
                 pskProfile.setPresharedKey(key);
-                // pass through
-
+                // $FALL-THROUGH$
             case L2TP_IPSEC:
             case L2TP:
                 L2tpProfile l2tpProfile = (L2tpProfile) p;
@@ -1007,8 +1017,6 @@
 
     // managing status check in a background thread
     private class StatusChecker {
-        private List<VpnProfile> mList;
-
         synchronized void check(final List<VpnProfile> list) {
             final ConditionVariable cv = new ConditionVariable();
             cv.close();
@@ -1027,7 +1035,7 @@
                             changeState(p, VpnState.IDLE);
                         }
                     }
-                    VpnSettings.this.unbindService(this);
+                    getActivity().unbindService(this);
                     showPreferences();
                 }
 
@@ -1035,7 +1043,7 @@
                     cv.open();
 
                     setDefaultState(list);
-                    VpnSettings.this.unbindService(this);
+                    getActivity().unbindService(this);
                     showPreferences();
                 }
             };
diff --git a/src/com/android/settings/vpn/VpnTypeSelection.java b/src/com/android/settings/vpn/VpnTypeSelection.java
index aa4bc5e..5990ac0 100644
--- a/src/com/android/settings/vpn/VpnTypeSelection.java
+++ b/src/com/android/settings/vpn/VpnTypeSelection.java
@@ -17,13 +17,14 @@
 package com.android.settings.vpn;
 
 import com.android.settings.R;
+import com.android.settings.SettingsPreferenceFragment;
 
+import android.app.Activity;
 import android.content.Intent;
 import android.net.vpn.VpnManager;
 import android.net.vpn.VpnType;
 import android.os.Bundle;
 import android.preference.Preference;
-import android.preference.PreferenceActivity;
 import android.preference.PreferenceScreen;
 
 import java.util.HashMap;
@@ -32,7 +33,7 @@
 /**
  * The activity to select a VPN type.
  */
-public class VpnTypeSelection extends PreferenceActivity {
+public class VpnTypeSelection extends SettingsPreferenceFragment {
     private Map<String, VpnType> mTypeMap = new HashMap<String, VpnType>();
 
     @Override
@@ -46,19 +47,20 @@
     @Override
     public boolean onPreferenceTreeClick(PreferenceScreen ps, Preference pref) {
         setResult(mTypeMap.get(pref.getTitle().toString()));
-        finish();
+        finishFragment();
         return true;
     }
 
     private void initTypeList() {
         PreferenceScreen root = getPreferenceScreen();
+        final Activity activity = getActivity();
         for (VpnType t : VpnManager.getSupportedVpnTypes()) {
             String displayName = t.getDisplayName();
             String message = String.format(
-                    getString(R.string.vpn_edit_title_add), displayName);
+                    activity.getString(R.string.vpn_edit_title_add), displayName);
             mTypeMap.put(message, t);
 
-            Preference pref = new Preference(this);
+            Preference pref = new Preference(activity);
             pref.setTitle(message);
             pref.setSummary(t.getDescriptionId());
             root.addPreference(pref);
@@ -66,8 +68,8 @@
     }
 
     private void setResult(VpnType type) {
-        Intent intent = new Intent(this, VpnSettings.class);
+        Intent intent = new Intent(getActivity(), VpnSettings.class);
         intent.putExtra(VpnSettings.KEY_VPN_TYPE, type.toString());
-        setResult(RESULT_OK, intent);
+        setResult(Activity.RESULT_OK, intent);
     }
 }
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..905f2a3 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);
                 }
             }
         }
@@ -669,4 +667,12 @@
         mSelectedAccessPoint = null;
         showConfigUi(null, true);
     }
+
+    /* package */ int getAccessPointsCount() {
+        if (mAccessPoints != null) {
+            return mAccessPoints.getPreferenceCount();
+        } else {
+            return 0;
+        }
+    }
 }
diff --git a/src/com/android/settings/wifi/WifiSettingsForSetupWizardXL.java b/src/com/android/settings/wifi/WifiSettingsForSetupWizardXL.java
index 2d26645..ef827f6 100644
--- a/src/com/android/settings/wifi/WifiSettingsForSetupWizardXL.java
+++ b/src/com/android/settings/wifi/WifiSettingsForSetupWizardXL.java
@@ -40,7 +40,7 @@
 
     static {
         stateMap.put(DetailedState.IDLE, DetailedState.DISCONNECTED);
-        stateMap.put(DetailedState.SCANNING, DetailedState.DISCONNECTED);
+        stateMap.put(DetailedState.SCANNING, DetailedState.SCANNING);
         stateMap.put(DetailedState.CONNECTING, DetailedState.CONNECTING);
         stateMap.put(DetailedState.AUTHENTICATING, DetailedState.CONNECTING);
         stateMap.put(DetailedState.OBTAINING_IPADDR, DetailedState.CONNECTING);
@@ -111,28 +111,40 @@
 
     public void updateConnectionState(DetailedState originalState) {
         final DetailedState state = stateMap.get(originalState);
-        final String message;
-        mProgressBar.setIndeterminate(false);
         switch (state) {
+        case SCANNING: {
+            // Let users know the device is working correctly though currently there's
+            // no visible network on the list.
+            if (mWifiSettings.getAccessPointsCount() == 0) {
+                mProgressBar.setIndeterminate(true);
+                mProgressText.setText(Summary.get(this, DetailedState.SCANNING));
+            } else {
+                // Users already already connected to a network, or see available networks.
+                mProgressBar.setIndeterminate(false);
+            }
+            break;
+        }
         case CONNECTING: {
-            message = Summary.get(this, state);
+            mProgressBar.setIndeterminate(false);
             mProgressBar.setProgress(1);
             mStatusText.setText(R.string.wifi_setup_status_connecting);
+            mProgressText.setText(Summary.get(this, state));
             break;
         }
         case CONNECTED: {
-            message = Summary.get(this, state);
+            mProgressBar.setIndeterminate(false);
             mProgressBar.setProgress(2);
             mStatusText.setText(R.string.wifi_setup_status_connected);
+            mProgressText.setText(Summary.get(this, state));
             break;
         }
         default:  // Not connected.
-            message = getString(R.string.wifi_setup_not_connected);
+            mProgressBar.setIndeterminate(false);
             mProgressBar.setProgress(0);
             mStatusText.setText(R.string.wifi_setup_status_select_network);
+            mProgressText.setText(getString(R.string.wifi_setup_not_connected));
             break;
         }
-        mProgressText.setText(message);
     }
 
     public void onWifiConfigPreferenceAttached(boolean isNewNetwork) {