Merge "TIF: Fix incorrect uses of INPUT_STATE_XXX"
diff --git a/api/current.txt b/api/current.txt
index 058053b..44cbe7b 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -35046,6 +35046,10 @@
     field public static final int KEYCODE_MUSIC = 209; // 0xd1
     field public static final int KEYCODE_MUTE = 91; // 0x5b
     field public static final int KEYCODE_N = 42; // 0x2a
+    field public static final int KEYCODE_NAVIGATE_IN = 262; // 0x106
+    field public static final int KEYCODE_NAVIGATE_NEXT = 261; // 0x105
+    field public static final int KEYCODE_NAVIGATE_OUT = 263; // 0x107
+    field public static final int KEYCODE_NAVIGATE_PREVIOUS = 260; // 0x104
     field public static final int KEYCODE_NOTIFICATION = 83; // 0x53
     field public static final int KEYCODE_NUM = 78; // 0x4e
     field public static final int KEYCODE_NUMPAD_0 = 144; // 0x90
diff --git a/api/system-current.txt b/api/system-current.txt
index 24da8782..9d3a3c9 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -37245,6 +37245,10 @@
     field public static final int KEYCODE_MUSIC = 209; // 0xd1
     field public static final int KEYCODE_MUTE = 91; // 0x5b
     field public static final int KEYCODE_N = 42; // 0x2a
+    field public static final int KEYCODE_NAVIGATE_IN = 262; // 0x106
+    field public static final int KEYCODE_NAVIGATE_NEXT = 261; // 0x105
+    field public static final int KEYCODE_NAVIGATE_OUT = 263; // 0x107
+    field public static final int KEYCODE_NAVIGATE_PREVIOUS = 260; // 0x104
     field public static final int KEYCODE_NOTIFICATION = 83; // 0x53
     field public static final int KEYCODE_NUM = 78; // 0x4e
     field public static final int KEYCODE_NUMPAD_0 = 144; // 0x90
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index e75f337..3e9b3d6 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -98,16 +98,6 @@
     public static final String CONNECTIVITY_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
 
     /**
-     * Identical to {@link #CONNECTIVITY_ACTION} broadcast, but sent without any
-     * historic {@link Settings.Global#CONNECTIVITY_CHANGE_DELAY}.
-     *
-     * @hide
-     */
-    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
-    public static final String CONNECTIVITY_ACTION_IMMEDIATE =
-            "android.net.conn.CONNECTIVITY_CHANGE_IMMEDIATE";
-
-    /**
      * The lookup key for a {@link NetworkInfo} object. Retrieve with
      * {@link android.content.Intent#getParcelableExtra(String)}.
      *
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 9d8a1ba..af23f11 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -283,6 +283,8 @@
     private static native void nativeWriteInterfaceToken(long nativePtr, String interfaceName);
     private static native void nativeEnforceInterface(long nativePtr, String interfaceName);
 
+    private static native long nativeGetBlobAshmemSize(long nativePtr);
+
     public final static Parcelable.Creator<String> STRING_CREATOR
              = new Parcelable.Creator<String>() {
         public String createFromParcel(Parcel source) {
@@ -2594,4 +2596,11 @@
             N--;
         }
     }
+
+    /**
+     * @hide For testing
+     */
+    public long getBlobAshmemSize() {
+        return nativeGetBlobAshmemSize(mNativePtr);
+    }
 }
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index 779560c..1ac3f45 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -747,8 +747,22 @@
     public static final int KEYCODE_TV_TIMER_PROGRAMMING = 258;
     /** Key code constant: Help key. */
     public static final int KEYCODE_HELP = 259;
+    /** Key code constant: Navigate to previous key. 
+     * Goes backward by one item in an ordered collection of items. */
+    public static final int KEYCODE_NAVIGATE_PREVIOUS = 260;
+    /** Key code constant: Navigate to next key. 
+     * Advances to the next item in an ordered collection of items. */
+    public static final int KEYCODE_NAVIGATE_NEXT   = 261;
+    /** Key code constant: Navigate in key.
+     * Activates the item that currently has focus or expands to the next level of a navigation 
+     * hierarchy. */
+    public static final int KEYCODE_NAVIGATE_IN     = 262;
+    /** Key code constant: Navigate out key.
+     * Backs out one level of a navigation hierarchy or collapses the item that currently has 
+     * focus. */
+    public static final int KEYCODE_NAVIGATE_OUT    = 263;
 
