summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/util/MergedConfiguration.java15
-rw-r--r--core/java/android/view/ViewRootImpl.java25
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java15
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java40
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java3
5 files changed, 61 insertions, 37 deletions
diff --git a/core/java/android/util/MergedConfiguration.java b/core/java/android/util/MergedConfiguration.java
index 68d0309cfc9e..ae6605043b2e 100644
--- a/core/java/android/util/MergedConfiguration.java
+++ b/core/java/android/util/MergedConfiguration.java
@@ -161,6 +161,21 @@ public class MergedConfiguration implements Parcelable {
return "{mGlobalConfig=" + mGlobalConfig + " mOverrideConfig=" + mOverrideConfig + "}";
}
+ @Override
+ public int hashCode() {
+ return mMergedConfig.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object that) {
+ if (!(that instanceof MergedConfiguration)) {
+ return false;
+ }
+
+ if (that == this) return true;
+ return mMergedConfig.equals(((MergedConfiguration) that).mMergedConfig);
+ }
+
public void dump(PrintWriter pw, String prefix) {
pw.println(prefix + "mGlobalConfig=" + mGlobalConfig);
pw.println(prefix + "mOverrideConfig=" + mOverrideConfig);
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index e27eab92319b..e38a55f76b7d 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -1904,14 +1904,16 @@ public final class ViewRootImpl implements ViewParent,
+ " outsets=" + mPendingOutsets.toShortString()
+ " surface=" + mSurface);
- final Configuration pendingMergedConfig =
- mPendingMergedConfiguration.getMergedConfiguration();
- if (pendingMergedConfig.seq != 0) {
+ // If the pending {@link MergedConfiguration} handed back from
+ // {@link #relayoutWindow} does not match the one last reported,
+ // WindowManagerService has reported back a frame from a configuration not yet
+ // handled by the client. In this case, we need to accept the configuration so we
+ // do not lay out and draw with the wrong configuration.
+ if (!mPendingMergedConfiguration.equals(mLastReportedMergedConfiguration)) {
if (DEBUG_CONFIGURATION) Log.v(mTag, "Visible with new config: "
- + pendingMergedConfig);
+ + mPendingMergedConfiguration.getMergedConfiguration());
performConfigurationChange(mPendingMergedConfiguration, !mFirst,
INVALID_DISPLAY /* same display */);
- pendingMergedConfig.seq = 0;
updatedConfiguration = true;
}
@@ -3596,6 +3598,13 @@ public final class ViewRootImpl implements ViewParent,
mView.setLayoutDirection(currentLayoutDirection);
}
mView.dispatchConfigurationChanged(config);
+
+ // We could have gotten this {@link Configuration} update after we called
+ // {@link #performTraversals} with an older {@link Configuration}. As a result, our
+ // window frame may be stale. We must ensure the next pass of {@link #performTraversals}
+ // catches this.
+ mForceNextWindowRelayout = true;
+ requestLayout();
}
}
@@ -3757,10 +3766,10 @@ public final class ViewRootImpl implements ViewParent,
SomeArgs args = (SomeArgs) msg.obj;
final int displayId = args.argi3;
- final MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4;
+ MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4;
final boolean displayChanged = mDisplay.getDisplayId() != displayId;
- if (mergedConfiguration != null) {
+ if (!mLastReportedMergedConfiguration.equals(mergedConfiguration)) {
// If configuration changed - notify about that and, maybe, about move to
// display.
performConfigurationChange(mergedConfiguration, false /* force */,
@@ -6094,7 +6103,7 @@ public final class ViewRootImpl implements ViewParent,
if (params != null) {
if (DBG) Log.d(mTag, "WindowLayout in layoutWindow:" + params);
}
- mPendingMergedConfiguration.getMergedConfiguration().seq = 0;
+
//Log.d(mTag, ">>>>>> CALLING relayout");
if (params != null && mOrigWindowType != params.type) {
// For compatibility with old apps, don't crash here.
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index ceddc4e23fe5..613c830f31f2 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -30,7 +30,6 @@ import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.Process.ROOT_UID;
import static android.os.Process.SHELL_UID;
import static android.os.Process.SYSTEM_UID;
-import static android.os.Process.THREAD_PRIORITY_DISPLAY;
import static android.os.Process.myPid;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
import static android.os.UserHandle.USER_NULL;
@@ -50,7 +49,6 @@ import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHA
import static android.view.WindowManager.LayoutParams.LAST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COMPATIBLE_WINDOW;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TASK_SNAPSHOT;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
@@ -233,7 +231,6 @@ import com.android.server.DisplayThread;
import com.android.server.EventLogTags;
import com.android.server.FgThread;
import com.android.server.LocalServices;
-import com.android.server.ThreadPriorityBooster;
import com.android.server.UiThread;
import com.android.server.Watchdog;
import com.android.server.input.InputManagerService;
@@ -2020,8 +2017,7 @@ public class WindowManagerService extends IWindowManager.Stub
win.setDisplayLayoutNeeded();
mWindowPlacerLocked.performSurfacePlacement(true);
}
- result = win.relayoutVisibleWindow(mergedConfiguration, result, attrChanges,
- oldVisibility);
+ result = win.relayoutVisibleWindow(result, attrChanges, oldVisibility);
try {
result = createSurfaceControl(outSurface, result, win, winAnimator);
@@ -2159,6 +2155,15 @@ public class WindowManagerService extends IWindowManager.Stub
if (!win.isGoneForLayoutLw()) {
win.mResizedWhileGone = false;
}
+
+ // We must always send the latest {@link MergedConfiguration}, regardless of whether we
+ // have already reported it. The client might not have processed the previous value yet
+ // and needs process it before handling the corresponding window frame. the variable
+ // {@code mergedConfiguration} is an out parameter that will be passed back to the
+ // client over IPC and checked there.
+ win.getMergedConfiguration(mergedConfiguration);
+ win.setReportedConfiguration(mergedConfiguration);
+
outFrame.set(win.mCompatFrame);
outOverscanInsets.set(win.mOverscanInsets);
outContentInsets.set(win.mContentInsets);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index f74948f8e7f0..d1fbf900ef70 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2207,8 +2207,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
}
- void prepareWindowToDisplayDuringRelayout(MergedConfiguration mergedConfiguration,
- boolean wasVisible) {
+ void prepareWindowToDisplayDuringRelayout(boolean wasVisible) {
// We need to turn on screen regardless of visibility.
if ((mAttrs.flags & FLAG_TURN_SCREEN_ON) != 0) {
if (DEBUG_VISIBILITY) Slog.v(TAG, "Relayout window turning screen on: " + this);
@@ -2230,16 +2229,16 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
if (isDrawnLw() && mService.okToDisplay()) {
mWinAnimator.applyEnterAnimationLocked();
}
+ }
- if (isConfigChanged()) {
- final Configuration globalConfig = mService.mRoot.getConfiguration();
- final Configuration overrideConfig = getMergedOverrideConfiguration();
- mergedConfiguration.setConfiguration(globalConfig, overrideConfig);
- if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this
- + " visible with new global config: " + globalConfig
- + " merged override config: " + overrideConfig);
- mLastReportedConfiguration.setTo(getConfiguration());
- }
+ void getMergedConfiguration(MergedConfiguration outConfiguration) {
+ final Configuration globalConfig = mService.mRoot.getConfiguration();
+ final Configuration overrideConfig = getMergedOverrideConfiguration();
+ outConfiguration.setConfiguration(globalConfig, overrideConfig);
+ }
+
+ void setReportedConfiguration(MergedConfiguration config) {
+ mLastReportedConfiguration.setTo(config.getMergedConfiguration());
}
void adjustStartingWindowFlags() {
@@ -3005,14 +3004,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
try {
if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this
+ ": " + mCompatFrame);
- final MergedConfiguration mergedConfiguration;
- if (isConfigChanged()) {
- mergedConfiguration = new MergedConfiguration(mService.mRoot.getConfiguration(),
- getMergedOverrideConfiguration());
- mLastReportedConfiguration.setTo(mergedConfiguration.getMergedConfiguration());
- } else {
- mergedConfiguration = null;
- }
+ final MergedConfiguration mergedConfiguration =
+ new MergedConfiguration(mService.mRoot.getConfiguration(),
+ getMergedOverrideConfiguration());
+
+ setReportedConfiguration(mergedConfiguration);
+
if (DEBUG_ORIENTATION && mWinAnimator.mDrawState == DRAW_PENDING)
Slog.i(TAG, "Resizing " + this + " WITH DRAW PENDING");
@@ -4342,8 +4339,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return !mLastSurfaceInsets.equals(mAttrs.surfaceInsets);
}
- int relayoutVisibleWindow(MergedConfiguration mergedConfiguration, int result, int attrChanges,
- int oldVisibility) {
+ int relayoutVisibleWindow(int result, int attrChanges, int oldVisibility) {
final boolean wasVisible = isVisibleLw();
result |= (!wasVisible || !isDrawnLw()) ? RELAYOUT_RES_FIRST_TIME : 0;
@@ -4366,7 +4362,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
mWinAnimator.mEnteringAnimation = true;
- prepareWindowToDisplayDuringRelayout(mergedConfiguration, wasVisible);
+ prepareWindowToDisplayDuringRelayout(wasVisible);
if ((attrChanges & FORMAT_CHANGED) != 0) {
// If the format can't be changed in place, preserve the old surface until the app draws
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
index c809c325726f..67db5f4d12dd 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
@@ -218,8 +218,7 @@ public class WindowStateTests extends WindowTestsBase {
root.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
root.mTurnOnScreen = false;
- root.prepareWindowToDisplayDuringRelayout(new MergedConfiguration(),
- wasVisible /*wasVisible*/);
+ root.prepareWindowToDisplayDuringRelayout(wasVisible /*wasVisible*/);
assertTrue(root.mTurnOnScreen);
}
}