Merge "Data usage fit and finish."
diff --git a/res/layout/vpn_dialog.xml b/res/layout/vpn_dialog.xml
index ffbfd4d..b4779e6 100644
--- a/res/layout/vpn_dialog.xml
+++ b/res/layout/vpn_dialog.xml
@@ -15,7 +15,7 @@
 -->
 
 <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
-        android:layout_width="wrap_content"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content">
     <LinearLayout android:layout_width="match_parent"
             android:layout_height="wrap_content"
@@ -96,15 +96,27 @@
                         android:prompt="@string/vpn_ipsec_ca_cert" />
             </LinearLayout>
 
+            <CheckBox style="@style/vpn_value" android:id="@+id/show_options"
+                    android:singleLine="false"
+                    android:text="@string/vpn_show_options"/>
+        </LinearLayout>
+
+        <LinearLayout android:id="@+id/options"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:orientation="vertical"
+                android:visibility="gone">
             <TextView style="@style/vpn_label" android:text="@string/vpn_search_domains"/>
             <EditText style="@style/vpn_value" android:id="@+id/search_domains"
                     android:hint="@string/vpn_not_used"/>
 
-            <!-- Not sure if we have time to make it. -->
-            <TextView style="@style/vpn_label" android:text="@string/vpn_routes"
-                    android:visibility="gone"/>
+            <TextView style="@style/vpn_label" android:text="@string/vpn_dns_servers"/>
+            <EditText style="@style/vpn_value" android:id="@+id/dns_servers"
+                    android:hint="@string/vpn_not_used"/>
+
+            <TextView style="@style/vpn_label" android:text="@string/vpn_routes"/>
             <EditText style="@style/vpn_value" android:id="@+id/routes"
-                    android:visibility="gone"/>
+                    android:hint="@string/vpn_not_used"/>
         </LinearLayout>
 
         <LinearLayout android:id="@+id/login"
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f846e19..7fd38c2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1542,6 +1542,8 @@
     <string name="screen_timeout_summary">Screen turns off automatically after <xliff:g id="timeout_description">%1$s</xliff:g></string>
     <!-- Wallpaper settings title [CHAR LIMIT=30] -->
     <string name="wallpaper_settings_title">Wallpaper</string>
+    <!-- Wallpaper settings fragment title [CHAR LIMIT=30] -->
+    <string name="wallpaper_settings_fragment_title">Select wallpaper from</string>
     <!-- Display settings screen, trigger for screen saver options -->
     <string name="dream_settings_title">Android Dreams</string>
     <!-- Display settings screen, summary for screen saver options -->
@@ -2739,6 +2741,8 @@
     <string name="power_usage_summary">What has been using the battery</string>
     <!-- Message to show when battery usage data is not available [CHAR LIMIT=30] -->
     <string name="power_usage_not_available">Battery usage data not available</string>
+    <!-- Display the battery level and status [CHAR_LIMIT=30] -->
+    <string name="power_usage_level_and_status">Battery level <xliff:g id="level">%1$s</xliff:g> - <xliff:g id="status">%2$s</xliff:g></string>
     <!-- Battery usage since unplugged -->
     <string name="battery_since_unplugged">Battery use since unplugged</string>
     <!-- Battery usage since user reset the stats -->
@@ -3490,18 +3494,21 @@
     <string name="vpn_ipsec_user_cert">IPSec user certificate</string>
     <!-- Selection label for the IPSec CA certificate of a VPN network. [CHAR LIMIT=40] -->
     <string name="vpn_ipsec_ca_cert">IPSec CA certificate</string>
+    <!-- Checkbox label to show advanced options of a VPN network. [CHAR LIMIT=40] -->
+    <string name="vpn_show_options">Show advanced options</string>
     <!-- Input label for the DNS search domains of a VPN network. [CHAR LIMIT=40] -->
     <string name="vpn_search_domains">DNS search domains</string>
+    <!-- Input label for the DNS servers of a VPN network. [CHAR LIMIT=40] -->
+    <string name="vpn_dns_servers">DNS servers (e.g. 8.8.8.8)</string>
     <!-- Input label for the forwarding routes of a VPN network. [CHAR LIMIT=40] -->