-    private static final int LAST_KEYCODE = KEYCODE_HELP;
+    private static final int LAST_KEYCODE = KEYCODE_NAVIGATE_OUT;
 
     // NOTE: If you add a new keycode here you must also add it to:
     //  isSystem()
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 3ad4f1c..48f0e71 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -269,7 +269,12 @@
                     if (false) {
                         Log.v(TAG, "Preloading " + line + "...");
                     }
-                    Class.forName(line);
+                    // Load and explicitly initialize the given class. Use the tree-argument version
+                    // of forName to avoid repeated stack lookups (to derive the caller's
+                    // class-loader). Use true to force initialization, and null for the boot
+                    // classpath class-loader (could as well cache the class-loader of this class in
+                    // a variable).
+                    Class.forName(line, true, null);
                     count++;
                 } catch (ClassNotFoundException e) {
                     Log.w(TAG, "Class not found for preloading: " + line);
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index 4f29c50..a3a0551 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -704,6 +704,15 @@
     return Parcel::getGlobalAllocCount();
 }
 
+static jlong android_os_Parcel_getBlobAshmemSize(JNIEnv* env, jclass clazz, jlong nativePtr)
+{
+    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+    if (parcel != NULL) {
+        return parcel->getBlobAshmemSize();
+    }
+    return 0;
+}
+
 // ----------------------------------------------------------------------------
 
 static const JNINativeMethod gParcelMethods[] = {
@@ -756,6 +765,8 @@
 
     {"getGlobalAllocSize",        "()J", (void*)android_os_Parcel_getGlobalAllocSize},
     {"getGlobalAllocCount",       "()J", (void*)android_os_Parcel_getGlobalAllocCount},
+
+    {"nativeGetBlobAshmemSize",       "(J)J", (void*)android_os_Parcel_getBlobAshmemSize},
 };
 
 const char* const kParcelPathName = "android/os/Parcel";
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index a5d391d..8f4d9a3 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -213,6 +213,7 @@
     <protected-broadcast android:name="android.intent.action.MEDIA_EJECT" />
 
     <protected-broadcast android:name="android.net.conn.CONNECTIVITY_CHANGE" />
+    <!-- @deprecated.  Only {@link android.net.ConnectivityManager.CONNECTIVITY_ACTION} is sent. -->
     <protected-broadcast android:name="android.net.conn.CONNECTIVITY_CHANGE_IMMEDIATE" />
     <protected-broadcast android:name="android.net.conn.DATA_ACTIVITY_CHANGE" />
     <protected-broadcast android:name="android.net.conn.BACKGROUND_DATA_SETTING_CHANGED" />
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index b8825b6..ef438ab 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1783,6 +1783,10 @@
         <enum name="KEYCODE_TV_MEDIA_CONTEXT_MENU" value="257" />
         <enum name="KEYCODE_TV_TIMER_PROGRAMMING" value="258" />
         <enum name="KEYCODE_HELP" value="259" />
+        <enum name="KEYCODE_NAVIGATE_PREVIOUS" value="260" />
+        <enum name="KEYCODE_NAVIGATE_NEXT" value="261" />
+        <enum name="KEYCODE_NAVIGATE_IN" value="262" />
+        <enum name="KEYCODE_NAVIGATE_OUT" value="263" />
     </attr>
 
     <!-- ***************************************************************** -->
diff --git a/docs/html/training/wearables/data-layer/index.jd b/docs/html/training/wearables/data-layer/index.jd
index 85b2c33..b49ea4d 100644
--- a/docs/html/training/wearables/data-layer/index.jd
+++ b/docs/html/training/wearables/data-layer/index.jd
@@ -58,6 +58,30 @@
   <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code>WearableListenerService</code></a>
   lets you listen for changes only when the user is actively using your app.
   </dd>
+
+  <dt><b>Channel</b></dt>
+  <dd>
+  You can use the
+  <a href="{@docRoot}reference/com/google/android/gms/wearable/ChannelApi.html"><code>ChannelApi</code></a>
+  class to transfer large data items, such as music and movie files, from a handheld to a wearable
+  device. The Channel API for data transfer has the following benefits:
+  <ul>
+    <li>Transfer large data files between two or more connected devices, without
+    the automatic synchronization provided when using
+    <a href="{@docRoot}reference/com/google/android/gms/wearable/Asset.html"><code>Asset</code></a>
+    objects attached to
+    <a href="{@docRoot}reference/com/google/android/gms/wearable/DataItem.html"><code>DataItem</code></a>
+    objects. The Channel API saves disk space unlike the
+    <a href="{@docRoot}reference/com/google/android/gms/wearable/DataApi.html"><code>DataApi</code></a>
+    class, which creates a copy of the assets on the local device before synchronizing with
+    connected devices.</li>
+    <li>Reliably send a file that is too large in size to send using the
+    <a href="{@docRoot}reference/com/google/android/gms/wearable/MessageApi.html"><code>MessageApi</code></a>
+    class.</li>
+    <li>Transfer streamed data, such as music pulled from a network server or voice
+    data from the microphone.</li>
+  </ul>
+  </dd>
 </dl>
 
 <p class="warning"><b>Warning:</b>
