Merge "Replace "A" icon with underline with simple "A" icon on font size settings screen Bug: 27694339" into nyc-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 72f567e..4b976b5 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -1550,8 +1550,22 @@
         </activity>
 
         <activity android:name=".SetupRedactionInterstitial"
+            android:enabled="false"
+            android:exported="true"
             android:taskAffinity="com.android.wizard"
-            android:theme="@style/SetupWizardDisableAppStartingTheme"/>
+            android:theme="@style/SetupWizardDisableAppStartingTheme"
+            android:icon="@drawable/ic_suggested_notifications">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.android.settings.suggested.category.DEFAULT_SETUP_WIZARD_ONLY" />
+            </intent-filter>
+            <meta-data android:name="com.android.settings.require_user_type"
+                       android:value="primary" />
+            <meta-data android:name="com.android.settings.title"
+                       android:resource="@string/notification_suggestion_title" />
+            <meta-data android:name="com.android.settings.summary"
+                       android:resource="@string/notification_suggestion_summary" />
+        </activity>
 
         <activity android:name=".notification.RedactionInterstitial"/>
 
diff --git a/res/drawable/ic_suggested_notifications.xml b/res/drawable/ic_suggested_notifications.xml
new file mode 100644
index 0000000..00bd736
--- /dev/null
+++ b/res/drawable/ic_suggested_notifications.xml
@@ -0,0 +1,25 @@
+<!--
+    Copyright (C) 2016 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24.0dp"
+        android:height="24.0dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="@color/suw_color_accent_light">
+    <path
+        android:fillColor="#FFFFFFFF"
+        android:pathData="M12.0,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0c0.0,1.0 0.89,2.0 2.0,2.0zm6.0,-6.0l0.0,-5.0c0.0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4.0c0.0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.0,0.67 -1.5,1.5l0.0,0.68C7.63,5.36 6.0,7.92 6.0,11.0l0.0,5.0l-2.0,2.0l0.0,1.0l16.0,0.0l0.0,-1.0l-2.0,-2.0z"/>
+</vector>
diff --git a/res/layout/vpn_dialog.xml b/res/layout/vpn_dialog.xml
index d7e7f95..620b43f 100644
--- a/res/layout/vpn_dialog.xml
+++ b/res/layout/vpn_dialog.xml
@@ -132,6 +132,9 @@
             <CheckBox style="@style/vpn_value" android:id="@+id/save_login"
                     android:singleLine="false"
                     android:text="@string/vpn_save_login"/>
+            <CheckBox style="@style/vpn_value" android:id="@+id/always_on_vpn"
+                android:singleLine="false"
+                android:text="@string/vpn_menu_lockdown"/>
         </LinearLayout>
     </LinearLayout>
 </ScrollView>
diff --git a/res/menu/vpn.xml b/res/menu/vpn.xml
index 22646d1..7b35c70 100644
--- a/res/menu/vpn.xml
+++ b/res/menu/vpn.xml
@@ -20,8 +20,4 @@
         android:title="@string/vpn_create"
         android:icon="@drawable/ic_menu_add_white"
         android:showAsAction="always" />
-    <item
-        android:id="@+id/vpn_lockdown"
-        android:title="@string/vpn_menu_lockdown"
-        android:showAsAction="never" />
 </menu>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 47fd603..d970857 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -7345,4 +7345,9 @@
     <!-- Message of the dialog box to confirm resetting rate-limiting in the system service ShortcutManager. [CHAR_LIMIT=none] -->
     <string name="confirm_reset_shortcut_manager_throttling_message">Reset ShortcutManager rate-limiting counters?</string>
 
+    <!-- Title of notification suggestion during optional steps of setup. [CHAR_LIMIT=40] -->
+    <string name="notification_suggestion_title">Control lock screen notifications</string>
+    <!-- Summary of notification suggestion during optional steps of setup. [CHAR_LIMIT=80] -->
+    <string name="notification_suggestion_summary">Show or hide notification content</string>
+
 </resources>
diff --git a/res/values/themes.xml b/res/values/themes.xml
index 7a02ea9..c85a4f1 100644
--- a/res/values/themes.xml
+++ b/res/values/themes.xml
@@ -295,6 +295,7 @@
         <item name="android:listPreferredItemPaddingStart">@dimen/suw_layout_margin_sides</item>
         <item name="android:textAppearanceListItemSmall">@android:style/TextAppearance.Material.Body1</item>
         <item name="android:windowAnimationStyle">@style/Animation.SuwWindowAnimation</item>
+        <item name="selectableItemBackground">?android:attr/selectableItemBackground</item>
 
         <item name="suwDividerCondition">both</item>
         <item name="suwListItemIconColor">?android:attr/colorAccent</item>
diff --git a/src/com/android/settings/ChooseLockGeneric.java b/src/com/android/settings/ChooseLockGeneric.java
index 3d5e271..abbb4c6 100644
--- a/src/com/android/settings/ChooseLockGeneric.java
+++ b/src/com/android/settings/ChooseLockGeneric.java
@@ -59,6 +59,12 @@
     public Intent getIntent() {
         Intent modIntent = new Intent(super.getIntent());
         modIntent.putExtra(EXTRA_SHOW_FRAGMENT, getFragmentClass().getName());
+
+        String action = modIntent.getAction();
+        if (DevicePolicyManager.ACTION_SET_NEW_PASSWORD.equals(action)
+                || DevicePolicyManager.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(action)) {
+            modIntent.putExtra(EXTRA_HIDE_DRAWER, true);
+        }
         return modIntent;
     }
 
@@ -110,6 +116,7 @@
         private LockPatternUtils mLockPatternUtils;
         private FingerprintManager mFingerprintManager;
         private int mUserId;
+        private boolean mHideDrawer = false;
         private RemovalCallback mRemovalCallback = new RemovalCallback() {
 
             @Override
@@ -154,6 +161,7 @@
             if (getActivity() instanceof ChooseLockGeneric.InternalActivity) {
                 mPasswordConfirmed = !confirmCredentials;
             }
+            mHideDrawer = getActivity().getIntent().getBooleanExtra(EXTRA_HIDE_DRAWER, false);
 
             mHasChallenge = getActivity().getIntent().getBooleanExtra(
                     ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
@@ -263,6 +271,7 @@
                         unlockMethodIntent);
                 intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT,
                         mForFingerprint);
+                intent.putExtra(EXTRA_HIDE_DRAWER, mHideDrawer);
                 startActivityForResult(intent, ENABLE_ENCRYPTION_REQUEST);
             } else {
                 if (mForChangeCredRequiredForBoot) {
@@ -613,6 +622,9 @@
                             mUserPassword, mUserId);
                 }
             }
+            if (intent != null) {
+                intent.putExtra(EXTRA_HIDE_DRAWER, mHideDrawer);
+            }
             return intent;
         }
 
diff --git a/src/com/android/settings/ChooseLockPassword.java b/src/com/android/settings/ChooseLockPassword.java
index 1376176..0e542e6 100644
--- a/src/com/android/settings/ChooseLockPassword.java
+++ b/src/com/android/settings/ChooseLockPassword.java
@@ -186,6 +186,7 @@
         private static final int MSG_SHOW_ERROR = 1;
 
         private int mUserId;
+        private boolean mHideDrawer = false;
 
         private Handler mHandler = new Handler() {
             @Override
@@ -267,6 +268,7 @@
                     mUserId));
 
             mChooseLockSettingsHelper = new ChooseLockSettingsHelper(getActivity());