-    <string name="vpn_routes">Forwarding routes</string>
+    <string name="vpn_routes">Forwarding routes (e.g. 10.0.0.0/8)</string>
     <!-- Input label for the username of a VPN network. [CHAR LIMIT=40] -->
     <string name="vpn_username">Username</string>
     <!-- Input label for the password of a VPN network. [CHAR LIMIT=40] -->
     <string name="vpn_password">Password</string>
     <!-- Checkbox label to save the username and the password for a VPN network. [CHAR LIMIT=40] -->
     <string name="vpn_save_login">Save account information</string>
-
-    <!-- Hint for not filling an optional field in a VPN configuration. [CHAR LIMIT=40] -->
+    <!-- Hint for not using an optional feature of a VPN network. [CHAR LIMIT=40] -->
     <string name="vpn_not_used">(not used)</string>
     <!-- Option to not use a CA certificate to verify the VPN server. [CHAR LIMIT=40] -->
     <string name="vpn_no_ca_cert">(do not verify server)</string>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index ffa7912..32e0a48 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -143,15 +143,14 @@
     <style name="vpn_label">
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">wrap_content</item>
-        <item name="android:textSize">16sp</item>
+        <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
     </style>
 
     <style name="vpn_value">
         <item name="android:layout_width">match_parent</item>
         <item name="android:layout_height">wrap_content</item>
-        <item name="android:textSize">18sp</item>
+        <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
         <item name="android:singleLine">true</item>
-        <item name="android:paddingBottom">1mm</item>
     </style>
 
     <style name="InputMethodPreferenceStyle">
diff --git a/res/xml/power_usage_summary.xml b/res/xml/power_usage_summary.xml
index b49b140..5fcae5c 100644
--- a/res/xml/power_usage_summary.xml
+++ b/res/xml/power_usage_summary.xml
@@ -17,4 +17,9 @@
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
         android:title="@string/battery_since_unplugged"
         android:key="app_list">
+    <Preference
+        style="?android:attr/preferenceInformationStyle"
+        android:key="battery_status"
+        android:persistent="false"
+    />
 </PreferenceScreen>
diff --git a/res/xml/wallpaper_settings.xml b/res/xml/wallpaper_settings.xml
index 63346f7..bb9e809 100644
--- a/res/xml/wallpaper_settings.xml
+++ b/res/xml/wallpaper_settings.xml
@@ -15,6 +15,6 @@
 -->
 
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
-        android:title="@string/wallpaper_settings_title">
+        android:title="@string/wallpaper_settings_fragment_title">
 
 </PreferenceScreen>
diff --git a/src/com/android/settings/AccessibilityTutorialActivity.java b/src/com/android/settings/AccessibilityTutorialActivity.java
index 21d0028..9ea9917 100644
--- a/src/com/android/settings/AccessibilityTutorialActivity.java
+++ b/src/com/android/settings/AccessibilityTutorialActivity.java
@@ -17,6 +17,7 @@
 package com.android.settings;
 
 import android.app.Activity;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
