Merge "[WifiSetup] Change illustration aspect ratio" into lmp-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 27738c3..af5af30 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -97,8 +97,7 @@
 
         <receiver android:name="ManagedProfileSetup">
             <intent-filter>
-                <action android:name="android.intent.action.BOOT_COMPLETED"/>
-                <action android:name="android.intent.action.PRE_BOOT_COMPLETED"/>
+                <action android:name="android.intent.action.USER_INITIALIZE"/>
             </intent-filter>
         </receiver>
 
diff --git a/res/layout/text_description_preference.xml b/res/layout/text_description_preference.xml
index 78eb02a..d71f078 100644
--- a/res/layout/text_description_preference.xml
+++ b/res/layout/text_description_preference.xml
@@ -16,9 +16,8 @@
 
 <TextView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/summary"
+    android:id="@android:id/summary"
     android:layout_width="fill_parent"
     android:layout_height="wrap_content"
-    android:textAppearance="?android:attr/textAppearanceMedium"
-    android:textColor="?android:attr/textColorSecondary"
+    android:textAppearance="@android:style/TextAppearance.Material.Body1"
     android:padding="16dip" />
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 077f571..34e9391 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -790,21 +790,21 @@
     <!-- Informational text in the first confirmation screen before starting device encryption -->
     <string name="crypt_keeper_desc" product="tablet">
     You can encrypt your accounts, settings, downloaded apps and their data,
-    media, and other files. After you encrypt your tablet, assuming you\’ve set up a screen lock
+    media, and other files. After you encrypt your tablet, assuming you\'ve set up a screen lock
     (that is, a pattern or numeric PIN or password), you\'ll need to unlock the screen to decrypt
     the tablet every time you power it on. The only other way to decrypt is to perform a factory
     data reset, erasing all your data.\n\nEncryption takes an hour or more. You must start with
-    a charged battery and keep your tablet plugged in throughout the process. If you interrupt,
-    you\’ll lose some or all of your data</string>
+    a charged battery and keep your tablet plugged in throughout the process. If you interrupt it,
+    you\'ll lose some or all of your data</string>
     <!-- Informational text in the first confirmation screen before starting device encryption -->
     <string name="crypt_keeper_desc" product="default">
     You can encrypt your accounts, settings, downloaded apps and their data,
-    media, and other files. After you encrypt your phone, assuming you’ve set up a screen lock
+    media, and other files. After you encrypt your phone, assuming you\'ve set up a screen lock
     (that is, a pattern or numeric PIN or password), you\'ll need to unlock the screen to decrypt
     the phone every time you power it on. The only other way to decrypt is to perform a factory
     data reset, erasing all your data.\n\nEncryption takes an hour or more. You must start with
-    a charged battery and keep your phone plugged in throughout the process. If you interrupt,
-    you\’ll lose some or all of your data.</string>
+    a charged battery and keep your phone plugged in throughout the process. If you interrupt it,
+    you\'ll lose some or all of your data.</string>
 
     <!-- Button text to start encryption process -->
     <string name="crypt_keeper_button_text" product="tablet">Encrypt tablet</string>
@@ -3570,8 +3570,12 @@
     <string name="accessibility_long_press_timeout_preference_title">Touch &amp; hold delay</string>
     <!-- Title for the accessibility preference to configure display color inversion. [CHAR LIMIT=NONE] -->
     <string name="accessibility_display_inversion_preference_title">Color inversion</string>
+    <!-- Subtitle for the accessibility preference to configure display color inversion. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_display_inversion_preference_subtitle">(Experimental) May affect performance</string>
     <!-- Title for the accessibility preference to configure display color space correction. [CHAR LIMIT=NONE] -->
-    <string name="accessibility_display_daltonizer_preference_title">Color space correction</string>
+    <string name="accessibility_display_daltonizer_preference_title">Color correction</string>
+    <!-- Subtitle for the accessibility preference to configure display color space correction. [CHAR LIMIT=NONE] -->
+    <string name="accessibility_display_daltonizer_preference_subtitle">This feature is experimental and may affect performance.</string>
 
     <!-- Title for the preference to show a tile for a particular feature in the Quick Settings pane. [CHAR LIMIT=NONE] -->
     <string name="enable_quick_setting">Show in Quick Settings</string>