+            mHideDrawer = getActivity().getIntent().getBooleanExtra(EXTRA_HIDE_DRAWER, false);
 
             if (intent.getBooleanExtra(
                     ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT, false)) {
@@ -673,6 +675,7 @@
             if (!wasSecureBefore) {
                 Intent intent = getRedactionInterstitialIntent(getActivity());
                 if (intent != null) {
+                    intent.putExtra(EXTRA_HIDE_DRAWER, mHideDrawer);
                     startActivity(intent);
                 }
             }
diff --git a/src/com/android/settings/ChooseLockPattern.java b/src/com/android/settings/ChooseLockPattern.java
index 185e489..1b71685 100644
--- a/src/com/android/settings/ChooseLockPattern.java
+++ b/src/com/android/settings/ChooseLockPattern.java
@@ -146,6 +146,7 @@
         private TextView mFooterLeftButton;
         private TextView mFooterRightButton;
         protected List<LockPatternView.Cell> mChosenPattern = null;
+        private boolean mHideDrawer = false;
 
         /**
          * The patten used during the help screen to show how to draw a pattern.
@@ -384,6 +385,7 @@
                 w.start(mChooseLockSettingsHelper.utils(), required,
                         false, 0, LockPatternUtils.stringToPattern(current), current, mUserId);
             }
+            mHideDrawer = getActivity().getIntent().getBooleanExtra(EXTRA_HIDE_DRAWER, false);
         }
 
         @Override
@@ -674,6 +676,7 @@
             if (!wasSecureBefore) {
                 Intent intent = getRedactionInterstitialIntent(getActivity());
                 if (intent != null) {
+                    intent.putExtra(EXTRA_HIDE_DRAWER, mHideDrawer);
                     startActivity(intent);
                 }
             }
diff --git a/src/com/android/settings/ChooseLockSettingsHelper.java b/src/com/android/settings/ChooseLockSettingsHelper.java
index b23b41a..21d26eb 100644
--- a/src/com/android/settings/ChooseLockSettingsHelper.java
+++ b/src/com/android/settings/ChooseLockSettingsHelper.java
@@ -210,6 +210,8 @@
         intent.putExtra(ConfirmDeviceCredentialBaseFragment.SHOW_WHEN_LOCKED, external);
         intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, hasChallenge);
         intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge);
+        // we should never have a drawer when confirming device credentials.
+        intent.putExtra(SettingsActivity.EXTRA_HIDE_DRAWER, true);
         intent.putExtra(Intent.EXTRA_USER_ID, userId);
         intent.setClassName(ConfirmDeviceCredentialBaseFragment.PACKAGE, activityClass.getName());
         if (external) {
diff --git a/src/com/android/settings/ConfirmDeviceCredentialBaseFragment.java b/src/com/android/settings/ConfirmDeviceCredentialBaseFragment.java
index 42279fd..cf0403c 100644
--- a/src/com/android/settings/ConfirmDeviceCredentialBaseFragment.java
+++ b/src/com/android/settings/ConfirmDeviceCredentialBaseFragment.java
@@ -50,7 +50,7 @@
 /**
  * Base fragment to be shared for PIN/Pattern/Password confirmation fragments.
  */
-public abstract class ConfirmDeviceCredentialBaseFragment extends InstrumentedFragment
+public abstract class ConfirmDeviceCredentialBaseFragment extends OptionsMenuFragment
         implements FingerprintUiHelper.Callback {
 
     public static final String PACKAGE = "com.android.settings";
diff --git a/src/com/android/settings/DeviceAdminSettings.java b/src/com/android/settings/DeviceAdminSettings.java
index ed68119..054ad41 100644
--- a/src/com/android/settings/DeviceAdminSettings.java
+++ b/src/com/android/settings/DeviceAdminSettings.java
@@ -119,7 +119,7 @@
     @Override
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
-
+        setHasOptionsMenu(true);
         Utils.forceCustomPadding(getListView(), true /* additive padding */);
     }
 
diff --git a/src/com/android/settings/MasterClear.java b/src/com/android/settings/MasterClear.java
index 75a4d67..17d3572 100644
--- a/src/com/android/settings/MasterClear.java
+++ b/src/com/android/settings/MasterClear.java
@@ -57,7 +57,7 @@
  *
  * This is the initial screen.
  */
-public class MasterClear extends InstrumentedFragment {
+public class MasterClear extends OptionsMenuFragment {
     private static final String TAG = "MasterClear";
 
     private static final int KEYGUARD_REQUEST = 55;
diff --git a/src/com/android/settings/MasterClearConfirm.java b/src/com/android/settings/MasterClearConfirm.java
index 7c14bad..d521ded 100644
--- a/src/com/android/settings/MasterClearConfirm.java
+++ b/src/com/android/settings/MasterClearConfirm.java
@@ -47,7 +47,7 @@
  *
  * This is the confirmation screen.
  */
-public class MasterClearConfirm extends InstrumentedFragment {
+public class MasterClearConfirm extends OptionsMenuFragment {
 
     private View mContentView;
     private boolean mEraseSdCard;
diff --git a/src/com/android/settings/OptionsMenuFragment.java b/src/com/android/settings/OptionsMenuFragment.java
new file mode 100644
index 0000000..2d05c96
--- /dev/null
+++ b/src/com/android/settings/OptionsMenuFragment.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2016 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;
+
+import android.os.Bundle;
+
+/**
+ * Base class for a fragment that has the options menu.
+ * SettingsPreferenceFragment automatically sets this, but some activities do not use
+ * preferences, and we need to call setHasOptionsMenu(true) for the back button on action bar.
+ * For preference fragments, use SettingsPreferenceFragment.
+ */
+public abstract class OptionsMenuFragment extends InstrumentedFragment {
+
+    @Override
+    public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+        setHasOptionsMenu(true);
+    }
+}
diff --git a/src/com/android/settings/ResetNetwork.java b/src/com/android/settings/ResetNetwork.java
index fe12924..995fe95 100644
--- a/src/com/android/settings/ResetNetwork.java
+++ b/src/com/android/settings/ResetNetwork.java
@@ -50,7 +50,7 @@
  *
  * This is the initial screen.
  */
-public class ResetNetwork extends InstrumentedFragment {
+public class ResetNetwork extends OptionsMenuFragment {
     private static final String TAG = "ResetNetwork";
 
     // Arbitrary to avoid conficts
diff --git a/src/com/android/settings/ResetNetworkConfirm.java b/src/com/android/settings/ResetNetworkConfirm.java
index 110398f..ece64b4 100644
--- a/src/com/android/settings/ResetNetworkConfirm.java
+++ b/src/com/android/settings/ResetNetworkConfirm.java
@@ -50,7 +50,7 @@
  *
  * This is the confirmation screen.
  */
-public class ResetNetworkConfirm extends InstrumentedFragment {
+public class ResetNetworkConfirm extends OptionsMenuFragment {
 
     private View mContentView;
     private int mSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java
index c3efb62..333f6b8 100644
--- a/src/com/android/settings/SecuritySettings.java
+++ b/src/com/android/settings/SecuritySettings.java
@@ -684,6 +684,9 @@
                     mCurrentProfilePassword, mCurrentDevicePassword,
                     profileQuality, MY_USER_ID);
         }
+        final boolean profilePatternVisibility =
+                mLockPatternUtils.isVisiblePatternEnabled(mProfileChallengeUserId);
+        mLockPatternUtils.setVisiblePatternEnabled(profilePatternVisibility, MY_USER_ID);
         mCurrentDevicePassword = null;
         mCurrentProfilePassword = null;
     }
diff --git a/src/com/android/settings/SettingsActivity.java b/src/com/android/settings/SettingsActivity.java
index c4585d1..cecf708 100644
--- a/src/com/android/settings/SettingsActivity.java
+++ b/src/com/android/settings/SettingsActivity.java
@@ -199,6 +199,8 @@
     public static final String EXTRA_SHOW_FRAGMENT_AS_SUBSETTING =
             ":settings:show_fragment_as_subsetting";
 
+    public static final String EXTRA_HIDE_DRAWER = ":settings:hide_drawer";
+
     public static final String META_DATA_KEY_FRAGMENT_CLASS =
         "com.android.settings.FRAGMENT_CLASS";
 
@@ -511,6 +513,9 @@
         if (intent.hasExtra(EXTRA_UI_OPTIONS)) {
             getWindow().setUiOptions(intent.getIntExtra(EXTRA_UI_OPTIONS, 0));
         }
+        if (intent.getBooleanExtra(EXTRA_HIDE_DRAWER, false)) {
+            setIsDrawerPresent(false);
+        }
 
         mDevelopmentPreferences = getSharedPreferences(DevelopmentSettings.PREF_FILE,
                 Context.MODE_PRIVATE);
diff --git a/src/com/android/settings/SettingsPreferenceFragment.java b/src/com/android/settings/SettingsPreferenceFragment.java
index e1cf58b..16df343 100644
--- a/src/com/android/settings/SettingsPreferenceFragment.java
+++ b/src/com/android/settings/SettingsPreferenceFragment.java
@@ -305,7 +305,7 @@
 
     @Override
     public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
-        if (!preferenceScreen.isAttached()) {
+        if (preferenceScreen != null && !preferenceScreen.isAttached()) {
             // Without ids generated, the RecyclerView won't animate changes to the preferences.
             preferenceScreen.setShouldUseGeneratedIds(mAnimationAllowed);
         }
diff --git a/src/com/android/settings/SetupChooseLockGeneric.java b/src/com/android/settings/SetupChooseLockGeneric.java
index 4f0d4ea..8aaca25 100644
--- a/src/com/android/settings/SetupChooseLockGeneric.java
+++ b/src/com/android/settings/SetupChooseLockGeneric.java
@@ -18,8 +18,10 @@
 
 import android.app.Activity;
 import android.app.admin.DevicePolicyManager;
+import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
 import android.content.res.Resources;
 import android.os.Bundle;
 import android.os.UserHandle;
@@ -118,6 +120,12 @@
                 data.putExtra(EXTRA_PASSWORD_QUALITY,
                         lockPatternUtils.getKeyguardStoredPasswordQuality(UserHandle.myUserId()));
 
+                PackageManager packageManager = getPackageManager();
+                ComponentName componentName = new ComponentName("com.android.settings",
+                        "com.android.settings.SetupRedactionInterstitial");
+                packageManager.setComponentEnabledSetting(componentName,
+                        PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
+                        PackageManager.DONT_KILL_APP);
                 super.onActivityResult(requestCode, resultCode, data);
             }
             // If the started activity was cancelled (e.g. the user presses back), then this
diff --git a/src/com/android/settings/SetupChooseLockPassword.java b/src/com/android/settings/SetupChooseLockPassword.java
index e1e0d51..00c30bc 100644
--- a/src/com/android/settings/SetupChooseLockPassword.java
+++ b/src/com/android/settings/SetupChooseLockPassword.java
@@ -109,11 +109,7 @@
 
         @Override
         protected Intent getRedactionInterstitialIntent(Context context) {
-            Intent intent = SetupRedactionInterstitial.createStartIntent(context);
-            if (intent != null) {
-                SetupWizardUtils.copySetupExtras(getActivity().getIntent(), intent);
-            }
-            return intent;
+            return null;
         }
 
         @Override
diff --git a/src/com/android/settings/SetupChooseLockPattern.java b/src/com/android/settings/SetupChooseLockPattern.java
index 3a548bc..a5eab11 100644
--- a/src/com/android/settings/SetupChooseLockPattern.java
+++ b/src/com/android/settings/SetupChooseLockPattern.java
@@ -105,11 +105,7 @@
 
         @Override
         protected Intent getRedactionInterstitialIntent(Context context) {
-            Intent intent = SetupRedactionInterstitial.createStartIntent(context);
-            if (intent != null) {
-                SetupWizardUtils.copySetupExtras(getActivity().getIntent(), intent);
-            }
-            return intent;
+            return null;
         }
 
         @Override
diff --git a/src/com/android/settings/SetupRedactionInterstitial.java b/src/com/android/settings/SetupRedactionInterstitial.java
index e967297..354016d 100644
--- a/src/com/android/settings/SetupRedactionInterstitial.java
+++ b/src/com/android/settings/SetupRedactionInterstitial.java
@@ -39,27 +39,17 @@
  */
 public class SetupRedactionInterstitial extends RedactionInterstitial {
 
-    public static Intent createStartIntent(Context ctx) {
-        Intent startIntent = RedactionInterstitial.createStartIntent(ctx, UserHandle.myUserId());
-        if (startIntent != null) {
-            startIntent.setClass(ctx, SetupRedactionInterstitial.class);
-            startIntent.putExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false)
-                    .putExtra(EXTRA_SHOW_FRAGMENT_TITLE_RESID, -1);
-        }
-        return startIntent;
-    }
-
     @Override
     public Intent getIntent() {
         Intent modIntent = new Intent(super.getIntent());
         modIntent.putExtra(EXTRA_SHOW_FRAGMENT,
-                SetupEncryptionInterstitialFragment.class.getName());
+                SetupRedactionInterstitialFragment.class.getName());
         return modIntent;
     }
 
     @Override
     protected boolean isValidFragment(String fragmentName) {
-        return SetupEncryptionInterstitialFragment.class.getName().equals(fragmentName);
+        return SetupRedactionInterstitialFragment.class.getName().equals(fragmentName);
     }
 
     @Override
@@ -68,7 +58,7 @@
         super.onApplyThemeResource(theme, resid, first);
     }
 
-    public static class SetupEncryptionInterstitialFragment extends RedactionInterstitialFragment
+    public static class SetupRedactionInterstitialFragment extends RedactionInterstitialFragment
             implements NavigationBar.NavigationBarListener {
 
         @Override
diff --git a/src/com/android/settings/TrustedCredentialsSettings.java b/src/com/android/settings/TrustedCredentialsSettings.java
index 62394de..e1f0109 100644
--- a/src/com/android/settings/TrustedCredentialsSettings.java
+++ b/src/com/android/settings/TrustedCredentialsSettings.java
@@ -66,7 +66,7 @@
 import java.util.HashMap;
 import java.util.List;
 
-public class TrustedCredentialsSettings extends InstrumentedFragment {
+public class TrustedCredentialsSettings extends OptionsMenuFragment {
 
     private static final String TAG = "TrustedCredentialsSettings";
 
diff --git a/src/com/android/settings/UserCredentialsSettings.java b/src/com/android/settings/UserCredentialsSettings.java
index e688450..96ef8e9 100644
--- a/src/com/android/settings/UserCredentialsSettings.java
+++ b/src/com/android/settings/UserCredentialsSettings.java
@@ -20,7 +20,6 @@
 import android.app.Dialog;
 import android.app.DialogFragment;
 import android.app.Fragment;
-import android.app.FragmentManager;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.AsyncTask;
@@ -46,14 +45,13 @@
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 
 import java.util.EnumSet;
-import java.util.Set;
 import java.util.SortedMap;
 import java.util.TreeMap;
 
 import static android.view.View.GONE;
 import static android.view.View.VISIBLE;
 
-public class UserCredentialsSettings extends InstrumentedFragment implements OnItemClickListener {
+public class UserCredentialsSettings extends OptionsMenuFragment implements OnItemClickListener {
     private static final String TAG = "UserCredentialsSettings";
 
     private View mRootView;
diff --git a/src/com/android/settings/accessibility/ToggleAutoclickPreferenceFragment.java b/src/com/android/settings/accessibility/ToggleAutoclickPreferenceFragment.java
index daa0c82..a1c8bc5 100644
--- a/src/com/android/settings/accessibility/ToggleAutoclickPreferenceFragment.java
+++ b/src/com/android/settings/accessibility/ToggleAutoclickPreferenceFragment.java
@@ -25,7 +25,6 @@
 import android.widget.Switch;
 
 import com.android.internal.logging.MetricsProto.MetricsEvent;
-import com.android.settings.InstrumentedFragment;
 import com.android.settings.R;
 import com.android.settings.SeekBarPreference;
 import com.android.settings.widget.SwitchBar;
diff --git a/src/com/android/settings/applications/ProcStatsData.java b/src/com/android/settings/applications/ProcStatsData.java
index 5e330b8..3c81374 100644
--- a/src/com/android/settings/applications/ProcStatsData.java
+++ b/src/com/android/settings/applications/ProcStatsData.java
@@ -28,11 +28,14 @@
 import android.util.Log;
 import android.util.SparseArray;
 
-import com.android.internal.app.IProcessStats;
 import com.android.internal.app.ProcessMap;
-import com.android.internal.app.ProcessStats;
-import com.android.internal.app.ProcessStats.ProcessDataCollection;
-import com.android.internal.app.ProcessStats.TotalMemoryUseCollection;
+import com.android.internal.app.procstats.DumpUtils;
+import com.android.internal.app.procstats.IProcessStats;
+import com.android.internal.app.procstats.ProcessState;
+import com.android.internal.app.procstats.ProcessStats;
+import com.android.internal.app.procstats.ProcessStats.ProcessDataCollection;
+import com.android.internal.app.procstats.ProcessStats.TotalMemoryUseCollection;
+import com.android.internal.app.procstats.ServiceState;
 import com.android.internal.util.MemInfoReader;
 import com.android.settings.R;
 import com.android.settings.Utils;
@@ -142,7 +145,7 @@
 
         long now = SystemClock.uptimeMillis();
 
-        memTotalTime = ProcessStats.dumpSingleTime(null, null, mStats.mMemFactorDurations,
+        memTotalTime = DumpUtils.dumpSingleTime(null, null, mStats.mMemFactorDurations,
                 mStats.mMemFactor, mStats.mStartTime, now);
 
         ProcessStats.TotalMemoryUseCollection totalMem = new ProcessStats.TotalMemoryUseCollection(
@@ -274,26 +277,26 @@
                 for (int iv = 0; iv < vpkgs.size(); iv++) {
                     final ProcessStats.PackageState st = vpkgs.valueAt(iv);
                     for (int iproc = 0; iproc < st.mProcesses.size(); iproc++) {
-                        final ProcessStats.ProcessState pkgProc = st.mProcesses.valueAt(iproc);
-                        final ProcessStats.ProcessState proc = mStats.mProcesses.get(pkgProc.mName,
-                                pkgProc.mUid);
+                        final ProcessState pkgProc = st.mProcesses.valueAt(iproc);
+                        final ProcessState proc = mStats.mProcesses.get(pkgProc.getName(),
+                                pkgProc.getUid());
                         if (proc == null) {
                             Log.w(TAG, "No process found for pkg " + st.mPackageName
-                                    + "/" + st.mUid + " proc name " + pkgProc.mName);
+                                    + "/" + st.mUid + " proc name " + pkgProc.getName());
                             continue;
                         }
-                        ProcStatsEntry ent = entriesMap.get(proc.mName, proc.mUid);
+                        ProcStatsEntry ent = entriesMap.get(proc.getName(), proc.getUid());
                         if (ent == null) {
                             ent = new ProcStatsEntry(proc, st.mPackageName, bgTotals, runTotals,
                                     mUseUss);
                             if (ent.mRunWeight > 0) {
-                                if (DEBUG) Log.d(TAG, "Adding proc " + proc.mName + "/"
-                                            + proc.mUid + ": time="
+                                if (DEBUG) Log.d(TAG, "Adding proc " + proc.getName() + "/"
+                                            + proc.getUid() + ": time="
                                             + ProcessStatsUi.makeDuration(ent.mRunDuration) + " ("
                                             + ((((double) ent.mRunDuration) / memTotalTime) * 100)
                                             + "%)"
                                             + " pss=" + ent.mAvgRunMem);
-                                entriesMap.put(proc.mName, proc.mUid, ent);
+                                entriesMap.put(proc.getName(), proc.getUid(), ent);
                                 procEntries.add(ent);
                             }
                         } else {
@@ -315,18 +318,18 @@
                 for (int iv = 0; iv < vpkgs.size(); iv++) {
                     ProcessStats.PackageState ps = vpkgs.valueAt(iv);
                     for (int is = 0, NS = ps.mServices.size(); is < NS; is++) {
-                        ProcessStats.ServiceState ss = ps.mServices.valueAt(is);
-                        if (ss.mProcessName != null) {
-                            ProcStatsEntry ent = entriesMap.get(ss.mProcessName,
+                        ServiceState ss = ps.mServices.valueAt(is);
+                        if (ss.getProcessName() != null) {
+                            ProcStatsEntry ent = entriesMap.get(ss.getProcessName(),
                                     uids.keyAt(iu));
                             if (ent != null) {
                                 if (DEBUG) Log.d(TAG, "Adding service " + ps.mPackageName
-                                            + "/" + ss.mName + "/" + uids.keyAt(iu) + " to proc "
-                                            + ss.mProcessName);
+                                            + "/" + ss.getName() + "/" + uids.keyAt(iu)
+                                            + " to proc " + ss.getProcessName());
                                 ent.addService(ss);
                             } else {
-                                Log.w(TAG, "No process " + ss.mProcessName + "/" + uids.keyAt(iu)
-                                        + " for service " + ss.mName);
+                                Log.w(TAG, "No process " + ss.getProcessName() + "/"
+                                        + uids.keyAt(iu) + " for service " + ss.getName());
                             }
                         }
                     }
diff --git a/src/com/android/settings/applications/ProcStatsEntry.java b/src/com/android/settings/applications/ProcStatsEntry.java
index 55f7bb8..36d397e 100644
--- a/src/com/android/settings/applications/ProcStatsEntry.java
+++ b/src/com/android/settings/applications/ProcStatsEntry.java
@@ -24,7 +24,9 @@
 import android.util.Log;
 import android.util.SparseArray;
 
-import com.android.internal.app.ProcessStats;
+import com.android.internal.app.procstats.ProcessStats;
+import com.android.internal.app.procstats.ProcessState;
+import com.android.internal.app.procstats.ServiceState;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -52,14 +54,14 @@
 
     ArrayMap<String, ArrayList<Service>> mServices = new ArrayMap<String, ArrayList<Service>>(1);
 
-    public ProcStatsEntry(ProcessStats.ProcessState proc, String packageName,
+    public ProcStatsEntry(ProcessState proc, String packageName,
             ProcessStats.ProcessDataCollection tmpBgTotals,
             ProcessStats.ProcessDataCollection tmpRunTotals, boolean useUss) {
-        ProcessStats.computeProcessData(proc, tmpBgTotals, 0);
-        ProcessStats.computeProcessData(proc, tmpRunTotals, 0);
-        mPackage = proc.mPackage;
-        mUid = proc.mUid;
-        mName = proc.mName;
+        proc.computeProcessData(tmpBgTotals, 0);
+        proc.computeProcessData(tmpRunTotals, 0);
+        mPackage = proc.getPackage();
+        mUid = proc.getUid();
+        mName = proc.getName();
         mPackages.add(packageName);
         mBgDuration = tmpBgTotals.totalTime;
         mAvgBgMem = useUss ? tmpBgTotals.avgUss : tmpBgTotals.avgPss;
@@ -69,7 +71,7 @@
         mAvgRunMem = useUss ? tmpRunTotals.avgUss : tmpRunTotals.avgPss;
         mMaxRunMem = useUss ? tmpRunTotals.maxUss : tmpRunTotals.maxPss;
         mRunWeight = mAvgRunMem * (double) mRunDuration;
-        if (DEBUG) Log.d(TAG, "New proc entry " + proc.mName + ": dur=" + mBgDuration
+        if (DEBUG) Log.d(TAG, "New proc entry " + proc.getName() + ": dur=" + mBgDuration
                 + " avgpss=" + mAvgBgMem + " weight=" + mBgWeight);
     }
 
@@ -149,7 +151,7 @@
                             + mUid + " in process " + mName);
                     continue;
                 }
-                ProcessStats.ProcessState pkgProc = pkgState.mProcesses.get(mName);
+                ProcessState pkgProc = pkgState.mProcesses.get(mName);
                 if (pkgProc == null) {
                     Log.w(TAG, "No process " + mName + " found in package state "
                             + mPackages.get(ipkg) + "/" + mUid);
@@ -252,11 +254,11 @@
         }
     }
 
-    public void addService(ProcessStats.ServiceState svc) {
-        ArrayList<Service> services = mServices.get(svc.mPackage);
+    public void addService(ServiceState svc) {
+        ArrayList<Service> services = mServices.get(svc.getPackage());
         if (services == null) {
             services = new ArrayList<Service>();
-            mServices.put(svc.mPackage, services);
+            mServices.put(svc.getPackage(), services);
         }
         services.add(new Service(svc));
     }
@@ -306,13 +308,12 @@
         final String mProcess;
         final long mDuration;
 
-        public Service(ProcessStats.ServiceState service) {
-            mPackage = service.mPackage;
-            mName = service.mName;
-            mProcess = service.mProcessName;
-            mDuration = ProcessStats.dumpSingleServiceTime(null, null, service,
-                    ProcessStats.ServiceState.SERVICE_RUN,
-                    ProcessStats.STATE_NOTHING, 0, 0);
+        public Service(ServiceState service) {
+            mPackage = service.getPackage();
+            mName = service.getName();
+            mProcess = service.getProcessName();
+            mDuration = service.dumpTime(null, null,
+                    ServiceState.SERVICE_RUN, ProcessStats.STATE_NOTHING, 0, 0);
         }
 
         public Service(Parcel in) {
diff --git a/src/com/android/settings/applications/ProcessStatsBase.java b/src/com/android/settings/applications/ProcessStatsBase.java
index ee53bf9..66c0371 100644
--- a/src/com/android/settings/applications/ProcessStatsBase.java
+++ b/src/com/android/settings/applications/ProcessStatsBase.java
@@ -23,7 +23,7 @@
 import android.widget.ArrayAdapter;
 import android.widget.Spinner;
 
-import com.android.internal.app.ProcessStats;
+import com.android.internal.app.procstats.ProcessStats;
 import com.android.settings.AppHeader;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
diff --git a/src/com/android/settings/applications/ProcessStatsMemDetail.java b/src/com/android/settings/applications/ProcessStatsMemDetail.java
index e60a368..6c7b90a 100644
--- a/src/com/android/settings/applications/ProcessStatsMemDetail.java
+++ b/src/com/android/settings/applications/ProcessStatsMemDetail.java
@@ -24,7 +24,7 @@
 import android.widget.ProgressBar;
 import android.widget.TextView;
 
-import com.android.internal.app.ProcessStats;
+import com.android.internal.app.procstats.ProcessStats;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.settings.InstrumentedFragment;
 import com.android.settings.R;
diff --git a/src/com/android/settings/applications/ProcessStatsUi.java b/src/com/android/settings/applications/ProcessStatsUi.java
index b26f4a7..fd0d7a7 100644
--- a/src/com/android/settings/applications/ProcessStatsUi.java
+++ b/src/com/android/settings/applications/ProcessStatsUi.java
@@ -27,7 +27,7 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 
-import com.android.internal.app.ProcessStats;
+import com.android.internal.app.procstats.ProcessStats;
 import com.android.internal.logging.MetricsProto.MetricsEvent;
 import com.android.settings.R;
 import com.android.settings.SettingsActivity;
diff --git a/src/com/android/settings/sim/SimSettings.java b/src/com/android/settings/sim/SimSettings.java
index adc9594..e783923 100644
--- a/src/com/android/settings/sim/SimSettings.java
+++ b/src/com/android/settings/sim/SimSettings.java
@@ -71,6 +71,10 @@
     private int mNumSlots;
     private Context mContext;
 
+    private int mPhoneCount = TelephonyManager.getDefault().getPhoneCount();
+    private int[] mCallState = new int[mPhoneCount];
+    private PhoneStateListener[] mPhoneStateListener = new PhoneStateListener[mPhoneCount];
+
     public SimSettings() {
         super(DISALLOW_CONFIG_SIM);
     }
@@ -177,7 +181,12 @@
         } else if (sir == null) {
             simPref.setSummary(R.string.sim_selection_required_pref);
         }
-        simPref.setEnabled(mSelectableSubInfos.size() >= 1);
+
+        boolean callStateIdle = isCallStateIdle();
+        final boolean ecbMode = SystemProperties.getBoolean(
+                TelephonyProperties.PROPERTY_INECM_MODE, false);
+        // Enable data preference in msim mode and call state idle
+        simPref.setEnabled((mSelectableSubInfos.size() >= 1) && callStateIdle && !ecbMode);
     }
 
     private void updateCallValues() {
@@ -199,10 +208,17 @@
     public void onResume() {
         super.onResume();
         mSubscriptionManager.addOnSubscriptionsChangedListener(mOnSubscriptionsChangeListener);
+        updateSubscriptions();
         final TelephonyManager tm =
                 (TelephonyManager) getActivity().getSystemService(Context.TELEPHONY_SERVICE);
-        tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
-        updateSubscriptions();
+        if (mSelectableSubInfos.size() > 1) {
+            Log.d(TAG, "Register for call state change");
+            for (int i = 0; i < mPhoneCount; i++) {
+                int subId = mSelectableSubInfos.get(i).getSubscriptionId();
+                tm.listen(getPhoneStateListener(i, subId),
+                        PhoneStateListener.LISTEN_CALL_STATE);
+            }
+        }
     }
 
     @Override
@@ -210,25 +226,30 @@
         super.onPause();
         mSubscriptionManager.removeOnSubscriptionsChangedListener(mOnSubscriptionsChangeListener);
         final TelephonyManager tm = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
-        tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
+        for (int i = 0; i < mPhoneCount; i++) {
+            if (mPhoneStateListener[i] != null) {
+                tm.listen(mPhoneStateListener[i], PhoneStateListener.LISTEN_NONE);
+                mPhoneStateListener[i] = null;
+            }
+        }
     }
 
-    private final PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+    private PhoneStateListener getPhoneStateListener(int phoneId, int subId) {
         // Disable Sim selection for Data when voice call is going on as changing the default data
         // sim causes a modem reset currently and call gets disconnected
         // ToDo : Add subtext on disabled preference to let user know that default data sim cannot
         // be changed while call is going on
-        @Override
-        public void onCallStateChanged(int state, String incomingNumber) {
-            if (DBG) log("PhoneStateListener.onCallStateChanged: state=" + state);
-             final Preference pref = findPreference(KEY_CELLULAR_DATA);
-            if (pref != null) {
-                final boolean ecbMode = SystemProperties.getBoolean(
-                        TelephonyProperties.PROPERTY_INECM_MODE, false);
-                pref.setEnabled((state == TelephonyManager.CALL_STATE_IDLE) && !ecbMode);
+        final int i = phoneId;
+        mPhoneStateListener[phoneId]  = new PhoneStateListener(subId) {
+            @Override
+            public void onCallStateChanged(int state, String incomingNumber) {
+                if (DBG) log("PhoneStateListener.onCallStateChanged: state=" + state);
+                mCallState[i] = state;
+                updateCellularDataValues();
             }
-        }
-    };
+        };
+        return mPhoneStateListener[phoneId];
+    }
 
     @Override
     public boolean onPreferenceTreeClick(final Preference preference) {
@@ -327,4 +348,15 @@
                     return result;
                 }
             };
+
+    private boolean isCallStateIdle() {
+        boolean callStateIdle = true;
+        for (int i = 0; i < mCallState.length; i++) {
+            if (TelephonyManager.CALL_STATE_IDLE != mCallState[i]) {
+                callStateIdle = false;
+            }
+        }
+        Log.d(TAG, "isCallStateIdle " + callStateIdle);
+        return callStateIdle;
+    }
 }
diff --git a/src/com/android/settings/users/UserSettings.java b/src/com/android/settings/users/UserSettings.java
index 2163245..af95056 100644
--- a/src/com/android/settings/users/UserSettings.java
+++ b/src/com/android/settings/users/UserSettings.java
@@ -140,6 +140,7 @@
     private int mRemovingUserId = -1;
     private int mAddedUserId = 0;
     private boolean mAddingUser;
+    private String mAddingUserName;
     private UserCapabilities mUserCaps;
     private boolean mShouldUpdateUserList = true;
     private final Object mUserLock = new Object();
@@ -402,15 +403,13 @@
     }
 
     private UserInfo createRestrictedProfile() {
-        UserInfo newUserInfo = mUserManager.createRestrictedProfile(
-                getResources().getString(R.string.user_new_profile_name));
+        UserInfo newUserInfo = mUserManager.createRestrictedProfile(mAddingUserName);
         assignDefaultPhoto(newUserInfo);
         return newUserInfo;
     }
 
     private UserInfo createTrustedUser() {
-        UserInfo newUserInfo = mUserManager.createUser(
-                getResources().getString(R.string.user_new_user_name), 0);
+        UserInfo newUserInfo = mUserManager.createUser(mAddingUserName, 0);
         if (newUserInfo != null) {
             assignDefaultPhoto(newUserInfo);
         }
@@ -418,6 +417,7 @@
     }
 
     private void onManageUserClicked(int userId, boolean newUser) {
+        mAddingUser = false;
         if (userId == UserPreference.USERID_GUEST_DEFAULTS) {
             Bundle extras = new Bundle();
             extras.putBoolean(UserDetailsSettings.EXTRA_USER_GUEST, true);
@@ -453,6 +453,7 @@
 
     private void onUserCreated(int userId) {
         mAddedUserId = userId;
+        mAddingUser = false;
         if (mUserManager.getUserInfo(userId).isRestricted()) {
             showDialog(DIALOG_SETUP_PROFILE);
         } else {
@@ -653,6 +654,8 @@
     private void addUserNow(final int userType) {
         synchronized (mUserLock) {
             mAddingUser = true;
+            mAddingUserName = userType == USER_TYPE_USER ? getString(R.string.user_new_user_name)
+                    : getString(R.string.user_new_profile_name);
             //updateUserList();
             new Thread() {
                 public void run() {
@@ -664,10 +667,10 @@
                         user = createRestrictedProfile();
                     }
                     if (user == null) {
+                        mAddingUser = false;
                         return;
                     }
                     synchronized (mUserLock) {
-                        mAddingUser = false;
                         if (userType == USER_TYPE_USER) {
                             mHandler.sendEmptyMessage(MESSAGE_UPDATE_LIST);
                             mHandler.sendMessage(mHandler.obtainMessage(
@@ -775,7 +778,7 @@
             UserPreference pref = new UserPreference(getPrefContext(), null,
                     UserPreference.USERID_UNKNOWN, null, null);
             pref.setEnabled(false);
-            pref.setTitle(R.string.user_new_user_name);
+            pref.setTitle(mAddingUserName);
             pref.setIcon(getEncircledDefaultIcon());
             userPreferences.add(pref);
         }
@@ -830,7 +833,7 @@
             boolean moreUsers = mUserManager.canAddMoreUsers();
             mAddUser.setOrder(Preference.DEFAULT_ORDER);
             preferenceScreen.addPreference(mAddUser);
-            mAddUser.setEnabled(moreUsers);
+            mAddUser.setEnabled(moreUsers && !mAddingUser);
             if (!moreUsers) {
                 mAddUser.setSummary(getString(R.string.user_add_max_count, getMaxRealUsers()));
             } else {
@@ -950,6 +953,7 @@
             }
         } else if (pref == mEmergencyInfoPreference) {
             Intent intent = new Intent(ACTION_EDIT_EMERGENCY_INFO);
+            intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
             startActivity(intent);
         }
         return false;
@@ -990,7 +994,6 @@
     @Override
     public void onDismiss(DialogInterface dialog) {
         synchronized (mUserLock) {
-            mAddingUser = false;
             mRemovingUserId = -1;
             updateUserList();
         }
diff --git a/src/com/android/settings/vpn2/ConfigDialog.java b/src/com/android/settings/vpn2/ConfigDialog.java
index 6b035fd..a13e29d 100644
--- a/src/com/android/settings/vpn2/ConfigDialog.java
+++ b/src/com/android/settings/vpn2/ConfigDialog.java
@@ -20,6 +20,7 @@
 import android.content.Context;
 import android.content.DialogInterface;
 import android.os.Bundle;
+import android.os.SystemProperties;
 import android.security.Credentials;
 import android.security.KeyStore;
 import android.text.Editable;
@@ -29,6 +30,7 @@
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
 import android.widget.CheckBox;
+import android.widget.CompoundButton;
 import android.widget.Spinner;
 import android.widget.TextView;
 
@@ -45,7 +47,8 @@
  * {@see AppDialog}
  */
 class ConfigDialog extends AlertDialog implements TextWatcher,
-        View.OnClickListener, AdapterView.OnItemSelectedListener {
+        View.OnClickListener, AdapterView.OnItemSelectedListener,
+        CompoundButton.OnCheckedChangeListener {
     private final KeyStore mKeyStore = KeyStore.getInstance();
     private final DialogInterface.OnClickListener mListener;
     private final VpnProfile mProfile;
@@ -72,6 +75,7 @@
     private Spinner mIpsecServerCert;
     private CheckBox mSaveLogin;
     private CheckBox mShowOptions;
+    private CheckBox mAlwaysOnVpn;
 
     ConfigDialog(Context context, DialogInterface.OnClickListener listener,
             VpnProfile profile, boolean editing, boolean exists) {
@@ -108,6 +112,7 @@
         mIpsecServerCert = (Spinner) mView.findViewById(R.id.ipsec_server_cert);
         mSaveLogin = (CheckBox) mView.findViewById(R.id.save_login);
         mShowOptions = (CheckBox) mView.findViewById(R.id.show_options);
+        mAlwaysOnVpn = (CheckBox) mView.findViewById(R.id.always_on_vpn);
 
         // Second, copy values from the profile.
         mName.setText(mProfile.name);
@@ -124,13 +129,21 @@
         mL2tpSecret.setText(mProfile.l2tpSecret);
         mIpsecIdentifier.setText(mProfile.ipsecIdentifier);
         mIpsecSecret.setText(mProfile.ipsecSecret);
-        loadCertificates(mIpsecUserCert, Credentials.USER_PRIVATE_KEY,
-                0, mProfile.ipsecUserCert);
+        loadCertificates(mIpsecUserCert, Credentials.USER_PRIVATE_KEY, 0, mProfile.ipsecUserCert);
         loadCertificates(mIpsecCaCert, Credentials.CA_CERTIFICATE,
                 R.string.vpn_no_ca_cert, mProfile.ipsecCaCert);
         loadCertificates(mIpsecServerCert, Credentials.USER_CERTIFICATE,
                 R.string.vpn_no_server_cert, mProfile.ipsecServerCert);
         mSaveLogin.setChecked(mProfile.saveLogin);
+        mAlwaysOnVpn.setChecked(mProfile.key.equals(VpnUtils.getLockdownVpn()));
+        mAlwaysOnVpn.setOnCheckedChangeListener(this);
+        // Update SaveLogin checkbox after Always-on checkbox is updated
+        updateSaveLoginStatus();
+
+        // Hide lockdown VPN on devices that require IMS authentication
+        if (SystemProperties.getBoolean("persist.radio.imsregrequired", false)) {
+            mAlwaysOnVpn.setVisibility(View.GONE);
+        }
 
         // Third, add listeners to required fields.
         mName.addTextChangedListener(this);
@@ -242,6 +255,27 @@
     public void onNothingSelected(AdapterView<?> parent) {
     }
 
+    @Override
+    public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
+        if (compoundButton == mAlwaysOnVpn) {
+            updateSaveLoginStatus();
+        }
+    }
+
+    public boolean isVpnAlwaysOn() {
+        return mAlwaysOnVpn.isChecked();
+    }
+
+    private void updateSaveLoginStatus() {
+        if (mAlwaysOnVpn.isChecked()) {
+            mSaveLogin.setChecked(true);
+            mSaveLogin.setEnabled(false);
+        } else {
+            mSaveLogin.setChecked(mProfile.saveLogin);
+            mSaveLogin.setEnabled(true);
+        }
+    }
+
     private void showAdvancedOptions() {
         mView.findViewById(R.id.options).setVisibility(View.VISIBLE);
         mShowOptions.setVisibility(View.GONE);
diff --git a/src/com/android/settings/vpn2/ConfigDialogFragment.java b/src/com/android/settings/vpn2/ConfigDialogFragment.java
index d145ba3..fc49fd8 100644
--- a/src/com/android/settings/vpn2/ConfigDialogFragment.java
+++ b/src/com/android/settings/vpn2/ConfigDialogFragment.java
@@ -22,6 +22,7 @@
 import android.app.DialogFragment;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.net.ConnectivityManager;
 import android.net.IConnectivityManager;
 import android.os.Bundle;
 import android.os.RemoteException;
@@ -112,8 +113,10 @@
             // Flush out old version of profile
             disconnect(profile);
 
+            updateLockdownVpn(dialog.isVpnAlwaysOn(), profile);
+
             // If we are not editing, connect!
-            if (!dialog.isEditing()) {
+            if (!dialog.isEditing() && !VpnUtils.isVpnLockdown(profile.key)) {
                 try {
                     connect(profile);
                 } catch (RemoteException e) {
@@ -128,15 +131,7 @@
             KeyStore keyStore = KeyStore.getInstance();
             keyStore.delete(Credentials.VPN + profile.key, KeyStore.UID_SELF);
 
-            // If this was the current lockdown VPN, clear it.
-            if (Arrays.equals(profile.key.getBytes(), keyStore.get(Credentials.LOCKDOWN_VPN))) {
-                keyStore.delete(Credentials.LOCKDOWN_VPN);
-                try {
-                    mService.updateLockdownVpn();
-                } catch (RemoteException e) {
-                    Log.e(TAG, "Failed to clear lockdown VPN configuration");
-                }
-            }
+            updateLockdownVpn(false, profile);
         }
         dismiss();
     }
@@ -147,6 +142,30 @@
         super.onCancel(dialog);
     }
 
+    private void updateLockdownVpn(boolean isVpnAlwaysOn, VpnProfile profile) {
+        // Save lockdown vpn
+        if (isVpnAlwaysOn) {
+            // Show toast if vpn profile is not valid
+            if (!profile.isValidLockdownProfile()) {
+                Toast.makeText(getContext(), R.string.vpn_lockdown_config_error,
+                        Toast.LENGTH_LONG).show();
+                return;
+            }
+
+            // Update only if lockdown vpn has been changed
+            if (!VpnUtils.isVpnLockdown(profile.key)) {
+                final ConnectivityManager conn = ConnectivityManager.from(getActivity());
+                conn.setAlwaysOnVpnPackageForUser(UserHandle.myUserId(), null);
+                VpnUtils.setLockdownVpn(getContext(), profile.key);
+            }
+        } else {
+            // update only if lockdown vpn has been changed
+            if (VpnUtils.isVpnLockdown(profile.key)) {
+                VpnUtils.clearLockdownVpn(getContext());
+            }
+        }
+    }
+
     private void connect(VpnProfile profile) throws RemoteException {
         try {
             mService.startLegacyVpn(profile);
diff --git a/src/com/android/settings/vpn2/LockdownConfigFragment.java b/src/com/android/settings/vpn2/LockdownConfigFragment.java
deleted file mode 100644
index 8f19fa6..0000000
--- a/src/com/android/settings/vpn2/LockdownConfigFragment.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2015 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.vpn2;
-
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.app.DialogFragment;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.content.pm.PackageManager;
-import android.content.res.Resources;
-import android.net.ConnectivityManager;
-import android.os.Bundle;
-import android.os.UserHandle;
-import android.os.UserManager;
-import android.security.Credentials;
-import android.security.KeyStore;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-import android.widget.Toast;
-
-import com.android.internal.net.VpnConfig;
-import com.android.internal.net.VpnProfile;
-import com.android.settings.R;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Dialog to configure always-on VPN.
- */
-public class LockdownConfigFragment extends DialogFragment {
-    private List<VpnProfile> mProfiles;
-    private List<AppVpnInfo> mApps;
-    private List<CharSequence> mTitles;
-    private int mCurrentIndex;
-
-    private static final String TAG_LOCKDOWN = "lockdown";
-    private static final String LOG_TAG = "LockdownConfigFragment";
-
-    private static class TitleAdapter extends ArrayAdapter<CharSequence> {
-        public TitleAdapter(Context context, List<CharSequence> objects) {
-            super(context, com.android.internal.R.layout.select_dialog_singlechoice_material,
-                    android.R.id.text1, objects);
-        }
-    }
-
-    public static void show(VpnSettings parent) {
-        if (!parent.isAdded()) return;
-
-        final LockdownConfigFragment dialog = new LockdownConfigFragment();
-        dialog.show(parent.getFragmentManager(), TAG_LOCKDOWN);
-    }
-
-    private void initProfiles(KeyStore keyStore, Resources res) {
-        final ConnectivityManager cm = ConnectivityManager.from(getActivity());
-        final String lockdownKey = VpnUtils.getLockdownVpn();
-        final String alwaysOnPackage =  cm.getAlwaysOnVpnPackageForUser(UserHandle.myUserId());
-
-        // Legacy VPN has a separate always-on mechanism which takes over the whole device, so
-        // this option is restricted to the primary user only.
-        if (UserManager.get(getContext()).isPrimaryUser()) {
-            mProfiles = VpnSettings.loadVpnProfiles(keyStore, VpnProfile.TYPE_PPTP);
-        } else {
-            mProfiles = Collections.<VpnProfile>emptyList();
-        }
-        mApps = VpnSettings.getVpnApps(getActivity(), /* includeProfiles */ false);
-
-        mTitles = new ArrayList<>(1 + mProfiles.size() + mApps.size());
-        mTitles.add(res.getText(R.string.vpn_lockdown_none));
-        mCurrentIndex = 0;
-
-        // Add true lockdown VPNs to the list first.
-        for (VpnProfile profile : mProfiles) {
-            if (TextUtils.equals(profile.key, lockdownKey)) {
-                mCurrentIndex = mTitles.size();
-            }
-            mTitles.add(profile.name);
-        }
-
-        // Add third-party app VPNs (VpnService) for the current profile to set as always-on.
-        for (AppVpnInfo app : mApps) {
-            try {
-                String appName = VpnConfig.getVpnLabel(getContext(), app.packageName).toString();
-                if (TextUtils.equals(app.packageName, alwaysOnPackage)) {
-                    mCurrentIndex = mTitles.size();
-                }
-                mTitles.add(appName);
-            } catch (PackageManager.NameNotFoundException pkgNotFound) {
-                Log.w(LOG_TAG, "VPN package not found: '" + app.packageName + "'", pkgNotFound);
-            }
-        }
-    }
-
-    @Override
-    public Dialog onCreateDialog(Bundle savedInstanceState) {
-        final Context context = getActivity();
-        final KeyStore keyStore = KeyStore.getInstance();
-
-        initProfiles(keyStore, context.getResources());
-
-        final AlertDialog.Builder builder = new AlertDialog.Builder(context);
-        final LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
-
-        builder.setTitle(R.string.vpn_menu_lockdown);
-
-        final View view = dialogInflater.inflate(R.layout.vpn_lockdown_editor, null, false);
-        final ListView listView = (ListView) view.findViewById(android.R.id.list);
-        listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
-        listView.setAdapter(new TitleAdapter(context, mTitles));
-        listView.setItemChecked(mCurrentIndex, true);
-        builder.setView(view);
-
-        builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
-            @Override
-            public void onClick(DialogInterface dialog, int which) {
-                final int newIndex = listView.getCheckedItemPosition();
-                if (mCurrentIndex == newIndex) return;
-
-                final ConnectivityManager conn = ConnectivityManager.from(getActivity());
-
-                if (newIndex == 0) {
-                    keyStore.delete(Credentials.LOCKDOWN_VPN);
-                    conn.setAlwaysOnVpnPackageForUser(UserHandle.myUserId(), null);
-                } else if (newIndex <= mProfiles.size()) {
-                    final VpnProfile profile = mProfiles.get(newIndex - 1);
-                    if (!profile.isValidLockdownProfile()) {
-                        Toast.makeText(context, R.string.vpn_lockdown_config_error,
-                                Toast.LENGTH_LONG).show();
-                        return;
-                    }
-                    conn.setAlwaysOnVpnPackageForUser(UserHandle.myUserId(), null);
-                    keyStore.put(Credentials.LOCKDOWN_VPN, profile.key.getBytes(),
-                            KeyStore.UID_SELF, /* flags */ 0);
-                } else {
-                    keyStore.delete(Credentials.LOCKDOWN_VPN);
-
-                    final AppVpnInfo appVpn = mApps.get(newIndex - 1 - mProfiles.size());
-                    conn.setAlwaysOnVpnPackageForUser(appVpn.userId, appVpn.packageName);
-                }
-
-                // kick profiles since we changed them
-                conn.updateLockdownVpn();
-            }
-        });
-
-        return builder.create();
-    }
-}
-
diff --git a/src/com/android/settings/vpn2/VpnSettings.java b/src/com/android/settings/vpn2/VpnSettings.java
index 64403dd..f605896 100644
--- a/src/com/android/settings/vpn2/VpnSettings.java
+++ b/src/com/android/settings/vpn2/VpnSettings.java
@@ -80,7 +80,6 @@
     private static final int RESCAN_MESSAGE = 0;
     private static final int RESCAN_INTERVAL_MS = 1000;
 
-    private static final String EXTRA_PICK_LOCKDOWN = "android.net.vpn.PICK_LOCKDOWN";
     private static final NetworkRequest VPN_REQUEST = new NetworkRequest.Builder()
             .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
             .removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
@@ -143,11 +142,6 @@
                 menu.getItem(i).setEnabled(!mUnavailable);
             }
         }
-
-        // Hide lockdown VPN on devices that require IMS authentication
-        if (SystemProperties.getBoolean("persist.radio.imsregrequired", false)) {
-            menu.findItem(R.id.vpn_lockdown).setVisible(false);
-        }
     }
 
     @Override
@@ -163,10 +157,6 @@
                 ConfigDialogFragment.show(this, profile, true /* editing */, false /* exists */);
                 return true;
             }
-            case R.id.vpn_lockdown: {
-                LockdownConfigFragment.show(this);
-                return true;
-            }
         }
         return super.onOptionsItemSelected(item);
     }
@@ -186,12 +176,6 @@
             getEmptyTextView().setText(R.string.vpn_no_vpns_added);
         }
 
-        final boolean pickLockdown = getActivity()
-                .getIntent().getBooleanExtra(EXTRA_PICK_LOCKDOWN, false);
-        if (pickLockdown) {
-            LockdownConfigFragment.show(this);
-        }
-
         // Start monitoring
         mConnectivityManager.registerNetworkCallback(VPN_REQUEST, mNetworkCallback);
 
diff --git a/src/com/android/settings/vpn2/VpnUtils.java b/src/com/android/settings/vpn2/VpnUtils.java
index 122816a..6afa79b 100644
--- a/src/com/android/settings/vpn2/VpnUtils.java
+++ b/src/com/android/settings/vpn2/VpnUtils.java
@@ -21,7 +21,9 @@
 import android.security.KeyStore;
 
 /**
- * Utility functions for vpn
+ * Utility functions for vpn.
+ *
+ * Keystore methods should only be called in system user
  */
 public class VpnUtils {
 
@@ -35,4 +37,15 @@
         // Always notify ConnectivityManager after keystore update
         context.getSystemService(ConnectivityManager.class).updateLockdownVpn();
     }
+
+    public static void setLockdownVpn(Context context, String lockdownKey) {
+        KeyStore.getInstance().put(Credentials.LOCKDOWN_VPN, lockdownKey.getBytes(),
+                KeyStore.UID_SELF, /* flags */ 0);
+        // Always notify ConnectivityManager after keystore update
+        context.getSystemService(ConnectivityManager.class).updateLockdownVpn();
+    }
+
+    public static boolean isVpnLockdown(String key) {
+        return key.equals(getLockdownVpn());
+    }
 }
diff --git a/src/com/android/settings/wifi/WifiConfigController.java b/src/com/android/settings/wifi/WifiConfigController.java
index 54bd3d0..ee6b503 100644
--- a/src/com/android/settings/wifi/WifiConfigController.java
+++ b/src/com/android/settings/wifi/WifiConfigController.java
@@ -682,7 +682,7 @@
         if (TextUtils.isEmpty(ipAddr)) return R.string.wifi_ip_settings_invalid_ip_address;
 
         Inet4Address inetAddr = getIPv4Address(ipAddr);
-        if (inetAddr == null) {
+        if (inetAddr == null || inetAddr.equals(Inet4Address.ANY)) {
             return R.string.wifi_ip_settings_invalid_ip_address;
         }
 
@@ -697,6 +697,8 @@
             // Set the hint as default after user types in ip address
             mNetworkPrefixLengthView.setText(mConfigUi.getContext().getString(
                     R.string.wifi_network_prefix_length_hint));
+        } catch (IllegalArgumentException e) {
+            return R.string.wifi_ip_settings_invalid_ip_address;
         }
 
         String gateway = mGatewayView.getText().toString();
@@ -715,6 +717,9 @@
             if (gatewayAddr == null) {
                 return R.string.wifi_ip_settings_invalid_gateway;
             }
+            if (gatewayAddr.isMulticastAddress()) {
+                return R.string.wifi_ip_settings_invalid_gateway;
+            }
             staticIpConfiguration.gateway = gatewayAddr;
         }