@@ -25,6 +26,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.provider.Settings;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.View;
@@ -52,9 +54,6 @@
  * available in Touch Exploration.
  */
 public class AccessibilityTutorialActivity extends Activity {
-    /** Intent action for launching this activity. */
-    public static final String ACTION = "com.android.settings.touchtutorial.LAUNCH_TUTORIAL";
-
     /** Instance state saving constant for the active module. */
     private static final String KEY_ACTIVE_MODULE = "active_module";
 
@@ -66,6 +65,9 @@
 
     private AccessibilityManager mAccessibilityManager;
 
+    /** Should touch exploration be disabled when this activity is paused? */
+    private boolean mDisableOnPause;
+
     private final AnimationListener mInAnimationListener = new AnimationListener() {
         @Override
         public void onAnimationEnd(Animation animation) {
@@ -115,6 +117,30 @@
     }
 
     @Override
+    protected void onResume() {
+        super.onResume();
+
+        final ContentResolver cr = getContentResolver();
+
+        if (Settings.Secure.getInt(cr, Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0) == 0) {
+            Settings.Secure.putInt(cr, Settings.Secure.TOUCH_EXPLORATION_ENABLED, 1);
+            mDisableOnPause = true;
+        } else {
+            mDisableOnPause = false;
+        }
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        if (mDisableOnPause) {
+            final ContentResolver cr = getContentResolver();
+            Settings.Secure.putInt(cr, Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0);
+        }
+    }
+
+    @Override
     protected void onSaveInstanceState(Bundle outState) {
         super.onSaveInstanceState(outState);
 
diff --git a/src/com/android/settings/BatteryInfo.java b/src/com/android/settings/BatteryInfo.java
index 3e037cf..d8046cf 100644
--- a/src/com/android/settings/BatteryInfo.java
+++ b/src/com/android/settings/BatteryInfo.java
@@ -90,26 +90,7 @@
                         + getString(R.string.battery_info_temperature_units));
                 mTechnology.setText("" + intent.getStringExtra("technology"));
                 
-                int status = intent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN);
-                String statusString;
-                if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
-                    statusString = getString(R.string.battery_info_status_charging);
-                    if (plugType > 0) {
-                        statusString = statusString + " " + getString(
-                                (plugType == BatteryManager.BATTERY_PLUGGED_AC)
-                                        ? R.string.battery_info_status_charging_ac
-                                        : R.string.battery_info_status_charging_usb);
-                    }
-                } else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) {
-                    statusString = getString(R.string.battery_info_status_discharging);
-                } else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING) {
-                    statusString = getString(R.string.battery_info_status_not_charging);
-                } else if (status == BatteryManager.BATTERY_STATUS_FULL) {
-                    statusString = getString(R.string.battery_info_status_full);
-                } else {
-                    statusString = getString(R.string.battery_info_status_unknown);
-                }
-                mStatus.setText(statusString);
+                mStatus.setText(Utils.getBatteryStatus(getResources(), intent));
 
                 switch (plugType) {
                     case 0:
diff --git a/src/com/android/settings/Settings.java b/src/com/android/settings/Settings.java
index c630ee2..ae7e24e 100644
--- a/src/com/android/settings/Settings.java
+++ b/src/com/android/settings/Settings.java
@@ -28,7 +28,9 @@
 import android.content.pm.PackageManager;
 import android.content.pm.PackageManager.NameNotFoundException;
 import android.os.Bundle;
+import android.preference.Preference;
 import android.preference.PreferenceActivity;
+import android.preference.PreferenceFragment;
 import android.text.TextUtils;
 import android.util.Log;
 import android.view.LayoutInflater;
@@ -535,6 +537,17 @@
     }
 
     @Override
