summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Sandler <dsandler@google.com>2010-10-08 15:13:22 -0400
committerDaniel Sandler <dsandler@google.com>2010-10-13 16:25:43 -0400
commite02d808abf370965c3c4e4d38af11bc69110fde2 (patch)
tree78e681d5f884ee5fd9a75f297b6c0384e6542a2c
parent3f703de0fbc4a626eacc2973926a99bb8e4fe8e2 (diff)
downloadframeworks_base-e02d808abf370965c3c4e4d38af11bc69110fde2.zip
frameworks_base-e02d808abf370965c3c4e4d38af11bc69110fde2.tar.gz
frameworks_base-e02d808abf370965c3c4e4d38af11bc69110fde2.tar.bz2
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
-rw-r--r--core/java/android/view/WindowManager.java13
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBar.aidl1
-rw-r--r--core/java/com/android/internal/statusbar/IStatusBarService.aidl3
-rw-r--r--packages/SystemUI/res/layout-xlarge/status_bar.xml1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java11
-rw-r--r--policy/src/com/android/internal/policy/impl/PhoneWindow.java6
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java35
-rw-r--r--services/java/com/android/server/StatusBarManagerService.java33
11 files changed, 120 insertions, 12 deletions
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index eddd04e..7cb4671 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 e884af8..34a5b11 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 0763f5e..90f4d48 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 494dfa8..295c79b 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 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 @@ 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 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 @@ 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 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 @@ 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 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 @@ 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 24c9443..db5f6c1 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 449bd4c..ec5b098 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 b1baec5..66e0214 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;
}
}