It's lights out for you, navigation bar!

Views requesting lights out mode will cause the navbar to
disappear (this is useful for viewing videos/photos/etc
using every pixel of the screen).

But there's a catch: any user activity at all will cause the
lights to come back on and the navbar to return.

Change-Id: I535ed3ba9ae7fab3282c402be256add765395b6f
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index 7f23ed5..7d21489 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -34,5 +34,6 @@
     void setMenuKeyVisible(boolean visible);
     void setImeWindowStatus(in IBinder token, int vis, int backDisposition);
     void setHardKeyboardStatus(boolean available, boolean enabled);
+    void userActivity();
 }
 
diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
index d6ca426..bfc717b 100644
--- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl
@@ -46,4 +46,5 @@
     void onNotificationClear(String pkg, String tag, int id);
     void setSystemUiVisibility(int vis);
     void setHardKeyboardEnabled(boolean enabled);
+    void userActivity();
 }
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
index eba4480..b97c6a5 100644
--- a/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -25,100 +25,106 @@
     android:layout_width="match_parent"
     >
 
-    <LinearLayout android:id="@+id/rot0"
-        android:layout_height="match_parent"
-        android:layout_width="match_parent"
-        android:paddingLeft="8dip"
-        android:paddingRight="8dip"
-        android:background="#FF000000"
-        android:orientation="horizontal"
-        >
-
-        <!-- navigation controls -->
-        <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:src="@drawable/ic_sysbar_back"
-            systemui:keyCode="4"
-            android:layout_weight="1"
-            />
-        <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:src="@drawable/ic_sysbar_home"
-            systemui:keyCode="3"
-            android:layout_weight="1"
-            />
-        <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:src="@drawable/ic_sysbar_menu"
-            systemui:keyCode="82"
-            android:layout_weight="1"
-            />
-    </LinearLayout>
-
-    <LinearLayout android:id="@+id/rot90"
+    <FrameLayout
+        android:id="@+id/background"
         android:layout_height="match_parent"
         android:layout_width="match_parent"
         android:background="#FF000000"
-        android:orientation="vertical"
-        android:visibility="gone"
         >
 
-        <!-- navigation controls -->
-        <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
+        <LinearLayout android:id="@+id/rot0"
+            android:layout_height="match_parent"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:src="@drawable/ic_sysbar_menu"
-            systemui:keyCode="82"
-            android:layout_weight="1"
-            />
-        <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:src="@drawable/ic_sysbar_home"
-            systemui:keyCode="3"
-            android:layout_weight="1"
-            />
-        <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:src="@drawable/ic_sysbar_back"
-            systemui:keyCode="4"
-            android:layout_weight="1"
-            />
-    </LinearLayout>
+            android:paddingLeft="8dip"
+            android:paddingRight="8dip"
+            android:orientation="horizontal"
+            >
 
-    <LinearLayout android:id="@+id/rot270"
-        android:layout_height="match_parent"
-        android:layout_width="match_parent"
-        android:background="#FF000000"
-        android:orientation="vertical"
-        android:visibility="gone"
-        >
+            <!-- navigation controls -->
+            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:src="@drawable/ic_sysbar_back"
+                systemui:keyCode="4"
+                android:layout_weight="1"
+                />
+            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:src="@drawable/ic_sysbar_home"
+                systemui:keyCode="3"
+                android:layout_weight="1"
+                />
+            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
+                android:layout_width="wrap_content"
+                android:layout_height="match_parent"
+                android:src="@drawable/ic_sysbar_menu"
+                systemui:keyCode="82"
+                android:layout_weight="1"
+                />
+        </LinearLayout>
 