+    public boolean onPreferenceStartFragment(PreferenceFragment caller, Preference pref) {
+        // Override the fragment title for Wallpaper settings
+        CharSequence title = pref.getTitle();
+        if (pref.getFragment().equals(WallpaperTypeSettings.class.getName())) {
+            title = getString(R.string.wallpaper_settings_fragment_title);
+        }
+        startPreferencePanel(pref.getFragment(), pref.getExtras(), 0, title, null, 0);
+        return true;
+    }
+
+    @Override
     public void setListAdapter(ListAdapter adapter) {
         if (mHeaders == null) {
             mHeaders = new ArrayList<Header>();
diff --git a/src/com/android/settings/TetherSettings.java b/src/com/android/settings/TetherSettings.java
index 9991725..f5bee3a 100644
--- a/src/com/android/settings/TetherSettings.java
+++ b/src/com/android/settings/TetherSettings.java
@@ -516,16 +516,13 @@
             mWifiConfig = mDialog.getConfig();
             if (mWifiConfig != null) {
                 /**
-                 * if soft AP is running, bring up with new config
-                 * else update the configuration alone
+                 * if soft AP is stopped, bring up
+                 * else restart with new config
+                 * TODO: update config on a running access point when framework support is added
                  */
                 if (mWifiManager.getWifiApState() == WifiManager.WIFI_AP_STATE_ENABLED) {
+                    mWifiManager.setWifiApEnabled(null, false);
                     mWifiManager.setWifiApEnabled(mWifiConfig, true);
-                    /**
-                     * There is no tether notification on changing AP
-                     * configuration. Update status with new config.
-                     */
-                    mWifiApEnabler.updateConfigSummary(mWifiConfig);
                 } else {
                     mWifiManager.setWifiApConfiguration(mWifiConfig);
                 }
diff --git a/src/com/android/settings/Utils.java b/src/com/android/settings/Utils.java
index 422ae90..b725d56 100644
--- a/src/com/android/settings/Utils.java
+++ b/src/com/android/settings/Utils.java
@@ -27,6 +27,7 @@
 import android.graphics.drawable.Drawable;
 import android.net.ConnectivityManager;
 import android.net.LinkProperties;
+import android.os.BatteryManager;
 import android.os.Bundle;
 import android.os.SystemProperties;
 import android.preference.Preference;
@@ -330,4 +331,38 @@
             return new Locale(brokenDownLocale[0], brokenDownLocale[1], brokenDownLocale[2]);
         }
     }
+
+    public static String getBatteryPercentage(Intent batteryChangedIntent) {
+        int level = batteryChangedIntent.getIntExtra("level", 0);
+        int scale = batteryChangedIntent.getIntExtra("scale", 100);
+        return String.valueOf(level * 100 / scale) + "%";
+    }
+
+    public static String getBatteryStatus(Resources res, Intent batteryChangedIntent) {
+        final Intent intent = batteryChangedIntent;
+
+        int plugType = intent.getIntExtra("plugged", 0);
+        int status = intent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN);
+        String statusString;
+        if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
+            statusString = res.getString(R.string.battery_info_status_charging);
+            if (plugType > 0) {
+                statusString = statusString
+                        + " "
+                        + res.getString((plugType == BatteryManager.BATTERY_PLUGGED_AC)
+                                ? R.string.battery_info_status_charging_ac
+                                : R.string.battery_info_status_charging_usb);
+            }
+        } else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) {
+            statusString = res.getString(R.string.battery_info_status_discharging);
+        } else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING) {
+            statusString = res.getString(R.string.battery_info_status_not_charging);
+        } else if (status == BatteryManager.BATTERY_STATUS_FULL) {
+            statusString = res.getString(R.string.battery_info_status_full);
+        } else {
+            statusString = res.getString(R.string.battery_info_status_unknown);
+        }
+
+        return statusString;
+    }
 }
diff --git a/src/com/android/settings/WallpaperTypeSettings.java b/src/com/android/settings/WallpaperTypeSettings.java
index fa0b4e4..fa5f0ac 100644
--- a/src/com/android/settings/WallpaperTypeSettings.java
+++ b/src/com/android/settings/WallpaperTypeSettings.java
@@ -16,13 +16,14 @@
 
 package com.android.settings;
 
+import android.app.Activity;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
-import android.graphics.drawable.Drawable;
 import android.os.Bundle;
 import android.preference.Preference;
+import android.preference.PreferenceScreen;
 
 import java.util.List;
 
@@ -32,7 +33,6 @@
         super.onCreate(savedInstanceState);
 
         addPreferencesFromResource(R.xml.wallpaper_settings);
-
         populateWallpaperTypes();
     }
 
@@ -43,6 +43,8 @@
         List<ResolveInfo> rList = pm.queryIntentActivities(intent,
                 PackageManager.MATCH_DEFAULT_ONLY);
 
+        final PreferenceScreen parent = getPreferenceScreen();
+        parent.setOrderingAsAdded(false);
         // Add Preference items for each of the matching activities
         for (ResolveInfo info : rList) {
             Preference pref = new Preference(getActivity());
@@ -53,7 +55,7 @@
             CharSequence label = info.loadLabel(pm);
             if (label == null) label = info.activityInfo.packageName;
             pref.setTitle(label);
-            getPreferenceScreen().addPreference(pref);
+            parent.addPreference(pref);
         }
     }
 }
