From 446079600ece83b22cb91865bcbeb694292b0108 Mon Sep 17 00:00:00 2001 From: Andrii Kulian Date: Thu, 16 Mar 2017 11:06:24 -0700 Subject: Separate global and override config sent to client There is some flakiness in View#onConfigurationChanged callback - if ViewRootImpl receives config update earlier than ActivityThread, it may not detect the configuration change and skip inner updates. Also now ViewRootImpl assumes that it receives the global config as a param, but instead it gets merged config from WM. This means that ViewRootImpl#sConfigCallbacks was sending incorrect values to the recipients. This CL switches to sending global and override configuration to the client separately. Also in case if there is a corresponding activity, it first updates it and waits for update callback to ViewRootImpl. This way global config and override config for activity will always be set first and resources will be updated before inner state of ViewRootImpl is updated. Bug: 35870157 Bug: 34164473 Test: android.server.cts.ActivityManagerDisplayTests Test: testOnMovedToDisplayCallback Change-Id: Ic9e7541cf25ecfac6ec90e48f7efb0ece91f657e --- core/java/android/app/ActivityThread.java | 66 ++++--- .../service/wallpaper/WallpaperService.java | 13 +- core/java/android/util/MergedConfiguration.aidl | 19 ++ core/java/android/util/MergedConfiguration.java | 122 ++++++++++++ core/java/android/view/AccessibilityIterators.java | 12 +- core/java/android/view/IWindow.aidl | 6 +- core/java/android/view/IWindowSession.aidl | 14 +- core/java/android/view/ViewRootImpl.java | 215 +++++++++++++++------ .../com/android/internal/view/BaseIWindow.java | 7 +- .../core/java/com/android/server/wm/Session.java | 6 +- .../com/android/server/wm/TaskSnapshotSurface.java | 12 +- .../android/server/wm/WindowManagerService.java | 5 +- .../java/com/android/server/wm/WindowState.java | 39 ++-- .../src/com/android/server/wm/TestIWindow.java | 4 +- .../layoutlib/bridge/android/BridgeWindow.java | 4 +- .../bridge/android/BridgeWindowSession.java | 4 +- 16 files changed, 401 insertions(+), 147 deletions(-) create mode 100644 core/java/android/util/MergedConfiguration.aidl create mode 100644 core/java/android/util/MergedConfiguration.java diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 44cc5b408f50..c6ed0c462219 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -335,6 +335,8 @@ public final class ActivityThread { Configuration overrideConfig; // Used for consolidating configs before sending on to Activity. private Configuration tmpConfig = new Configuration(); + // Callback used for updating activity override config. + ViewRootImpl.ActivityConfigCallback configCallback; ActivityClientRecord nextIdle; ProfilerInfo profilerInfo; @@ -370,6 +372,14 @@ public final class ActivityThread { stopped = false; hideForNow = false; nextIdle = null; + configCallback = (Configuration overrideConfig, int newDisplayId) -> { + if (activity == null) { + throw new IllegalStateException( + "Received config update for non-existing activity"); + } + activity.mMainThread.handleActivityConfigurationChanged( + new ActivityConfigChangeData(token, overrideConfig), newDisplayId); + }; } public boolean isPreHoneycomb() { @@ -3679,6 +3689,12 @@ public final class ActivityThread { if (r.activity.mVisibleFromClient) { r.activity.makeVisible(); } + final ViewRootImpl viewRoot = r.activity.mDecor.getViewRootImpl(); + if (viewRoot != null) { + // TODO: Figure out the best place to set the callback. + // This looks like a place where decor view is already initialized. + viewRoot.setActivityConfigCallback(r.configCallback); + } } if (!r.onlyLocalRequest) { @@ -5027,7 +5043,7 @@ public final class ActivityThread { * @param displayId Id of the display where activity was moved to, -1 if there was no move and * value didn't change. */ - private void handleActivityConfigurationChanged(ActivityConfigChangeData data, int displayId) { + void handleActivityConfigurationChanged(ActivityConfigChangeData data, int displayId) { ActivityClientRecord r = mActivities.get(data.activityToken); // Check input params. if (r == null || r.activity == null) { @@ -5044,6 +5060,7 @@ public final class ActivityThread { // Perform updates. r.overrideConfig = data.overrideConfig; + final ViewRootImpl viewRoot = r.activity.mDecor.getViewRootImpl(); if (movedToDifferentDisplay) { if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity moved to display, activity:" + r.activityInfo.name + ", displayId=" + displayId @@ -5051,13 +5068,15 @@ public final class ActivityThread { performConfigurationChangedForActivity(r, mCompatConfiguration, displayId, true /* movedToDifferentDisplay */); - final ViewRootImpl viewRoot = r.activity.mDecor.getViewRootImpl(); viewRoot.onMovedToDisplay(displayId); } else { if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: " + r.activityInfo.name + ", config=" + data.overrideConfig); performConfigurationChangedForActivity(r, mCompatConfiguration); } + // Notify the ViewRootImpl instance about configuration changes. It may have initiated this + // update to make sure that resources are updated before updating itself. + viewRoot.updateConfiguration(); mSomeActivitiesChanged = true; } @@ -6282,35 +6301,26 @@ public final class ActivityThread { // add dropbox logging to libcore DropBox.setReporter(new DropBoxReporter()); - ViewRootImpl.addConfigCallback(new ComponentCallbacks2() { - @Override - public void onConfigurationChanged(Configuration newConfig) { - synchronized (mResourcesManager) { - // We need to apply this change to the resources - // immediately, because upon returning the view - // hierarchy will be informed about it. - if (mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null)) { - updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(), - mResourcesManager.getConfiguration().getLocales()); - - // This actually changed the resources! Tell - // everyone about it. - if (mPendingConfiguration == null || - mPendingConfiguration.isOtherSeqNewer(newConfig)) { - mPendingConfiguration = newConfig; - - sendMessage(H.CONFIGURATION_CHANGED, newConfig); - } + ViewRootImpl.ConfigChangedCallback configChangedCallback + = (Configuration globalConfig) -> { + synchronized (mResourcesManager) { + // We need to apply this change to the resources immediately, because upon returning + // the view hierarchy will be informed about it. + if (mResourcesManager.applyConfigurationToResourcesLocked(globalConfig, + null /* compat */)) { + updateLocaleListFromAppContext(mInitialApplication.getApplicationContext(), + mResourcesManager.getConfiguration().getLocales()); + + // This actually changed the resources! Tell everyone about it. + if (mPendingConfiguration == null + || mPendingConfiguration.isOtherSeqNewer(globalConfig)) { + mPendingConfiguration = globalConfig; + sendMessage(H.CONFIGURATION_CHANGED, globalConfig); } } } - @Override - public void onLowMemory() { - } - @Override - public void onTrimMemory(int level) { - } - }); + }; + ViewRootImpl.addConfigCallback(configChangedCallback); } public static ActivityThread systemMain() { diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java index 483a49ba1697..6bbb0ff9861b 100644 --- a/core/java/android/service/wallpaper/WallpaperService.java +++ b/core/java/android/service/wallpaper/WallpaperService.java @@ -18,11 +18,11 @@ package android.service.wallpaper; import android.content.res.TypedArray; import android.graphics.Canvas; +import android.util.MergedConfiguration; import android.view.WindowInsets; import com.android.internal.R; import com.android.internal.os.HandlerCaller; -import com.android.internal.util.ScreenShapeHelper; import com.android.internal.view.BaseIWindow; import com.android.internal.view.BaseSurfaceHolder; @@ -32,7 +32,6 @@ import android.app.Service; import android.app.WallpaperManager; import android.content.Context; import android.content.Intent; -import android.content.res.Configuration; import android.graphics.PixelFormat; import android.graphics.Rect; import android.hardware.display.DisplayManager; @@ -55,7 +54,6 @@ import android.view.SurfaceHolder; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; -import android.view.WindowManager.LayoutParams; import android.view.WindowManagerGlobal; import java.io.FileDescriptor; @@ -169,7 +167,7 @@ public abstract class WallpaperService extends Service { final Rect mFinalSystemInsets = new Rect(); final Rect mFinalStableInsets = new Rect(); final Rect mBackdropFrame = new Rect(); - final Configuration mConfiguration = new Configuration(); + final MergedConfiguration mMergedConfiguration = new MergedConfiguration(); final WindowManager.LayoutParams mLayout = new WindowManager.LayoutParams(); @@ -288,7 +286,7 @@ public abstract class WallpaperService extends Service { @Override public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, - Configuration newConfig, Rect backDropRect, boolean forceLayout, + MergedConfiguration mergedConfiguration, Rect backDropRect, boolean forceLayout, boolean alwaysConsumeNavBar, int displayId) { Message msg = mCaller.obtainMessageIO(MSG_WINDOW_RESIZED, reportDraw ? 1 : 0, outsets); @@ -568,7 +566,8 @@ public abstract class WallpaperService extends Service { out.print(mVisibleInsets.toShortString()); out.print(" mWinFrame="); out.print(mWinFrame.toShortString()); out.print(" mContentInsets="); out.println(mContentInsets.toShortString()); - out.print(prefix); out.print("mConfiguration="); out.println(mConfiguration); + out.print(prefix); out.print("mConfiguration="); + out.println(mMergedConfiguration.getMergedConfiguration()); out.print(prefix); out.print("mLayout="); out.println(mLayout); synchronized (mLock) { out.print(prefix); out.print("mPendingXOffset="); out.print(mPendingXOffset); @@ -695,7 +694,7 @@ public abstract class WallpaperService extends Service { mWindow, mWindow.mSeq, mLayout, mWidth, mHeight, View.VISIBLE, 0, mWinFrame, mOverscanInsets, mContentInsets, mVisibleInsets, mStableInsets, mOutsets, mBackdropFrame, - mConfiguration, mSurfaceHolder.mSurface); + mMergedConfiguration, mSurfaceHolder.mSurface); if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface + ", frame=" + mWinFrame); diff --git a/core/java/android/util/MergedConfiguration.aidl b/core/java/android/util/MergedConfiguration.aidl new file mode 100644 index 000000000000..c24dbbec68a6 --- /dev/null +++ b/core/java/android/util/MergedConfiguration.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package android.util; + +parcelable MergedConfiguration; \ No newline at end of file diff --git a/core/java/android/util/MergedConfiguration.java b/core/java/android/util/MergedConfiguration.java new file mode 100644 index 000000000000..d94af8a68fc1 --- /dev/null +++ b/core/java/android/util/MergedConfiguration.java @@ -0,0 +1,122 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package android.util; + +import android.annotation.NonNull; +import android.content.res.Configuration; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Container that holds global and override config and their merge product. + * Merged configuration updates automatically whenever global or override configs are updated via + * setters. + * + * {@hide} + */ +public class MergedConfiguration implements Parcelable { + + private Configuration mGlobalConfig = new Configuration(); + private Configuration mOverrideConfig = new Configuration(); + private Configuration mMergedConfig = new Configuration(); + + public MergedConfiguration() { + } + + public MergedConfiguration(Configuration globalConfig, Configuration overrideConfig) { + setConfiguration(globalConfig, overrideConfig); + } + + public MergedConfiguration(MergedConfiguration mergedConfiguration) { + setConfiguration(mergedConfiguration.getGlobalConfiguration(), + mergedConfiguration.getOverrideConfiguration()); + } + + private MergedConfiguration(Parcel in) { + readFromParcel(in); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelable(mGlobalConfig, flags); + dest.writeParcelable(mOverrideConfig, flags); + dest.writeParcelable(mMergedConfig, flags); + } + + public void readFromParcel(Parcel source) { + mGlobalConfig = source.readParcelable(Configuration.class.getClassLoader()); + mOverrideConfig = source.readParcelable(Configuration.class.getClassLoader()); + mMergedConfig = source.readParcelable(Configuration.class.getClassLoader()); + } + + @Override + public int describeContents() { + return 0; + } + + public static final Creator CREATOR = new Creator() { + @Override + public MergedConfiguration createFromParcel(Parcel in) { + return new MergedConfiguration(in); + } + + @Override + public MergedConfiguration[] newArray(int size) { + return new MergedConfiguration[size]; + } + }; + + /** + * Update global and override configurations. + * Merged configuration will automatically be updated. + * @param globalConfig New global configuration. + * @param overrideConfig New override configuration. + */ + public void setConfiguration(Configuration globalConfig, Configuration overrideConfig) { + mGlobalConfig.setTo(globalConfig); + mOverrideConfig.setTo(overrideConfig); + updateMergedConfig(); + } + + /** + * @return Stored global configuration value. + */ + @NonNull + public Configuration getGlobalConfiguration() { + return mGlobalConfig; + } + + /** + * @return Stored override configuration value. + */ + public Configuration getOverrideConfiguration() { + return mOverrideConfig; + } + + /** + * @return Stored merged configuration value. + */ + public Configuration getMergedConfiguration() { + return mMergedConfig; + } + + /** Update merged config when global or override config changes. */ + private void updateMergedConfig() { + mMergedConfig.setTo(mGlobalConfig); + mMergedConfig.updateFrom(mOverrideConfig); + } +} diff --git a/core/java/android/view/AccessibilityIterators.java b/core/java/android/view/AccessibilityIterators.java index e59937dae055..ca54bef1e780 100644 --- a/core/java/android/view/AccessibilityIterators.java +++ b/core/java/android/view/AccessibilityIterators.java @@ -16,7 +16,6 @@ package android.view; -import android.content.ComponentCallbacks; import android.content.res.Configuration; import java.text.BreakIterator; @@ -65,7 +64,7 @@ public final class AccessibilityIterators { } static class CharacterTextSegmentIterator extends AbstractTextSegmentIterator - implements ComponentCallbacks { + implements ViewRootImpl.ConfigChangedCallback { private static CharacterTextSegmentIterator sInstance; private Locale mLocale; @@ -144,19 +143,14 @@ public final class AccessibilityIterators { } @Override - public void onConfigurationChanged(Configuration newConfig) { - Locale locale = newConfig.locale; + public void onConfigurationChanged(Configuration globalConfig) { + final Locale locale = globalConfig.getLocales().get(0); if (!mLocale.equals(locale)) { mLocale = locale; onLocaleChanged(locale); } } - @Override - public void onLowMemory() { - /* ignore */ - } - protected void onLocaleChanged(Locale locale) { mImpl = BreakIterator.getCharacterInstance(locale); } diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl index 14b2abec2adb..611cc6337fb4 100644 --- a/core/java/android/view/IWindow.aidl +++ b/core/java/android/view/IWindow.aidl @@ -17,7 +17,6 @@ package android.view; -import android.content.res.Configuration; import android.graphics.Rect; import android.os.Bundle; import android.os.ParcelFileDescriptor; @@ -26,6 +25,7 @@ import android.view.KeyEvent; import android.view.MotionEvent; import com.android.internal.os.IResultReceiver; +import android.util.MergedConfiguration; /** * API back to a client window that the Window Manager uses to inform it of @@ -49,8 +49,8 @@ oneway interface IWindow { void resized(in Rect frame, in Rect overscanInsets, in Rect contentInsets, in Rect visibleInsets, in Rect stableInsets, in Rect outsets, boolean reportDraw, - in Configuration newConfig, in Rect backDropFrame, boolean forceLayout, - boolean alwaysConsumeNavBar, int displayId); + in MergedConfiguration newMergedConfiguration, in Rect backDropFrame, + boolean forceLayout, boolean alwaysConsumeNavBar, int displayId); void moved(int newX, int newY); void dispatchAppVisibility(boolean visible); void dispatchGetNewSurface(); diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl index 7e6af11a62c7..51d65144f260 100644 --- a/core/java/android/view/IWindowSession.aidl +++ b/core/java/android/view/IWindowSession.aidl @@ -11,17 +11,17 @@ ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and +** See the License for the specific language governing permissions and ** limitations under the License. */ package android.view; import android.content.ClipData; -import android.content.res.Configuration; import android.graphics.Rect; import android.graphics.Region; import android.os.Bundle; +import android.util.MergedConfiguration; import android.view.InputChannel; import android.view.IWindow; import android.view.IWindowId; @@ -83,9 +83,9 @@ interface IWindowSession { * treat as real display. Example of such area is a chin in some models of wearable devices. * @param outBackdropFrame Rect which is used draw the resizing background during a resize * operation. - * @param outConfiguration New configuration of window, if it is now - * becoming visible and the global configuration has changed since it - * was last displayed. + * @param outMergedConfiguration New config container that holds global, override and merged + * config for window, if it is now becoming visible and the merged configuration has changed + * since it was last displayed. * @param outSurface Object in which is placed the new display surface. * * @return int Result flags: {@link WindowManagerGlobal#RELAYOUT_SHOW_FOCUS}, @@ -95,8 +95,8 @@ interface IWindowSession { int requestedWidth, int requestedHeight, int viewVisibility, int flags, out Rect outFrame, out Rect outOverscanInsets, out Rect outContentInsets, out Rect outVisibleInsets, out Rect outStableInsets, - out Rect outOutsets, out Rect outBackdropFrame, out Configuration outConfig, - out Surface outSurface); + out Rect outOutsets, out Rect outBackdropFrame, + out MergedConfiguration outMergedConfiguration, out Surface outSurface); /* * Notify the window manager that an application is relaunching and diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index ed4238501c5a..048b7c22237c 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -16,6 +16,7 @@ package android.view; +import static android.view.Display.INVALID_DISPLAY; import static android.view.View.PFLAG_DRAW_ANIMATION; import static android.view.WindowCallbacks.RESIZE_MODE_DOCKED_DIVIDER; import static android.view.WindowCallbacks.RESIZE_MODE_FREEFORM; @@ -28,10 +29,10 @@ import android.Manifest; import android.animation.LayoutTransition; import android.annotation.NonNull; import android.app.ActivityManager; +import android.app.ActivityThread; import android.app.ResourcesManager; import android.content.ClipData; import android.content.ClipDescription; -import android.content.ComponentCallbacks; import android.content.Context; import android.content.pm.PackageManager; import android.content.res.CompatibilityInfo; @@ -67,6 +68,7 @@ import android.os.Trace; import android.util.AndroidRuntimeException; import android.util.DisplayMetrics; import android.util.Log; +import android.util.MergedConfiguration; import android.util.Slog; import android.util.TimeUtils; import android.util.TypedValue; @@ -161,7 +163,44 @@ public final class ViewRootImpl implements ViewParent, static final ArrayList sFirstDrawHandlers = new ArrayList(); static boolean sFirstDrawComplete = false; - static final ArrayList sConfigCallbacks = new ArrayList(); + /** + * Callback for notifying about global configuration changes. + */ + public interface ConfigChangedCallback { + + /** Notifies about global config change. */ + void onConfigurationChanged(Configuration globalConfig); + } + + private static final ArrayList sConfigCallbacks = new ArrayList<>(); + + /** + * Callback for notifying activities about override configuration changes. + */ + public interface ActivityConfigCallback { + + /** + * Notifies about override config change and/or move to different display. + * @param overrideConfig New override config to apply to activity. + * @param newDisplayId New display id, {@link Display#INVALID_DISPLAY} if not changed. + */ + void onConfigurationChanged(Configuration overrideConfig, int newDisplayId); + } + + /** + * Callback used to notify corresponding activity about override configuration change and make + * sure that all resources are set correctly before updating the ViewRootImpl's internal state. + */ + private ActivityConfigCallback mActivityConfigCallback; + + /** + * Used when configuration change first updates the config of corresponding activity. + * In that case we receive a call back from {@link ActivityThread} and this flag is used to + * preserve the initial value. + * + * @see #performConfigurationChange(Configuration, Configuration, boolean, int) + */ + private boolean mForceNextConfigUpdate; /** * Signals that compatibility booleans have been initialized according to @@ -344,8 +383,12 @@ public final class ViewRootImpl implements ViewParent, private WindowInsets mLastWindowInsets; - final Configuration mLastConfiguration = new Configuration(); - final Configuration mPendingConfiguration = new Configuration(); + /** Last applied configuration obtained from resources. */ + private final Configuration mLastConfigurationFromResources = new Configuration(); + /** Last configuration reported from WM or via {@link #MSG_UPDATE_CONFIGURATION}. */ + private final MergedConfiguration mLastReportedMergedConfiguration = new MergedConfiguration(); + /** Configurations waiting to be applied. */ + private final MergedConfiguration mPendingMergedConfiguration = new MergedConfiguration(); boolean mScrollMayChange; @SoftInputModeFlags @@ -480,12 +523,18 @@ public final class ViewRootImpl implements ViewParent, } } - public static void addConfigCallback(ComponentCallbacks callback) { + /** Add static config callback to be notified about global config changes. */ + public static void addConfigCallback(ConfigChangedCallback callback) { synchronized (sConfigCallbacks) { sConfigCallbacks.add(callback); } } + /** Add activity config callback to be notified about override config changes. */ + public void setActivityConfigCallback(ActivityConfigCallback callback) { + mActivityConfigCallback = callback; + } + public void addWindowCallbacks(WindowCallbacks callback) { if (USE_MT_RENDERER) { synchronized (mWindowCallbacks) { @@ -1558,6 +1607,7 @@ public final class ViewRootImpl implements ViewParent, mFullRedrawNeeded = true; mLayoutRequested = true; + final Configuration config = mContext.getResources().getConfiguration(); if (shouldUseDisplaySize(lp)) { // NOTE -- system code, won't try to do compat mode. Point size = new Point(); @@ -1565,7 +1615,6 @@ public final class ViewRootImpl implements ViewParent, desiredWindowWidth = size.x; desiredWindowHeight = size.y; } else { - Configuration config = mContext.getResources().getConfiguration(); desiredWindowWidth = dipToPx(config.screenWidthDp); desiredWindowHeight = dipToPx(config.screenHeightDp); } @@ -1577,11 +1626,11 @@ public final class ViewRootImpl implements ViewParent, mAttachInfo.mHasWindowFocus = false; mAttachInfo.mWindowVisibility = viewVisibility; mAttachInfo.mRecomputeGlobalAttributes = false; - mLastConfiguration.setTo(host.getResources().getConfiguration()); + mLastConfigurationFromResources.setTo(config); mLastSystemUiVisibility = mAttachInfo.mSystemUiVisibility; // Set the layout direction if it has not been set before (inherit is the default) if (mViewLayoutDirectionInitial == View.LAYOUT_DIRECTION_INHERIT) { - host.setLayoutDirection(mLastConfiguration.getLayoutDirection()); + host.setLayoutDirection(config.getLayoutDirection()); } host.dispatchAttachedToWindow(mAttachInfo, 0); mAttachInfo.mTreeObserver.dispatchOnWindowAttachedChange(true); @@ -1826,11 +1875,14 @@ public final class ViewRootImpl implements ViewParent, + " outsets=" + mPendingOutsets.toShortString() + " surface=" + mSurface); - if (mPendingConfiguration.seq != 0) { + final Configuration pendingMergedConfig = + mPendingMergedConfiguration.getMergedConfiguration(); + if (pendingMergedConfig.seq != 0) { if (DEBUG_CONFIGURATION) Log.v(mTag, "Visible with new config: " - + mPendingConfiguration); - updateConfiguration(new Configuration(mPendingConfiguration), !mFirst); - mPendingConfiguration.seq = 0; + + pendingMergedConfig); + performConfigurationChange(mPendingMergedConfiguration, !mFirst, + INVALID_DISPLAY /* same display */); + pendingMergedConfig.seq = 0; updatedConfiguration = true; } @@ -3388,43 +3440,82 @@ public final class ViewRootImpl implements ViewParent, unscheduleTraversals(); } - void updateConfiguration(Configuration config, boolean force) { + /** + * Notifies all callbacks that configuration and/or display has changed and updates internal + * state. + * @param mergedConfiguration New global and override config in {@link MergedConfiguration} + * container. + * @param force Flag indicating if we should force apply the config. + * @param newDisplayId Id of new display if moved, {@link Display#INVALID_DISPLAY} if not + * changed. + */ + private void performConfigurationChange(MergedConfiguration mergedConfiguration, boolean force, + int newDisplayId) { + if (mergedConfiguration == null) { + throw new IllegalArgumentException("No merged config provided."); + } + + Configuration globalConfig = mergedConfiguration.getGlobalConfiguration(); + final Configuration overrideConfig = mergedConfiguration.getOverrideConfiguration(); if (DEBUG_CONFIGURATION) Log.v(mTag, - "Applying new config to window " - + mWindowAttributes.getTitle() - + ": " + config); + "Applying new config to window " + mWindowAttributes.getTitle() + + ", globalConfig: " + globalConfig + + ", overrideConfig: " + overrideConfig); - CompatibilityInfo ci = mDisplay.getDisplayAdjustments().getCompatibilityInfo(); + final CompatibilityInfo ci = mDisplay.getDisplayAdjustments().getCompatibilityInfo(); if (!ci.equals(CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO)) { - config = new Configuration(config); - ci.applyToConfiguration(mNoncompatDensity, config); + globalConfig = new Configuration(globalConfig); + ci.applyToConfiguration(mNoncompatDensity, globalConfig); } synchronized (sConfigCallbacks) { for (int i=sConfigCallbacks.size()-1; i>=0; i--) { - sConfigCallbacks.get(i).onConfigurationChanged(config); + sConfigCallbacks.get(i).onConfigurationChanged(globalConfig); } } - if (mView != null) { - // At this point the resources have been updated to - // have the most recent config, whatever that is. Use - // the one in them which may be newer. - final Resources localResources = mView.getResources(); - config = localResources.getConfiguration(); - if (force || mLastConfiguration.diff(config) != 0) { - // Update the display with new DisplayAdjustments. - mDisplay = ResourcesManager.getInstance().getAdjustedDisplay( - mDisplay.getDisplayId(), localResources); - final int lastLayoutDirection = mLastConfiguration.getLayoutDirection(); - final int currentLayoutDirection = config.getLayoutDirection(); - mLastConfiguration.setTo(config); - if (lastLayoutDirection != currentLayoutDirection && - mViewLayoutDirectionInitial == View.LAYOUT_DIRECTION_INHERIT) { - mView.setLayoutDirection(currentLayoutDirection); - } - mView.dispatchConfigurationChanged(config); + mLastReportedMergedConfiguration.setConfiguration(globalConfig, overrideConfig); + + mForceNextConfigUpdate = force; + if (mActivityConfigCallback != null) { + // An activity callback is set - notify it about override configuration update. + // This basically initiates a round trip to ActivityThread and back, which will ensure + // that corresponding activity and resources are updated before updating inner state of + // ViewRootImpl. Eventually it will call #updateConfiguration(). + mActivityConfigCallback.onConfigurationChanged(overrideConfig, newDisplayId); + } else { + // There is no activity callback - update the configuration right away. + updateConfiguration(); + } + mForceNextConfigUpdate = false; + } + + /** + * Update display and views if last applied merged configuration changed. + */ + public void updateConfiguration() { + if (mView == null) { + return; + } + + // At this point the resources have been updated to + // have the most recent config, whatever that is. Use + // the one in them which may be newer. + final Resources localResources = mView.getResources(); + final Configuration config = localResources.getConfiguration(); + if (mForceNextConfigUpdate || mLastConfigurationFromResources.diff(config) != 0) { + // Update the display with new DisplayAdjustments. + mDisplay = ResourcesManager.getInstance().getAdjustedDisplay( + mDisplay.getDisplayId(), localResources); + + final int lastLayoutDirection = mLastConfigurationFromResources.getLayoutDirection(); + final int currentLayoutDirection = config.getLayoutDirection(); + mLastConfigurationFromResources.setTo(config); + if (lastLayoutDirection != currentLayoutDirection + && mViewLayoutDirectionInitial == View.LAYOUT_DIRECTION_INHERIT) { + mView.setLayoutDirection(currentLayoutDirection); } + mView.dispatchConfigurationChanged(config); } } @@ -3582,13 +3673,16 @@ public final class ViewRootImpl implements ViewParent, if (mAdded) { SomeArgs args = (SomeArgs) msg.obj; - if (mDisplay.getDisplayId() != args.argi3) { - onMovedToDisplay(args.argi3); + final int displayId = args.argi3; + final boolean displayChanged = mDisplay.getDisplayId() != displayId; + if (displayChanged) { + onMovedToDisplay(displayId); } - Configuration config = (Configuration) args.arg4; - if (config != null) { - updateConfiguration(config, false); + final MergedConfiguration mergedConfiguration = (MergedConfiguration) args.arg4; + if (mergedConfiguration != null) { + performConfigurationChange(mergedConfiguration, false /* force */, + displayChanged ? displayId : INVALID_DISPLAY /* same display */); } final boolean framesChanged = !mWinFrame.equals(args.arg1) @@ -3759,11 +3853,19 @@ public final class ViewRootImpl implements ViewParent, handleDispatchSystemUiVisibilityChanged((SystemUiVisibilityInfo) msg.obj); } break; case MSG_UPDATE_CONFIGURATION: { - Configuration config = (Configuration)msg.obj; - if (config.isOtherSeqNewer(mLastConfiguration)) { - config = mLastConfiguration; + Configuration config = (Configuration) msg.obj; + if (config.isOtherSeqNewer( + mLastReportedMergedConfiguration.getMergedConfiguration())) { + // If we already have a newer merged config applied - use its global part. + config = mLastReportedMergedConfiguration.getGlobalConfiguration(); } - updateConfiguration(config, false); + + // Use the newer global config and last reported override config. + mPendingMergedConfiguration.setConfiguration(config, + mLastReportedMergedConfiguration.getOverrideConfiguration()); + + performConfigurationChange(mPendingMergedConfiguration, false /* force */, + INVALID_DISPLAY /* same display */); } break; case MSG_CLEAR_ACCESSIBILITY_FOCUS_HOST: { setAccessibilityFocus(null, null); @@ -5902,7 +6004,7 @@ public final class ViewRootImpl implements ViewParent, if (params != null) { if (DBG) Log.d(mTag, "WindowLayout in layoutWindow:" + params); } - mPendingConfiguration.seq = 0; + mPendingMergedConfiguration.getMergedConfiguration().seq = 0; //Log.d(mTag, ">>>>>> CALLING relayout"); if (params != null && mOrigWindowType != params.type) { // For compatibility with old apps, don't crash here. @@ -5918,8 +6020,8 @@ public final class ViewRootImpl implements ViewParent, (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility, insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, mWinFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets, - mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingConfiguration, - mSurface); + mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, + mPendingMergedConfiguration, mSurface); mPendingAlwaysConsumeNavBar = (relayoutResult & WindowManagerGlobal.RELAYOUT_RES_CONSUME_ALWAYS_NAV_BAR) != 0; @@ -6199,9 +6301,9 @@ public final class ViewRootImpl implements ViewParent, } } - public void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets, + private void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, - Configuration newConfig, Rect backDropFrame, boolean forceLayout, + MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeNavBar, int displayId) { if (DEBUG_LAYOUT) Log.v(mTag, "Resizing " + this + ": frame=" + frame.toShortString() + " contentInsets=" + contentInsets.toShortString() @@ -6233,7 +6335,8 @@ public final class ViewRootImpl implements ViewParent, args.arg1 = sameProcessCall ? new Rect(frame) : frame; args.arg2 = sameProcessCall ? new Rect(contentInsets) : contentInsets; args.arg3 = sameProcessCall ? new Rect(visibleInsets) : visibleInsets; - args.arg4 = sameProcessCall && newConfig != null ? new Configuration(newConfig) : newConfig; + args.arg4 = sameProcessCall && mergedConfiguration != null + ? new MergedConfiguration(mergedConfiguration) : null; args.arg5 = sameProcessCall ? new Rect(overscanInsets) : overscanInsets; args.arg6 = sameProcessCall ? new Rect(stableInsets) : stableInsets; args.arg7 = sameProcessCall ? new Rect(outsets) : outsets; @@ -7243,13 +7346,13 @@ public final class ViewRootImpl implements ViewParent, @Override public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, - Configuration newConfig, Rect backDropFrame, boolean forceLayout, + MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeNavBar, int displayId) { final ViewRootImpl viewAncestor = mViewAncestor.get(); if (viewAncestor != null) { viewAncestor.dispatchResized(frame, overscanInsets, contentInsets, - visibleInsets, stableInsets, outsets, reportDraw, newConfig, backDropFrame, - forceLayout, alwaysConsumeNavBar, displayId); + visibleInsets, stableInsets, outsets, reportDraw, mergedConfiguration, + backDropFrame, forceLayout, alwaysConsumeNavBar, displayId); } } diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java index ce51dc4ead9e..361fd3da97c7 100644 --- a/core/java/com/android/internal/view/BaseIWindow.java +++ b/core/java/com/android/internal/view/BaseIWindow.java @@ -16,12 +16,12 @@ package com.android.internal.view; -import android.content.res.Configuration; import android.graphics.Rect; import android.hardware.input.InputManager; import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.os.RemoteException; +import android.util.MergedConfiguration; import android.view.DragEvent; import android.view.IWindow; import android.view.IWindowSession; @@ -39,8 +39,9 @@ public class BaseIWindow extends IWindow.Stub { @Override public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, - Rect stableInsets, Rect outsets, boolean reportDraw, Configuration newConfig, - Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeNavBar, int displayId) { + Rect stableInsets, Rect outsets, boolean reportDraw, + MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout, + boolean alwaysConsumeNavBar, int displayId) { if (reportDraw) { try { mSession.finishDrawing(this); diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java index 4df513eb27f4..30e0dedd7c99 100644 --- a/services/core/java/com/android/server/wm/Session.java +++ b/services/core/java/com/android/server/wm/Session.java @@ -28,7 +28,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.content.ClipData; import android.content.Context; -import android.content.res.Configuration; import android.graphics.Rect; import android.graphics.Region; import android.os.Binder; @@ -39,6 +38,7 @@ import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; import android.os.UserHandle; +import android.util.MergedConfiguration; import android.util.Slog; import android.view.Display; import android.view.IWindow; @@ -216,13 +216,13 @@ public class Session extends IWindowSession.Stub int requestedWidth, int requestedHeight, int viewFlags, int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, Rect outStableInsets, Rect outsets, Rect outBackdropFrame, - Configuration outConfig, Surface outSurface) { + MergedConfiguration mergedConfiguration, Surface outSurface) { if (false) Slog.d(TAG_WM, ">>>>>> ENTERED relayout from " + Binder.getCallingPid()); int res = mService.relayoutWindow(this, window, seq, attrs, requestedWidth, requestedHeight, viewFlags, flags, outFrame, outOverscanInsets, outContentInsets, outVisibleInsets, - outStableInsets, outsets, outBackdropFrame, outConfig, outSurface); + outStableInsets, outsets, outBackdropFrame, mergedConfiguration, outSurface); if (false) Slog.d(TAG_WM, "<<<<<< EXITING relayout to " + Binder.getCallingPid()); return res; diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java index c0598ca0238d..04403e2712c1 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java @@ -27,7 +27,6 @@ import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; import android.app.ActivityManager.TaskDescription; -import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; @@ -38,6 +37,7 @@ import android.os.Handler; import android.os.Looper; import android.os.Message; import android.os.RemoteException; +import android.util.MergedConfiguration; import android.util.Slog; import android.view.IWindowSession; import android.view.Surface; @@ -78,7 +78,7 @@ class TaskSnapshotSurface implements StartingSurface { final Surface surface = new Surface(); final Rect tmpRect = new Rect(); final Rect tmpFrame = new Rect(); - final Configuration tmpConfiguration = new Configuration(); + final MergedConfiguration tmpMergedConfiguration = new MergedConfiguration(); int fillBackgroundColor = Color.WHITE; synchronized (service.mWindowMap) { layoutParams.type = TYPE_APPLICATION_STARTING; @@ -122,7 +122,7 @@ class TaskSnapshotSurface implements StartingSurface { window.setOuter(snapshotSurface); try { session.relayout(window, window.mSeq, layoutParams, -1, -1, View.VISIBLE, 0, tmpFrame, - tmpRect, tmpRect, tmpRect, tmpRect, tmpRect, tmpRect, tmpConfiguration, + tmpRect, tmpRect, tmpRect, tmpRect, tmpRect, tmpRect, tmpMergedConfiguration, surface); } catch (RemoteException e) { // Local call. @@ -221,9 +221,9 @@ class TaskSnapshotSurface implements StartingSurface { @Override public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, - Rect stableInsets, Rect outsets, boolean reportDraw, Configuration newConfig, - Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeNavBar, - int displayId) { + Rect stableInsets, Rect outsets, boolean reportDraw, + MergedConfiguration mergedConfiguration, Rect backDropFrame, boolean forceLayout, + boolean alwaysConsumeNavBar, int displayId) { if (reportDraw) { sHandler.obtainMessage(MSG_REPORT_DRAW, mOuter).sendToTarget(); } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 5551afec76e8..7539cd4b8cab 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -150,6 +150,7 @@ import android.os.UserHandle; import android.os.WorkSource; import android.provider.Settings; import android.util.ArraySet; +import android.util.MergedConfiguration; import android.util.DisplayMetrics; import android.util.EventLog; import android.util.Log; @@ -1813,7 +1814,7 @@ public class WindowManagerService extends IWindowManager.Stub int requestedHeight, int viewVisibility, int flags, Rect outFrame, Rect outOverscanInsets, Rect outContentInsets, Rect outVisibleInsets, Rect outStableInsets, Rect outOutsets, Rect outBackdropFrame, - Configuration outConfig, Surface outSurface) { + MergedConfiguration mergedConfiguration, Surface outSurface) { int result = 0; boolean configChanged; boolean hasStatusBarPermission = @@ -1925,7 +1926,7 @@ public class WindowManagerService extends IWindowManager.Stub if (viewVisibility == View.VISIBLE && (win.mAppToken == null || win.mAttrs.type == TYPE_APPLICATION_STARTING || !win.mAppToken.clientHidden)) { - result = win.relayoutVisibleWindow(outConfig, result, attrChanges, + result = win.relayoutVisibleWindow(mergedConfiguration, result, attrChanges, oldVisibility); try { result = createSurfaceControl(outSurface, result, win, winAnimator); diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 4e593d86f7c0..ca5d551e8e0d 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -114,6 +114,7 @@ import android.os.SystemClock; import android.os.Trace; import android.os.UserHandle; import android.os.WorkSource; +import android.util.MergedConfiguration; import android.util.DisplayMetrics; import android.util.Slog; import android.util.TimeUtils; @@ -2265,7 +2266,7 @@ class WindowState extends WindowContainer implements WindowManagerP } } - void prepareWindowToDisplayDuringRelayout(Configuration outConfig) { + void prepareWindowToDisplayDuringRelayout(MergedConfiguration mergedConfiguration) { if ((mAttrs.softInputMode & SOFT_INPUT_MASK_ADJUST) == SOFT_INPUT_ADJUST_RESIZE) { mLayoutNeeded = true; @@ -2278,10 +2279,13 @@ class WindowState extends WindowContainer implements WindowManagerP mTurnOnScreen = true; } if (isConfigChanged()) { - outConfig.setTo(getConfiguration()); - if (DEBUG_CONFIGURATION) Slog.i(TAG, "Window " + this + " visible with new config: " - + outConfig); - mLastReportedConfiguration.setTo(outConfig); + 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()); } } @@ -3027,12 +3031,13 @@ class WindowState extends WindowContainer implements WindowManagerP try { if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to " + this + ": " + mCompatFrame); - final Configuration newConfig; + final MergedConfiguration mergedConfiguration; if (isConfigChanged()) { - newConfig = new Configuration(getConfiguration()); - mLastReportedConfiguration.setTo(newConfig); + mergedConfiguration = new MergedConfiguration(mService.mRoot.getConfiguration(), + getMergedOverrideConfiguration()); + mLastReportedConfiguration.setTo(mergedConfiguration.getMergedConfiguration()); } else { - newConfig = null; + mergedConfiguration = null; } if (DEBUG_ORIENTATION && mWinAnimator.mDrawState == DRAW_PENDING) Slog.i(TAG, "Resizing " + this + " WITH DRAW PENDING"); @@ -3054,7 +3059,7 @@ class WindowState extends WindowContainer implements WindowManagerP public void run() { try { dispatchResized(frame, overscanInsets, contentInsets, visibleInsets, - stableInsets, outsets, reportDraw, newConfig, + stableInsets, outsets, reportDraw, mergedConfiguration, reportOrientation, displayId); } catch (RemoteException e) { // Not a remote call, RemoteException won't be raised. @@ -3063,7 +3068,7 @@ class WindowState extends WindowContainer implements WindowManagerP }); } else { dispatchResized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets, - outsets, reportDraw, newConfig, reportOrientation, displayId); + outsets, reportDraw, mergedConfiguration, reportOrientation, displayId); } //TODO (multidisplay): Accessibility supported only for the default display. @@ -3120,14 +3125,14 @@ class WindowState extends WindowContainer implements WindowManagerP private void dispatchResized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, Rect stableInsets, Rect outsets, boolean reportDraw, - Configuration newConfig, boolean reportOrientation, int displayId) + MergedConfiguration mergedConfiguration, boolean reportOrientation, int displayId) throws RemoteException { final boolean forceRelayout = isDragResizeChanged() || mResizedWhileNotDragResizing || reportOrientation; mClient.resized(frame, overscanInsets, contentInsets, visibleInsets, stableInsets, outsets, - reportDraw, newConfig, getBackdropFrame(frame), - forceRelayout, mPolicy.isNavBarForcedShownLw(this), displayId); + reportDraw, mergedConfiguration, getBackdropFrame(frame), forceRelayout, + mPolicy.isNavBarForcedShownLw(this), displayId); mDragResizingChangeReported = true; } @@ -4341,8 +4346,8 @@ class WindowState extends WindowContainer implements WindowManagerP return !mLastSurfaceInsets.equals(mAttrs.surfaceInsets); } - int relayoutVisibleWindow(Configuration outConfig, int result, - int attrChanges, int oldVisibility) { + int relayoutVisibleWindow(MergedConfiguration mergedConfiguration, int result, int attrChanges, + int oldVisibility) { result |= !isVisibleLw() ? RELAYOUT_RES_FIRST_TIME : 0; if (mAnimatingExit) { Slog.d(TAG, "relayoutVisibleWindow: " + this + " mAnimatingExit=true, mRemoveOnExit=" @@ -4363,7 +4368,7 @@ class WindowState extends WindowContainer implements WindowManagerP mWinAnimator.mEnteringAnimation = true; if ((result & RELAYOUT_RES_FIRST_TIME) != 0) { - prepareWindowToDisplayDuringRelayout(outConfig); + prepareWindowToDisplayDuringRelayout(mergedConfiguration); } 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/TestIWindow.java b/services/tests/servicestests/src/com/android/server/wm/TestIWindow.java index b6dc9a5b6e34..0a644b60d224 100644 --- a/services/tests/servicestests/src/com/android/server/wm/TestIWindow.java +++ b/services/tests/servicestests/src/com/android/server/wm/TestIWindow.java @@ -18,11 +18,11 @@ package com.android.server.wm; import com.android.internal.os.IResultReceiver; -import android.content.res.Configuration; import android.graphics.Rect; import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.os.RemoteException; +import android.util.MergedConfiguration; import android.view.DragEvent; import android.view.IWindow; @@ -36,7 +36,7 @@ public class TestIWindow extends IWindow.Stub { @Override public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets, - Rect stableInsets, Rect outsets, boolean reportDraw, Configuration newConfig, + Rect stableInsets, Rect outsets, boolean reportDraw, MergedConfiguration mergedConfig, Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeNavBar, int displayId) throws RemoteException { 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 468949117635..ffbe7c43ceab 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 @@ -18,12 +18,12 @@ package com.android.layoutlib.bridge.android; import com.android.internal.os.IResultReceiver; -import android.content.res.Configuration; import android.graphics.Rect; import android.os.Bundle; import android.os.IBinder; import android.os.ParcelFileDescriptor; import android.os.RemoteException; +import android.util.MergedConfiguration; import android.view.DragEvent; import android.view.IWindow; @@ -50,7 +50,7 @@ public final class BridgeWindow implements IWindow { @Override public void resized(Rect rect, Rect rect2, Rect rect3, Rect rect4, Rect rect5, Rect rect6, - boolean b, Configuration configuration, Rect rect7, boolean b2, boolean b3, int i0) + boolean b, MergedConfiguration mergedConfig, Rect rect7, boolean b2, boolean b3, int i0) throws RemoteException { // 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 4dfe47be0ef6..2c883940510e 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 @@ -17,12 +17,12 @@ package com.android.layoutlib.bridge.android; import android.content.ClipData; -import android.content.res.Configuration; import android.graphics.Rect; import android.graphics.Region; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; +import android.util.MergedConfiguration; import android.view.IWindow; import android.view.IWindowId; import android.view.IWindowSession; @@ -89,7 +89,7 @@ public final class BridgeWindowSession implements IWindowSession { @Override public int relayout(IWindow iWindow, int i, LayoutParams layoutParams, int i2, int i3, int i4, int i5, Rect rect, Rect rect2, Rect rect3, Rect rect4, Rect rect5, - Rect rect6, Rect rect7, Configuration configuration, Surface surface) + Rect rect6, Rect rect7, MergedConfiguration mergedConfig, Surface surface) throws RemoteException { // pass for now. return 0; -- cgit v1.2.3-59-g8ed1b