-        <!-- navigation controls -->
-        <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
+        <LinearLayout android:id="@+id/rot90"
+            android:layout_height="match_parent"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:src="@drawable/ic_sysbar_back"
-            systemui:keyCode="4"
-            android:layout_weight="1"
-            />
-        <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
+            android:orientation="vertical"
+            android:visibility="gone"
+            >
+
+            <!-- navigation controls -->
+            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:src="@drawable/ic_sysbar_menu"
+                systemui:keyCode="82"
+                android:layout_weight="1"
+                />
+            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:src="@drawable/ic_sysbar_home"
+                systemui:keyCode="3"
+                android:layout_weight="1"
+                />
+            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:src="@drawable/ic_sysbar_back"
+                systemui:keyCode="4"
+                android:layout_weight="1"
+                />
+        </LinearLayout>
+
+        <LinearLayout android:id="@+id/rot270"
+            android:layout_height="match_parent"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:src="@drawable/ic_sysbar_home"
-            systemui:keyCode="3"
-            android:layout_weight="1"
-            />
-        <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:src="@drawable/ic_sysbar_menu"
-            systemui:keyCode="82"
-            android:layout_weight="1"
-            />
-    </LinearLayout>
+            android:orientation="vertical"
+            android:visibility="gone"
+            >
+
+            <!-- navigation controls -->
+            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:src="@drawable/ic_sysbar_back"
+                systemui:keyCode="4"
+                android:layout_weight="1"
+                />
+            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:src="@drawable/ic_sysbar_home"
+                systemui:keyCode="3"
+                android:layout_weight="1"
+                />
+            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/menu"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:src="@drawable/ic_sysbar_menu"
+                systemui:keyCode="82"
+                android:layout_weight="1"
+                />
+        </LinearLayout>
+    
+    </FrameLayout>
 </com.android.systemui.statusbar.phone.NavigationBarView>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index d55a7c2..da1e1c5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -35,28 +35,33 @@
 public class CommandQueue extends IStatusBar.Stub {
     private static final String TAG = "StatusBar.CommandQueue";
 
-    private static final int MSG_MASK = 0xffff0000;
-    private static final int INDEX_MASK = 0x0000ffff;
+    private static final int INDEX_MASK = 0xffff;
+    private static final int MSG_SHIFT  = 16;
+    private static final int MSG_MASK   = 0xffff << MSG_SHIFT;
 
-    private static final int MSG_ICON = 0x00010000;
-    private static final int OP_SET_ICON = 1;
+
+    private static final int MSG_ICON                   = 1 << MSG_SHIFT;
+    private static final int OP_SET_ICON    = 1;
     private static final int OP_REMOVE_ICON = 2;
 
-    private static final int MSG_ADD_NOTIFICATION = 0x00020000;
-    private static final int MSG_UPDATE_NOTIFICATION = 0x00030000;
-    private static final int MSG_REMOVE_NOTIFICATION = 0x00040000;
+    private static final int MSG_ADD_NOTIFICATION       = 2 << MSG_SHIFT;
+    private static final int MSG_UPDATE_NOTIFICATION    = 3 << MSG_SHIFT;
+    private static final int MSG_REMOVE_NOTIFICATION    = 4 << MSG_SHIFT;
 
-    private static final int MSG_DISABLE = 0x00050000;
+    private static final int MSG_DISABLE                = 5 << MSG_SHIFT;
 
-    private static final int MSG_SET_VISIBILITY = 0x00060000;
-    private static final int OP_EXPAND = 1;
-    private static final int OP_COLLAPSE = 2;
+    private static final int MSG_SET_VISIBILITY         = 6 << MSG_SHIFT;
+    private static final int OP_EXPAND      = 1;
+    private static final int OP_COLLAPSE    = 2;
 
-    private static final int MSG_SET_LIGHTS_ON = 0x00070000;
+    private static final int MSG_SET_LIGHTS_ON          = 7 << MSG_SHIFT;
 
-    private static final int MSG_SHOW_MENU = 0x00080000;
-    private static final int MSG_SHOW_IME_BUTTON = 0x00090000;
-    private static final int MSG_SET_HARD_KEYBOARD_STATUS = 0x000a0000;
+    private static final int MSG_SHOW_MENU              = 8 << MSG_SHIFT;
+    private static final int MSG_SHOW_IME_BUTTON        = 9 << MSG_SHIFT;
+    private static final int MSG_SET_HARD_KEYBOARD_STATUS = 10 << MSG_SHIFT;
+    
+    private static final int MSG_USER_ACTIVITY          = 11 << MSG_SHIFT;
+
 
     private StatusBarIconList mList;
     private Callbacks mCallbacks;
@@ -85,6 +90,7 @@
         public void setMenuKeyVisible(boolean visible);
         public void setImeWindowStatus(IBinder token, int vis, int backDisposition);
         public void setHardKeyboardStatus(boolean available, boolean enabled);
+        public void userActivity();
     }
 
     public CommandQueue(Callbacks callbacks, StatusBarIconList list) {
@@ -183,6 +189,13 @@
         }
     }
 