diff --git a/src/com/android/settings/deviceinfo/Status.java b/src/com/android/settings/deviceinfo/Status.java
index 456bc98..987fab8 100644
--- a/src/com/android/settings/deviceinfo/Status.java
+++ b/src/com/android/settings/deviceinfo/Status.java
@@ -157,33 +157,8 @@
         public void onReceive(Context context, Intent intent) {
             String action = intent.getAction();
             if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
-
-                int level = intent.getIntExtra("level", 0);
-                int scale = intent.getIntExtra("scale", 100);
-
-                mBatteryLevel.setSummary(String.valueOf(level * 100 / scale) + "%");
-
-                int plugType = intent.getIntExtra("plugged", 0);
-                int status = intent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN);
-                String statusString;
-                if (status == BatteryManager.BATTERY_STATUS_CHARGING) {
-                    statusString = getString(R.string.battery_info_status_charging);
-                    if (plugType > 0) {
-                        statusString = statusString + " " + getString(
-                                (plugType == BatteryManager.BATTERY_PLUGGED_AC)
-                                        ? R.string.battery_info_status_charging_ac
-                                        : R.string.battery_info_status_charging_usb);
-                    }
-                } else if (status == BatteryManager.BATTERY_STATUS_DISCHARGING) {
-                    statusString = getString(R.string.battery_info_status_discharging);
-                } else if (status == BatteryManager.BATTERY_STATUS_NOT_CHARGING) {
-                    statusString = getString(R.string.battery_info_status_not_charging);
-                } else if (status == BatteryManager.BATTERY_STATUS_FULL) {
-                    statusString = getString(R.string.battery_info_status_full);
-                } else {
-                    statusString = getString(R.string.battery_info_status_unknown);
-                }
-                mBatteryStatus.setSummary(statusString);
+                mBatteryLevel.setSummary(Utils.getBatteryPercentage(intent));
+                mBatteryStatus.setSummary(Utils.getBatteryStatus(getResources(), intent));
             }
         }
     };
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index d46853d..f28ba93 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -16,10 +16,14 @@
 
 package com.android.settings.fuelgauge;
 
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.hardware.SensorManager;
 import android.os.BatteryStats;
 import android.os.BatteryStats.Uid;
+import android.os.BatteryManager;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
@@ -64,6 +68,9 @@
 
     private static final String TAG = "PowerUsageSummary";
 
+    private static final String KEY_APP_LIST = "app_list";
+    private static final String KEY_BATTERY_STATUS = "battery_status";
+
     private static final int MENU_STATS_TYPE = Menu.FIRST;
     private static final int MENU_STATS_REFRESH = Menu.FIRST + 1;
 
@@ -76,6 +83,7 @@
     private final List<BatterySipper> mBluetoothSippers = new ArrayList<BatterySipper>();
 
     private PreferenceGroup mAppListGroup;
+    private Preference mBatteryStatusPref;
 
     private int mStatsType = BatteryStats.STATS_SINCE_CHARGED;
 
@@ -96,7 +104,23 @@
     private ArrayList<BatterySipper> mRequestQueue = new ArrayList<BatterySipper>();
     private Thread mRequestThread;
     private boolean mAbort;
-    
+
+    private BroadcastReceiver mBatteryInfoReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            String action = intent.getAction();
+            if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
+                String batteryLevel = com.android.settings.Utils.getBatteryPercentage(intent);
+                String batteryStatus = com.android.settings.Utils.getBatteryStatus(getResources(),
+                        intent);
+                String batterySummary = context.getResources().getString(
+                        R.string.power_usage_level_and_status, batteryLevel, batteryStatus);
+                mBatteryStatusPref.setTitle(batterySummary);
+            }
+        }
+    };
+
     @Override
     public void onCreate(Bundle icicle) {
         super.onCreate(icicle);
@@ -108,7 +132,8 @@
         addPreferencesFromResource(R.xml.power_usage_summary);
         mBatteryInfo = IBatteryStats.Stub.asInterface(
                 ServiceManager.getService("batteryinfo"));
-        mAppListGroup = (PreferenceGroup) findPreference("app_list");
+        mAppListGroup = (PreferenceGroup) findPreference(KEY_APP_LIST);
+        mBatteryStatusPref = mAppListGroup.findPreference(KEY_BATTERY_STATUS);
         mPowerProfile = new PowerProfile(getActivity());
         setHasOptionsMenu(true);
     }
@@ -117,6 +142,8 @@
     public void onResume() {
         super.onResume();
         mAbort = false;
+        getActivity().registerReceiver(mBatteryInfoReceiver,
+                new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
         refreshStats();
     }
 
@@ -126,6 +153,7 @@
             mAbort = true;
         }
         mHandler.removeMessages(MSG_UPDATE_NAME_ICON);