diff --git a/media/java/android/media/MediaSync.java b/media/java/android/media/MediaSync.java
index 9446c0c..e6bc10d 100644
--- a/media/java/android/media/MediaSync.java
+++ b/media/java/android/media/MediaSync.java
@@ -49,7 +49,7 @@
  *     public void onReturnAudioBuffer(MediaSync sync, ByteBuffer audioBuffer, int bufferIndex) {
  *         ...
  *     }
- * });
+ * }, null);
  * // This needs to be done since sync is paused on creation.
  * sync.setPlaybackRate(1.0f, MediaSync.PLAYBACK_RATE_AUDIO_MODE_RESAMPLE);
  *
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
index 41ec3b0..5af7783 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -266,9 +266,6 @@
         final int failedAttemptsBeforeWipe =
                 dpm.getMaximumFailedPasswordsForWipe(null, currentUser);
 
-        final int failedAttemptWarning = LockPatternUtils.FAILED_ATTEMPTS_BEFORE_RESET
-                - LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
-
         final int remainingBeforeWipe = failedAttemptsBeforeWipe > 0 ?
                 (failedAttemptsBeforeWipe - failedAttempts)
                 : Integer.MAX_VALUE; // because DPM returns 0 if no restriction
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 67a0bc6..f12fd0c 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -909,37 +909,25 @@
     <string name="disconnect_vpn">Disconnect VPN</string>
 
     <!-- Monitoring dialog device owner body text [CHAR LIMIT=400] -->
-    <string name="monitoring_description_device_owned">This device is managed by:\n<xliff:g id="organization">%1$s</xliff:g>\n\nYour administrator can monitor your device and network activity, including emails, apps and secure websites.\n\nFor more information, contact your administrator.</string>
-
-    <!-- Monitoring dialog non-legacy VPN text [CHAR LIMIT=400] -->
-    <string name="monitoring_description_vpn">You gave \"<xliff:g id="application">%1$s</xliff:g>\" permission to set up a VPN connection.\n\nThis app can monitor your device and network activity, including emails, apps and secure websites.</string>
-
-    <!-- Monitoring dialog legacy VPN text [CHAR LIMIT=400] -->
-    <string name="monitoring_description_legacy_vpn">You\'re connected to a VPN (\"<xliff:g id="application">%1$s</xliff:g>\").\n\nYour VPN service provider can monitor your device and network activity including emails, apps, and secure websites.</string>
-
-    <!-- Monitoring dialog non-legacy VPN with device owner text [CHAR LIMIT=400] -->
-    <string name="monitoring_description_vpn_device_owned">This device is managed by:\n<xliff:g id="organization">%1$s</xliff:g>\n\nYour administrator is capable of monitoring your network activity including emails, apps, and secure websites. For more information, contact your administrator.\n\nAlso, you gave \"<xliff:g id="application">%2$s</xliff:g>\" permission to set up a VPN connection. This app can monitor network activity too.</string>
-
-    <!-- Monitoring dialog legacy VPN with device owner text [CHAR LIMIT=400] -->
-    <string name="monitoring_description_legacy_vpn_device_owned">This device is managed by:\n<xliff:g id="organization">%1$s</xliff:g>\n\nYour administrator is capable of monitoring your network activity including emails, apps, and secure websites. For more information, contact your administrator.\n\nAlso, you\'re connected to a VPN (\"<xliff:g id="application">%2$s</xliff:g>\"). Your VPN service provider can monitor network activity too.</string>
+    <string name="monitoring_description_device_owned">Your device is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour administrator can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information. For more information, contact your administrator.</string>
 
     <!-- Monitoring dialog profile owner body text [CHAR LIMIT=400] -->
-    <string name="monitoring_description_profile_owned">This profile is managed by:\n<xliff:g id="organization">%1$s</xliff:g>\n\nYour administrator can monitor your device and network activity, including emails, apps and secure websites.\n\nFor more information, contact your administrator.</string>
+    <string name="monitoring_description_profile_owned">Your work profile is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour administrator is capable of monitoring your network activity including emails, apps and secure websites.\n\nFor more information, contact your administrator.</string>
 
     <!-- Monitoring dialog device and profile owner body text [CHAR LIMIT=400] -->