@@ -4650,11 +4654,11 @@
     <string name="wimax_settings">4G</string>
     <string name="status_wimax_mac_address">4G MAC address</string>
     <!-- This is displayed to the user when the device needs to be decrypted -->
-    <string name="enter_password">Type password to decrypt storage</string>
+    <string name="enter_password">To start Android, enter your password</string>
     <!-- Informational text on the pin entry screen prompting the user for their pin -->
-    <string name="enter_pin">Enter your PIN to decrypt storage</string>
+    <string name="enter_pin">To start Android, enter your PIN</string>
     <!-- Informational text on the pattern entry screen prompting the user for their pattern -->
-    <string name="enter_pattern">Draw your pattern to decrypt storage</string>
+    <string name="enter_pattern">To start Android, draw your pattern</string>
     <!-- This is displayed when the password is entered incorrectly -->
     <string name="try_again">Try again.</string>
 
@@ -5257,11 +5261,13 @@
     <!-- Title for Guest user [CHAR LIMIT=35] -->
     <string name="user_guest">Guest</string>
     <!-- Label for item to exit guest mode [CHAR LIMIT=35] -->
-    <string name="user_exit_guest_title">Exit guest</string>
+    <string name="user_exit_guest_title">Remove guest</string>
     <!-- Title of dialog to user to confirm exiting guest. [CHAR LIMIT=50] -->
-    <string name="user_exit_guest_confirm_title">Exiting guest session?</string>
+    <string name="user_exit_guest_confirm_title">Remove guest?</string>
     <!-- Message to user to confirm exiting guest. [CHAR LIMIT=none] -->
-    <string name="user_exit_guest_confirm_message">Ending the guest session will remove local data.</string>
+    <string name="user_exit_guest_confirm_message">All apps and data in this session will be deleted.</string>
+    <!-- Label for button in confirmation dialog when exiting guest session [CHAR LIMIT=35] -->
+    <string name="user_exit_guest_dialog_remove">Remove</string>
 
     <!-- Title of preference to enable calling[CHAR LIMIT=40] -->
     <string name="user_enable_calling">Allow phone calls</string>
diff --git a/res/xml/accessibility_daltonizer_settings.xml b/res/xml/accessibility_daltonizer_settings.xml
index 30a5444..62c0dfc 100644
--- a/res/xml/accessibility_daltonizer_settings.xml
+++ b/res/xml/accessibility_daltonizer_settings.xml
@@ -17,6 +17,12 @@
 <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
     android:title="@string/accessibility_display_daltonizer_preference_title" >
 
+    <Preference
+        android:summary="@string/accessibility_display_daltonizer_preference_subtitle"
+        android:layout="@layout/text_description_preference"
+        android:persistent="false"
+        android:selectable="false" />
+
     <ListPreference
         android:entries="@array/daltonizer_type_entries"
         android:entryValues="@array/daltonizer_type_values"
diff --git a/res/xml/accessibility_settings.xml b/res/xml/accessibility_settings.xml
index a870074..d2d7711 100644
--- a/res/xml/accessibility_settings.xml
+++ b/res/xml/accessibility_settings.xml
@@ -86,6 +86,7 @@
         <SwitchPreference
             android:key="toggle_inversion_preference"
             android:title="@string/accessibility_display_inversion_preference_title"
+            android:summary="@string/accessibility_display_inversion_preference_subtitle"
             android:persistent="false" />
         <PreferenceScreen
             android:fragment="com.android.settings.accessibility.ToggleDaltonizerPreferenceFragment"
diff --git a/src/com/android/settings/ApnSettings.java b/src/com/android/settings/ApnSettings.java
index b8864f3..d214df2 100644
--- a/src/com/android/settings/ApnSettings.java
+++ b/src/com/android/settings/ApnSettings.java
@@ -133,7 +133,9 @@
         mMobileStateFilter = new IntentFilter(
                 TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED);
 
-        setHasOptionsMenu(true);
+        if (!mUm.hasUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS)) {
+            setHasOptionsMenu(true);
+        }
     }
 
     @Override