+    public void userActivity() {
+        synchronized (mList) {
+            mHandler.removeMessages(MSG_USER_ACTIVITY);
+            mHandler.obtainMessage(MSG_USER_ACTIVITY, 0, 0, null).sendToTarget();
+        }
+    }
+
     private final class H extends Handler {
         public void handleMessage(Message msg) {
             final int what = msg.what & MSG_MASK;
@@ -249,6 +262,9 @@
                 case MSG_SET_HARD_KEYBOARD_STATUS:
                     mCallbacks.setHardKeyboardStatus(msg.arg1 != 0, msg.arg2 != 0);
                     break;
+                case MSG_USER_ACTIVITY:
+                    mCallbacks.userActivity();
+                    break;
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index ec169e5..7d6c57b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -16,29 +16,73 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ObjectAnimator;
 import android.content.Context;
+import android.os.ServiceManager;
 import android.util.AttributeSet;
 import android.view.Display;
 import android.view.KeyEvent;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.Surface;
 import android.view.WindowManager;
 import android.widget.LinearLayout;
 import android.content.res.Configuration;
 
+import com.android.internal.statusbar.IStatusBarService;
+
 import com.android.systemui.R;
 
 public class NavigationBarView extends LinearLayout {
+    protected IStatusBarService mBarService;
     final Display mDisplay;
     View[] mRotatedViews = new View[4];
+    View mBackground;
+    Animator mLastAnimator = null;
 
     public NavigationBarView(Context context, AttributeSet attrs) {
         super(context, attrs);
         mDisplay = ((WindowManager)context.getSystemService(
                 Context.WINDOW_SERVICE)).getDefaultDisplay();
+        mBarService = IStatusBarService.Stub.asInterface(
+                ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+
+        //setLayerType(View.LAYER_TYPE_HARDWARE, null);
+
+        setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
+            @Override
+            public void onSystemUiVisibilityChange(int visibility) {
+                boolean on = (visibility == View.STATUS_BAR_VISIBLE);
+                android.util.Log.d("NavigationBarView", "LIGHTS " 
+                    + (on ? "ON" : "OUT"));
+                setLights(on);
+            }
+        });
+    }
+
+    private void setLights(final boolean on) {
+        float oldAlpha = mBackground.getAlpha();
+        android.util.Log.d("NavigationBarView", "animating alpha: " + oldAlpha + " -> "
+            + (on ? 1f : 0f));
+
+        if (mLastAnimator != null && mLastAnimator.isRunning()) mLastAnimator.cancel();
+
+        mLastAnimator = ObjectAnimator.ofFloat(mBackground, "alpha", oldAlpha, on ? 1f : 0f)
+            .setDuration(on ? 250 : 1500);
+        mLastAnimator.addListener(new AnimatorListenerAdapter() {
+            @Override
+            public void onAnimationEnd(Animator _a) {
+                mLastAnimator = null;
+            }
+        });
+        mLastAnimator.start();
     }
 
     public void onFinishInflate() {
+        mBackground = findViewById(R.id.background);
+
         mRotatedViews[Surface.ROTATION_0] = 
         mRotatedViews[Surface.ROTATION_180] = findViewById(R.id.rot0);
 
@@ -47,6 +91,13 @@
         mRotatedViews[Surface.ROTATION_270] = findViewById(R.id.rot270);
     }
 
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        // immediately bring up the lights
+        setLights(true);
+        return false; // pass it on
+    }
+
     public void reorient() {
         final int rot = mDisplay.getRotation();
         for (int i=0; i<4; i++) {
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 b4adde6..ef78740 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -36,12 +36,14 @@
 import android.os.RemoteException;
 import android.os.Handler;
 import android.os.Message;
+import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.text.TextUtils;
 import android.util.Slog;
 import android.util.Log;
 import android.view.Display;
 import android.view.Gravity;
+import android.view.IWindowManager;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.MotionEvent;
@@ -101,6 +103,8 @@
     int mIconSize;
     Display mDisplay;
 
+    IWindowManager mWindowManager;
+
     PhoneStatusBarView mStatusBarView;
     int mPixelFormat;
     H mHandler = new H();
@@ -201,6 +205,9 @@
         mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
                 .getDefaultDisplay();
 
+        mWindowManager = IWindowManager.Stub.asInterface(
+                ServiceManager.getService(Context.WINDOW_SERVICE));
+
         super.start();
 
         addNavigationBar();
@@ -1103,12 +1110,23 @@
     }
 
     public void setLightsOn(boolean on) {
+        Log.v(TAG, "lights " + (on ? "on" : "off"));
         if (!on) {
             // All we do for "lights out" mode on a phone is hide the status bar,
             // which the window manager does.  But we do need to hide the windowshade
             // on our own.
             animateCollapse();
         }
+        notifyLightsChanged(on);
+    }
+
+    private void notifyLightsChanged(boolean shown) {
+        try {
+            Slog.d(TAG, "lights " + (shown?"on":"out"));
+            mWindowManager.statusBarVisibilityChanged(
+                    shown ? View.STATUS_BAR_VISIBLE : View.STATUS_BAR_HIDDEN);
+        } catch (RemoteException ex) {
+        }
     }
 
     // Not supported
@@ -1519,6 +1537,12 @@
         }
     }
 