-    <string name="monitoring_description_device_and_profile_owned">This device is managed by:\n<xliff:g id="organization">%1$s</xliff:g>\nYour profile is managed by:\n<xliff:g id="organization">%2$s</xliff:g>\n\nYour administrator can monitor your device and network activity, including emails, apps and secure websites.\n\nFor more information, contact your administrator.</string>
+    <string name="monitoring_description_device_and_profile_owned">Your device is managed by:\n<xliff:g id="organization">%1$s</xliff:g>.\nYour work profile is managed by:\n<xliff:g id="organization">%2$s</xliff:g>.\n\nYour administrator can monitor your device and network activity, including emails, apps and secure websites.\n\nFor more information, contact your administrator.</string>
 
-    <!-- Monitoring dialog non-legacy VPN with profile owner text [CHAR LIMIT=400] -->
-    <string name="monitoring_description_vpn_profile_owned">This profile is managed by:\n<xliff:g id="organization">%1$s</xliff:g>\n\nYour administrator is capable of monitoring your network activity including emails, apps, and secure websites. For more information, contact your administrator.\n\nAlso, you gave \"<xliff:g id="application">%2$s</xliff:g>\" permission to set up a VPN connection. This app can monitor network activity too.</string>
+    <!-- Monitoring dialog VPN text [CHAR LIMIT=400] -->
+    <string name="monitoring_description_vpn">You gave an app permission to set up a VPN connection.\n\nThis app can monitor your device and network activity, including emails, apps and secure websites.</string>
 
-    <!-- Monitoring dialog legacy VPN with profile owner text [CHAR LIMIT=400] -->
-    <string name="monitoring_description_legacy_vpn_profile_owned">This profile is managed by:\n<xliff:g id="organization">%1$s</xliff:g>\n\nYour administrator is capable of monitoring your network activity including emails, apps, and secure websites. For more information, contact your administrator.\n\nAlso, you\'re connected to a VPN (\"<xliff:g id="application">%2$s</xliff:g>\"). Your VPN service provider can monitor network activity too.</string>
+    <!-- Monitoring dialog VPN with device owner text [CHAR LIMIT=400] -->
+    <string name="monitoring_description_vpn_device_owned">Your device is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour administrator can monitor and manage settings, corporate access, apps, data associated with your device, and your device\'s location information.\n\nYou\'re connected to a VPN, which can monitor your network activity, including emails, apps, and websites.\n\nFor more information, contact your administrator.</string>
 
-    <!-- Monitoring dialog non-legacy VPN with device and profile owner text [CHAR LIMIT=400] -->
-    <string name="monitoring_description_vpn_device_and_profile_owned">This device is managed by:\n<xliff:g id="organization">%1$s</xliff:g>\nYour profile is managed by:\n<xliff:g id="organization">%2$s</xliff:g>\n\nYour administrator is capable of monitoring your network activity including emails, apps, and secure websites. For more information, contact your administrator.\n\nAlso, you gave \"<xliff:g id="application">%3$s</xliff:g>\" permission to set up a VPN connection. This app can monitor network activity too.</string>
+    <!-- Monitoring dialog VPN with profile owner text [CHAR LIMIT=400] -->
+    <string name="monitoring_description_vpn_profile_owned">Your work profile is managed by <xliff:g id="organization">%1$s</xliff:g>.\n\nYour administrator is capable of monitoring your network activity including emails, apps, and secure websites.\n\nFor more information, contact your administrator.\n\nYou\'re also connected to a VPN, which can monitor your network activity.</string>
 
-    <!-- Monitoring dialog legacy VPN with device and profile owner text [CHAR LIMIT=400] -->
-    <string name="monitoring_description_legacy_vpn_device_and_profile_owned">This device is managed by:\n<xliff:g id="organization">%1$s</xliff:g>\nYour profile is managed by:\n<xliff:g id="organization">%2$s</xliff:g>\n\nYour administrator is capable of monitoring your network activity including emails, apps, and secure websites. For more information, contact your administrator.\n\nAlso, you\'re connected to a VPN (\"<xliff:g id="application">%3$s</xliff:g>\"). Your VPN service provider can monitor network activity too.</string>
+    <!-- Monitoring dialog VPN with device and profile owner text [CHAR LIMIT=400] -->
+    <string name="monitoring_description_vpn_device_and_profile_owned">Your device is managed by <xliff:g id="organization">%1$s</xliff:g>.\nYour work profile is managed by:\n<xliff:g id="organization">%2$s</xliff:g>.\n\nYour administrator is capable of monitoring your network activity including emails, apps, and secure websites.\n\nFor more information, contact your administrator.\n\nYou\'re also connected to a VPN, which can monitor your personal network activity</string>
 
     <!-- Indication on the keyguard that appears when the user disables trust agents until the next time they unlock manually. [CHAR LIMIT=NONE] -->
     <string name="keyguard_indication_trust_disabled">Device will stay locked until you manually unlock</string>
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
index 0ab644a..d8e3984 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
@@ -18,9 +18,11 @@
 import android.app.AlertDialog;
 import android.content.Context;
 import android.content.DialogInterface;