+        getActivity().unregisterReceiver(mBatteryInfoReceiver);
         super.onPause();
     }
 
@@ -335,6 +363,8 @@
         mBluetoothSippers.clear();
         mAppListGroup.setOrderingAsAdded(false);
 
+        mBatteryStatusPref.setOrder(-2);
+        mAppListGroup.addPreference(mBatteryStatusPref);
         BatteryHistoryPreference hist = new BatteryHistoryPreference(getActivity(), mStats);
         hist.setOrder(-1);
         mAppListGroup.addPreference(hist);
diff --git a/src/com/android/settings/vpn2/VpnDialog.java b/src/com/android/settings/vpn2/VpnDialog.java
index d644700..c1a4531 100644
--- a/src/com/android/settings/vpn2/VpnDialog.java
+++ b/src/com/android/settings/vpn2/VpnDialog.java
@@ -27,15 +27,18 @@
 import android.text.Editable;
 import android.text.TextWatcher;
 import android.view.View;
+import android.view.WindowManager;
 import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemSelectedListener;
 import android.widget.ArrayAdapter;
 import android.widget.Button;
 import android.widget.CheckBox;
 import android.widget.Spinner;
 import android.widget.TextView;
 
-class VpnDialog extends AlertDialog implements TextWatcher, OnItemSelectedListener {
+import java.net.InetAddress;
+
+class VpnDialog extends AlertDialog implements TextWatcher,
+        View.OnClickListener, AdapterView.OnItemSelectedListener {
     private final KeyStore mKeyStore = KeyStore.getInstance();
     private final DialogInterface.OnClickListener mListener;
     private final VpnProfile mProfile;
@@ -50,6 +53,7 @@
     private TextView mUsername;
     private TextView mPassword;
     private TextView mSearchDomains;
+    private TextView mDnsServers;
     private TextView mRoutes;
     private CheckBox mMppe;
     private TextView mL2tpSecret;
@@ -82,6 +86,7 @@
         mUsername = (TextView) mView.findViewById(R.id.username);
         mPassword = (TextView) mView.findViewById(R.id.password);
         mSearchDomains = (TextView) mView.findViewById(R.id.search_domains);
+        mDnsServers = (TextView) mView.findViewById(R.id.dns_servers);
         mRoutes = (TextView) mView.findViewById(R.id.routes);
         mMppe = (CheckBox) mView.findViewById(R.id.mppe);
         mL2tpSecret = (TextView) mView.findViewById(R.id.l2tp_secret);
@@ -98,6 +103,7 @@
         mUsername.setText(mProfile.username);
         mPassword.setText(mProfile.password);
         mSearchDomains.setText(mProfile.searchDomains);
+        mDnsServers.setText(mProfile.dnsServers);
         mRoutes.setText(mProfile.routes);
         mMppe.setChecked(mProfile.mppe);
         mL2tpSecret.setText(mProfile.l2tpSecret);
@@ -115,6 +121,8 @@
         mServer.addTextChangedListener(this);
         mUsername.addTextChangedListener(this);
         mPassword.addTextChangedListener(this);
+        mDnsServers.addTextChangedListener(this);
+        mRoutes.addTextChangedListener(this);
         mIpsecSecret.addTextChangedListener(this);
         mIpsecUserCert.setOnItemSelectedListener(this);
 
@@ -131,6 +139,15 @@
             // Show type-specific fields.
             changeType(mProfile.type);
 
+            // Show advanced options directly if any of them is set.
+            View showOptions = mView.findViewById(R.id.show_options);
+            if (mProfile.searchDomains.isEmpty() && mProfile.dnsServers.isEmpty() &&
+                    mProfile.routes.isEmpty()) {
+                showOptions.setOnClickListener(this);
+            } else {
+                onClick(showOptions);
+            }
+
             // Create a button to save the profile.
             setButton(DialogInterface.BUTTON_POSITIVE,
                     context.getString(R.string.vpn_save), mListener);
@@ -155,6 +172,10 @@
         // Disable the action button if necessary.
         getButton(DialogInterface.BUTTON_POSITIVE)
                 .setEnabled(mEditing ? valid : validate(false));
+
+        // Workaround to resize the dialog for the input method.
+        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE |
+                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
     }
 
     @Override
@@ -171,6 +192,12 @@
     }
 
     @Override
