Merge "Add NetworkMonitor. At present the network evaluation / captive portal detection is disabled pending addition of API to bind socket to network."
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
index d8e5b8a..a9206e7 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
@@ -297,7 +297,7 @@
      * @param event The key event
      * @return whether the event was consumed as a media key.
      */
-    private boolean interceptMediaKey(KeyEvent event) {
+    public boolean interceptMediaKey(KeyEvent event) {
         final int keyCode = event.getKeyCode();
         if (event.getAction() == KeyEvent.ACTION_DOWN) {
             switch (keyCode) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 1ffb4ee..d8e1766 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.phone;
 
 import android.content.Context;
+import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -160,4 +161,9 @@
             return false;
         }
     }
+
+    public boolean interceptMediaKey(KeyEvent event) {
+        ensureView();
+        return mKeyguardView.interceptMediaKey(event);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 922ac05..23b0594 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -68,6 +68,7 @@
 import android.util.Log;
 import android.view.Display;
 import android.view.Gravity;
+import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
@@ -2767,6 +2768,11 @@
         }
     }
 
+    public boolean interceptMediaKey(KeyEvent event) {
+        return mState == StatusBarState.KEYGUARD
+                && mStatusBarKeyguardViewManager.interceptMediaKey(event);
+    }
+
     public boolean onMenuPressed() {
         return mState == StatusBarState.KEYGUARD && mStatusBarKeyguardViewManager.onMenuPressed();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 48c54fc..2ae21ac 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -20,6 +20,7 @@
 import android.os.Bundle;
 import android.os.RemoteException;
 import android.util.Slog;
+import android.view.KeyEvent;
 import android.view.View;
 import android.view.ViewGroup;
 
@@ -220,10 +221,15 @@
                 mPhoneStatusBar.getNavigationBarView().setVisibility(View.GONE);
             }
         }
+        mStatusBarWindowManager.setBouncerShowing(mBouncer.isShowing());
         mPhoneStatusBar.setBouncerShowing(mBouncer.isShowing());
     }
 
     public boolean onMenuPressed() {
         return mBouncer.onMenuPressed();
     }
+
+    public boolean interceptMediaKey(KeyEvent event) {
+        return mBouncer.interceptMediaKey(event);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
index 8809d18..46a637b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java
@@ -111,7 +111,8 @@
     }
 
     private void applyFocusableFlag(State state) {
-        if (state.isKeyguardShowingAndNotOccluded() && state.keyguardNeedsInput) {
+        if (state.isKeyguardShowingAndNotOccluded() && state.keyguardNeedsInput
+                && state.bouncerShowing) {
             mLp.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
             mLp.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
         } else if (state.isKeyguardShowingAndNotOccluded() || state.statusBarFocusable) {
@@ -196,6 +197,11 @@
         apply(mCurrentState);
     }
 
+    public void setBouncerShowing(boolean showing) {
+        mCurrentState.bouncerShowing = showing;
+        apply(mCurrentState);
+    }
+
     /**
      * @param state The {@link StatusBarState} of the status bar.
      */
@@ -211,6 +217,7 @@
         boolean statusBarExpanded;
         boolean statusBarFocusable;
         long keyguardUserActivityTimeout;
+        boolean bouncerShowing;
 
         /**
          * The {@link BaseStatusBar} state from the status bar.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index e802d185..b51626d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -103,6 +103,9 @@
                     return mService.onMenuPressed();
                 }
         }
+        if (mService.interceptMediaKey(event)) {
+            return true;
+        }
         return super.dispatchKeyEvent(event);
     }
 
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index bd28e04..5e3325c 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -17,11 +17,9 @@
 package com.android.server.pm;
 
 import android.app.AppGlobals;
-import android.content.BroadcastReceiver;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ILauncherApps;
 import android.content.pm.IOnAppsChangedListener;
@@ -157,10 +155,26 @@
         }
     }
 
+    /**
+     * Checks if the user is enabled.
+     */
+    private boolean isUserEnabled(UserHandle user) {
+        long ident = Binder.clearCallingIdentity();
+        try {
+            UserInfo targetUserInfo = mUm.getUserInfo(user.getIdentifier());
+            return targetUserInfo != null && targetUserInfo.isEnabled();
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
     @Override
     public List<ResolveInfo> getLauncherActivities(String packageName, UserHandle user)
             throws RemoteException {
         ensureInUserProfiles(user, "Cannot retrieve activities for unrelated profile " + user);
+        if (!isUserEnabled(user)) {
+            return new ArrayList<ResolveInfo>();
+        }
 
         final Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);
         mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
@@ -179,6 +193,9 @@
     public ResolveInfo resolveActivity(Intent intent, UserHandle user)
             throws RemoteException {
         ensureInUserProfiles(user, "Cannot resolve activity for unrelated profile " + user);
+        if (!isUserEnabled(user)) {
+            return null;
+        }
 
         long ident = Binder.clearCallingIdentity();
         try {
@@ -193,6 +210,10 @@
     public boolean isPackageEnabled(String packageName, UserHandle user)
             throws RemoteException {
         ensureInUserProfiles(user, "Cannot check package for unrelated profile " + user);
+        if (!isUserEnabled(user)) {
+            return false;
+        }
+
         long ident = Binder.clearCallingIdentity();
         try {
             IPackageManager pm = AppGlobals.getPackageManager();
@@ -207,6 +228,10 @@
     public boolean isActivityEnabled(ComponentName component, UserHandle user)
             throws RemoteException {
         ensureInUserProfiles(user, "Cannot check component for unrelated profile " + user);
+        if (!isUserEnabled(user)) {
+            return false;
+        }
+
         long ident = Binder.clearCallingIdentity();
         try {
             IPackageManager pm = AppGlobals.getPackageManager();
@@ -221,6 +246,9 @@
     public void startActivityAsUser(ComponentName component, Rect sourceBounds,
             Bundle opts, UserHandle user) throws RemoteException {
         ensureInUserProfiles(user, "Cannot start activity for unrelated profile " + user);
+        if (!isUserEnabled(user)) {
+            throw new IllegalStateException("Cannot start activity for disabled profile "  + user);
+        }
 
         Intent launchIntent = new Intent(Intent.ACTION_MAIN);
         launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
@@ -228,7 +256,6 @@
         launchIntent.setSourceBounds(sourceBounds);
         launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
 
-        final int callingUserId = UserHandle.getCallingUserId();
         long ident = Binder.clearCallingIdentity();
         try {
             mContext.startActivityAsUser(launchIntent, opts, user);