summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2011-10-06 11:51:27 -0700
committerDianne Hackborn <hackbod@google.com>2011-10-06 14:57:37 -0700
commit9a230e01a1237749a8a19a5de8d46531b0c8ca6a (patch)
treec62734c0dcd00cc9add7c70bd60e8946e0915735
parentfe7fcd23d5b306db7b1fb31c901cbcbb6b66db1d (diff)
downloadframeworks_base-9a230e01a1237749a8a19a5de8d46531b0c8ca6a.zip
frameworks_base-9a230e01a1237749a8a19a5de8d46531b0c8ca6a.tar.gz
frameworks_base-9a230e01a1237749a8a19a5de8d46531b0c8ca6a.tar.bz2
Fix issue #5371530: SYSTEMUI_FLAG_HIDE_NAVIGATION reasserts itself immediately
This cleans up how ui flags are managed between the client and window manager. It still reports the global UI mode state to the callback, but we now only clear certain flags when the system goes out of a state (currently this just means the hide nav bar mode), and don't corrupt other flags in the application when the global state changes. Also introduces a sequence number between the app and window manager, to avoid using bad old data coming from the app during these transitions. Change-Id: I40bbd12d9b7b69fc0ff1c7dc0cb58a933d4dfb23
-rw-r--r--core/java/android/service/wallpaper/WallpaperService.java4
-rw-r--r--core/java/android/view/IWindow.aidl3
-rw-r--r--core/java/android/view/IWindowSession.aidl7
-rw-r--r--core/java/android/view/SurfaceView.java6
-rw-r--r--core/java/android/view/View.java30
-rw-r--r--core/java/android/view/ViewGroup.java12
-rw-r--r--core/java/android/view/ViewRootImpl.java65
-rw-r--r--core/java/android/view/WindowManagerPolicy.java6
-rw-r--r--core/java/com/android/internal/view/BaseIWindow.java5
-rwxr-xr-xpolicy/src/com/android/internal/policy/impl/PhoneWindowManager.java3
-rw-r--r--services/java/com/android/server/wm/Session.java12
-rw-r--r--services/java/com/android/server/wm/WindowManagerService.java35
-rw-r--r--services/java/com/android/server/wm/WindowState.java12
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindow.java3
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowSession.java6
15 files changed, 160 insertions, 49 deletions
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 713bb91..ba94ab2 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 0e482d6..715fa7b 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 990af08..282d7be 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 cbdb38e..9a57ea0 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 8e5aefd..c7507f8 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1925,6 +1925,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.
*
* @see #findViewsWithText(ArrayList, CharSequence, int)
@@ -13027,6 +13036,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) {
@@ -13035,6 +13046,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 &quot;drag shadow&quot;. The default implementation
@@ -14108,7 +14126,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 <strong>global</strong> changes to the system UI
+ * state, not just what the application is requesting.
*
* @see View#setOnSystemUiVisibilityChangeListener(android.view.View.OnSystemUiVisibilityChangeListener)
*/
@@ -14118,7 +14137,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
+ * <strong>global</strong> state of the UI visibility flags, not what your
+ * app is currently applying.
*/
public void onSystemUiVisibilityChange(int visibility);
}
@@ -14376,6 +14397,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.
*/
boolean mKeepScreenOn;
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 5b4a6f8..9266ae2 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 <count; i++) {
+ final View child = children[i];
+ child.updateLocalSystemUiVisibility(localValue, localChanges);
+ }
+ }
+
/**
* {@inheritDoc}
*/
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index e7c91f9..bc60b44 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -165,6 +165,8 @@ public final class ViewRootImpl extends Handler implements ViewParent,
final int mTargetSdkVersion;
+ int mSeq;
+
View mView;
View mFocusedView;
View mRealFocusedView; // this is not set to null in touch mode
@@ -308,6 +310,13 @@ public final class ViewRootImpl extends Handler implements ViewParent,
return sWindowSession;
}
}
+
+ static final class SystemUiVisibilityInfo {
+ int seq;
+ int globalVisibility;
+ int localValue;
+ int localChanges;
+ }
public ViewRootImpl(Context context) {
super();
@@ -465,7 +474,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
}
try {
mOrigWindowType = mWindowAttributes.type;
- res = sWindowSession.add(mWindow, mWindowAttributes,
+ res = sWindowSession.add(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mAttachInfo.mContentInsets,
mInputChannel);
} catch (RemoteException e) {
@@ -1045,16 +1054,21 @@ public final class ViewRootImpl extends Handler implements ViewParent,
attachInfo.mRecomputeGlobalAttributes = false;
boolean oldScreenOn = attachInfo.mKeepScreenOn;
int oldVis = attachInfo.mSystemUiVisibility;
+ boolean oldHasSystemUiListeners = attachInfo.mHasSystemUiListeners;
attachInfo.mKeepScreenOn = false;
attachInfo.mSystemUiVisibility = 0;
attachInfo.mHasSystemUiListeners = false;
host.dispatchCollectViewAttributes(0);
if (attachInfo.mKeepScreenOn != oldScreenOn
|| attachInfo.mSystemUiVisibility != oldVis
- || attachInfo.mHasSystemUiListeners) {
+ || attachInfo.mHasSystemUiListeners != oldHasSystemUiListeners) {
params = lp;
}
}
+ if (attachInfo.mForceReportNewAttributes) {
+ attachInfo.mForceReportNewAttributes = false;
+ params = lp;
+ }
if (mFirst || attachInfo.mViewVisibilityChanged) {
attachInfo.mViewVisibilityChanged = false;
@@ -1136,9 +1150,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
params.flags |= WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
}
params.subtreeSystemUiVisibility = attachInfo.mSystemUiVisibility;
- params.hasSystemUiListeners = attachInfo.mHasSystemUiListeners
- || params.subtreeSystemUiVisibility != 0
- || params.systemUiVisibility != 0;
+ params.hasSystemUiListeners = attachInfo.mHasSystemUiListeners;
}
if (DEBUG_LAYOUT) {
Log.i(TAG, "host=w:" + host.getMeasuredWidth() + ", h:" +
@@ -2545,7 +2557,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
handleDragEvent(event);
} break;
case DISPATCH_SYSTEM_UI_VISIBILITY: {
- handleDispatchSystemUiVisibilityChanged(msg.arg1);
+ handleDispatchSystemUiVisibilityChanged((SystemUiVisibilityInfo)msg.obj);
} break;
case UPDATE_CONFIGURATION: {
Configuration config = (Configuration)msg.obj;
@@ -3429,12 +3441,27 @@ public final class ViewRootImpl extends Handler implements ViewParent,
event.recycle();
}
- public void handleDispatchSystemUiVisibilityChanged(int visibility) {
+ public void handleDispatchSystemUiVisibilityChanged(SystemUiVisibilityInfo args) {
+ if (mSeq != args.seq) {
+ // The sequence has changed, so we need to update our value and make
+ // sure to do a traversal afterward so the window manager is given our
+ // most recent data.
+ mSeq = args.seq;
+ mAttachInfo.mForceReportNewAttributes = true;
+ scheduleTraversals();
+ }
if (mView == null) return;
- if (mAttachInfo != null) {
- mAttachInfo.mSystemUiVisibility = visibility;
+ if (args.localChanges != 0) {
+ if (mAttachInfo != null) {
+ mAttachInfo.mSystemUiVisibility =
+ (mAttachInfo.mSystemUiVisibility&~args.localChanges)
+ | (args.localValue&args.localChanges);
+ }
+ mView.updateLocalSystemUiVisibility(args.localValue, args.localChanges);
+ mAttachInfo.mRecomputeGlobalAttributes = true;
+ scheduleTraversals();
}
- mView.dispatchSystemUiVisibilityChanged(visibility);
+ mView.dispatchSystemUiVisibilityChanged(args.globalVisibility);
}
public void getLastTouchPoint(Point outLocation) {
@@ -3493,7 +3520,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
}
}
int relayoutResult = sWindowSession.relayout(
- mWindow, params,
+ mWindow, mSeq, params,
(int) (mView.getMeasuredWidth() * appScale + 0.5f),
(int) (mView.getMeasuredHeight() * appScale + 0.5f),
viewVisibility, insetsPending, mWinFrame,
@@ -3796,8 +3823,14 @@ public final class ViewRootImpl extends Handler implements ViewParent,
sendMessage(msg);
}
- public void dispatchSystemUiVisibilityChanged(int visibility) {
- sendMessage(obtainMessage(DISPATCH_SYSTEM_UI_VISIBILITY, visibility, 0));
+ public void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility,
+ int localValue, int localChanges) {
+ SystemUiVisibilityInfo args = new SystemUiVisibilityInfo();
+ args.seq = seq;
+ args.globalVisibility = globalVisibility;
+ args.localValue = localValue;
+ args.localChanges = localChanges;
+ sendMessage(obtainMessage(DISPATCH_SYSTEM_UI_VISIBILITY, args));
}
/**
@@ -4052,10 +4085,12 @@ public final class ViewRootImpl extends Handler implements ViewParent,
}
}
- public void dispatchSystemUiVisibilityChanged(int visibility) {
+ public void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility,
+ int localValue, int localChanges) {
final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
- viewAncestor.dispatchSystemUiVisibilityChanged(visibility);
+ viewAncestor.dispatchSystemUiVisibilityChanged(seq, globalVisibility,
+ localValue, localChanges);
}
}
}
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 4f67675..aaf45e5 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -237,6 +237,12 @@ public interface WindowManagerPolicy {
public WindowManager.LayoutParams getAttrs();
/**
+ * Retrieve the current system UI visibility flags associated with
+ * this window.
+ */
+ public int getSystemUiVisibility();
+
+ /**
* Get the layer at which this window's surface will be Z-ordered.
*/
public int getSurfaceLayer();
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index b9948fe..b227700 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -27,6 +27,7 @@ import android.view.IWindowSession;
public class BaseIWindow extends IWindow.Stub {
private IWindowSession mSession;
+ public int mSeq;
public void setSession(IWindowSession session) {
mSession = session;
@@ -69,7 +70,9 @@ public class BaseIWindow extends IWindow.Stub {
public void dispatchDragEvent(DragEvent event) {
}
- public void dispatchSystemUiVisibilityChanged(int visibility) {
+ public void dispatchSystemUiVisibilityChanged(int seq, int globalUi,
+ int localValue, int localChanges) {
+ mSeq = seq;
}
public void dispatchWallpaperCommand(String action, int x, int y,
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index ed67707..8dfa364 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -3497,8 +3497,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// If there is no window focused, there will be nobody to handle the events
// anyway, so just hang on in whatever state we're in until things settle down.
if (mFocusedWindow != null) {
- final WindowManager.LayoutParams params = mFocusedWindow.getAttrs();
- final int visibility = params.systemUiVisibility | params.subtreeSystemUiVisibility;
+ final int visibility = mFocusedWindow.getSystemUiVisibility();
mHandler.post(new Runnable() {
public void run() {
if (mStatusBarService == null) {
diff --git a/services/java/com/android/server/wm/Session.java b/services/java/com/android/server/wm/Session.java
index 2e0c9ab..10882f9 100644
--- a/services/java/com/android/server/wm/Session.java
+++ b/services/java/com/android/server/wm/Session.java
@@ -134,28 +134,28 @@ final class Session extends IWindowSession.Stub
}
}
- public int add(IWindow window, WindowManager.LayoutParams attrs,
+ public int add(IWindow window, int seq, WindowManager.LayoutParams attrs,
int viewVisibility, Rect outContentInsets, InputChannel outInputChannel) {
- return mService.addWindow(this, window, attrs, viewVisibility, outContentInsets,
+ return mService.addWindow(this, window, seq, attrs, viewVisibility, outContentInsets,
outInputChannel);
}
- public int addWithoutInputChannel(IWindow window, WindowManager.LayoutParams attrs,
+ public int addWithoutInputChannel(IWindow window, int seq, WindowManager.LayoutParams attrs,
int viewVisibility, Rect outContentInsets) {
- return mService.addWindow(this, window, attrs, viewVisibility, outContentInsets, null);
+ return mService.addWindow(this, window, seq, attrs, viewVisibility, outContentInsets, null);
}
public void remove(IWindow window) {
mService.removeWindow(this, window);
}
- public int relayout(IWindow window, WindowManager.LayoutParams attrs,
+ public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags,
boolean insetsPending, Rect outFrame, Rect outContentInsets,
Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
if (false) Slog.d(WindowManagerService.TAG, ">>>>>> 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 8e98ec4..f8525ad 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);
@@ -9088,13 +9091,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 3640a15..47f74fb 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 8e673ad..e13380e 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 ab8c4ec..1d97e15 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.