+    public void onClick(View showOptions) {
+        showOptions.setVisibility(View.GONE);
+        mView.findViewById(R.id.options).setVisibility(View.VISIBLE);
+    }
+
+    @Override
     public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
         if (parent == mType) {
             changeType(position);
@@ -221,7 +248,9 @@
         if (!editing) {
             return mUsername.getText().length() != 0 && mPassword.getText().length() != 0;
         }
-        if (mName.getText().length() == 0 || mServer.getText().length() == 0) {
+        if (mName.getText().length() == 0 || mServer.getText().length() == 0 ||
+                !validateAddresses(mDnsServers.getText().toString(), false) ||
+                !validateAddresses(mRoutes.getText().toString(), true)) {
             return false;
         }
         switch (mType.getSelectedItemPosition()) {
@@ -239,6 +268,33 @@
         return false;
     }
 
+    private boolean validateAddresses(String addresses, boolean cidr) {
+        try {
+            for (String address : addresses.split(" ")) {
+                if (address.isEmpty()) {
+                    continue;
+                }
+                // Legacy VPN currently only supports IPv4.
+                int prefixLength = 32;
+                if (cidr) {
+                    String[] parts = address.split("/", 2);
+                    address = parts[0];
+                    prefixLength = Integer.parseInt(parts[1]);
+                }
+                byte[] bytes = InetAddress.parseNumericAddress(address).getAddress();
+                int integer = (bytes[3] & 0xFF) | (bytes[2] & 0xFF) << 8 |
+                        (bytes[1] & 0xFF) << 16 | (bytes[0] & 0xFF) << 24;
+                if (bytes.length != 4 || prefixLength < 0 || prefixLength > 32 ||
+                        (prefixLength < 32 && (integer << prefixLength) != 0)) {
+                    return false;
+                }
+            }
+        } catch (Exception e) {
+            return false;
+        }
+        return true;
+    }
+
     private void loadCertificates(Spinner spinner, String prefix, int firstId, String selected) {
         Context context = getContext();
         String first = (firstId == 0) ? "" : context.getString(firstId);
@@ -279,6 +335,7 @@
         profile.username = mUsername.getText().toString();
         profile.password = mPassword.getText().toString();
         profile.searchDomains = mSearchDomains.getText().toString().trim();
+        profile.dnsServers = mDnsServers.getText().toString().trim();
         profile.routes = mRoutes.getText().toString().trim();
 
         // Then, save type-specific fields.
diff --git a/src/com/android/settings/vpn2/VpnSettings.java b/src/com/android/settings/vpn2/VpnSettings.java
index 4dbb6bd..2ab99e8 100644
--- a/src/com/android/settings/vpn2/VpnSettings.java
+++ b/src/com/android/settings/vpn2/VpnSettings.java
@@ -108,7 +108,7 @@
                 Credentials.getInstance().unlock(getActivity());
             } else {
                 // We already tried, but it is still not working!
-                getActivity().getFragmentManager().popBackStack();
+                finishFragment();
             }
             mUnlocking = !mUnlocking;
             return;
@@ -429,8 +429,11 @@
         config.interfaze = interfaze;
         config.session = profile.name;
         config.routes = profile.routes;
+        if (!profile.dnsServers.isEmpty()) {
+            config.dnsServers = Arrays.asList(profile.dnsServers.split(" +"));
+        }
         if (!profile.searchDomains.isEmpty()) {
-            config.searchDomains = Arrays.asList(profile.searchDomains.split(" "));
+            config.searchDomains = Arrays.asList(profile.searchDomains.split(" +"));
         }
 
         mService.startLegacyVpn(config, racoon, mtpd);
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index 897280f..876fd99 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -112,8 +112,8 @@
     private TextView mProxyPortView;
     private TextView mProxyExclusionListView;
 
-    private IpAssignment mIpAssignment;
-    private ProxySettings mProxySettings;
+    private IpAssignment mIpAssignment = IpAssignment.UNASSIGNED;
+    private ProxySettings mProxySettings = ProxySettings.UNASSIGNED;
     private LinkProperties mLinkProperties = new LinkProperties();
 
     // True when this instance is used in SetupWizard XL context.