Merge changes Iaa7bc042,Icc312fc9,I50ba06ed into honeycomb

* changes:
  Make keyguard also ask to turn the back button off, now that it is controlled separately.
  Allow independent control of the back and the other navigation buttons.
  Allow the status bar disable flags to be used as View's system ui visibility fields.
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index 97e6931..1af0983 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -22,6 +22,7 @@
 import android.os.RemoteException;
 import android.os.IBinder;
 import android.os.ServiceManager;
+import android.view.View;
 
 import com.android.internal.statusbar.IStatusBarService;
 
@@ -31,52 +32,24 @@
  * @hide
  */
 public class StatusBarManager {
-    /**
-     * Flag for {@link #disable} to make the status bar not expandable.  Unless you also
-     * set {@link #DISABLE_NOTIFICATION_ICONS}, new notifications will continue to show.
-     */
-    public static final int DISABLE_EXPAND = 0x00000001;
 
-    /**
-     * Flag for {@link #disable} to hide notification icons and scrolling ticker text.
-     */
-    public static final int DISABLE_NOTIFICATION_ICONS = 0x00000002;
+    public static final int DISABLE_EXPAND = View.STATUS_BAR_DISABLE_EXPAND;
+    public static final int DISABLE_NOTIFICATION_ICONS = View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS;
+    public static final int DISABLE_NOTIFICATION_ALERTS
+            = View.STATUS_BAR_DISABLE_NOTIFICATION_ALERTS;
+    public static final int DISABLE_NOTIFICATION_TICKER
+            = View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER;
+    public static final int DISABLE_SYSTEM_INFO = View.STATUS_BAR_DISABLE_SYSTEM_INFO;
+    public static final int DISABLE_NAVIGATION = View.STATUS_BAR_DISABLE_NAVIGATION;
+    public static final int DISABLE_BACK = View.STATUS_BAR_DISABLE_BACK;
+    public static final int DISABLE_CLOCK = View.STATUS_BAR_DISABLE_CLOCK;
 
-    /**
-     * Flag for {@link #disable} to disable incoming notification alerts.  This will not block
-     * icons, but it will block sound, vibrating and other visual or aural notifications.
-     */
-    public static final int DISABLE_NOTIFICATION_ALERTS = 0x00000004;
-
-    /**
-     * Flag for {@link #disable} to hide only the scrolling ticker.  Note that
-     * {@link #DISABLE_NOTIFICATION_ICONS} implies {@link #DISABLE_NOTIFICATION_TICKER}.
-     */
-    public static final int DISABLE_NOTIFICATION_TICKER = 0x00000008;
-
-    /**
-     * Flag for {@link #disable} to hide the center system info area.
-     */
-    public static final int DISABLE_SYSTEM_INFO = 0x00000010;
-
-    /**
-     * Flag for {@link #disable} to hide only the navigation buttons.  Don't use this
-     * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
-     */
-    public static final int DISABLE_NAVIGATION = 0x00000020;
-
-    /**
-     * Flag for {@link #disable} to hide only the clock.  You might use this if your activity has
-     * its own clock making the status bar's clock redundant.
-     */
-    public static final int DISABLE_CLOCK = 0x00000040;
-
-
-    /**
-     * Re-enable all of the status bar features that you've disabled.
-     */
     public static final int DISABLE_NONE = 0x00000000;
 
+    public static final int DISABLE_MASK = DISABLE_EXPAND | DISABLE_NOTIFICATION_ICONS
+            | DISABLE_NOTIFICATION_ALERTS | DISABLE_NOTIFICATION_TICKER
+            | DISABLE_SYSTEM_INFO| DISABLE_NAVIGATION | DISABLE_BACK | DISABLE_CLOCK;
+
     private Context mContext;
     private IStatusBarService mService;
     private IBinder mToken = new Binder();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d0b150b..fc0039e 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1732,6 +1732,102 @@
     public static final int STATUS_BAR_HIDDEN = 0x00000001;
 
     /**
+     * @hide
+     *
+     * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
+     * out of the public fields to keep the undefined bits out of the developer's way.
+     *
+     * Flag to make the status bar not expandable.  Unless you also
+     * set {@link #STATUS_BAR_DISABLE_NOTIFICATION_ICONS}, new notifications will continue to show.
+     */
+    public static final int STATUS_BAR_DISABLE_EXPAND = 0x00010000;
+
+    /**
+     * @hide
+     *
+     * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
+     * out of the public fields to keep the undefined bits out of the developer's way.
+     *
+     * Flag to hide notification icons and scrolling ticker text.
+     */
+    public static final int STATUS_BAR_DISABLE_NOTIFICATION_ICONS = 0x00020000;
+
+    /**
+     * @hide
+     *
+     * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
+     * out of the public fields to keep the undefined bits out of the developer's way.
+     *
+     * Flag to disable incoming notification alerts.  This will not block
+     * icons, but it will block sound, vibrating and other visual or aural notifications.
+     */
+    public static final int STATUS_BAR_DISABLE_NOTIFICATION_ALERTS = 0x00040000;
+
+    /**
+     * @hide
+     *
+     * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
+     * out of the public fields to keep the undefined bits out of the developer's way.
+     *
+     * Flag to hide only the scrolling ticker.  Note that
+     * {@link #STATUS_BAR_DISABLE_NOTIFICATION_ICONS} implies
+     * {@link #STATUS_BAR_DISABLE_NOTIFICATION_TICKER}.
+     */
+    public static final int STATUS_BAR_DISABLE_NOTIFICATION_TICKER = 0x00080000;
+
+    /**
+     * @hide
+     *
+     * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
+     * out of the public fields to keep the undefined bits out of the developer's way.
+     *
+     * Flag to hide the center system info area.
+     */
+    public static final int STATUS_BAR_DISABLE_SYSTEM_INFO = 0x00100000;
+
+    /**
+     * @hide
+     *
+     * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
+     * out of the public fields to keep the undefined bits out of the developer's way.
+     *
+     * Flag to hide only the navigation buttons.  Don't use this
+     * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
+     *
+     * THIS DOES NOT DISABLE THE BACK BUTTON
+     */
+    public static final int STATUS_BAR_DISABLE_NAVIGATION = 0x00200000;
+
+    /**
+     * @hide
+     *
+     * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
+     * out of the public fields to keep the undefined bits out of the developer's way.
+     *
+     * Flag to hide only the back button.  Don't use this
+     * unless you're a special part of the system UI (i.e., setup wizard, keyguard).
+     */
+    public static final int STATUS_BAR_DISABLE_BACK = 0x00400000;
+
+    /**
+     * @hide
+     *
+     * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
+     * out of the public fields to keep the undefined bits out of the developer's way.
+     *
+     * Flag to hide only the clock.  You might use this if your activity has
+     * its own clock making the status bar's clock redundant.
+     */
+    public static final int STATUS_BAR_DISABLE_CLOCK = 0x00800000;
+
+
+    /**
+     * @hide
+     */
+    public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = STATUS_BAR_HIDDEN;
+    
+
+    /**
      * Controls the over-scroll mode for this view.
      * See {@link #overScrollBy(int, int, int, int, int, int, int, int, boolean)},
      * {@link #OVER_SCROLL_ALWAYS}, {@link #OVER_SCROLL_IF_CONTENT_SCROLLS},
@@ -10839,7 +10935,8 @@
     public void dispatchSystemUiVisibilityChanged(int visibility) {
         mSystemUiVisibility = visibility;
         if (mOnSystemUiVisibilityChangeListener != null) {
-            mOnSystemUiVisibilityChangeListener.onSystemUiVisibilityChange(visibility);
+            mOnSystemUiVisibilityChangeListener.onSystemUiVisibilityChange(
+                    visibility & ~PUBLIC_STATUS_BAR_VISIBILITY_MASK);
         }
     }
 
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml
index f355e17..6c173c9 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml
@@ -44,20 +44,20 @@
                 />
 
             <!-- navigation controls -->
+            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
+                android:layout_width="80dip"
+                android:layout_height="match_parent"
+                android:src="@drawable/ic_sysbar_back"
+                android:layout_alignParentLeft="true"
+                systemui:keyCode="4"
+                />
             <LinearLayout
                 android:id="@+id/navigationArea"
                 android:layout_width="wrap_content"
                 android:layout_height="match_parent"
-                android:layout_alignParentLeft="true"
+                android:layout_toRightOf="@+id/back"
                 android:orientation="horizontal"
                 >
-
-                <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
-                    android:layout_width="80dip"
-                    android:layout_height="match_parent"
-                    android:src="@drawable/ic_sysbar_back"
-                    systemui:keyCode="4"
-                    />
                 <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
                     android:layout_width="80dip"
                     android:layout_height="match_parent"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 8dc0afb..6c8a20d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -368,8 +368,8 @@
                 (ImageView)sb.findViewById(R.id.network_type));
 
         // The navigation buttons
+        mBackButton = (ImageView)sb.findViewById(R.id.back);
         mNavigationArea = sb.findViewById(R.id.navigationArea);
-        mBackButton = (ImageView)mNavigationArea.findViewById(R.id.back);
         mHomeButton = mNavigationArea.findViewById(R.id.home);
         mMenuButton = mNavigationArea.findViewById(R.id.menu);
         mRecentButton = mNavigationArea.findViewById(R.id.recent_apps);
@@ -793,6 +793,18 @@
                 mInputMethodSwitchButton.setScreenLocked(false);
             }
         }
+        if ((diff & StatusBarManager.DISABLE_BACK) != 0) {
+            if ((state & StatusBarManager.DISABLE_BACK) != 0) {
+                Slog.i(TAG, "DISABLE_BACK: yes");
+                mBackButton.setVisibility(View.INVISIBLE);
+                mInputMethodSwitchButton.setScreenLocked(true);
+            } else {
+                Slog.i(TAG, "DISABLE_BACK: no");
+                mBackButton.setVisibility(View.VISIBLE);
+                mInputMethodSwitchButton.setScreenLocked(false);
+            }
+        }
+
     }
 
     private boolean hasTicker(Notification n) {
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java b/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
index 6b52454..36afd75 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewBase.java
@@ -50,6 +50,8 @@
     public KeyguardViewBase(Context context) {
         super(context);
 
+        setSystemUiVisibility(STATUS_BAR_DISABLE_BACK);
+
         // This is a faster way to draw the background on devices without hardware acceleration
         setBackgroundDrawable(new Drawable() {
             @Override
@@ -235,4 +237,9 @@
         return false;
     }
 
+    @Override
+    public void dispatchSystemUiVisibilityChanged(int visibility) {
+        super.dispatchSystemUiVisibilityChanged(visibility);
+        setSystemUiVisibility(STATUS_BAR_DISABLE_BACK);
+    }
 }
diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java
index cdbf237..1a2f867 100644
--- a/services/java/com/android/server/StatusBarManagerService.java
+++ b/services/java/com/android/server/StatusBarManagerService.java
@@ -67,6 +67,7 @@
 
     // for disabling the status bar
     ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>();
+    IBinder mSysUiVisToken = new Binder();
     int mDisabled = 0;
 
     Object mLock = new Object();
@@ -141,25 +142,29 @@
     public void disable(int what, IBinder token, String pkg) {
         enforceStatusBar();
 
+        synchronized (mLock) {
+            disableLocked(what, token, pkg);
+        }
+    }
+
+    private void disableLocked(int what, IBinder token, String pkg) {
         // It's important that the the callback and the call to mBar get done
         // in the same order when multiple threads are calling this function
         // so they are paired correctly.  The messages on the handler will be
         // handled in the order they were enqueued, but will be outside the lock.
-        synchronized (mDisableRecords) {
-            manageDisableListLocked(what, token, pkg);
-            final int net = gatherDisableActionsLocked();
-            if (net != mDisabled) {
-                mDisabled = net;
-                mHandler.post(new Runnable() {
-                        public void run() {
-                            mNotificationCallbacks.onSetDisabled(net);
-                        }
-                    });
-                if (mBar != null) {
-                    try {
-                        mBar.disable(net);
-                    } catch (RemoteException ex) {
+        manageDisableListLocked(what, token, pkg);
+        final int net = gatherDisableActionsLocked();
+        if (net != mDisabled) {
+            mDisabled = net;
+            mHandler.post(new Runnable() {
+                    public void run() {
+                        mNotificationCallbacks.onSetDisabled(net);
                     }
+                });
+            if (mBar != null) {
+                try {
+                    mBar.disable(net);
+                } catch (RemoteException ex) {
                 }
             }
         }
@@ -294,6 +299,8 @@
         synchronized (mLock) {
             final boolean lightsOn = (vis & View.STATUS_BAR_HIDDEN) == 0;
             updateLightsOnLocked(lightsOn);
+            disableLocked(vis & StatusBarManager.DISABLE_MASK, mSysUiVisToken,
+                    "WindowManager.LayoutParams");
         }
     }
 
@@ -452,37 +459,35 @@
             Slog.d(TAG, "manageDisableList what=0x" + Integer.toHexString(what) + " pkg=" + pkg);
         }
         // update the list
-        synchronized (mDisableRecords) {
-            final int N = mDisableRecords.size();
-            DisableRecord tok = null;
-            int i;
-            for (i=0; i<N; i++) {
-                DisableRecord t = mDisableRecords.get(i);
-                if (t.token == token) {
-                    tok = t;
-                    break;
-                }
+        final int N = mDisableRecords.size();
+        DisableRecord tok = null;
+        int i;
+        for (i=0; i<N; i++) {
+            DisableRecord t = mDisableRecords.get(i);
+            if (t.token == token) {
+                tok = t;
+                break;
             }
-            if (what == 0 || !token.isBinderAlive()) {
-                if (tok != null) {
-                    mDisableRecords.remove(i);
-                    tok.token.unlinkToDeath(tok, 0);
-                }
-            } else {
-                if (tok == null) {
-                    tok = new DisableRecord();
-                    try {
-                        token.linkToDeath(tok, 0);
-                    }
-                    catch (RemoteException ex) {
-                        return; // give up
-                    }
-                    mDisableRecords.add(tok);
-                }
-                tok.what = what;
-                tok.token = token;
-                tok.pkg = pkg;
+        }
+        if (what == 0 || !token.isBinderAlive()) {
+            if (tok != null) {
+                mDisableRecords.remove(i);
+                tok.token.unlinkToDeath(tok, 0);
             }
+        } else {
+            if (tok == null) {
+                tok = new DisableRecord();
+                try {
+                    token.linkToDeath(tok, 0);
+                }
+                catch (RemoteException ex) {
+                    return; // give up
+                }
+                mDisableRecords.add(tok);
+            }
+            tok.what = what;
+            tok.token = token;
+            tok.pkg = pkg;
         }
     }
 
@@ -523,7 +528,7 @@
             }
         }
 
-        synchronized (mDisableRecords) {
+        synchronized (mLock) {
             final int N = mDisableRecords.size();
             pw.println("  mDisableRecords.size=" + N
                     + " mDisabled=0x" + Integer.toHexString(mDisabled));
diff --git a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
index 5fd946e..13665e1 100644
--- a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
+++ b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
@@ -70,6 +70,12 @@
     }
 
     private Test[] mTests = new Test[] {
+        new Test("DISABLE_NAVIGATION") {
+            public void run() {
+                View v = findViewById(android.R.id.list);
+                v.setSystemUiVisibility(View.STATUS_BAR_DISABLE_NAVIGATION);
+            }
+        },
         new Test("STATUS_BAR_HIDDEN") {
             public void run() {
                 View v = findViewById(android.R.id.list);
@@ -77,7 +83,7 @@
                 v.setOnSystemUiVisibilityChangeListener(mOnSystemUiVisibilityChangeListener);
             }
         },
-        new Test("not STATUS_BAR_HIDDEN") {
+        new Test("no setSystemUiVisibility") {
             public void run() {
                 View v = findViewById(android.R.id.list);
                 v.setSystemUiVisibility(View.STATUS_BAR_VISIBLE);