+import android.content.Intent;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
+import android.os.UserHandle;
 import android.util.Log;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -38,6 +40,8 @@
     protected static final String TAG = "QSFooter";
     protected static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
 
+    private static final String ACTION_VPN_SETTINGS = "android.net.vpn.SETTINGS";
+
     private final View mRootView;
     private final TextView mFooterText;
     private final ImageView mFooterIcon;
@@ -128,50 +132,42 @@
     @Override
     public void onClick(DialogInterface dialog, int which) {
         if (which == DialogInterface.BUTTON_NEGATIVE) {
-            mSecurityController.disconnectFromVpn();
+            final Intent settingsIntent = new Intent(ACTION_VPN_SETTINGS);
+            mContext.startActivityAsUser(settingsIntent, UserHandle.CURRENT);
         }
     }
 
     private void createDialog() {
+        boolean hasDeviceOwner = mSecurityController.hasDeviceOwner();
+        boolean hasProfile = mSecurityController.hasProfileOwner();
+        boolean hasVpn = mSecurityController.isVpnEnabled();
+
         mDialog = new SystemUIDialog(mContext);
-        mDialog.setTitle(getTitle());
-        mDialog.setMessage(getMessage());
+        mDialog.setTitle(getTitle(hasDeviceOwner, hasProfile));
+        mDialog.setMessage(getMessage(hasDeviceOwner, hasProfile, hasVpn));
         mDialog.setButton(DialogInterface.BUTTON_POSITIVE, getPositiveButton(), this);
-        if (mSecurityController.isVpnEnabled()) {
+        if (hasVpn) {
             mDialog.setButton(DialogInterface.BUTTON_NEGATIVE, getNegativeButton(), this);
         }
         mDialog.show();
     }
 
     private String getNegativeButton() {
-        if (mSecurityController.isLegacyVpn()) {
-            return mContext.getString(R.string.disconnect_vpn);
-        } else {
-            return mContext.getString(R.string.disable_vpn);
-        }
+        return mContext.getString(R.string.status_bar_settings_settings_button);
     }
 
     private String getPositiveButton() {
         return mContext.getString(R.string.quick_settings_done);
     }
 
-    private String getMessage() {
-        if (mSecurityController.hasDeviceOwner()) {
-            if (mSecurityController.hasProfileOwner()) {
-                if (mSecurityController.isVpnEnabled()) {
-                    if (mSecurityController.isLegacyVpn()) {
-                        return mContext.getString(
-                                R.string.monitoring_description_legacy_vpn_device_and_profile_owned,
-                                mSecurityController.getDeviceOwnerName(),
-                                mSecurityController.getProfileOwnerName(),
-                                mSecurityController.getLegacyVpnName());
-                    } else {
-                        return mContext.getString(
-                                R.string.monitoring_description_vpn_device_and_profile_owned,
-                                mSecurityController.getDeviceOwnerName(),
-                                mSecurityController.getProfileOwnerName(),
-                                mSecurityController.getVpnApp());
-                    }
+    private String getMessage(boolean hasDeviceOwner, boolean hasProfile, boolean hasVpn) {
+        if (hasDeviceOwner) {
+            if (hasProfile) {
+                if (hasVpn) {
+                    return mContext.getString(
+                            R.string.monitoring_description_vpn_device_and_profile_owned,
+                            mSecurityController.getDeviceOwnerName(),
+                            mSecurityController.getProfileOwnerName());
                 } else {
                     return mContext.getString(
                             R.string.monitoring_description_device_and_profile_owned,
@@ -179,57 +175,33 @@
                             mSecurityController.getProfileOwnerName());
                 }
             } else {
-                if (mSecurityController.isVpnEnabled()) {
-                    if (mSecurityController.isLegacyVpn()) {
-                        return mContext.getString(
-                                R.string.monitoring_description_legacy_vpn_device_owned,
-                                mSecurityController.getDeviceOwnerName(),
-                                mSecurityController.getLegacyVpnName());
-                    } else {
-                        return mContext.getString(R.string.monitoring_description_vpn_device_owned,
-                                mSecurityController.getDeviceOwnerName(),
-                                mSecurityController.getVpnApp());
-                    }
+                if (hasVpn) {
+                    return mContext.getString(R.string.monitoring_description_vpn_device_owned,
+                            mSecurityController.getDeviceOwnerName());
                 } else {
                     return mContext.getString(R.string.monitoring_description_device_owned,
                             mSecurityController.getDeviceOwnerName());
                 }
             }
-        } else if (mSecurityController.hasProfileOwner()) {
-            if (mSecurityController.isVpnEnabled()) {
-                if (mSecurityController.isLegacyVpn()) {
-                    return mContext.getString(
-                            R.string.monitoring_description_legacy_vpn_profile_owned,
-                            mSecurityController.getProfileOwnerName(),
-                            mSecurityController.getLegacyVpnName());
-                } else {
-                    return mContext.getString(
-                            R.string.monitoring_description_vpn_profile_owned,
-                            mSecurityController.getProfileOwnerName(),
-                            mSecurityController.getVpnApp());
-                }
+        } else if (hasProfile) {
+            if (hasVpn) {
+                return mContext.getString(
+                        R.string.monitoring_description_vpn_profile_owned,
+                        mSecurityController.getProfileOwnerName());
             } else {
                 return mContext.getString(
                         R.string.monitoring_description_profile_owned,
                         mSecurityController.getProfileOwnerName());
             }
         } else {
-            if (mSecurityController.isLegacyVpn()) {
-                return mContext.getString(R.string.monitoring_description_legacy_vpn,
-                        mSecurityController.getLegacyVpnName());
-
-            } else {
-                return mContext.getString(R.string.monitoring_description_vpn,
-                        mSecurityController.getVpnApp());
-            }
+            return mContext.getString(R.string.monitoring_description_vpn);
         }
     }
 
-    private int getTitle() {
-        if (mSecurityController.hasDeviceOwner()) {
+    private int getTitle(boolean hasDeviceOwner, boolean hasProfile) {
+        if (hasDeviceOwner) {
             return R.string.monitoring_title_device_owned;
-        }
-        if (mSecurityController.hasProfileOwner()) {
+        } else if (hasProfile) {
             return R.string.monitoring_title_profile_owned;
         }
         return R.string.monitoring_title;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 5cf6a6e..9adf028 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -173,7 +173,7 @@
         filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
         filter.addAction(TelephonyIntents.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED);
         filter.addAction(TelephonyIntents.SPN_STRINGS_UPDATED_ACTION);
-        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE);
+        filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
         filter.addAction(ConnectivityManager.INET_CONDITION_ACTION);
         filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
         filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
@@ -331,7 +331,7 @@
             Log.d(TAG, "onReceive: intent=" + intent);
         }
         final String action = intent.getAction();
-        if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE) ||
+        if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION) ||
                 action.equals(ConnectivityManager.INET_CONDITION_ACTION)) {
             updateConnectivity();
         } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java
index 6148feb..e1e022d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityController.java
@@ -22,10 +22,6 @@
     String getDeviceOwnerName();
     String getProfileOwnerName();
     boolean isVpnEnabled();
-    String getVpnApp();
-    boolean isLegacyVpn();
-    String getLegacyVpnName();
-    void disconnectFromVpn();
     void onUserSwitched(int newUserId);
 
     void addCallback(SecurityControllerCallback callback);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
index f0dd943..4f47cc6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -19,6 +19,7 @@
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
 import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
 import android.net.ConnectivityManager;
 import android.net.ConnectivityManager.NetworkCallback;
 import android.net.IConnectivityManager;
@@ -27,10 +28,14 @@
 import android.net.NetworkRequest;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.os.UserManager;
 import android.text.TextUtils;
 import android.util.Log;
+import android.util.SparseArray;
 
 import com.android.internal.net.VpnConfig;
+import com.android.internal.net.VpnInfo;
 
 import java.io.FileDescriptor;
 import java.io.PrintWriter;
@@ -50,15 +55,13 @@
 
     private final Context mContext;
     private final ConnectivityManager mConnectivityManager;
-    private final IConnectivityManager mConnectivityService = IConnectivityManager.Stub.asInterface(
-                ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
+    private final IConnectivityManager mConnectivityManagerService;
     private final DevicePolicyManager mDevicePolicyManager;
+    private final UserManager mUserManager;
     private final ArrayList<SecurityControllerCallback> mCallbacks
             = new ArrayList<SecurityControllerCallback>();
 
-    private VpnConfig mVpnConfig;
-    private String mVpnName;
-    private int mCurrentVpnNetworkId = NO_NETWORK;
+    private SparseArray<Boolean> mCurrentVpnUsers = new SparseArray<>();
     private int mCurrentUserId;
 
     public SecurityControllerImpl(Context context) {
@@ -67,6 +70,10 @@
                 context.getSystemService(Context.DEVICE_POLICY_SERVICE);
         mConnectivityManager = (ConnectivityManager)
                 context.getSystemService(Context.CONNECTIVITY_SERVICE);
+        mConnectivityManagerService = IConnectivityManager.Stub.asInterface(
+                ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
+        mUserManager = (UserManager)
+                context.getSystemService(Context.USER_SERVICE);
 
         // TODO: re-register network callback on user change.
         mConnectivityManager.registerNetworkCallback(REQUEST, mNetworkCallback);
@@ -75,9 +82,7 @@
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println("SecurityController state:");
-        pw.print("  mCurrentVpnNetworkId="); pw.println(mCurrentVpnNetworkId);
-        pw.print("  mVpnConfig="); pw.println(mVpnConfig);
-        pw.print("  mVpnName="); pw.println(mVpnName);
+        pw.print("  mCurrentVpnUsers=" + mCurrentVpnUsers);
     }
 
     @Override
@@ -86,56 +91,33 @@
     }
 
     @Override
-    public boolean hasProfileOwner() {
-        return !TextUtils.isEmpty(mDevicePolicyManager.getProfileOwnerNameAsUser(mCurrentUserId));
-    }
-
-    @Override
     public String getDeviceOwnerName() {
         return mDevicePolicyManager.getDeviceOwnerName();
     }
 
     @Override
-    public String getProfileOwnerName() {
-        return mDevicePolicyManager.getProfileOwnerNameAsUser(mCurrentUserId);
+    public boolean hasProfileOwner() {
+        boolean result = false;
+        for (UserInfo profile : mUserManager.getProfiles(mCurrentUserId)) {
+            result |= (mDevicePolicyManager.getProfileOwnerAsUser(profile.id) != null);
+        }
+        return result;
     }
 
+    @Override
+    public String getProfileOwnerName() {
+        for (UserInfo profile : mUserManager.getProfiles(mCurrentUserId)) {
+            String name = mDevicePolicyManager.getProfileOwnerNameAsUser(profile.id);
+            if (name != null) {
+                return name;
+            }
+        }
+        return null;
+    }
 
     @Override
     public boolean isVpnEnabled() {
-        return mCurrentVpnNetworkId != NO_NETWORK;
-    }
-
-    @Override
-    public boolean isLegacyVpn() {
-        return mVpnConfig.legacy;
-    }
-
-    @Override
-    public String getVpnApp() {
-        return mVpnName;
-    }
-
-    @Override
-    public String getLegacyVpnName() {
-        return mVpnConfig.session;
-    }
-
-    @Override
-    public void disconnectFromVpn() {
-        try {
-            if (isLegacyVpn()) {
-                mConnectivityService.prepareVpn(VpnConfig.LEGACY_VPN, VpnConfig.LEGACY_VPN);
-            } else {
-                // Prevent this app from initiating VPN connections in the future without user
-                // intervention.
-                mConnectivityService.setVpnPackageAuthorization(false);
-
-                mConnectivityService.prepareVpn(mVpnConfig.user, VpnConfig.LEGACY_VPN);
-            }
-        } catch (Exception e) {
-            Log.e(TAG, "Unable to disconnect from VPN", e);
-        }
+        return mCurrentVpnUsers.get(mCurrentUserId) != null;
     }
 
     @Override
@@ -158,14 +140,6 @@
         fireCallbacks();
     }
 
-    private void setCurrentNetid(int netId) {
-        if (netId != mCurrentVpnNetworkId) {
-            mCurrentVpnNetworkId = netId;
-            updateState();
-            fireCallbacks();
-        }
-    }
-
     private void fireCallbacks() {
         for (SecurityControllerCallback callback : mCallbacks) {
             callback.onStateChanged();
@@ -173,27 +147,30 @@
     }
 
     private void updateState() {
+        // Find all users with an active VPN
+        SparseArray<Boolean> vpnUsers = new SparseArray<>();
         try {
-            mVpnConfig = mConnectivityService.getVpnConfig();
+            for (VpnInfo vpn : mConnectivityManagerService.getAllVpnInfo()) {
+                UserInfo user = mUserManager.getUserInfo(UserHandle.getUserId(vpn.ownerUid));
+                int groupId = (user.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID ?
+                        user.profileGroupId : user.id);
 
-            if (mVpnConfig != null && !mVpnConfig.legacy) {
-                mVpnName = VpnConfig.getVpnLabel(mContext, mVpnConfig.user).toString();
+                vpnUsers.put(groupId, Boolean.TRUE);
             }
-        } catch (RemoteException | NameNotFoundException e) {
-            Log.w(TAG, "Unable to get current VPN", e);
+        } catch (RemoteException rme) {
+            // Roll back to previous state
+            Log.e(TAG, "Unable to list active VPNs", rme);
+            return;
         }
+        mCurrentVpnUsers = vpnUsers;
     }
 
     private final NetworkCallback mNetworkCallback = new NetworkCallback() {
         @Override
         public void onAvailable(Network network) {
-            NetworkCapabilities networkCapabilities =
-                    mConnectivityManager.getNetworkCapabilities(network);
-            if (DEBUG) Log.d(TAG, "onAvailable " + network.netId + " : " + networkCapabilities);
-            if (networkCapabilities != null &&
-                    networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {
-                setCurrentNetid(network.netId);
-            }
+            if (DEBUG) Log.d(TAG, "onAvailable " + network.netId);
+            updateState();
+            fireCallbacks();
         };
 
         // TODO Find another way to receive VPN lost.  This may be delayed depending on
@@ -201,9 +178,8 @@
         @Override
         public void onLost(Network network) {
             if (DEBUG) Log.d(TAG, "onLost " + network.netId);
-            if (mCurrentVpnNetworkId == network.netId) {
-                setCurrentNetid(NO_NETWORK);
-            }
+            updateState();
+            fireCallbacks();
         };
     };
 
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 4e3abad..bba3580 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -18,7 +18,6 @@
 
 import static android.Manifest.permission.RECEIVE_DATA_ACTIVITY_CHANGE;
 import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
-import static android.net.ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE;
 import static android.net.ConnectivityManager.NETID_UNSET;
 import static android.net.ConnectivityManager.TYPE_NONE;
 import static android.net.ConnectivityManager.TYPE_VPN;
@@ -1386,7 +1385,6 @@
 
     public void sendConnectedBroadcast(NetworkInfo info) {
         enforceConnectivityInternalPermission();
-        sendGeneralBroadcast(info, CONNECTIVITY_ACTION_IMMEDIATE);
         sendGeneralBroadcast(info, CONNECTIVITY_ACTION);
     }
 
@@ -4365,9 +4363,6 @@
             }
             intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION,
                     mDefaultInetConditionPublished);
-            final Intent immediateIntent = new Intent(intent);
-            immediateIntent.setAction(CONNECTIVITY_ACTION_IMMEDIATE);
-            sendStickyBroadcast(immediateIntent);
             sendStickyBroadcast(intent);
             if (newDefaultAgent != null) {
                 sendConnectedBroadcast(newDefaultAgent.networkInfo);
diff --git a/services/core/java/com/android/server/location/GpsLocationProvider.java b/services/core/java/com/android/server/location/GpsLocationProvider.java
index d0b25f7..a72c77e 100644
--- a/services/core/java/com/android/server/location/GpsLocationProvider.java
+++ b/services/core/java/com/android/server/location/GpsLocationProvider.java
@@ -2012,7 +2012,7 @@
             intentFilter = new IntentFilter();
             intentFilter.addAction(ALARM_WAKEUP);
             intentFilter.addAction(ALARM_TIMEOUT);
-            intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION_IMMEDIATE);
+            intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
             intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
             intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
             intentFilter.addAction(Intent.ACTION_SCREEN_ON);
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index fce01e5..ad85b59 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -4215,8 +4215,9 @@
     /** {@inheritDoc} */
     @Override
     public int finishPostLayoutPolicyLw() {
-        if (mWinShowWhenLocked != null &&
-                mWinShowWhenLocked != mTopFullscreenOpaqueWindowState) {
+        if (mWinShowWhenLocked != null && mTopFullscreenOpaqueWindowState != null &&
+                mWinShowWhenLocked.getAppToken() != mTopFullscreenOpaqueWindowState.getAppToken()
+                && isKeyguardLocked()) {
             // A dialog is dismissing the keyguard. Put the wallpaper behind it and hide the
             // fullscreen window.
             // TODO: Make sure FLAG_SHOW_WALLPAPER is restored when dialog is dismissed. Or not.