diff options
| author | 2017-08-18 17:46:25 +0000 | |
|---|---|---|
| committer | 2017-08-18 17:46:25 +0000 | |
| commit | 58cb974e4e3f8bc93faf39e2042c9cceb276b540 (patch) | |
| tree | 3fd7b388df8083676660682a0d7a5d96d3233916 | |
| parent | 997eafcbf273a13e488303bc00ed50b44c094e49 (diff) | |
| parent | 822e5121271be122da5bfb57bb94f5725abd88e1 (diff) | |
Merge "Introducing WindowConfiguration"
| -rw-r--r-- | core/java/android/app/WindowConfiguration.aidl | 19 | ||||
| -rw-r--r-- | core/java/android/app/WindowConfiguration.java | 225 | ||||
| -rw-r--r-- | core/java/android/content/pm/ActivityInfo.java | 7 | ||||
| -rw-r--r-- | core/java/android/content/res/Configuration.java | 106 | ||||
| -rw-r--r-- | core/java/android/view/DisplayInfo.java | 9 | ||||
| -rw-r--r-- | services/core/java/com/android/server/am/ActivityRecord.java | 20 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/DisplayContent.java | 5 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/DockedStackDividerController.java | 4 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/StackWindowController.java | 14 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java | 2 | ||||
| -rw-r--r-- | services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java (renamed from services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java) | 161 |
11 files changed, 391 insertions, 181 deletions
diff --git a/core/java/android/app/WindowConfiguration.aidl b/core/java/android/app/WindowConfiguration.aidl new file mode 100644 index 000000000000..1a70f524b278 --- /dev/null +++ b/core/java/android/app/WindowConfiguration.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.app; + +parcelable WindowConfiguration; diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java new file mode 100644 index 000000000000..86abaa37bab1 --- /dev/null +++ b/core/java/android/app/WindowConfiguration.java @@ -0,0 +1,225 @@ +/* + * 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.app; + +import android.annotation.IntDef; +import android.annotation.NonNull; +import android.content.res.Configuration; +import android.graphics.Rect; +import android.os.Parcel; +import android.os.Parcelable; +import android.view.DisplayInfo; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Class that contains windowing configuration/state for other objects that contain windows directly + * or indirectly. E.g. Activities, Task, Displays, ... + * The test class is {@link com.android.server.wm.WindowConfigurationTests} which must be kept + * up-to-date and ran anytime changes are made to this class. + * @hide + */ +public class WindowConfiguration implements Parcelable, Comparable<WindowConfiguration> { + + /** + * {@link android.graphics.Rect} defining app bounds. The dimensions override usages of + * {@link DisplayInfo#appHeight} and {@link DisplayInfo#appWidth} and mirrors these values at + * the display level. Lower levels can override these values to provide custom bounds to enforce + * features such as a max aspect ratio. + */ + private Rect mAppBounds; + + @IntDef(flag = true, + value = { + WINDOW_CONFIG_APP_BOUNDS, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface WindowConfig {} + + /** Bit that indicates that the {@link #mAppBounds} changed. */ + public static final int WINDOW_CONFIG_APP_BOUNDS = 1 << 0; + + public WindowConfiguration() { + unset(); + } + + public WindowConfiguration(WindowConfiguration configuration) { + setTo(configuration); + } + + private WindowConfiguration(Parcel in) { + readFromParcel(in); + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelable(mAppBounds, flags); + } + + private void readFromParcel(Parcel source) { + mAppBounds = source.readParcelable(Rect.class.getClassLoader()); + } + + @Override + public int describeContents() { + return 0; + } + + public static final Creator<WindowConfiguration> CREATOR = new Creator<WindowConfiguration>() { + @Override + public WindowConfiguration createFromParcel(Parcel in) { + return new WindowConfiguration(in); + } + + @Override + public WindowConfiguration[] newArray(int size) { + return new WindowConfiguration[size]; + } + }; + + /** + * Set {@link #mAppBounds} to the input Rect. + * @param rect The rect value to set {@link #mAppBounds} to. + * @see #getAppBounds() + */ + public void setAppBounds(Rect rect) { + if (rect == null) { + mAppBounds = null; + return; + } + + setAppBounds(rect.left, rect.top, rect.right, rect.bottom); + } + + /** + * @see #setAppBounds(Rect) + * @see #getAppBounds() + */ + public void setAppBounds(int left, int top, int right, int bottom) { + if (mAppBounds == null) { + mAppBounds = new Rect(); + } + + mAppBounds.set(left, top, right, bottom); + } + + /** + * @see #setAppBounds(Rect) + */ + public Rect getAppBounds() { + return mAppBounds; + } + + public void setTo(WindowConfiguration other) { + setAppBounds(other.mAppBounds); + } + + /** Set this object to completely undefined. */ + public void unset() { + setToDefaults(); + } + + public void setToDefaults() { + setAppBounds(null); + } + + /** + * Copies the fields from delta into this Configuration object, keeping + * track of which ones have changed. Any undefined fields in {@code delta} + * are ignored and not copied in to the current Configuration. + * + * @return a bit mask of the changed fields, as per {@link #diff} + */ + public @WindowConfig int updateFrom(@NonNull WindowConfiguration delta) { + int changed = 0; + if (delta.mAppBounds != null && !delta.mAppBounds.equals(mAppBounds)) { + changed |= WINDOW_CONFIG_APP_BOUNDS; + setAppBounds(delta.mAppBounds); + } + return changed; + } + + /** + * Return a bit mask of the differences between this Configuration object and the given one. + * Does not change the values of either. Any undefined fields in <var>other</var> are ignored. + * @param other The configuration to diff against. + * @param compareUndefined If undefined values should be compared. + * @return Returns a bit mask indicating which configuration + * values has changed, containing any combination of {@link WindowConfig} flags. + * + * @see Configuration#diff(Configuration) + */ + public @WindowConfig long diff(WindowConfiguration other, boolean compareUndefined) { + long changes = 0; + + // Make sure that one of the values is not null and that they are not equal. + if ((compareUndefined || other.mAppBounds != null) + && mAppBounds != other.mAppBounds + && (mAppBounds == null || !mAppBounds.equals(other.mAppBounds))) { + changes |= WINDOW_CONFIG_APP_BOUNDS; + } + + return changes; + } + + @Override + public int compareTo(WindowConfiguration that) { + int n = 0; + if (mAppBounds == null && that.mAppBounds != null) { + return 1; + } else if (mAppBounds != null && that.mAppBounds == null) { + return -1; + } else if (mAppBounds != null && that.mAppBounds != null) { + n = mAppBounds.left - that.mAppBounds.left; + if (n != 0) return n; + n = mAppBounds.top - that.mAppBounds.top; + if (n != 0) return n; + n = mAppBounds.right - that.mAppBounds.right; + if (n != 0) return n; + n = mAppBounds.bottom - that.mAppBounds.bottom; + if (n != 0) return n; + } + + // if (n != 0) return n; + return n; + } + + @Override + public boolean equals(Object that) { + if (that == null) return false; + if (that == this) return true; + if (!(that instanceof WindowConfiguration)) { + return false; + } + return this.compareTo((WindowConfiguration) that) == 0; + } + + @Override + public int hashCode() { + int result = 0; + if (mAppBounds != null) { + result = 31 * result + mAppBounds.hashCode(); + } + return result; + } + + @Override + public String toString() { + return "{mAppBounds=" + mAppBounds + "}"; + } +} diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index ca5fa6be1323..92f4849e7d8e 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -780,6 +780,13 @@ public class ActivityInfo extends ComponentInfo * constant starts at the high bits. */ public static final int CONFIG_FONT_SCALE = 0x40000000; + /** + * Bit indicating changes to window configuration that isn't exposed to apps. + * This is for internal use only and apps don't handle it. + * @hide + * {@link Configuration}. + */ + public static final int CONFIG_WINDOW_CONFIGURATION = 0x20000000; /** @hide * Unfortunately the constants for config changes in native code are diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index f7cccd56f079..780e6f769290 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -19,15 +19,14 @@ package android.content.res; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.app.WindowConfiguration; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo.Config; -import android.graphics.Rect; import android.os.Build; import android.os.LocaleList; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; -import android.view.DisplayInfo; import android.view.View; import com.android.internal.util.XmlUtils; @@ -42,7 +41,6 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Locale; - /** * This class describes all device configuration information that can * impact the resources the application retrieves. This includes both @@ -298,13 +296,11 @@ public final class Configuration implements Parcelable, Comparable<Configuration /** * @hide - * {@link android.graphics.Rect} defining app bounds. The dimensions override usages of - * {@link DisplayInfo#appHeight} and {@link DisplayInfo#appWidth} and mirrors these values at - * the display level. Lower levels can override these values to provide custom bounds to enforce - * features such as a max aspect ratio. - * TODO(b/36812336): Move appBounds out of {@link Configuration}. + * Configuration relating to the windowing state of the object associated with this + * Configuration. Contents of this field are not intended to affect resources, but need to be + * communicated and propagated at the same time as the rest of Configuration. */ - public Rect appBounds; + public final WindowConfiguration windowConfiguration = new WindowConfiguration(); /** @hide */ static public int resetScreenLayout(int curLayout) { @@ -895,9 +891,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration compatScreenWidthDp = o.compatScreenWidthDp; compatScreenHeightDp = o.compatScreenHeightDp; compatSmallestScreenWidthDp = o.compatSmallestScreenWidthDp; - setAppBounds(o.appBounds); assetsSeq = o.assetsSeq; seq = o.seq; + windowConfiguration.setTo(o.windowConfiguration); } public String toString() { @@ -1046,9 +1042,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration case NAVIGATIONHIDDEN_YES: sb.append("/h"); break; default: sb.append("/"); sb.append(navigationHidden); break; } - if (appBounds != null) { - sb.append(" appBounds="); sb.append(appBounds); - } + sb.append(" winConfig="); sb.append(windowConfiguration); if (assetsSeq != 0) { sb.append(" as.").append(assetsSeq); } @@ -1083,8 +1077,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration smallestScreenWidthDp = compatSmallestScreenWidthDp = SMALLEST_SCREEN_WIDTH_DP_UNDEFINED; densityDpi = DENSITY_DPI_UNDEFINED; assetsSeq = ASSETS_SEQ_UNDEFINED; - appBounds = null; seq = 0; + windowConfiguration.setToDefaults(); } /** @@ -1183,7 +1177,6 @@ public final class Configuration implements Parcelable, Comparable<Configuration changed |= ActivityInfo.CONFIG_ORIENTATION; orientation = delta.orientation; } - if (((delta.screenLayout & SCREENLAYOUT_SIZE_MASK) != SCREENLAYOUT_SIZE_UNDEFINED) && (delta.screenLayout & SCREENLAYOUT_SIZE_MASK) != (screenLayout & SCREENLAYOUT_SIZE_MASK)) { @@ -1271,10 +1264,6 @@ public final class Configuration implements Parcelable, Comparable<Configuration if (delta.compatSmallestScreenWidthDp != SMALLEST_SCREEN_WIDTH_DP_UNDEFINED) { compatSmallestScreenWidthDp = delta.compatSmallestScreenWidthDp; } - if (delta.appBounds != null && !delta.appBounds.equals(appBounds)) { - changed |= ActivityInfo.CONFIG_SCREEN_SIZE; - setAppBounds(delta.appBounds); - } if (delta.assetsSeq != ASSETS_SEQ_UNDEFINED && delta.assetsSeq != assetsSeq) { changed |= ActivityInfo.CONFIG_ASSETS_PATHS; assetsSeq = delta.assetsSeq; @@ -1282,6 +1271,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration if (delta.seq != 0) { seq = delta.seq; } + if (windowConfiguration.updateFrom(delta.windowConfiguration) != 0) { + changed |= ActivityInfo.CONFIG_WINDOW_CONFIGURATION; + } return changed; } @@ -1433,13 +1425,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration changed |= ActivityInfo.CONFIG_ASSETS_PATHS; } - // Make sure that one of the values is not null and that they are not equal. - if ((compareUndefined || delta.appBounds != null) - && appBounds != delta.appBounds - && (appBounds == null || (!publicOnly && !appBounds.equals(delta.appBounds)) - || (publicOnly && (appBounds.width() != delta.appBounds.width() - || appBounds.height() != delta.appBounds.height())))) { - changed |= ActivityInfo.CONFIG_SCREEN_SIZE; + // WindowConfiguration differences aren't considered public... + if (!publicOnly + && windowConfiguration.diff(delta.windowConfiguration, compareUndefined) != 0) { + changed |= ActivityInfo.CONFIG_WINDOW_CONFIGURATION; } return changed; @@ -1537,7 +1526,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration dest.writeInt(compatScreenWidthDp); dest.writeInt(compatScreenHeightDp); dest.writeInt(compatSmallestScreenWidthDp); - dest.writeValue(appBounds); + dest.writeValue(windowConfiguration); dest.writeInt(assetsSeq); dest.writeInt(seq); } @@ -1573,7 +1562,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration compatScreenWidthDp = source.readInt(); compatScreenHeightDp = source.readInt(); compatSmallestScreenWidthDp = source.readInt(); - appBounds = (Rect) source.readValue(null); + windowConfiguration.setTo((WindowConfiguration) source.readValue(null)); assetsSeq = source.readInt(); seq = source.readInt(); } @@ -1663,21 +1652,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration if (n != 0) return n; n = this.assetsSeq - that.assetsSeq; if (n != 0) return n; - - if (this.appBounds == null && that.appBounds != null) { - return 1; - } else if (this.appBounds != null && that.appBounds == null) { - return -1; - } else if (this.appBounds != null && that.appBounds != null) { - n = this.appBounds.left - that.appBounds.left; - if (n != 0) return n; - n = this.appBounds.top - that.appBounds.top; - if (n != 0) return n; - n = this.appBounds.right - that.appBounds.right; - if (n != 0) return n; - n = this.appBounds.bottom - that.appBounds.bottom; - if (n != 0) return n; - } + n = windowConfiguration.compareTo(that.windowConfiguration); + if (n != 0) return n; // if (n != 0) return n; return n; @@ -1768,33 +1744,6 @@ public final class Configuration implements Parcelable, Comparable<Configuration /** * @hide * - * Helper method for setting the app bounds. - */ - public void setAppBounds(Rect rect) { - if (rect == null) { - appBounds = null; - return; - } - - setAppBounds(rect.left, rect.top, rect.right, rect.bottom); - } - - /** - * @hide - * - * Helper method for setting the app bounds. - */ - public void setAppBounds(int left, int top, int right, int bottom) { - if (appBounds == null) { - appBounds = new Rect(); - } - - appBounds.set(left, top, right, bottom); - } - - /** - * @hide - * * Clears the locale without changing layout direction. */ public void clearLocales() { @@ -2282,6 +2231,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration if (base.assetsSeq != change.assetsSeq) { delta.assetsSeq = change.assetsSeq; } + + if (!base.windowConfiguration.equals(change.windowConfiguration)) { + delta.windowConfiguration.setTo(change.windowConfiguration); + } return delta; } @@ -2354,10 +2307,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration SMALLEST_SCREEN_WIDTH_DP_UNDEFINED); configOut.densityDpi = XmlUtils.readIntAttribute(parser, XML_ATTR_DENSITY, DENSITY_DPI_UNDEFINED); - configOut.appBounds = - Rect.unflattenFromString(XmlUtils.readStringAttribute(parser, XML_ATTR_APP_BOUNDS)); - // For persistence, we don't care about assetsSeq, so do not read it out. + // For persistence, we don't care about assetsSeq and WindowConfiguration, so do not read it + // out. } @@ -2427,11 +2379,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration XmlUtils.writeIntAttribute(xml, XML_ATTR_DENSITY, config.densityDpi); } - if (config.appBounds != null) { - XmlUtils.writeStringAttribute(xml, XML_ATTR_APP_BOUNDS, - config.appBounds.flattenToString()); - } - - // For persistence, we do not care about assetsSeq, so do not write it out. + // For persistence, we do not care about assetsSeq and window configuration, so do not write + // it out. } } diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java index c5c6b378bb74..b813ddb63859 100644 --- a/core/java/android/view/DisplayInfo.java +++ b/core/java/android/view/DisplayInfo.java @@ -23,6 +23,7 @@ import static android.view.DisplayInfoProto.LOGICAL_WIDTH; import android.content.res.CompatibilityInfo; import android.content.res.Configuration; +import android.graphics.Rect; import android.os.Parcel; import android.os.Parcelable; import android.util.ArraySet; @@ -568,10 +569,10 @@ public final class DisplayInfo implements Parcelable { outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi; outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi; - width = configuration != null && configuration.appBounds != null - ? configuration.appBounds.width() : width; - height = configuration != null && configuration.appBounds != null - ? configuration.appBounds.height() : height; + final Rect appBounds = configuration != null + ? configuration.windowConfiguration.getAppBounds() : null; + width = appBounds != null ? appBounds.width() : width; + height = appBounds != null ? appBounds.height() : height; outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width; outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height; diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index e9e073cd716f..a2e30676e3d4 100644 --- a/services/core/java/com/android/server/am/ActivityRecord.java +++ b/services/core/java/com/android/server/am/ActivityRecord.java @@ -46,6 +46,7 @@ import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT; import static android.content.pm.ActivityInfo.CONFIG_SCREEN_SIZE; import static android.content.pm.ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE; import static android.content.pm.ActivityInfo.CONFIG_UI_MODE; +import static android.content.pm.ActivityInfo.CONFIG_WINDOW_CONFIGURATION; import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE; import static android.content.pm.ActivityInfo.FLAG_SHOW_WHEN_LOCKED; import static android.content.pm.ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS; @@ -429,11 +430,11 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo pw.print("\""); pw.print(" primaryColor="); pw.println(Integer.toHexString(taskDescription.getPrimaryColor())); - pw.print(prefix); pw.print(" backgroundColor="); + pw.print(prefix + " backgroundColor="); pw.println(Integer.toHexString(taskDescription.getBackgroundColor())); - pw.print(prefix); pw.print(" statusBarColor="); + pw.print(prefix + " statusBarColor="); pw.println(Integer.toHexString(taskDescription.getStatusBarColor())); - pw.print(prefix); pw.print(" navigationBarColor="); + pw.print(prefix + " navigationBarColor="); pw.println(Integer.toHexString(taskDescription.getNavigationBarColor())); } if (iconFilename == null && taskDescription.getIcon() != null) { @@ -2311,9 +2312,9 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo // We must base this on the parent configuration, because we set our override // configuration's appBounds based on the result of this method. If we used our own // configuration, it would be influenced by past invocations. - final Configuration configuration = getParent().getConfiguration(); - final int containingAppWidth = configuration.appBounds.width(); - final int containingAppHeight = configuration.appBounds.height(); + final Rect appBounds = getParent().getConfiguration().windowConfiguration.getAppBounds(); + final int containingAppWidth = appBounds.width(); + final int containingAppHeight = appBounds.height(); int maxActivityWidth = containingAppWidth; int maxActivityHeight = containingAppHeight; @@ -2342,8 +2343,7 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo outBounds.set(0, 0, maxActivityWidth, maxActivityHeight); // Position the activity frame on the opposite side of the nav bar. final int navBarPosition = service.mWindowManager.getNavBarPosition(); - final int left = navBarPosition == NAV_BAR_LEFT - ? configuration.appBounds.right - outBounds.width() : 0; + final int left = navBarPosition == NAV_BAR_LEFT ? appBounds.right - outBounds.width() : 0; outBounds.offsetTo(left, 0 /* top */); } @@ -2574,6 +2574,10 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo changes &= ~CONFIG_SMALLEST_SCREEN_SIZE; } } + // We don't want window configuration to cause relaunches. + if ((changes & CONFIG_WINDOW_CONFIGURATION) != 0) { + changes &= ~CONFIG_WINDOW_CONFIGURATION; + } return changes; } diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 2df773e3d0d1..2e7f8221594b 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -1205,8 +1205,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo final int leftInset = mTmpRect.left; final int topInset = mTmpRect.top; // appBounds at the root level should mirror the app screen size. - config.setAppBounds(leftInset /*left*/, topInset /*top*/, leftInset + displayInfo.appWidth /*right*/, - topInset + displayInfo.appHeight /*bottom*/); + config.windowConfiguration.setAppBounds(leftInset /* left */, topInset /* top */, + leftInset + displayInfo.appWidth /* right */, + topInset + displayInfo.appHeight /* bottom */); final boolean rotated = (displayInfo.rotation == Surface.ROTATION_90 || displayInfo.rotation == Surface.ROTATION_270); diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java index 2b45d67120d9..ce21991e1b3e 100644 --- a/services/core/java/com/android/server/wm/DockedStackDividerController.java +++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java @@ -241,8 +241,8 @@ public class DockedStackDividerController implements DimLayerUser { final int leftInset = mTmpRect.left; final int topInset = mTmpRect.top; - config.setAppBounds(leftInset /*left*/, topInset /*top*/, leftInset + appWidth /*right*/, - topInset + appHeight /*bottom*/); + config.windowConfiguration.setAppBounds(leftInset /*left*/, topInset /*top*/, + leftInset + appWidth /*right*/, topInset + appHeight /*bottom*/); config.screenWidthDp = (int) (mService.mPolicy.getConfigDisplayWidth(dw, dh, rotation, baseConfig.uiMode, diff --git a/services/core/java/com/android/server/wm/StackWindowController.java b/services/core/java/com/android/server/wm/StackWindowController.java index 9c44c14d7866..358b8bee17c2 100644 --- a/services/core/java/com/android/server/wm/StackWindowController.java +++ b/services/core/java/com/android/server/wm/StackWindowController.java @@ -16,11 +16,9 @@ package com.android.server.wm; -import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import android.app.ActivityManager.StackId; -import android.app.RemoteAction; import android.content.res.Configuration; import android.graphics.Rect; import android.os.Handler; @@ -30,11 +28,9 @@ import android.util.Slog; import android.util.SparseArray; import android.view.DisplayInfo; -import com.android.server.UiThread; import com.android.internal.annotations.VisibleForTesting; import java.lang.ref.WeakReference; -import java.util.List; import static com.android.server.wm.WindowContainer.POSITION_BOTTOM; import static com.android.server.wm.WindowContainer.POSITION_TOP; @@ -278,9 +274,9 @@ public class StackWindowController int width; int height; - final Rect parentAppBounds = parentConfig.appBounds; + final Rect parentAppBounds = parentConfig.windowConfiguration.getAppBounds(); - config.setAppBounds(!bounds.isEmpty() ? bounds : null); + config.windowConfiguration.setAppBounds(!bounds.isEmpty() ? bounds : null); boolean intersectParentBounds = false; if (StackId.tasksAreFloating(mStackId)) { @@ -295,7 +291,7 @@ public class StackWindowController nonDecorBounds.inset(mTmpNonDecorInsets); // Move app bounds to zero to apply intersection with parent correctly. They are // used only for evaluating width and height, so it's OK to move them around. - config.appBounds.offsetTo(0, 0); + config.windowConfiguration.getAppBounds().offsetTo(0, 0); intersectParentBounds = true; } width = (int) (stableBounds.width() / density); @@ -319,8 +315,8 @@ public class StackWindowController intersectParentBounds = true; } - if (intersectParentBounds && config.appBounds != null) { - config.appBounds.intersect(parentAppBounds); + if (intersectParentBounds && config.windowConfiguration.getAppBounds() != null) { + config.windowConfiguration.getAppBounds().intersect(parentAppBounds); } config.screenWidthDp = width; diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java index 2252c85dddf2..47a3a7242a44 100644 --- a/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java +++ b/services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java @@ -126,7 +126,7 @@ public class ActivityRecordTests extends ActivityTestsBase { // Verify with nav bar on the right. when(service.mWindowManager.getNavBarPosition()).thenReturn(navBarPosition); - task.getConfiguration().setAppBounds(taskBounds); + task.getConfiguration().windowConfiguration.setAppBounds(taskBounds); record.info.maxAspectRatio = aspectRatio; record.ensureActivityConfigurationLocked(0 /* globalChanges */, false /* preserveWindow */); assertEquals(expectedActivityBounds, record.getBounds()); diff --git a/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java index 432cfc7a22ee..78643bd593a7 100644 --- a/services/tests/servicestests/src/com/android/server/wm/AppBoundsTests.java +++ b/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java @@ -11,36 +11,38 @@ * 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 + * limitations under the License. */ package com.android.server.wm; -import android.app.ActivityManager; -import android.content.pm.ActivityInfo; -import android.content.res.Configuration; -import android.graphics.Rect; -import android.view.DisplayInfo; import org.junit.Test; +import android.app.WindowConfiguration; +import android.content.res.Configuration; +import android.graphics.Rect; import android.platform.test.annotations.Presubmit; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; +import android.view.DisplayInfo; +import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; +import static android.app.WindowConfiguration.WINDOW_CONFIG_APP_BOUNDS; +import static android.content.pm.ActivityInfo.CONFIG_WINDOW_CONFIGURATION; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; /** - * Test class to exercise logic related to {@link android.content.res.Configuration#appBounds}. + * Test class to for {@link android.app.WindowConfiguration}. * * Build/Install/Run: - * bit FrameworksServicesTests:com.android.server.wm.AppBoundsTests + * bit FrameworksServicesTests:com.android.server.wm.WindowConfigurationTests */ @SmallTest @Presubmit @org.junit.runner.RunWith(AndroidJUnit4.class) -public class AppBoundsTests extends WindowTestsBase { +public class WindowConfigurationTests extends WindowTestsBase { private Rect mParentBounds; @Override @@ -49,44 +51,82 @@ public class AppBoundsTests extends WindowTestsBase { mParentBounds = new Rect(10 /*left*/, 30 /*top*/, 80 /*right*/, 60 /*bottom*/); } - /** - * Ensures that appBounds causes {@link android.content.pm.ActivityInfo.CONFIG_APP_BOUNDS} diff. - */ + /** Tests {@link android.app.WindowConfiguration#diff(WindowConfiguration, boolean)}. */ @Test - public void testAppBoundsConfigurationDiff() { - final Configuration config = new Configuration(); + public void testDiff() { + final Configuration config1 = new Configuration(); + final WindowConfiguration winConfig1 = config1.windowConfiguration; final Configuration config2 = new Configuration(); - config.appBounds = new Rect(0, 1, 1, 0); - config2.appBounds = new Rect(1, 2, 2, 1); + final WindowConfiguration winConfig2 = config2.windowConfiguration; + final Configuration config3 = new Configuration(); + final WindowConfiguration winConfig3 = config3.windowConfiguration; + + winConfig1.setAppBounds(0, 1, 1, 0); + winConfig2.setAppBounds(1, 2, 2, 1); + winConfig3.setAppBounds(winConfig1.getAppBounds()); + + + assertEquals(CONFIG_WINDOW_CONFIGURATION, config1.diff(config2)); + assertEquals(0, config1.diffPublicOnly(config2)); + assertEquals(WINDOW_CONFIG_APP_BOUNDS, + winConfig1.diff(winConfig2, false /* compareUndefined */)); + + assertEquals(0, config1.diff(config3)); + assertEquals(0, config1.diffPublicOnly(config3)); + assertEquals(0, winConfig1.diff(winConfig3, false /* compareUndefined */)); + } + + /** Tests {@link android.app.WindowConfiguration#compareTo(WindowConfiguration)}. */ + @Test + public void testConfigurationCompareTo() throws Exception { + final Configuration blankConfig = new Configuration(); + final WindowConfiguration blankWinConfig = new WindowConfiguration(); + + final Configuration config1 = new Configuration(); + final WindowConfiguration winConfig1 = config1.windowConfiguration; + winConfig1.setAppBounds(1, 2, 3, 4); + + final Configuration config2 = new Configuration(config1); + final WindowConfiguration winConfig2 = config2.windowConfiguration; + + assertEquals(config1.compareTo(config2), 0); + assertEquals(winConfig1.compareTo(winConfig2), 0); + + // Different bounds + winConfig2.setAppBounds(0, 2, 3, 4); - assertEquals(ActivityInfo.CONFIG_SCREEN_SIZE, config.diff(config2)); - assertEquals(0, config.diffPublicOnly(config2)); + assertNotEquals(config1.compareTo(config2), 0); + assertNotEquals(winConfig1.compareTo(winConfig2), 0); + + // No bounds + assertEquals(config1.compareTo(blankConfig), -1); + assertEquals(winConfig1.compareTo(blankWinConfig), -1); + + assertEquals(blankConfig.compareTo(config1), 1); + assertEquals(blankWinConfig.compareTo(winConfig1), 1); } - /** - * Ensures the configuration app bounds at the root level match the app dimensions. - */ + /** Ensures the configuration app bounds at the root level match the app dimensions. */ @Test - public void testRootConfigurationBounds() throws Exception { + public void testAppBounds_RootConfigurationBounds() throws Exception { final DisplayInfo info = mDisplayContent.getDisplayInfo(); info.appWidth = 1024; info.appHeight = 768; - final Configuration config = sWm.computeNewConfiguration(mDisplayContent.getDisplayId()); + final Rect appBounds = sWm.computeNewConfiguration( + mDisplayContent.getDisplayId()).windowConfiguration.getAppBounds(); // The bounds should always be positioned in the top left. - assertEquals(config.appBounds.left, 0); - assertEquals(config.appBounds.top, 0); + assertEquals(appBounds.left, 0); + assertEquals(appBounds.top, 0); // The bounds should equal the defined app width and height - assertEquals(config.appBounds.width(), info.appWidth); - assertEquals(config.appBounds.height(), info.appHeight); + assertEquals(appBounds.width(), info.appWidth); + assertEquals(appBounds.height(), info.appHeight); } - /** - * Ensures that bounds are clipped to their parent. - */ + /** Ensures that bounds are clipped to their parent. */ @Test - public void testBoundsClipping() throws Exception { + public void testAppBounds_BoundsClipping() throws Exception { final Rect shiftedBounds = new Rect(mParentBounds); shiftedBounds.offset(10, 10); final Rect expectedBounds = new Rect(mParentBounds); @@ -95,42 +135,34 @@ public class AppBoundsTests extends WindowTestsBase { expectedBounds); } - /** - * Ensures that empty bounds are not propagated to the configuration. - */ + /** Ensures that empty bounds are not propagated to the configuration. */ @Test - public void testEmptyBounds() throws Exception { + public void testAppBounds_EmptyBounds() throws Exception { final Rect emptyBounds = new Rect(); testStackBoundsConfiguration(null /*stackId*/, mParentBounds, emptyBounds, null /*ExpectedBounds*/); } - /** - * Ensures that bounds on freeform stacks are not clipped. - */ + /** Ensures that bounds on freeform stacks are not clipped. */ @Test - public void testFreeFormBounds() throws Exception { + public void testAppBounds_FreeFormBounds() throws Exception { final Rect freeFormBounds = new Rect(mParentBounds); freeFormBounds.offset(10, 10); - testStackBoundsConfiguration(ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID, - mParentBounds, freeFormBounds, freeFormBounds); + testStackBoundsConfiguration(FREEFORM_WORKSPACE_STACK_ID, mParentBounds, freeFormBounds, + freeFormBounds); } - /** - * Ensures that fully contained bounds are not clipped. - */ + /** Ensures that fully contained bounds are not clipped. */ @Test - public void testContainedBounds() throws Exception { + public void testAppBounds_ContainedBounds() throws Exception { final Rect insetBounds = new Rect(mParentBounds); insetBounds.inset(5, 5, 5, 5); testStackBoundsConfiguration(null /*stackId*/, mParentBounds, insetBounds, insetBounds); } - /** - * Ensures that full screen free form bounds are clipped - */ + /** Ensures that full screen free form bounds are clipped */ @Test - public void testFullScreenFreeFormBounds() throws Exception { + public void testAppBounds_FullScreenFreeFormBounds() throws Exception { final Rect fullScreenBounds = new Rect(0, 0, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight); testStackBoundsConfiguration(null /*stackId*/, mParentBounds, fullScreenBounds, @@ -144,40 +176,17 @@ public class AppBoundsTests extends WindowTestsBase { : createStackControllerOnDisplay(mDisplayContent); final Configuration parentConfig = mDisplayContent.getConfiguration(); - parentConfig.setAppBounds(parentBounds); + parentConfig.windowConfiguration.setAppBounds(parentBounds); final Configuration config = new Configuration(); + final WindowConfiguration winConfig = config.windowConfiguration; stackController.adjustConfigurationForBounds(bounds, null /*insetBounds*/, new Rect() /*nonDecorBounds*/, new Rect() /*stableBounds*/, false /*overrideWidth*/, false /*overrideHeight*/, mDisplayInfo.logicalDensityDpi, config, parentConfig); // Assert that both expected and actual are null or are equal to each other - assertTrue((expectedConfigBounds == null && config.appBounds == null) - || expectedConfigBounds.equals(config.appBounds)); + assertTrue((expectedConfigBounds == null && winConfig.getAppBounds() == null) + || expectedConfigBounds.equals(winConfig.getAppBounds())); } - /** - * Ensures appBounds are considered in {@link Configuration#compareTo(Configuration)}. - */ - @Test - public void testConfigurationCompareTo() throws Exception { - final Configuration blankConfig = new Configuration(); - - final Configuration config1 = new Configuration(); - config1.appBounds = new Rect(1, 2, 3, 4); - - final Configuration config2 = new Configuration(config1); - - assertEquals(config1.compareTo(config2), 0); - - config2.appBounds.left = 0; - - // Different bounds - assertNotEquals(config1.compareTo(config2), 0); - - // No bounds - assertEquals(config1.compareTo(blankConfig), -1); - assertEquals(blankConfig.compareTo(config1), 1); - - } } |