diff --git a/src/com/android/settings/ManagedProfileSetup.java b/src/com/android/settings/ManagedProfileSetup.java
index 1b3c838..198abe0 100644
--- a/src/com/android/settings/ManagedProfileSetup.java
+++ b/src/com/android/settings/ManagedProfileSetup.java
@@ -22,6 +22,7 @@
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.util.Log;
 import android.os.UserHandle;
 import android.os.UserManager;
 
@@ -37,6 +38,7 @@
  * adds cross-profile intent filters for the appropriate Settings activities).
  */
 public class ManagedProfileSetup extends BroadcastReceiver {
+    private static final String TAG = "Settings";
     private static final String PRIMARY_PROFILE_SETTING =
             "com.android.settings.PRIMARY_PROFILE_CONTROLLED";
 
@@ -46,7 +48,8 @@
         if (!Utils.isManagedProfile(um)) {
             return;
         }
-
+        Log.i(TAG, "Received broadcast: " + broadcast.getAction()
+                + ". Setting up intent forwarding for managed profile.");
         final PackageManager pm  = context.getPackageManager();
         // Clear any previous intent forwarding we set up
         pm.clearCrossProfileIntentFilters(UserHandle.myUserId());
diff --git a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
index 9fe70df..b23035b 100644
--- a/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleFeaturePreferenceFragment.java
@@ -55,10 +55,10 @@
                 getActivity());
         setPreferenceScreen(preferenceScreen);
         mSummaryPreference = new Preference(getActivity()) {
-                @Override
+            @Override
             protected void onBindView(View view) {
                 super.onBindView(view);
-                TextView summaryView = (TextView) view.findViewById(R.id.summary);
+                final TextView summaryView = (TextView) view.findViewById(android.R.id.summary);
                 summaryView.setText(getSummary());
                 sendAccessibilityEvent(summaryView);
             }
diff --git a/src/com/android/settings/accounts/AccountSettings.java b/src/com/android/settings/accounts/AccountSettings.java
index 2eb89b0..891fdbb 100644
--- a/src/com/android/settings/accounts/AccountSettings.java
+++ b/src/com/android/settings/accounts/AccountSettings.java
@@ -137,7 +137,7 @@
                             currentProfile.getIdentifier()));
             menu.findItem(R.id.account_settings_menu_auto_sync_personal).setVisible(false);
             menu.findItem(R.id.account_settings_menu_auto_sync_work).setVisible(false);
-        } else {
+        } else if (mProfiles.size() > 1) {
             // We assume there's only one managed profile, otherwise UI needs to change
             final UserHandle managedProfile = mProfiles.valueAt(1).userInfo.getUserHandle();
 
@@ -152,6 +152,8 @@
                     .setChecked(ContentResolver.getMasterSyncAutomaticallyAsUser(
                             managedProfile.getIdentifier()));
             menu.findItem(R.id.account_settings_menu_auto_sync).setVisible(false);
+         } else {
+             Log.w(TAG, "Method onPrepareOptionsMenu called before mProfiles was initialized");
          }
     }
 