+    public void userActivity() {
+        try {
+            mBarService.setSystemUiVisibility(View.STATUS_BAR_VISIBLE);
+        } catch (RemoteException ex) { }
+    }
+
     /**
      * The LEDs are turned o)ff when the notification panel is shown, even just a little bit.
      * This was added last-minute and is inconsistent with the way the rest of the notifications
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 58c4d5a..f74fcc6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -1565,6 +1565,9 @@
         return true;
     }
 
+    public void userActivity() {
+    }
+
     public class TouchOutsideListener implements View.OnTouchListener {
         private int mMsg;
         private StatusBarPanel mPanel;
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 6632f34..75768f0 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -2869,6 +2869,10 @@
                 mHandler.postDelayed(mScreenLockTimeout, mLockScreenTimeout);
             }
         }
+
+        try {
+            mStatusBarService.userActivity();
+        } catch (RemoteException ex) {}
     }
 
     Runnable mScreenLockTimeout = new Runnable() {
diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java
index 8df8177..1d2072c 100644
--- a/services/java/com/android/server/StatusBarManagerService.java
+++ b/services/java/com/android/server/StatusBarManagerService.java
@@ -122,6 +122,11 @@
     // ================================================================================
     // From IStatusBarService
     // ================================================================================
+    public void userActivity() {
+        if (mBar != null) try {
+            mBar.userActivity();
+        } catch (RemoteException ex) {}
+    }
     public void expand() {
         enforceExpandStatusBar();
 
diff --git a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
index 13665e1..0129114 100644
--- a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
+++ b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java
@@ -79,15 +79,22 @@
         new Test("STATUS_BAR_HIDDEN") {
             public void run() {
                 View v = findViewById(android.R.id.list);
-                v.setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
                 v.setOnSystemUiVisibilityChangeListener(mOnSystemUiVisibilityChangeListener);
+                v.setSystemUiVisibility(View.STATUS_BAR_HIDDEN);
+            }
+        },
+        new Test("STATUS_BAR_VISIBLE") {
+            public void run() {
+                View v = findViewById(android.R.id.list);
+                v.setOnSystemUiVisibilityChangeListener(mOnSystemUiVisibilityChangeListener);
+                v.setSystemUiVisibility(View.STATUS_BAR_VISIBLE);
             }
         },
         new Test("no setSystemUiVisibility") {
             public void run() {
                 View v = findViewById(android.R.id.list);
-                v.setSystemUiVisibility(View.STATUS_BAR_VISIBLE);
                 v.setOnSystemUiVisibilityChangeListener(null);
+                v.setSystemUiVisibility(View.STATUS_BAR_VISIBLE);
             }
         },
         new Test("Double Remove") {