diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 713bb9108c8ae..ba94ab26e0448 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -565,7 +565,7 @@ public abstract class WallpaperService extends Service {
mLayout.windowAnimations =
com.android.internal.R.style.Animation_Wallpaper;
mInputChannel = new InputChannel();
- if (mSession.add(mWindow, mLayout, View.VISIBLE, mContentInsets,
+ if (mSession.add(mWindow, mWindow.mSeq, mLayout, View.VISIBLE, mContentInsets,
mInputChannel) < 0) {
Log.w(TAG, "Failed to add window while updating wallpaper surface.");
return;
@@ -580,7 +580,7 @@ public abstract class WallpaperService extends Service {
mDrawingAllowed = true;
final int relayoutResult = mSession.relayout(
- mWindow, mLayout, mWidth, mHeight,
+ mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
View.VISIBLE, false, mWinFrame, mContentInsets,
mVisibleInsets, mConfiguration, mSurfaceHolder.mSurface);
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index 0e482d6046ab4..715fa7b4eacb4 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -74,5 +74,6 @@ oneway interface IWindow {
/**
* System chrome visibility changes
*/
- void dispatchSystemUiVisibilityChanged(int visibility);
+ void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility,
+ int localValue, int localChanges);
}
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 990af083d859d..282d7be6d9fbb 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -34,10 +34,10 @@ import android.view.Surface;
* {@hide}
*/
interface IWindowSession {
- int add(IWindow window, in WindowManager.LayoutParams attrs,
+ int add(IWindow window, int seq, in WindowManager.LayoutParams attrs,
in int viewVisibility, out Rect outContentInsets,
out InputChannel outInputChannel);
- int addWithoutInputChannel(IWindow window, in WindowManager.LayoutParams attrs,
+ int addWithoutInputChannel(IWindow window, int seq, in WindowManager.LayoutParams attrs,
in int viewVisibility, out Rect outContentInsets);
void remove(IWindow window);
@@ -49,6 +49,7 @@ interface IWindowSession {
* to draw the window's contents.
*
* @param window The window being modified.
+ * @param seq Ordering sequence number.
* @param attrs If non-null, new attributes to apply to the window.
* @param requestedWidth The width the window wants to be.
* @param requestedHeight The height the window wants to be.
@@ -77,7 +78,7 @@ interface IWindowSession {
* @return int Result flags: {@link WindowManagerImpl#RELAYOUT_SHOW_FOCUS},
* {@link WindowManagerImpl#RELAYOUT_FIRST_TIME}.
*/
- int relayout(IWindow window, in WindowManager.LayoutParams attrs,
+ int relayout(IWindow window, int seq, in WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewVisibility,
boolean insetsPending, out Rect outFrame, out Rect outContentInsets,
out Rect outVisibleInsets, out Configuration outConfig,
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index cbdb38e3181a4..9a57ea0679c44 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -266,7 +266,7 @@ public class SurfaceView extends View {
try {
DisplayMetrics metrics = getResources().getDisplayMetrics();
mLayout.x = metrics.widthPixels * 3;
- mSession.relayout(mWindow, mLayout, mWidth, mHeight, VISIBLE, false,
+ mSession.relayout(mWindow, mWindow.mSeq, mLayout, mWidth, mHeight, VISIBLE, false,
mWinFrame, mContentInsets, mVisibleInsets, mConfiguration, mSurface);
} catch (RemoteException e) {
// Ignore
@@ -492,7 +492,7 @@ public class SurfaceView extends View {
mWindow = new MyWindow(this);
mLayout.type = mWindowType;
mLayout.gravity = Gravity.LEFT|Gravity.TOP;
- mSession.addWithoutInputChannel(mWindow, mLayout,
+ mSession.addWithoutInputChannel(mWindow, mWindow.mSeq, mLayout,
mVisible ? VISIBLE : GONE, mContentInsets);
}
@@ -513,7 +513,7 @@ public class SurfaceView extends View {
mDrawingStopped = !visible;
final int relayoutResult = mSession.relayout(
- mWindow, mLayout, mWidth, mHeight,
+ mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
visible ? VISIBLE : GONE, false, mWinFrame, mContentInsets,
mVisibleInsets, mConfiguration, mSurface);
if ((relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 43654d2e601a4..15544ccc4887d 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1924,6 +1924,15 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
*/
public static final int PUBLIC_STATUS_BAR_VISIBILITY_MASK = 0x0000FFFF;
+ /**
+ * These are the system UI flags that can be cleared by events outside
+ * of an application. Currently this is just the ability to tap on the
+ * screen while hiding the navigation bar to have it return.
+ * @hide
+ */
+ public static final int SYSTEM_UI_CLEARABLE_FLAGS =
+ SYSTEM_UI_FLAG_LOW_PROFILE | SYSTEM_UI_FLAG_HIDE_NAVIGATION;
+
/**
* Find views that render the specified text.
*
@@ -13019,6 +13028,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
/**
+ * Dispatch callbacks to {@link #setOnSystemUiVisibilityChangeListener} down
+ * the view hierarchy.
*/
public void dispatchSystemUiVisibilityChanged(int visibility) {
if (mOnSystemUiVisibilityChangeListener != null) {
@@ -13027,6 +13038,13 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
}
}
+ void updateLocalSystemUiVisibility(int localValue, int localChanges) {
+ int val = (mSystemUiVisibility&~localChanges) | (localValue&localChanges);
+ if (val != mSystemUiVisibility) {
+ setSystemUiVisibility(val);
+ }
+ }
+
/**
* Creates an image that the system displays during the drag and drop
* operation. This is called a "drag shadow". The default implementation
@@ -14100,7 +14118,8 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
/**
* Interface definition for a callback to be invoked when the status bar changes
- * visibility.
+ * visibility. This reports global changes to the system UI
+ * state, not just what the application is requesting.
*
* @see View#setOnSystemUiVisibilityChangeListener(android.view.View.OnSystemUiVisibilityChangeListener)
*/
@@ -14110,7 +14129,9 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
* {@link View#setSystemUiVisibility(int)}.
*
* @param visibility Bitwise-or of flags {@link #SYSTEM_UI_FLAG_LOW_PROFILE} or
- * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}.
+ * {@link #SYSTEM_UI_FLAG_HIDE_NAVIGATION}. This tells you the
+ * global state of the UI visibility flags, not what your
+ * app is currently applying.
*/
public void onSystemUiVisibilityChange(int visibility);
}
@@ -14367,6 +14388,11 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
*/
boolean mRecomputeGlobalAttributes;
+ /**
+ * Always report new attributes at next traversal.
+ */
+ boolean mForceReportNewAttributes;
+
/**
* Set during a traveral if any views want to keep the screen on.
*/
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 5b4a6f8a78e62..9266ae25bcdd4 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -1200,6 +1200,18 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
}
+ @Override
+ void updateLocalSystemUiVisibility(int localValue, int localChanges) {
+ super.updateLocalSystemUiVisibility(localValue, localChanges);
+
+ final int count = mChildrenCount;
+ final View[] children = mChildren;
+ for (int i=0; i >>>>> ENTERED relayout from "
+ Binder.getCallingPid());
- int res = mService.relayoutWindow(this, window, attrs,
+ int res = mService.relayoutWindow(this, window, seq, attrs,
requestedWidth, requestedHeight, viewFlags, insetsPending,
outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
if (false) Slog.d(WindowManagerService.TAG, "<<<<<< EXITING relayout to "
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index f1994d1667257..540c51894758e 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -1948,7 +1948,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- public int addWindow(Session session, IWindow client,
+ public int addWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int viewVisibility,
Rect outContentInsets, InputChannel outInputChannel) {
int res = mPolicy.checkAddPermission(attrs);
@@ -2040,7 +2040,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
win = new WindowState(this, session, client, token,
- attachedWindow, attrs, viewVisibility);
+ attachedWindow, seq, attrs, viewVisibility);
if (win.mDeathRecipient == null) {
// Client has apparently died, so there is no reason to
// continue.
@@ -2467,7 +2467,7 @@ public class WindowManagerService extends IWindowManager.Stub
return null;
}
- public int relayoutWindow(Session session, IWindow client,
+ public int relayoutWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int requestedWidth,
int requestedHeight, int viewVisibility, boolean insetsPending,
Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
@@ -2477,13 +2477,13 @@ public class WindowManagerService extends IWindowManager.Stub
boolean configChanged;
// if they don't have this permission, mask out the status bar bits
+ int systemUiVisibility = 0;
if (attrs != null) {
- if (((attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility)
- & StatusBarManager.DISABLE_MASK) != 0) {
+ systemUiVisibility = (attrs.systemUiVisibility|attrs.subtreeSystemUiVisibility);
+ if ((systemUiVisibility & StatusBarManager.DISABLE_MASK) != 0) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
!= PackageManager.PERMISSION_GRANTED) {
- attrs.systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
- attrs.subtreeSystemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
+ systemUiVisibility &= ~StatusBarManager.DISABLE_MASK;
}
}
}
@@ -2496,6 +2496,9 @@ public class WindowManagerService extends IWindowManager.Stub
}
win.mRequestedWidth = requestedWidth;
win.mRequestedHeight = requestedHeight;
+ if (attrs != null && seq == win.mSeq) {
+ win.mSystemUiVisibility = systemUiVisibility;
+ }
if (attrs != null) {
mPolicy.adjustWindowParamsLw(attrs);
@@ -9095,13 +9098,27 @@ public class WindowManagerService extends IWindowManager.Stub
@Override
public void statusBarVisibilityChanged(int visibility) {
mInputManager.setSystemUiVisibility(visibility);
+
synchronized (mWindowMap) {
final int N = mWindows.size();
for (int i = 0; i < N; i++) {
WindowState ws = mWindows.get(i);
try {
- if (ws.getAttrs().hasSystemUiListeners) {
- ws.mClient.dispatchSystemUiVisibilityChanged(visibility);
+ int curValue = ws.mSystemUiVisibility;
+ int diff = curValue ^ visibility;
+ // We are only interested in differences of one of the
+ // clearable flags...
+ diff &= View.SYSTEM_UI_CLEARABLE_FLAGS;
+ // ...if it has actually been cleared.
+ diff &= ~visibility;
+ int newValue = (curValue&~diff) | (visibility&diff);
+ if (newValue != curValue) {
+ ws.mSeq++;
+ ws.mSystemUiVisibility = newValue;
+ }
+ if (newValue != curValue || ws.mAttrs.hasSystemUiListeners) {
+ ws.mClient.dispatchSystemUiVisibilityChanged(ws.mSeq,
+ visibility, newValue, diff);
}
} catch (RemoteException e) {
// so sorry
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 3640a15284b2d..47f74fb4a676e 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -76,8 +76,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
final boolean mIsImWindow;
final boolean mIsWallpaper;
final boolean mIsFloatingLayer;
+ int mSeq;
boolean mEnforceSizeCompat;
int mViewVisibility;
+ int mSystemUiVisibility;
boolean mPolicyVisibility = true;
boolean mPolicyVisibilityAfterAnim = true;
boolean mAppFreezing;
@@ -282,7 +284,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
boolean mWasPaused;
WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
- WindowState attachedWindow, WindowManager.LayoutParams a,
+ WindowState attachedWindow, int seq, WindowManager.LayoutParams a,
int viewVisibility) {
mService = service;
mSession = s;
@@ -292,6 +294,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
mViewVisibility = viewVisibility;
DeathRecipient deathRecipient = new DeathRecipient();
mAlpha = a.alpha;
+ mSeq = seq;
mEnforceSizeCompat = (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0;
if (WindowManagerService.localLOGV) Slog.v(
WindowManagerService.TAG, "Window " + this + " client=" + c.asBinder()
@@ -551,6 +554,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
return mAttrs;
}
+ public int getSystemUiVisibility() {
+ return mSystemUiVisibility;
+ }
+
public int getSurfaceLayer() {
return mLayer;
}
@@ -1597,6 +1604,9 @@ final class WindowState implements WindowManagerPolicy.WindowState {
pw.print(" mLastHidden="); pw.print(mLastHidden);
pw.print(" mHaveFrame="); pw.print(mHaveFrame);
pw.print(" mObscured="); pw.println(mObscured);
+ pw.print(prefix); pw.print("mSeq="); pw.print(mSeq);
+ pw.print(" mSystemUiVisibility=0x");
+ pw.println(Integer.toHexString(mSystemUiVisibility));
}
if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
pw.print(prefix); pw.print("mPolicyVisibility=");
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
index 8e673adc77f14..e13380e7e2ddb 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java
@@ -85,7 +85,8 @@ public final class BridgeWindow implements IWindow {
// pass for now.
}
- public void dispatchSystemUiVisibilityChanged(int visibility) {
+ public void dispatchSystemUiVisibilityChanged(int seq, int globalUi,
+ int localValue, int localChanges) {
// pass for now.
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
index ab8c4ec75152f..1d97e1506866c 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java
@@ -37,14 +37,14 @@ import android.view.WindowManager.LayoutParams;
*/
public final class BridgeWindowSession implements IWindowSession {
- public int add(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3,
+ public int add(IWindow arg0, int seq, LayoutParams arg1, int arg2, Rect arg3,
InputChannel outInputchannel)
throws RemoteException {
// pass for now.
return 0;
}
- public int addWithoutInputChannel(IWindow arg0, LayoutParams arg1, int arg2, Rect arg3)
+ public int addWithoutInputChannel(IWindow arg0, int seq, LayoutParams arg1, int arg2, Rect arg3)
throws RemoteException {
// pass for now.
return 0;
@@ -78,7 +78,7 @@ public final class BridgeWindowSession implements IWindowSession {
return null;
}
- public int relayout(IWindow arg0, LayoutParams arg1, int arg2, int arg3, int arg4,
+ public int relayout(IWindow arg0, int seq, LayoutParams arg1, int arg2, int arg3, int arg4,
boolean arg4_5, Rect arg5, Rect arg6, Rect arg7, Configuration arg7b, Surface arg8)
throws RemoteException {
// pass for now.