Dynamically show the menu button on the system bar.

Windows with FLAG_NEEDS_MENU_KEY (or windowNeedsMenuKey=true
in their theme) will cause the system bar to show a menu
icon. (Note that the phone's status bar currently ignores
this, but phones tend to have hardware menu keys anyway.)

Additionally, all windows whose package's SDK version is
pre-Honeycomb will have FLAG_NEEDS_MENU_KEY set by default.

Bug: 3003728

Change-Id: I2d983763a726ea4f32cd1af9b0390e30478b11d1
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 81091e3..c164eb4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -54,6 +54,8 @@
 
     private static final int MSG_SET_LIGHTS_ON = 0x00070000;
 
+    private static final int MSG_SHOW_MENU = 0x00080000;
+
     private StatusBarIconList mList;
     private Callbacks mCallbacks;
     private Handler mHandler = new H();
@@ -78,6 +80,7 @@
         public void animateExpand();
         public void animateCollapse();
         public void setLightsOn(boolean on);
+        public void setMenuKeyVisible(boolean visible);
     }
 
     public CommandQueue(Callbacks callbacks, StatusBarIconList list) {
@@ -153,6 +156,13 @@
         }
     }
 
+    public void setMenuKeyVisible(boolean visible) {
+        synchronized (mList) {
+            mHandler.removeMessages(MSG_SHOW_MENU);
+            mHandler.obtainMessage(MSG_SHOW_MENU, visible ? 1 : 0, 0, null).sendToTarget();
+        }
+    }
+
     private final class H extends Handler {
         public void handleMessage(Message msg) {
             final int what = msg.what & MSG_MASK;
@@ -210,6 +220,9 @@
                 case MSG_SET_LIGHTS_ON:
                     mCallbacks.setLightsOn(msg.arg1 != 0);
                     break;
+                case MSG_SHOW_MENU:
+                    mCallbacks.setMenuKeyVisible(msg.arg1 != 0);
+                    break;
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
index 57ebd27..9fbfc64 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
@@ -1013,6 +1013,9 @@
         }
     }
 
+    // Not supported
+    public void setMenuKeyVisible(boolean visible) { }
+
     private class Launcher implements View.OnClickListener {
         private PendingIntent mIntent;
         private String mPkg;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
index 695fdba..5594a47 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
@@ -72,15 +72,16 @@
         mCommandQueue = new CommandQueue(this, iconList);
         mBarService = IStatusBarService.Stub.asInterface(
                 ServiceManager.getService(Context.STATUS_BAR_SERVICE));
-        boolean[] lightsOn = new boolean[1];
+        boolean[] switches = new boolean[2];
         try {
             mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys, notifications,
-                    lightsOn);
+                    switches);
         } catch (RemoteException ex) {
             // If the system process isn't there we're doomed anyway.
         }
 
-        setLightsOn(lightsOn[0]);
+        setLightsOn(switches[0]);
+        setMenuKeyVisible(switches[1]);
 
         // Set up the initial icon state
         int N = iconList.size();
@@ -120,7 +121,11 @@
         // TODO lp.windowAnimations = R.style.Animation_StatusBar;
         WindowManagerImpl.getDefault().addView(sb, lp);
 
-        Slog.d(TAG, "Added status bar view w/ gravity 0x" + Integer.toHexString(lp.gravity));
+        Slog.d(TAG, "Added status bar view: gravity=0x" + Integer.toHexString(lp.gravity) 
+                    + " icons=" + iconList.size()
+                    + " lights=" + (switches[0]?"on":"off")
+                    + " menu=" + (switches[1]?"visible":"invisible")
+                    );
     }
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
index 0e26f52..69e9a94 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
@@ -79,6 +79,7 @@
     View mNotificationButtons;
     View mSystemInfo;
     View mNavigationArea;
+    View mMenuButton;
 
     NotificationPanel mNotificationPanel;
     SystemPanel mSystemPanel;
@@ -205,6 +206,7 @@
 
         // The navigation buttons
         mNavigationArea = sb.findViewById(R.id.navigationArea);
+        mMenuButton = mNavigationArea.findViewById(R.id.menu);
 
         // set the initial view visibility
         setAreThereNotifications();
@@ -503,6 +505,15 @@
         }
     }
 
+    public void setMenuKeyVisible(boolean visible) {
+        if (DEBUG) {
+            Slog.d(TAG, (visible?"showing":"hiding") + " the MENU button");
+        }
+        setViewVisibility(mMenuButton,
+                visible ? View.VISIBLE : View.INVISIBLE,
+                visible ? R.anim.navigation_in : R.anim.navigation_out);
+    }
+
     private void setAreThereNotifications() {
         final boolean hasClearable = mNotns.hasClearableItems();