diff options
11 files changed, 120 insertions, 12 deletions
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index eddd04ebd314..7cb4671b4ae2 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -611,6 +611,19 @@ public interface WindowManager extends ViewManager { * {@hide} */ public static final int FLAG_SPLIT_TOUCH = 0x00800000; + /** + * Flag for a window belonging to an activity that responds to {@link KeyEvent#KEYCODE_MENU} + * and therefore needs a Menu key. For devices where Menu is a physical button this flag is + * ignored, but on devices where the Menu key is drawn in software it may be hidden unless + * this flag is set. + * + * (Note that Action Bars, when available, are the preferred way to offer additional + * functions otherwise accessed via an options menu.) + * + * {@hide} + */ + public static final int FLAG_NEEDS_MENU_KEY = 0x01000000; + /** Window flag: *sigh* The lock screen wants to continue running its * animation while it is fading. A kind-of hack to allow this. Maybe * in the future we just make this the default behavior. diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index e884af824eb2..34a5b118626e 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -31,5 +31,6 @@ oneway interface IStatusBar void animateExpand(); void animateCollapse(); void setLightsOn(boolean on); + void setMenuKeyVisible(boolean visible); } diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index 0763f5e6938a..90f4d480ff2e 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -31,12 +31,13 @@ interface IStatusBarService void setIconVisibility(String slot, boolean visible); void removeIcon(String slot); void setActiveWindowIsFullscreen(boolean fullscreen); + void setMenuKeyVisible(boolean visible); // ---- Methods below are for use by the status bar policy services ---- // You need the STATUS_BAR_SERVICE permission void registerStatusBar(IStatusBar callbacks, out StatusBarIconList iconList, out List<IBinder> notificationKeys, out List<StatusBarNotification> notifications, - out boolean[] lightsOn); + out boolean[] switches); void onPanelRevealed(); void onNotificationClick(String pkg, String tag, int id); void onNotificationError(String pkg, String tag, int id, diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml index 494dfa88b727..295c79b72a5d 100644 --- a/packages/SystemUI/res/layout-xlarge/status_bar.xml +++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml @@ -144,6 +144,7 @@ android:paddingLeft="4dip" android:paddingRight="4dip" systemui:keyCode="82" + android:visibility="invisible" /> <ImageButton android:id="@+id/recent" android:layout_width="wrap_content" diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index 81091e3f79ee..c164eb41d1fc 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 @@ public class CommandQueue extends IStatusBar.Stub { 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 class CommandQueue extends IStatusBar.Stub { 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 class CommandQueue extends IStatusBar.Stub { } } + 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 @@ public class CommandQueue extends IStatusBar.Stub { 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 57ebd275e8c6..9fbfc64f4949 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 @@ public class PhoneStatusBarService extends StatusBarService { } } + // 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 695fdbac9b64..5594a47fb7b3 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 @@ public abstract class StatusBarService extends Service implements CommandQueue.C 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 @@ public abstract class StatusBarService extends Service implements CommandQueue.C // 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 0e26f5241678..69e9a94a3078 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 @@ public class TabletStatusBarService extends StatusBarService { View mNotificationButtons; View mSystemInfo; View mNavigationArea; + View mMenuButton; NotificationPanel mNotificationPanel; SystemPanel mSystemPanel; @@ -205,6 +206,7 @@ public class TabletStatusBarService extends StatusBarService { // 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 class TabletStatusBarService extends StatusBarService { } } + 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(); diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index 24c9443ea98e..db5f6c15d323 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -21,6 +21,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; +import static android.view.WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY; import com.android.internal.view.BaseSurfaceHolder; import com.android.internal.view.RootViewSurfaceTaker; @@ -2324,6 +2325,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { setFlags(FLAG_SHOW_WALLPAPER, FLAG_SHOW_WALLPAPER&(~getForcedWindowFlags())); } + if (getContext().getApplicationInfo().targetSdkVersion + < android.os.Build.VERSION_CODES.HONEYCOMB) { + addFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY); + } + WindowManager.LayoutParams params = getAttributes(); if (!hasSoftInputMode()) { diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 449bd4c45741..ec5b09842fa6 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -287,6 +287,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { Intent mDeskDockIntent; boolean mSearchKeyPressed; boolean mConsumeSearchKeyUp; + boolean mShowMenuKey = false; // track FLAG_NEEDS_MENU_KEY on frontmost window // support for activating the lock screen while the screen is on boolean mAllowLockscreenWhenOn; @@ -1603,8 +1604,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { /** {@inheritDoc} */ public int finishAnimationLw() { int changes = 0; - boolean topIsFullscreen = false; + + final WindowManager.LayoutParams lp = (mTopFullscreenOpaqueWindowState != null) + ? mTopFullscreenOpaqueWindowState.getAttrs() + : null; + if (mStatusBar != null) { if (localLOGV) Log.i(TAG, "force=" + mForceStatusBar + " top=" + mTopFullscreenOpaqueWindowState); @@ -1612,7 +1617,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (DEBUG_LAYOUT) Log.v(TAG, "Showing status bar"); if (mStatusBar.showLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT; } else if (mTopFullscreenOpaqueWindowState != null) { - final WindowManager.LayoutParams lp = mTopFullscreenOpaqueWindowState.getAttrs(); if (localLOGV) { Log.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw() + " shown frame: " + mTopFullscreenOpaqueWindowState.getShownFrameLw()); @@ -1637,10 +1641,26 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } } - - if (topIsFullscreen != mTopIsFullscreen) { + + boolean topNeedsMenu = mShowMenuKey; + if (lp != null) { + topNeedsMenu = (lp.flags & WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0; + } + + if (DEBUG_LAYOUT) Log.v(TAG, "Top window " + + (topNeedsMenu ? "needs" : "does not need") + + " the MENU key"); + + final boolean changedFullscreen = (mTopIsFullscreen != topIsFullscreen); + final boolean changedMenu = (topNeedsMenu != mShowMenuKey); + + if (changedFullscreen || changedMenu) { final boolean topIsFullscreenF = topIsFullscreen; + final boolean topNeedsMenuF = topNeedsMenu; + mTopIsFullscreen = topIsFullscreen; + mShowMenuKey = topNeedsMenu; + mHandler.post(new Runnable() { public void run() { if (mStatusBarService == null) { @@ -1654,7 +1674,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { final IStatusBarService sbs = mStatusBarService; if (mStatusBarService != null) { try { - sbs.setActiveWindowIsFullscreen(topIsFullscreenF); + if (changedFullscreen) { + sbs.setActiveWindowIsFullscreen(topIsFullscreenF); + } + if (changedMenu) { + sbs.setMenuKeyVisible(topNeedsMenuF); + } } catch (RemoteException e) { // This should be impossible because we're in the same process. mStatusBarService = null; diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java index b1baec5156f5..66e021463f4c 100644 --- a/services/java/com/android/server/StatusBarManagerService.java +++ b/services/java/com/android/server/StatusBarManagerService.java @@ -72,6 +72,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub // We usually call it lights out mode, but double negatives are annoying boolean mLightsOn = true; + boolean mMenuVisible = false; + private class DisableRecord implements IBinder.DeathRecipient { String pkg; int what; @@ -246,6 +248,32 @@ public class StatusBarManagerService extends IStatusBarService.Stub } } + /** + * Hide or show the on-screen Menu key. Only call this from the window manager, typically in + * response to a window with FLAG_NEEDS_MENU_KEY set. + */ + public void setMenuKeyVisible(final boolean visible) { + enforceStatusBar(); + + if (SPEW) Slog.d(TAG, (visible?"showing":"hiding") + " MENU key"); + + synchronized(mLock) { + if (mMenuVisible != visible) { + mMenuVisible = visible; + mHandler.post(new Runnable() { + public void run() { + if (mBar != null) { + try { + mBar.setMenuKeyVisible(visible); + } catch (RemoteException ex) { + } + } + } + }); + } + } + } + /** * This is used for the automatic version of lights-out mode. Only call this from * the window manager. @@ -317,7 +345,7 @@ public class StatusBarManagerService extends IStatusBarService.Stub // ================================================================================ public void registerStatusBar(IStatusBar bar, StatusBarIconList iconList, List<IBinder> notificationKeys, List<StatusBarNotification> notifications, - boolean lightsOn[]) { + boolean switches[]) { enforceStatusBarService(); Slog.i(TAG, "registerStatusBar bar=" + bar); @@ -332,7 +360,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub } } synchronized (mLock) { - lightsOn[0] = mLightsOn; + switches[0] = mLightsOn; + switches[1] = mMenuVisible; } } |