diff --git a/src/com/android/settings/location/DimmableIconPreference.java b/src/com/android/settings/location/DimmableIconPreference.java
new file mode 100644
index 0000000..acde1c1
--- /dev/null
+++ b/src/com/android/settings/location/DimmableIconPreference.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settings.location;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.preference.Preference;
+import android.util.AttributeSet;
+
+/**
+ * A preference item that can dim the icon when it's disabled, either directly or because its parent
+ * is disabled.
+ */
+public class DimmableIconPreference extends Preference {
+    private static final int ICON_ALPHA_ENABLED = 255;
+    private static final int ICON_ALPHA_DISABLED = 102;
+
+    public DimmableIconPreference(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    public DimmableIconPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    public DimmableIconPreference(Context context) {
+        super(context);
+    }
+
+    private void dimIcon(boolean dimmed) {
+        Drawable icon = getIcon();
+        if (icon != null) {
+            icon.mutate().setAlpha(dimmed ? ICON_ALPHA_DISABLED : ICON_ALPHA_ENABLED);
+            setIcon(icon);
+        }
+    }
+
+    @Override
+    public void onParentChanged(Preference parent, boolean disableChild) {
+        dimIcon(disableChild);
+        super.onParentChanged(parent, disableChild);
+    }
+
+    @Override
+    public void setEnabled(boolean enabled) {
+        dimIcon(!enabled);
+        super.setEnabled(enabled);
+    }
+}
diff --git a/src/com/android/settings/location/InjectedSetting.java b/src/com/android/settings/location/InjectedSetting.java
index d8a3f49..5f4440a 100644
--- a/src/com/android/settings/location/InjectedSetting.java
+++ b/src/com/android/settings/location/InjectedSetting.java
@@ -23,7 +23,7 @@
 import com.android.internal.util.Preconditions;
 
 /**
- * Specifies a setting that is being injected into Settings > Location > Location services.
+ * Specifies a setting that is being injected into Settings &gt; Location &gt; Location services.
  *
  * @see android.location.SettingInjectorService
  */
diff --git a/src/com/android/settings/location/RecentLocationApps.java b/src/com/android/settings/location/RecentLocationApps.java
index 7c59927..e28f96b 100644
--- a/src/com/android/settings/location/RecentLocationApps.java
+++ b/src/com/android/settings/location/RecentLocationApps.java
@@ -81,7 +81,7 @@
      * Subclass of {@link Preference} to intercept views and allow content description to be set on
      * them for accessibility purposes.
      */
-    private static class AccessiblePreference extends Preference {
+    private static class AccessiblePreference extends DimmableIconPreference {
         public CharSequence mContentDescription;
 
         public AccessiblePreference(Context context, CharSequence contentDescription) {
diff --git a/src/com/android/settings/location/SettingsInjector.java b/src/com/android/settings/location/SettingsInjector.java
index 5f8d030..edf67b8 100644
--- a/src/com/android/settings/location/SettingsInjector.java
+++ b/src/com/android/settings/location/SettingsInjector.java
@@ -247,7 +247,7 @@
      * Adds an injected setting to the root.
      */
     private Preference addServiceSetting(List<Preference> prefs, InjectedSetting info) {
-        Preference pref = new Preference(mContext);
+        Preference pref = new DimmableIconPreference(mContext);
         pref.setTitle(info.title);
         pref.setSummary(null);
         PackageManager pm = mContext.getPackageManager();
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 9ad34a9..726fc00 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -630,14 +630,14 @@
                 Dialog dlg = new AlertDialog.Builder(context)
                         .setTitle(R.string.user_exit_guest_confirm_title)
                         .setMessage(R.string.user_exit_guest_confirm_message)
-                        .setPositiveButton(android.R.string.yes,
+                        .setPositiveButton(R.string.user_exit_guest_dialog_remove,
                                 new DialogInterface.OnClickListener() {
                                     @Override
                                     public void onClick(DialogInterface dialog, int which) {
                                         exitGuest();
                                     }
                                 })
-                        .setNegativeButton(android.R.string.no, null)
+                        .setNegativeButton(android.R.string.cancel, null)
                         .create();
                 return dlg;
             }
diff --git a/src/com/android/settings/widget/SwitchBar.java b/src/com/android/settings/widget/SwitchBar.java
index e24d83f..c15ac41 100644
--- a/src/com/android/settings/widget/SwitchBar.java
+++ b/src/com/android/settings/widget/SwitchBar.java
@@ -124,7 +124,7 @@
     public void setEnabled(boolean enabled) {
         super.setEnabled(enabled);
         mTextView.setEnabled(enabled);
-        mSwitch.setEnabled(false);
+        mSwitch.setEnabled(enabled);
     }
 
     public final ToggleSwitch getSwitch() {
diff --git a/src/com/android/settings/wifi/AdvancedWifiSettings.java b/src/com/android/settings/wifi/AdvancedWifiSettings.java
index 236aecd..a57097b 100644
--- a/src/com/android/settings/wifi/AdvancedWifiSettings.java
+++ b/src/com/android/settings/wifi/AdvancedWifiSettings.java
@@ -135,7 +135,9 @@
             wifiAssistant.setOnPreferenceChangeListener(this);
             wifiAssistant.setChecked(checked);
         } else {
-            getPreferenceScreen().removePreference(wifiAssistant);
+            if (wifiAssistant != null) {
+                getPreferenceScreen().removePreference(wifiAssistant);
+            }
         }
 
         Intent wifiDirectIntent = new Intent(context,
diff --git a/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java b/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java
index a91d153..10c86dc 100644
--- a/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java
+++ b/src/com/android/settings/wifi/SavedAccessPointsWifiSettings.java
@@ -53,6 +53,9 @@
     private Bundle mAccessPointSavedState;
     private AccessPoint mSelectedAccessPoint;
 
+    // Instance state key
+    private static final String SAVE_DIALOG_ACCESS_POINT_STATE = "wifi_ap_state";
+
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
@@ -69,6 +72,13 @@
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
         mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
+
+        if (savedInstanceState != null) {
+            if (savedInstanceState.containsKey(SAVE_DIALOG_ACCESS_POINT_STATE)) {
+                mAccessPointSavedState =
+                    savedInstanceState.getBundle(SAVE_DIALOG_ACCESS_POINT_STATE);
+            }
+        }
     }
 
     private void initPreferences() {
@@ -150,6 +160,11 @@
     public Dialog onCreateDialog(int dialogId) {
         switch (dialogId) {
             case WifiSettings.WIFI_DIALOG_ID:
+                if (mDlgAccessPoint == null) { // For re-launch from saved state
+                    mDlgAccessPoint = new AccessPoint(getActivity(), mAccessPointSavedState);
+                    // Reset the saved access point data
+                    mAccessPointSavedState = null;
+                }
                 mSelectedAccessPoint = mDlgAccessPoint;
                 mDialog = new WifiDialog(getActivity(), this, mDlgAccessPoint, false);
                 return mDialog;
@@ -159,6 +174,20 @@
     }
 
     @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+
+        // If the dialog is showing, save its state.
+        if (mDialog != null && mDialog.isShowing()) {
+            if (mDlgAccessPoint != null) {
+                mAccessPointSavedState = new Bundle();
+                mDlgAccessPoint.saveWifiState(mAccessPointSavedState);
+                outState.putBundle(SAVE_DIALOG_ACCESS_POINT_STATE, mAccessPointSavedState);
+            }
+        }
+    }
+
+    @Override
     public void onClick(DialogInterface dialogInterface, int button) {
         if (button == WifiDialog.BUTTON_FORGET && mSelectedAccessPoint != null) {
             mWifiManager.forget(mSelectedAccessPoint.networkId, null);
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index fc2276a..3b07b9f 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -24,11 +24,11 @@
 import android.net.IpConfiguration.IpAssignment;
 import android.net.IpConfiguration.ProxySettings;
 import android.net.LinkAddress;
-import android.net.LinkProperties;
 import android.net.NetworkInfo.DetailedState;
 import android.net.NetworkUtils;
 import android.net.ProxyInfo;
 import android.net.RouteInfo;
+import android.net.StaticIpConfiguration;
 import android.net.Uri;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiConfiguration.AuthAlgorithm;
@@ -61,6 +61,7 @@
 import com.android.settings.R;
 
 import java.net.InetAddress;
+import java.net.Inet4Address;
 import java.util.Iterator;
 
 /**
@@ -137,7 +138,8 @@
 
     private IpAssignment mIpAssignment = IpAssignment.UNASSIGNED;
     private ProxySettings mProxySettings = ProxySettings.UNASSIGNED;
-    private LinkProperties mLinkProperties = new LinkProperties();
+    private ProxyInfo mHttpProxy = null;
+    private StaticIpConfiguration mStaticIpConfiguration = null;
 
     private String[] mLevels;
     private boolean mEdit;
@@ -216,13 +218,15 @@
                 if (config.getIpAssignment() == IpAssignment.STATIC) {
                     mIpSettingsSpinner.setSelection(STATIC_IP);
                     showAdvancedFields = true;
+                    // Display IP address.
+                    StaticIpConfiguration staticConfig = config.getStaticIpConfiguration();
+                    if (staticConfig != null && staticConfig.ipAddress != null) {
+                        addRow(group, R.string.wifi_ip_address,
+                           staticConfig.ipAddress.getAddress().getHostAddress());
+                    }
                 } else {
                     mIpSettingsSpinner.setSelection(DHCP);
                 }
-                //Display IP addresses
-                for(InetAddress a : config.getLinkProperties().getAddresses()) {
-                    addRow(group, R.string.wifi_ip_address, a.getHostAddress());
-                }
 
 
                 if (config.getProxySettings() == ProxySettings.STATIC) {
@@ -462,19 +466,20 @@
         }
 
         config.setIpConfiguration(
-                new IpConfiguration(mIpAssignment, mProxySettings, mLinkProperties));
+                new IpConfiguration(mIpAssignment, mProxySettings,
+                                    mStaticIpConfiguration, mHttpProxy));
 
         return config;
     }
 
     private boolean ipAndProxyFieldsAreValid() {
-        mLinkProperties.clear();
         mIpAssignment = (mIpSettingsSpinner != null &&
                 mIpSettingsSpinner.getSelectedItemPosition() == STATIC_IP) ?
                 IpAssignment.STATIC : IpAssignment.DHCP;
 
         if (mIpAssignment == IpAssignment.STATIC) {
-            int result = validateIpConfigFields(mLinkProperties);
+            mStaticIpConfiguration = new StaticIpConfiguration();
+            int result = validateIpConfigFields(mStaticIpConfiguration);
             if (result != 0) {
                 return false;
             }
@@ -482,6 +487,7 @@
 
         final int selectedPosition = mProxySettingsSpinner.getSelectedItemPosition();
         mProxySettings = ProxySettings.NONE;
+        mHttpProxy = null;
         if (selectedPosition == PROXY_STATIC && mProxyHostView != null) {
             mProxySettings = ProxySettings.STATIC;
             String host = mProxyHostView.getText().toString();
@@ -496,8 +502,7 @@
                 result = R.string.proxy_error_invalid_port;
             }
             if (result == 0) {
-                ProxyInfo proxyProperties= new ProxyInfo(host, port, exclusionList);
-                mLinkProperties.setHttpProxy(proxyProperties);
+                mHttpProxy = new ProxyInfo(host, port, exclusionList);
             } else {
                 return false;
             }
@@ -511,22 +516,27 @@
             if (uri == null) {
                 return false;
             }
-            ProxyInfo proxyInfo = new ProxyInfo(uri);
-            mLinkProperties.setHttpProxy(proxyInfo);
+            mHttpProxy = new ProxyInfo(uri);
         }
         return true;
     }
 
-    private int validateIpConfigFields(LinkProperties linkProperties) {
+    private Inet4Address getIPv4Address(String text) {
+        try {
+            return (Inet4Address) NetworkUtils.numericToInetAddress(text);
+        } catch (IllegalArgumentException|ClassCastException e) {
+            return null;
+        }
+    }
+
+    private int validateIpConfigFields(StaticIpConfiguration staticIpConfiguration) {
         if (mIpAddressView == null) return 0;
 
         String ipAddr = mIpAddressView.getText().toString();
         if (TextUtils.isEmpty(ipAddr)) return R.string.wifi_ip_settings_invalid_ip_address;
 
-        InetAddress inetAddr = null;
-        try {
-            inetAddr = NetworkUtils.numericToInetAddress(ipAddr);
-        } catch (IllegalArgumentException e) {
+        Inet4Address inetAddr = getIPv4Address(ipAddr);
+        if (inetAddr == null) {
             return R.string.wifi_ip_settings_invalid_ip_address;
         }
 
@@ -536,7 +546,7 @@
             if (networkPrefixLength < 0 || networkPrefixLength > 32) {
                 return R.string.wifi_ip_settings_invalid_network_prefix_length;
             }
-            linkProperties.addLinkAddress(new LinkAddress(inetAddr, networkPrefixLength));
+            staticIpConfiguration.ipAddress = new LinkAddress(inetAddr, networkPrefixLength);
         } catch (NumberFormatException e) {
             // Set the hint as default after user types in ip address
             mNetworkPrefixLengthView.setText(mConfigUi.getContext().getString(
@@ -555,13 +565,11 @@
             } catch (java.net.UnknownHostException u) {
             }
         } else {
-            InetAddress gatewayAddr = null;
-            try {
-                gatewayAddr = NetworkUtils.numericToInetAddress(gateway);
-            } catch (IllegalArgumentException e) {
+            InetAddress gatewayAddr = getIPv4Address(gateway);
+            if (gatewayAddr == null) {
                 return R.string.wifi_ip_settings_invalid_gateway;
             }
-            linkProperties.addRoute(new RouteInfo(gatewayAddr));
+            staticIpConfiguration.gateway = gatewayAddr;
         }
 
         String dns = mDns1View.getText().toString();
@@ -571,22 +579,20 @@
             //If everything else is valid, provide hint as a default option
             mDns1View.setText(mConfigUi.getContext().getString(R.string.wifi_dns1_hint));
         } else {
-            try {
-                dnsAddr = NetworkUtils.numericToInetAddress(dns);
-            } catch (IllegalArgumentException e) {
+            dnsAddr = getIPv4Address(dns);
+            if (dnsAddr == null) {
                 return R.string.wifi_ip_settings_invalid_dns;
             }
-            linkProperties.addDnsServer(dnsAddr);
+            staticIpConfiguration.dnsServers.add(dnsAddr);
         }
 
         if (mDns2View.length() > 0) {
             dns = mDns2View.getText().toString();
-            try {
-                dnsAddr = NetworkUtils.numericToInetAddress(dns);
-            } catch (IllegalArgumentException e) {
+            dnsAddr = getIPv4Address(dns);
+            if (dnsAddr == null) {
                 return R.string.wifi_ip_settings_invalid_dns;
             }
-            linkProperties.addDnsServer(dnsAddr);
+            staticIpConfiguration.dnsServers.add(dnsAddr);
         }
         return 0;
     }
@@ -797,28 +803,26 @@
                 mDns2View.addTextChangedListener(this);
             }
             if (config != null) {
-                LinkProperties linkProperties = config.getLinkProperties();
-                Iterator<LinkAddress> iterator = linkProperties.getLinkAddresses().iterator();
-                if (iterator.hasNext()) {
-                    LinkAddress linkAddress = iterator.next();
-                    mIpAddressView.setText(linkAddress.getAddress().getHostAddress());
-                    mNetworkPrefixLengthView.setText(Integer.toString(linkAddress
-                            .getNetworkPrefixLength()));
-                }
-
-                for (RouteInfo route : linkProperties.getRoutes()) {
-                    if (route.isDefaultRoute()) {
-                        mGatewayView.setText(route.getGateway().getHostAddress());
-                        break;
+                StaticIpConfiguration staticConfig = config.getStaticIpConfiguration();
+                if (staticConfig != null) {
+                    if (staticConfig.ipAddress != null) {
+                        mIpAddressView.setText(
+                                staticConfig.ipAddress.getAddress().getHostAddress());
+                        mNetworkPrefixLengthView.setText(Integer.toString(staticConfig.ipAddress
+                                .getNetworkPrefixLength()));
                     }
-                }
 
-                Iterator<InetAddress> dnsIterator = linkProperties.getDnsServers().iterator();
-                if (dnsIterator.hasNext()) {
-                    mDns1View.setText(dnsIterator.next().getHostAddress());
-                }
-                if (dnsIterator.hasNext()) {
-                    mDns2View.setText(dnsIterator.next().getHostAddress());
+                    if (staticConfig.gateway != null) {
+                        mGatewayView.setText(staticConfig.gateway.getHostAddress());
+                    }
+
+                    Iterator<InetAddress> dnsIterator = staticConfig.dnsServers.iterator();
+                    if (dnsIterator.hasNext()) {
+                        mDns1View.setText(dnsIterator.next().getHostAddress());
+                    }
+                    if (dnsIterator.hasNext()) {
+                        mDns2View.setText(dnsIterator.next().getHostAddress());
+                    }
                 }
             }
         } else {
@@ -848,7 +852,7 @@
                 mProxyExclusionListView.addTextChangedListener(this);
             }
             if (config != null) {
-                ProxyInfo proxyProperties = config.getLinkProperties().getHttpProxy();
+                ProxyInfo proxyProperties = config.getHttpProxy();
                 if (proxyProperties != null) {
                     mProxyHostView.setText(proxyProperties.getHost());
                     mProxyPortView.setText(Integer.toString(proxyProperties.getPort()));
@@ -865,7 +869,7 @@
                 mProxyPacView.addTextChangedListener(this);
             }
             if (config != null) {
-                ProxyInfo proxyInfo = config.getLinkProperties().getHttpProxy();
+                ProxyInfo proxyInfo = config.getHttpProxy();
                 if (proxyInfo != null) {
                     mProxyPacView.setText(proxyInfo.getPacFileUrl().toString());
                 }