diff options
10 files changed, 126 insertions, 34 deletions
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl index 4501bd7..e884af8 100644 --- a/core/java/com/android/internal/statusbar/IStatusBar.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl @@ -30,5 +30,6 @@ oneway interface IStatusBar void disable(int state); void animateExpand(); void animateCollapse(); + void setLightsOn(boolean on); } diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index 2307669..07cc43e 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -30,11 +30,13 @@ interface IStatusBarService void setIcon(String slot, String iconPackage, int iconId, int iconLevel); void setIconVisibility(String slot, boolean visible); void removeIcon(String slot); + void setActiveWindowIsFullscreen(boolean fullscreen); // ---- 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 List<IBinder> notificationKeys, out List<StatusBarNotification> notifications, + out boolean[] lightsOn); void onPanelRevealed(); void onNotificationClick(String pkg, String tag, int id); void onNotificationError(String pkg, String tag, int id, diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index 2c0af65..3ef12f9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -52,6 +52,8 @@ public class CommandQueue extends IStatusBar.Stub { private static final int OP_EXPAND = 1; private static final int OP_COLLAPSE = 2; + private static final int MSG_SET_LIGHTS_ON = 0x00070000; + private StatusBarIconList mList; private Callbacks mCallbacks; private Handler mHandler = new H(); @@ -75,6 +77,7 @@ public class CommandQueue extends IStatusBar.Stub { public void disable(int state); public void animateExpand(); public void animateCollapse(); + public void setLightsOn(boolean on); } public CommandQueue(Callbacks callbacks, StatusBarIconList list) { @@ -143,6 +146,13 @@ public class CommandQueue extends IStatusBar.Stub { } } + public void setLightsOn(boolean on) { + synchronized (mList) { + mHandler.removeMessages(MSG_SET_LIGHTS_ON); + mHandler.obtainMessage(MSG_SET_LIGHTS_ON, on ? 1 : 0, 0, null).sendToTarget(); + } + } + private final class H extends Handler { public void handleMessage(Message msg) { final int what = msg.what & MSG_MASK; @@ -194,6 +204,10 @@ public class CommandQueue extends IStatusBar.Stub { } else { mCallbacks.animateCollapse(); } + break; + case MSG_SET_LIGHTS_ON: + mCallbacks.setLightsOn(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 48243ff..e945981 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java @@ -1011,6 +1011,15 @@ public class PhoneStatusBarService extends StatusBarService { return false; } + public void setLightsOn(boolean on) { + 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(); + } + } + 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 a64c3e7..695fdba 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java @@ -72,12 +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]; try { - mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys, notifications); + mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys, notifications, + lightsOn); } catch (RemoteException ex) { // If the system process isn't there we're doomed anyway. } + setLightsOn(lightsOn[0]); + // Set up the initial icon state int N = iconList.size(); int viewIndex = 0; 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 6f74924..b33af99 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java @@ -56,8 +56,6 @@ public class TabletStatusBarService extends StatusBarService { private static final int MAX_IMAGE_LEVEL = 10000; - - int mIconSize; H mHandler = new H(); @@ -493,6 +491,14 @@ public class TabletStatusBarService extends StatusBarService { mHandler.sendEmptyMessage(H.MSG_CLOSE_SYSTEM_PANEL); } + public void setLightsOn(boolean on) { + //Slog.d(TAG, "setLightsOn on=" + on); + if (!on) { + animateCollapse(); + } + // TODO: implement lights out mode + } + public void notificationIconsClicked(View v) { if (DEBUG) Slog.d(TAG, "clicked notification icons"); mHandler.removeMessages(H.MSG_CLOSE_SYSTEM_PANEL); diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 6e5db2b..7009c65 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -177,6 +177,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { Context mContext; IWindowManager mWindowManager; LocalPowerManager mPowerManager; + IStatusBarService mStatusBarService; Vibrator mVibrator; // Vibrator for giving feedback of orientation changes // Vibrator pattern for haptic feedback of a long press. @@ -263,6 +264,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { static final Rect mTmpVisibleFrame = new Rect(); WindowState mTopFullscreenOpaqueWindowState; + boolean mTopIsFullscreen; boolean mForceStatusBar; boolean mHideLockScreen; boolean mDismissKeyguard; @@ -1555,8 +1557,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { /** {@inheritDoc} */ public int finishAnimationLw() { int changes = 0; - - boolean hiding = false; + + boolean topIsFullscreen = false; if (mStatusBar != null) { if (localLOGV) Log.i(TAG, "force=" + mForceStatusBar + " top=" + mTopFullscreenOpaqueWindowState); @@ -1564,18 +1566,22 @@ 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) { - //Log.i(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw() - // + " shown frame: " + mTopFullscreenOpaqueWindowState.getShownFrameLw()); - //Log.i(TAG, "attr: " + mTopFullscreenOpaqueWindowState.getAttrs()); - WindowManager.LayoutParams lp = - mTopFullscreenOpaqueWindowState.getAttrs(); - boolean hideStatusBar = - (lp.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0; - if (hideStatusBar) { + final WindowManager.LayoutParams lp = mTopFullscreenOpaqueWindowState.getAttrs(); + if (localLOGV) { + Log.d(TAG, "frame: " + mTopFullscreenOpaqueWindowState.getFrameLw() + + " shown frame: " + mTopFullscreenOpaqueWindowState.getShownFrameLw()); + Log.d(TAG, "attr: " + mTopFullscreenOpaqueWindowState.getAttrs() + + " lp.flags=0x" + Integer.toHexString(lp.flags)); + } + topIsFullscreen = (lp.flags & WindowManager.LayoutParams.FLAG_FULLSCREEN) != 0; + // The subtle difference between the window for mTopFullscreenOpaqueWindowState + // and mTopIsFullscreen is that that mTopIsFullscreen is set only if the window + // has the FLAG_FULLSCREEN set. Not sure if there is another way that to be the + // case though. + if (topIsFullscreen) { if (mStatusBarCanHide) { if (DEBUG_LAYOUT) Log.v(TAG, "Hiding status bar"); if (mStatusBar.hideLw(true)) changes |= FINISH_LAYOUT_REDO_LAYOUT; - hiding = true; } else if (localLOGV) { Log.v(TAG, "Preventing status bar from hiding by policy"); } @@ -1586,21 +1592,36 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } - if (changes != 0 && hiding) { - IStatusBarService sbs = IStatusBarService.Stub.asInterface(ServiceManager.getService("statusbar")); - if (sbs != null) { - try { - // Make sure the window shade is hidden. - sbs.collapse(); - } catch (RemoteException e) { - } - } + if (topIsFullscreen != mTopIsFullscreen) { + final boolean topIsFullscreenF = topIsFullscreen; + mTopIsFullscreen = topIsFullscreen; + mHandler.post(new Runnable() { + public void run() { + if (mStatusBarService == null) { + // This is the one that can not go away, but it doesn't come up + // before the window manager does, so don't fail if it doesn't + // exist. This works as long as no fullscreen windows come up + // before the status bar service does. + mStatusBarService = IStatusBarService.Stub.asInterface( + ServiceManager.getService("statusbar")); + } + final IStatusBarService sbs = mStatusBarService; + if (mStatusBarService != null) { + try { + sbs.setActiveWindowIsFullscreen(topIsFullscreenF); + } catch (RemoteException e) { + // This should be impossible because we're in the same process. + mStatusBarService = null; + } + } + } + }); } // Hide the key guard if a visible window explicitly specifies that it wants to be displayed // when the screen is locked if (mKeyguard != null) { - if (localLOGV) Log.v(TAG, "finishLayoutLw::mHideKeyguard="+mHideLockScreen); + if (localLOGV) Log.v(TAG, "finishAnimationLw::mHideKeyguard="+mHideLockScreen); if (mDismissKeyguard && !mKeyguardMediator.isSecure()) { if (mKeyguard.hideLw(true)) { changes |= FINISH_LAYOUT_REDO_LAYOUT diff --git a/services/java/com/android/server/StatusBarManagerService.java b/services/java/com/android/server/StatusBarManagerService.java index 717c309..dc86eeb 100644 --- a/services/java/com/android/server/StatusBarManagerService.java +++ b/services/java/com/android/server/StatusBarManagerService.java @@ -68,6 +68,10 @@ public class StatusBarManagerService extends IStatusBarService.Stub ArrayList<DisableRecord> mDisableRecords = new ArrayList<DisableRecord>(); int mDisabled = 0; + Object mLock = new Object(); + // We usually call it lights out mode, but double negatives are annoying + boolean mLightsOn = true; + private class DisableRecord implements IBinder.DeathRecipient { String pkg; int what; @@ -242,6 +246,30 @@ public class StatusBarManagerService extends IStatusBarService.Stub } } + public void setActiveWindowIsFullscreen(boolean fullscreen) { + // We could get away with a separate permission here, but STATUS_BAR is + // signatureOrSystem which is probably good enough. There is no public API + // for this, so the question is a security issue, not an API compatibility issue. + enforceStatusBar(); + + final boolean lightsOn = !fullscreen; + synchronized (mLock) { + if (mLightsOn != lightsOn) { + mLightsOn = lightsOn; + mHandler.post(new Runnable() { + public void run() { + if (mBar != null) { + try { + mBar.setLightsOn(lightsOn); + } catch (RemoteException ex) { + } + } + } + }); + } + } + } + private void enforceStatusBar() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR, "StatusBarManagerService"); @@ -262,7 +290,8 @@ public class StatusBarManagerService extends IStatusBarService.Stub // Callbacks from the status bar service. // ================================================================================ public void registerStatusBar(IStatusBar bar, StatusBarIconList iconList, - List<IBinder> notificationKeys, List<StatusBarNotification> notifications) { + List<IBinder> notificationKeys, List<StatusBarNotification> notifications, + boolean lightsOn[]) { enforceStatusBarService(); Slog.i(TAG, "registerStatusBar bar=" + bar); @@ -276,6 +305,9 @@ public class StatusBarManagerService extends IStatusBarService.Stub notifications.add(e.getValue()); } } + synchronized (mLock) { + lightsOn[0] = mLightsOn; + } } /** diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index b6a090f..94b010b 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -23,6 +23,7 @@ import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW; import static android.view.WindowManager.LayoutParams.FLAG_DIM_BEHIND; import static android.view.WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS; +import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN; import static android.view.WindowManager.LayoutParams.FLAG_SYSTEM_ERROR; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; @@ -7038,6 +7039,9 @@ public class WindowManagerService extends IWindowManager.Stub frame.right >= mCompatibleScreenFrame.right && frame.bottom >= mCompatibleScreenFrame.bottom; } else { + if ((mAttrs.flags & FLAG_FULLSCREEN) != 0) { + return true; + } return frame.left <= 0 && frame.top <= 0 && frame.right >= screenWidth && frame.bottom >= screenHeight; diff --git a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java index b665d2f..e31711e 100644 --- a/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java +++ b/tests/StatusBar/src/com/android/statusbartest/StatusBarTest.java @@ -60,20 +60,19 @@ public class StatusBarTest extends TestActivity } private Test[] mTests = new Test[] { - new Test("Hide") { + new Test("Hide (FLAG_FULLSCREEN)") { public void run() { Window win = getWindow(); - WindowManager.LayoutParams winParams = win.getAttributes(); - winParams.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN; - win.setAttributes(winParams); + win.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN); + Log.d(TAG, "flags=" + Integer.toHexString(win.getAttributes().flags)); } }, - new Test("Show") { + new Test("Show (~FLAG_FULLSCREEN)") { public void run() { Window win = getWindow(); - WindowManager.LayoutParams winParams = win.getAttributes(); - winParams.flags &= ~WindowManager.LayoutParams.FLAG_FULLSCREEN; - win.setAttributes(winParams); + win.setFlags(0, WindowManager.LayoutParams.FLAG_FULLSCREEN); + Log.d(TAG, "flags=" + Integer.toHexString(win.getAttributes().flags)); } }, new Test("Immersive: Enter") { |