diff options
40 files changed, 746 insertions, 1150 deletions
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index dbb3ecd0bc36..0f60eaebd59f 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -508,6 +508,8 @@ message Atom {          MediaPlaybackStateChanged media_playback_state_changed = 322;          MediaPlaybackErrorReported media_playback_error_reported = 323;          MediaPlaybackTrackChanged media_playback_track_changed = 324; +        WifiScanReported wifi_scan_reported = 325 [(module) = "wifi"]; +        WifiPnoScanReported wifi_pno_scan_reported = 326  [(module) = "wifi"];          // StatsdStats tracks platform atoms with ids upto 500.          // Update StatsdStats::kMaxPushedAtomId when atom ids here approach that value. @@ -12374,3 +12376,115 @@ message Experiments {      // Experiment IDs sent by the player.      repeated int64 experiments = 1;  } + +/** + * Logs when a Wifi network scan happens. + * + * Logged from: + *   frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiMetrics.java + */ +message WifiScanReported { +    enum Type { +        TYPE_UNKNOWN = 0; + +        // Single scan. +        TYPE_SINGLE = 1; + +        // Background scan (deprecated, should not happen). +        TYPE_BACKGROUND = 2; +    } + +    enum Result { +        RESULT_UNKNOWN = 0; + +        // Failed to start scan. +        RESULT_FAILED_TO_START = 1; + +        // The HAL reported a scan failure after the scan was started. +        RESULT_FAILED_TO_SCAN = 2; + +        // Scan succeeded. +        RESULT_SUCCESS = 3; +    } + +    enum Source { +        SOURCE_UNKNOWN = 0; + +        // No work source set - not possible to determine the origin. +        SOURCE_NO_WORK_SOURCE = 1; + +        // The Wifi stack. +        SOURCE_WIFI_STACK = 2; + +        // GMS on behalf of some other app. +        SOURCE_GMS = 3; + +        // Settings app. +        SOURCE_SETTINGS_APP = 4; + +        // Other app directly. +        SOURCE_OTHER_APP = 5; +    } + +    enum Importance { +        IMPORTANCE_UNKNOWN = 0; + +        // Foreground app. Corresponds to the value of +        // ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND or less. +        IMPORTANCE_FOREGROUND = 1; + +        // Foreground service. Corresponds to the value of +        // ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND_SERVICE +        IMPORTANCE_FOREGROUND_SERVICE = 2; + +        // Everything else. +        IMPORTANCE_BACKGROUND = 3; +    } + +    // Scan type +    optional Type type = 1; + +    // Outcome: success/failure +    optional Result result = 2; + +    // What initiated a scan. +    optional Source source = 3; + +    // Process importance of the initiator. +    // This is only available for non-system calls. +    optional Importance importance = 4; + +    // Time taken for the scan. +    optional int32 scan_duration_millis = 5; + +    // Count of found networks. +    optional int32 count_networks_found = 6; +} + +/** + * Logs when a Wifi PNO (Preferred Network Offload) scan happens. + * + * Logged from: + *   frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiMetrics.java + */ +message WifiPnoScanReported { +    enum State { +        UNKNOWN = 0; + +        // Scan started. +        STARTED = 1; + +        // Scan failed to start (e.g. bad request, unsupported by hardware, etc). +        FAILED_TO_START = 2; + +        // Scan completed and a network was found. +        // Note - due to implementation constraints, nothing is reported when a scan completes but +        // doesn't find any networks. +        FINISHED_NETWORKS_FOUND = 3; + +        // Scan failed. +        FAILED = 4; +    } + +    optional State state = 1; +} diff --git a/core/api/current.txt b/core/api/current.txt index 419ae51b1de9..f665512070f5 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -15483,6 +15483,8 @@ package android.graphics {      method @NonNull public String flattenToString();      method public int height();      method public void inset(int, int); +    method public void inset(@NonNull android.graphics.Insets); +    method public void inset(int, int, int, int);      method @CheckResult public boolean intersect(int, int, int, int);      method @CheckResult public boolean intersect(@NonNull android.graphics.Rect);      method public boolean intersects(int, int, int, int); diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 6e141b89f925..d83c0adb3ae1 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -11,6 +11,11 @@ package android.app {      field public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage";    } +  public class BroadcastOptions { +    method public int getMaxManifestReceiverApiLevel(); +    method public void setMaxManifestReceiverApiLevel(int); +  } +    public abstract class HomeVisibilityListener {      ctor public HomeVisibilityListener();      method public abstract void onHomeVisibilityChanged(boolean); diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java index 3789a44e1d55..03dca30f8560 100644 --- a/core/java/android/app/BroadcastOptions.java +++ b/core/java/android/app/BroadcastOptions.java @@ -127,6 +127,7 @@ public class BroadcastOptions {       * them.  This only applies to receivers declared in the app's AndroidManifest.xml.       * @hide       */ +    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)      public void setMaxManifestReceiverApiLevel(int apiLevel) {          mMaxManifestReceiverApiLevel = apiLevel;      } @@ -135,6 +136,7 @@ public class BroadcastOptions {       * Return {@link #setMaxManifestReceiverApiLevel}.       * @hide       */ +    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)      public int getMaxManifestReceiverApiLevel() {          return mMaxManifestReceiverApiLevel;      } diff --git a/core/java/android/app/SharedPreferencesImpl.java b/core/java/android/app/SharedPreferencesImpl.java index bc1bcbc4f80e..1ebf56550e03 100644 --- a/core/java/android/app/SharedPreferencesImpl.java +++ b/core/java/android/app/SharedPreferencesImpl.java @@ -19,7 +19,7 @@ package android.app;  import android.annotation.Nullable;  import android.compat.Compatibility;  import android.compat.annotation.ChangeId; -import android.compat.annotation.EnabledAfter; +import android.compat.annotation.EnabledSince;  import android.compat.annotation.UnsupportedAppUsage;  import android.content.SharedPreferences;  import android.os.Build; @@ -71,7 +71,7 @@ final class SharedPreferencesImpl implements SharedPreferences {       * {@link android.content.SharedPreferences.Editor#clear Editor.clear}.       */      @ChangeId -    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q) +    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.R)      private static final long CALLBACK_ON_CLEAR_CHANGE = 119147584L;      // Lock ordering rules: diff --git a/core/java/android/content/om/OverlayManager.java b/core/java/android/content/om/OverlayManager.java index fd3d48f2fd0e..217f637cf9e3 100644 --- a/core/java/android/content/om/OverlayManager.java +++ b/core/java/android/content/om/OverlayManager.java @@ -23,7 +23,7 @@ import android.annotation.SystemApi;  import android.annotation.SystemService;  import android.compat.Compatibility;  import android.compat.annotation.ChangeId; -import android.compat.annotation.EnabledAfter; +import android.compat.annotation.EnabledSince;  import android.content.Context;  import android.os.Build;  import android.os.Process; @@ -90,7 +90,7 @@ public class OverlayManager {       * java.lang.IllegalStateException}, which existed in the source prior to R.       */      @ChangeId -    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q) +    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.R)      private static final long THROW_SECURITY_EXCEPTIONS = 147340954;      /** diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java index ac29f2eb5c0b..41b2fb4d2097 100644 --- a/core/java/android/view/InsetsState.java +++ b/core/java/android/view/InsetsState.java @@ -238,6 +238,22 @@ public class InsetsState implements Parcelable {                  (legacySystemUiFlags & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0);      } +    public Rect calculateInsets(Rect frame, @InsetsType int types, boolean ignoreVisibility) { +        Insets insets = Insets.NONE; +        for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) { +            InsetsSource source = mSources[type]; +            if (source == null) { +                continue; +            } +            int publicType = InsetsState.toPublicType(type); +            if ((publicType & types) == 0) { +                continue; +            } +            insets = Insets.max(source.calculateInsets(frame, ignoreVisibility), insets); +        } +        return insets.toRect(); +    } +      public Rect calculateVisibleInsets(Rect frame, @SoftInputModeFlags int softInputMode) {          Insets insets = Insets.NONE;          for (int type = FIRST_TYPE; type <= LAST_TYPE; type++) { diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 33a1f228e2ad..2bea0d6b4b04 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -1023,6 +1023,15 @@ public final class ViewRootImpl implements ViewParent,                  }                  mForceDecorViewVisibility = (mWindowAttributes.privateFlags                          & PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY) != 0; + +                if (mView instanceof RootViewSurfaceTaker) { +                    PendingInsetsController pendingInsetsController = +                            ((RootViewSurfaceTaker) mView).providePendingInsetsController(); +                    if (pendingInsetsController != null) { +                        pendingInsetsController.replayAndAttach(mInsetsController); +                    } +                } +                  try {                      mOrigWindowType = mWindowAttributes.type;                      mAttachInfo.mRecomputeGlobalAttributes = true; @@ -1160,14 +1169,6 @@ public final class ViewRootImpl implements ViewParent,                  mFirstInputStage = nativePreImeStage;                  mFirstPostImeInputStage = earlyPostImeStage;                  mPendingInputEventQueueLengthCounterName = "aq:pending:" + counterSuffix; - -                if (mView instanceof RootViewSurfaceTaker) { -                    PendingInsetsController pendingInsetsController = -                            ((RootViewSurfaceTaker) mView).providePendingInsetsController(); -                    if (pendingInsetsController != null) { -                        pendingInsetsController.replayAndAttach(mInsetsController); -                    } -                }              }          }      } diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java index 8b0cf3bb86dc..2168dd01089d 100644 --- a/core/java/android/view/WindowInsets.java +++ b/core/java/android/view/WindowInsets.java @@ -1344,6 +1344,9 @@ public final class WindowInsets {              if ((types & NAVIGATION_BARS) != 0) {                  result.append("navigationBars |");              } +            if ((types & CAPTION_BAR) != 0) { +                result.append("captionBar |"); +            }              if ((types & IME) != 0) {                  result.append("ime |");              } diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto index ce52a352e10b..32a40d9a285b 100644 --- a/core/proto/android/server/windowmanagerservice.proto +++ b/core/proto/android/server/windowmanagerservice.proto @@ -239,9 +239,9 @@ message DisplayAreaChildProto {  message DisplayFramesProto {      option (.android.msg_privacy).dest = DEST_AUTOMATIC; -    optional .android.graphics.RectProto stable_bounds = 1; -    optional .android.graphics.RectProto dock = 2; -    optional .android.graphics.RectProto current = 3; +    optional .android.graphics.RectProto stable_bounds = 1 [deprecated=true]; +    optional .android.graphics.RectProto dock = 2 [deprecated=true]; +    optional .android.graphics.RectProto current = 3 [deprecated=true];  }  message DisplayRotationProto { @@ -499,19 +499,19 @@ message WindowFramesProto {      option (.android.msg_privacy).dest = DEST_AUTOMATIC;      optional .android.graphics.RectProto containing_frame = 1; -    optional .android.graphics.RectProto content_frame = 2; -    optional .android.graphics.RectProto decor_frame = 3; +    optional .android.graphics.RectProto content_frame = 2 [deprecated=true]; +    optional .android.graphics.RectProto decor_frame = 3 [deprecated=true];      optional .android.graphics.RectProto display_frame = 4;      optional .android.graphics.RectProto frame = 5;      optional .android.graphics.RectProto outset_frame = 6;      optional .android.graphics.RectProto overscan_frame = 7 [deprecated=true];      optional .android.graphics.RectProto parent_frame = 8; -    optional .android.graphics.RectProto visible_frame = 9; +    optional .android.graphics.RectProto visible_frame = 9 [deprecated=true];      optional .android.view.DisplayCutoutProto cutout = 10; -    optional .android.graphics.RectProto content_insets = 11; +    optional .android.graphics.RectProto content_insets = 11 [deprecated=true];      optional .android.graphics.RectProto overscan_insets = 12 [deprecated=true]; -    optional .android.graphics.RectProto visible_insets = 13; -    optional .android.graphics.RectProto stable_insets = 14; +    optional .android.graphics.RectProto visible_insets = 13 [deprecated=true]; +    optional .android.graphics.RectProto stable_insets = 14 [deprecated=true];      optional .android.graphics.RectProto outsets = 15;  } diff --git a/graphics/java/android/graphics/Rect.java b/graphics/java/android/graphics/Rect.java index 081b851d1333..87ca9607dbce 100644 --- a/graphics/java/android/graphics/Rect.java +++ b/graphics/java/android/graphics/Rect.java @@ -433,10 +433,10 @@ public final class Rect implements Parcelable {      /**       * Insets the rectangle on all sides specified by the dimensions of {@code insets}. -     * @hide +     *       * @param insets The insets to inset the rect by.       */ -    public void inset(Insets insets) { +    public void inset(@NonNull Insets insets) {          left += insets.left;          top += insets.top;          right -= insets.right; @@ -445,7 +445,7 @@ public final class Rect implements Parcelable {      /**       * Insets the rectangle on all sides specified by the insets. -     * @hide +     *       * @param left The amount to add from the rectangle's left       * @param top The amount to add from the rectangle's top       * @param right The amount to subtract from the rectangle's right diff --git a/media/java/android/media/metrics/IPlaybackMetricsManager.aidl b/media/java/android/media/metrics/IPlaybackMetricsManager.aidl new file mode 100644 index 000000000000..fcb7d608f662 --- /dev/null +++ b/media/java/android/media/metrics/IPlaybackMetricsManager.aidl @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2020 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.media.metrics; + +import android.media.metrics.PlaybackMetrics; + +/** + * Interface to the playback manager service. + * @hide + */ +interface IPlaybackMetricsManager { +    void reportPlaybackMetrics(in PlaybackMetrics metrics, int userId); +}
\ No newline at end of file diff --git a/media/java/android/media/metrics/OWNERS b/media/java/android/media/metrics/OWNERS new file mode 100644 index 000000000000..f8696efcf8f6 --- /dev/null +++ b/media/java/android/media/metrics/OWNERS @@ -0,0 +1,3 @@ +essick@google.com +nchalko@google.com +shubang@google.com
\ No newline at end of file diff --git a/media/java/android/media/metrics/PlaybackMetrics.aidl b/media/java/android/media/metrics/PlaybackMetrics.aidl new file mode 100644 index 000000000000..321025b4813b --- /dev/null +++ b/media/java/android/media/metrics/PlaybackMetrics.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2020 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.media.metrics; + +parcelable PlaybackMetrics; diff --git a/media/java/android/media/metrics/PlaybackMetrics.java b/media/java/android/media/metrics/PlaybackMetrics.java new file mode 100644 index 000000000000..82a58036cfa4 --- /dev/null +++ b/media/java/android/media/metrics/PlaybackMetrics.java @@ -0,0 +1,88 @@ +/* + * Copyright (C) 2020 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.media.metrics; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Objects; + +/** + * This class is used to store playback data. + * @hide + */ +public final class PlaybackMetrics implements Parcelable { +    private int mStreamSourceType; + +    /** +     * Creates a new PlaybackMetrics. +     * +     * @hide +     */ +    public PlaybackMetrics(int streamSourceType) { +        this.mStreamSourceType = streamSourceType; +    } + +    public int getStreamSourceType() { +        return mStreamSourceType; +    } + +    @Override +    public boolean equals(@Nullable Object o) { + +        if (this == o) return true; +        if (o == null || getClass() != o.getClass()) return false; +        PlaybackMetrics that = (PlaybackMetrics) o; +        return mStreamSourceType == that.mStreamSourceType; +    } + +    @Override +    public int hashCode() { +        return Objects.hash(mStreamSourceType); +    } + +    @Override +    public void writeToParcel(@NonNull Parcel dest, int flags) { +        dest.writeInt(mStreamSourceType); +    } + +    @Override +    public int describeContents() { +        return 0; +    } + +    /** @hide */ +    /* package-private */ PlaybackMetrics(@NonNull Parcel in) { +        int streamSourceType = in.readInt(); +        this.mStreamSourceType = streamSourceType; +    } + +    public static final @NonNull Parcelable.Creator<PlaybackMetrics> CREATOR = +            new Parcelable.Creator<PlaybackMetrics>() { +                @Override +                public PlaybackMetrics[] newArray(int size) { +                    return new PlaybackMetrics[size]; +                } + +                @Override +                public PlaybackMetrics createFromParcel(@NonNull Parcel in) { +                    return new PlaybackMetrics(in); +                } +            }; +} diff --git a/media/java/android/media/metrics/PlaybackMetricsManager.java b/media/java/android/media/metrics/PlaybackMetricsManager.java new file mode 100644 index 000000000000..3606f53d7220 --- /dev/null +++ b/media/java/android/media/metrics/PlaybackMetricsManager.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 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.media.metrics; + +import android.os.RemoteException; + +/** + * @hide + */ +public class PlaybackMetricsManager { +    // TODO: unhide APIs. +    private static final String TAG = "PlaybackMetricsManager"; + +    private IPlaybackMetricsManager mService; +    private int mUserId; + +    /** +     * @hide +     */ +    public PlaybackMetricsManager(IPlaybackMetricsManager service, int userId) { +        mService = service; +        mUserId = userId; +    } + +    /** +     * Reports playback metrics. +     */ +    public void reportPlaybackMetrics(PlaybackMetrics metrics) { +        try { +            mService.reportPlaybackMetrics(metrics, mUserId); +        } catch (RemoteException e) { +            throw e.rethrowFromSystemServer(); +        } +    } +} diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java index 3091a7178377..163788f4a4df 100644 --- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java +++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java @@ -21,7 +21,7 @@ import android.net.ConnectivityManager;  import android.net.IDnsResolver;  import android.net.INetd;  import android.net.InetAddresses; -import android.net.InterfaceConfiguration; +import android.net.InterfaceConfigurationParcel;  import android.net.IpPrefix;  import android.net.LinkAddress;  import android.net.LinkProperties; @@ -447,9 +447,10 @@ public class Nat464Xlat extends BaseNetworkObserver {      private LinkAddress getLinkAddress(String iface) {          try { -            InterfaceConfiguration config = mNMService.getInterfaceConfig(iface); -            return config.getLinkAddress(); -        } catch (RemoteException | IllegalStateException e) { +            final InterfaceConfigurationParcel config = mNetd.interfaceGetCfg(iface); +            return new LinkAddress( +                    InetAddresses.parseNumericAddress(config.ipv4Addr), config.prefixLength); +        } catch (IllegalArgumentException | RemoteException | ServiceSpecificException e) {              Slog.e(TAG, "Error getting link properties: " + e);              return null;          } diff --git a/services/core/java/com/android/server/media/metrics/OWNERS b/services/core/java/com/android/server/media/metrics/OWNERS new file mode 100644 index 000000000000..f8696efcf8f6 --- /dev/null +++ b/services/core/java/com/android/server/media/metrics/OWNERS @@ -0,0 +1,3 @@ +essick@google.com +nchalko@google.com +shubang@google.com
\ No newline at end of file diff --git a/services/core/java/com/android/server/media/metrics/PlaybackMetricsManagerService.java b/services/core/java/com/android/server/media/metrics/PlaybackMetricsManagerService.java new file mode 100644 index 000000000000..adb98695161a --- /dev/null +++ b/services/core/java/com/android/server/media/metrics/PlaybackMetricsManagerService.java @@ -0,0 +1,51 @@ +/* + * Copyright 2020 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 com.android.server.media.metrics; + +import android.content.Context; +import android.media.metrics.IPlaybackMetricsManager; +import android.media.metrics.PlaybackMetrics; + +import com.android.server.SystemService; + +/** + * System service manages playback metrics. + */ +public final class PlaybackMetricsManagerService extends SystemService { + +    /** +     * Initializes the playback metrics manager service. +     * +     * @param context The system server context. +     */ +    public PlaybackMetricsManagerService(Context context) { +        super(context); +    } + +    @Override +    public void onStart() { +        // TODO: make the service name a constant in Context.java +        publishBinderService("playback_metrics", new BinderService()); +    } + +    private final class BinderService extends IPlaybackMetricsManager.Stub { +        @Override +        public void reportPlaybackMetrics(PlaybackMetrics metrics, int userId) { +            // TODO: log it to statsd +        } +    } +} diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index 22ebf306c474..d8b750ea7484 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -288,6 +288,7 @@ import android.view.RemoteAnimationDefinition;  import android.view.RemoteAnimationTarget;  import android.view.SurfaceControl;  import android.view.SurfaceControl.Transaction; +import android.view.WindowInsets.Type;  import android.view.WindowManager;  import android.view.WindowManager.LayoutParams;  import android.view.animation.Animation; @@ -4232,7 +4233,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A                                  // Force add to mResizingWindows, so that we are guaranteed to get                                  // another reportDrawn callback. -                                w.resetLastContentInsets(); +                                w.forceReportingResized();                              }                          }, true /* traverseTopToBottom */);                      } @@ -6195,9 +6196,17 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A          // destination of the thumbnail header animation. If this is a full screen          // window scenario, we use the whole display as the target.          WindowState win = findMainWindow(); -        final Rect appRect = win != null ? win.getContentFrame() : -                new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight); -        final Rect insets = win != null ? win.getContentInsets() : null; +        Rect insets; +        Rect appRect; +        if (win != null) { +            insets = win.getInsetsStateWithVisibilityOverride().calculateInsets( +                    win.getFrame(), Type.systemBars(), false /* ignoreVisibility */); +            appRect = new Rect(win.getFrame()); +            appRect.inset(insets); +        } else { +            insets = null; +            appRect = new Rect(0, 0, displayInfo.appWidth, displayInfo.appHeight); +        }          final Configuration displayConfig = mDisplayContent.getConfiguration();          return getDisplayContent().mAppTransition.createThumbnailAspectScaleAnimationLocked(                  appRect, insets, thumbnailHeader, task, displayConfig.uiMode, @@ -7932,8 +7941,8 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A          if (task == null || mainWindow == null) {              return null;          } -        final Rect insets = new Rect(); -        mainWindow.getContentInsets(insets); +        final Rect insets = mainWindow.getInsetsStateWithVisibilityOverride().calculateInsets( +                task.getBounds(), Type.systemBars(), false /* ignoreVisibility */);          InsetUtils.addInsets(insets, getLetterboxInsets());          return new RemoteAnimationTarget(task.mTaskId, record.getMode(), diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index c2f43fe453dc..388422e19090 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -51,6 +51,9 @@ import static android.view.Surface.ROTATION_180;  import static android.view.Surface.ROTATION_270;  import static android.view.Surface.ROTATION_90;  import static android.view.View.GONE; +import static android.view.WindowInsets.Type.displayCutout; +import static android.view.WindowInsets.Type.ime; +import static android.view.WindowInsets.Type.systemBars;  import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;  import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;  import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; @@ -756,7 +759,7 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp                  if (!w.getFrame().isEmpty()) {                      w.updateLastFrames();                  } -                w.updateLastInsetValues(); +                w.onResizeHandled();                  w.updateLocationInParentDisplayIfNeeded();              } @@ -2562,7 +2565,9 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp      }      void getStableRect(Rect out) { -        out.set(mDisplayFrames.mStable); +        final InsetsState state = mDisplayContent.getInsetsStateController().getRawInsetsState(); +        out.set(state.getDisplayFrame()); +        out.inset(state.calculateInsets(out, systemBars(), true /* ignoreVisibility */));      }      /** @@ -2690,12 +2695,13 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp                  // If the task is freeformed, enlarge the area to account for outside                  // touch area for resize.                  mTmpRect.inset(-delta, -delta); -                // Intersect with display content rect. If we have system decor (status bar/ +                // Intersect with display content frame. If we have system decor (status bar/                  // navigation bar), we want to exclude that from the tap detection.                  // Otherwise, if the app is partially placed under some system button (eg.                  // Recents, Home), pressing that button would cause a full series of                  // unwanted transfer focus/resume/pause, before we could go home. -                mTmpRect.intersect(mDisplayFrames.mContent); +                mTmpRect.inset(getInsetsStateController().getRawInsetsState().calculateInsets( +                        mTmpRect, systemBars() | ime(), false /* ignoreVisibility */));              }              mTouchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE);          } @@ -2783,10 +2789,25 @@ class DisplayContent extends RootDisplayArea implements WindowManagerPolicy.Disp          final WindowState imeWin = mInputMethodWindow;          final boolean imeVisible = imeWin != null && imeWin.isVisible()                  && imeWin.isDisplayed(); -        final int imeHeight = mDisplayFrames.getInputMethodWindowVisibleHeight(); +        final int imeHeight = getInputMethodWindowVisibleHeight();          mPinnedStackControllerLocked.setAdjustedForIme(imeVisible, imeHeight);      } +    int getInputMethodWindowVisibleHeight() { +        final InsetsState state = getInsetsStateController().getRawInsetsState(); +        final InsetsSource imeSource = state.peekSource(ITYPE_IME); +        if (imeSource == null || !imeSource.isVisible()) { +            return 0; +        } +        final Rect imeFrame = imeSource.getVisibleFrame() != null +                ? imeSource.getVisibleFrame() : imeSource.getFrame(); +        final Rect dockFrame = mTmpRect; +        dockFrame.set(state.getDisplayFrame()); +        dockFrame.inset(state.calculateInsets(dockFrame, systemBars() | displayCutout(), +                false /* ignoreVisibility */)); +        return dockFrame.bottom - imeFrame.top; +    } +      void prepareFreezingTaskBounds() {          forAllTaskDisplayAreas(TaskDisplayArea::prepareFreezingTaskBounds);      } diff --git a/services/core/java/com/android/server/wm/DisplayFrames.java b/services/core/java/com/android/server/wm/DisplayFrames.java index d67f3f967e66..7f3cb49d20e5 100644 --- a/services/core/java/com/android/server/wm/DisplayFrames.java +++ b/services/core/java/com/android/server/wm/DisplayFrames.java @@ -16,10 +16,6 @@  package com.android.server.wm; -import static com.android.server.wm.DisplayFramesProto.CURRENT; -import static com.android.server.wm.DisplayFramesProto.DOCK; -import static com.android.server.wm.DisplayFramesProto.STABLE_BOUNDS; -  import android.annotation.NonNull;  import android.graphics.Rect;  import android.util.proto.ProtoOutputStream; @@ -43,51 +39,6 @@ public class DisplayFrames {       */      public final Rect mUnrestricted = new Rect(); -    /** -     * The current size of the screen; these may be different than (0,0)-(dw,dh) if the status bar -     * can't be hidden; in that case it effectively carves out that area of the display from all -     * other windows. -     */ -    public final Rect mRestricted = new Rect(); - -    /** -     * During layout, the current screen borders accounting for any currently visible system UI -     * elements. -     */ -    public final Rect mSystem = new Rect(); - -    /** For applications requesting stable content insets, these are them. */ -    public final Rect mStable = new Rect(); - -    /** -     * For applications requesting stable content insets but have also set the fullscreen window -     * flag, these are the stable dimensions without the status bar. -     */ -    public final Rect mStableFullscreen = new Rect(); - -    /** -     * During layout, the current screen borders with all outer decoration (status bar, input method -     * dock) accounted for. -     */ -    public final Rect mCurrent = new Rect(); - -    /** -     * During layout, the frame in which content should be displayed to the user, accounting for all -     * screen decoration except for any space they deem as available for other content. This is -     * usually the same as mCurrent*, but may be larger if the screen decor has supplied content -     * insets. -     */ -    public final Rect mContent = new Rect(); - -    /** -     * During layout, the frame in which voice content should be displayed to the user, accounting -     * for all screen decoration except for any space they deem as available for other content. -     */ -    public final Rect mVoiceContent = new Rect(); - -    /** During layout, the current screen borders along which input method windows are placed. */ -    public final Rect mDock = new Rect(); -      /** The display cutout used for layout (after rotation) */      @NonNull public WmDisplayCutout mDisplayCutout = WmDisplayCutout.NO_CUTOUT; @@ -118,15 +69,6 @@ public class DisplayFrames {      public void onBeginLayout() {          mUnrestricted.set(0, 0, mDisplayWidth, mDisplayHeight); -        mRestricted.set(mUnrestricted); -        mSystem.set(mUnrestricted); -        mDock.set(mUnrestricted); -        mContent.set(mUnrestricted); -        mVoiceContent.set(mUnrestricted); -        mStable.set(mUnrestricted); -        mStableFullscreen.set(mUnrestricted); -        mCurrent.set(mUnrestricted); -          mDisplayCutout = mDisplayInfoCutout;          mDisplayCutoutSafe.set(Integer.MIN_VALUE, Integer.MIN_VALUE,                  Integer.MAX_VALUE, Integer.MAX_VALUE); @@ -147,15 +89,8 @@ public class DisplayFrames {          }      } -    public int getInputMethodWindowVisibleHeight() { -        return mDock.bottom - mCurrent.bottom; -    } -      public void dumpDebug(ProtoOutputStream proto, long fieldId) {          final long token = proto.start(fieldId); -        mStable.dumpDebug(proto, STABLE_BOUNDS); -        mDock.dumpDebug(proto, DOCK); -        mCurrent.dumpDebug(proto, CURRENT);          proto.end(token);      } @@ -163,14 +98,6 @@ public class DisplayFrames {          pw.println(prefix + "DisplayFrames w=" + mDisplayWidth + " h=" + mDisplayHeight                  + " r=" + mRotation);          final String myPrefix = prefix + "  "; -        dumpFrame(mStable, "mStable", myPrefix, pw); -        dumpFrame(mStableFullscreen, "mStableFullscreen", myPrefix, pw); -        dumpFrame(mDock, "mDock", myPrefix, pw); -        dumpFrame(mCurrent, "mCurrent", myPrefix, pw); -        dumpFrame(mSystem, "mSystem", myPrefix, pw); -        dumpFrame(mContent, "mContent", myPrefix, pw); -        dumpFrame(mVoiceContent, "mVoiceContent", myPrefix, pw); -        dumpFrame(mRestricted, "mRestricted", myPrefix, pw);          dumpFrame(mUnrestricted, "mUnrestricted", myPrefix, pw);          pw.println(myPrefix + "mDisplayCutout=" + mDisplayCutout);      } diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index fc3fc4731e7d..11a436ec26c4 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -68,9 +68,6 @@ import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_  import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP;  import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;  import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY; -import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; -import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; -import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;  import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;  import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;  import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; @@ -323,7 +320,6 @@ public class DisplayPolicy {      private boolean mLastImmersiveMode; -    private StatusBarManagerInternal mStatusBarInternal;      private final BarController mStatusBarController;      private final BarController mNavigationBarController; @@ -333,12 +329,6 @@ public class DisplayPolicy {      private WindowState mSystemUiControllingWindow; -    // The states of decor windows from the last layout. These are used to generate another display -    // layout in different bounds but with the same states. -    private boolean mLastNavVisible; -    private boolean mLastNavTranslucent; -    private boolean mLastNavAllowedHidden; -      private int mLastDisableFlags;      private int mLastAppearance;      private int mLastFullscreenAppearance; @@ -1568,18 +1558,14 @@ public class DisplayPolicy {              simulateLayoutDecorWindow(mNavigationBar, displayFrames, insetsState,                      simulatedWindowFrames, barContentFrames,                      contentFrame -> layoutNavigationBar(displayFrames, -                            mDisplayContent.getConfiguration().uiMode, mLastNavVisible, -                            mLastNavTranslucent, mLastNavAllowedHidden, -                            contentFrame)); +                            mDisplayContent.getConfiguration().uiMode, contentFrame));          }          if (mStatusBar != null) {              simulateLayoutDecorWindow(mStatusBar, displayFrames, insetsState,                      simulatedWindowFrames, barContentFrames, -                    contentFrame -> layoutStatusBar(displayFrames, mLastAppearance, -                            contentFrame)); +                    contentFrame -> layoutStatusBar(displayFrames, contentFrame));          }          layoutScreenDecorWindows(displayFrames, simulatedWindowFrames); -        postAdjustDisplayFrames(displayFrames);      }      /** @@ -1596,35 +1582,11 @@ public class DisplayPolicy {          mSystemGestures.screenWidth = displayFrames.mUnrestricted.width();          mSystemGestures.screenHeight = displayFrames.mUnrestricted.height(); -        // For purposes of putting out fake window up to steal focus, we will -        // drive nav being hidden only by whether it is requested. -        final int appearance = mLastAppearance; -        final int behavior = mLastBehavior; -        final InsetsSourceProvider provider = -                mDisplayContent.getInsetsStateController().peekSourceProvider(ITYPE_NAVIGATION_BAR); -        boolean navVisible = provider != null ? provider.isClientVisible() -                : InsetsState.getDefaultVisibility(ITYPE_NAVIGATION_BAR); -        boolean navTranslucent = (appearance & APPEARANCE_OPAQUE_NAVIGATION_BARS) == 0; -        boolean immersive = (behavior & BEHAVIOR_SHOW_BARS_BY_SWIPE) != 0; -        boolean immersiveSticky = (behavior & BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE) != 0; -        boolean navAllowedHidden = immersive || immersiveSticky; -        navTranslucent &= !immersiveSticky;  // transient trumps translucent -          updateHideNavInputEventReceiver(); -        // For purposes of positioning and showing the nav bar, if we have decided that it can't -        // be hidden (because of the screen aspect ratio), then take that into account. -        navVisible |= !canHideNavigationBar(); - -        layoutNavigationBar(displayFrames, uiMode, navVisible, -                navTranslucent, navAllowedHidden, null /* simulatedContentFrame */); -        if (DEBUG_LAYOUT) Slog.i(TAG, "mDock rect:" + displayFrames.mDock); -        layoutStatusBar(displayFrames, appearance, null /* simulatedContentFrame */); +        layoutNavigationBar(displayFrames, uiMode, null /* simulatedContentFrame */); +        layoutStatusBar(displayFrames, null /* simulatedContentFrame */);          layoutScreenDecorWindows(displayFrames, null /* simulatedFrames */); -        postAdjustDisplayFrames(displayFrames); -        mLastNavVisible = navVisible; -        mLastNavTranslucent = navTranslucent; -        mLastNavAllowedHidden = navAllowedHidden;      }      void updateHideNavInputEventReceiver() { @@ -1679,26 +1641,6 @@ public class DisplayPolicy {          state.getSource(ITYPE_BOTTOM_DISPLAY_CUTOUT).setFrame(u.left, s.bottom, u.right, u.bottom);      } -    /** Enforces the last layout policy for display frames. */ -    private void postAdjustDisplayFrames(DisplayFrames displayFrames) { -        if (displayFrames.mDisplayCutoutSafe.top > displayFrames.mUnrestricted.top) { -            // Make sure that the zone we're avoiding for the cutout is at least as tall as the -            // status bar; otherwise fullscreen apps will end up cutting halfway into the status -            // bar. -            displayFrames.mDisplayCutoutSafe.top = Math.max(displayFrames.mDisplayCutoutSafe.top, -                    displayFrames.mStable.top); -        } - -        // In case this is a virtual display, and the host display has insets that overlap this -        // virtual display, apply the insets of the overlapped area onto the current and content -        // frame of this virtual display. This let us layout windows in the virtual display as -        // expected when the window needs to avoid overlap with the system windows. -        // TODO: Generalize the forwarded insets, so that we can handle system windows other than -        // IME. -        displayFrames.mCurrent.inset(mForwardedInsets); -        displayFrames.mContent.inset(mForwardedInsets); -    } -      /**       * Layout the decor windows with {@link #PRIVATE_FLAG_IS_SCREEN_DECOR}.       * @@ -1714,9 +1656,6 @@ public class DisplayPolicy {          sTmpRect.setEmpty();          final int displayId = displayFrames.mDisplayId; -        final Rect dockFrame = displayFrames.mDock; -        final int displayHeight = displayFrames.mDisplayHeight; -        final int displayWidth = displayFrames.mDisplayWidth;          for (int i = mScreenDecorWindows.size() - 1; i >= 0; --i) {              final WindowState w = mScreenDecorWindows.valueAt(i); @@ -1732,10 +1671,7 @@ public class DisplayPolicy {              getRotatedWindowBounds(displayFrames, w, sTmpScreenDecorFrame);              final WindowFrames windowFrames = w.getLayoutingWindowFrames();              windowFrames.setFrames(sTmpScreenDecorFrame /* parentFrame */, -                    sTmpScreenDecorFrame /* displayFrame */, -                    sTmpScreenDecorFrame /* contentFrame */, -                    sTmpScreenDecorFrame /* visibleFrame */, sTmpRect /* decorFrame */, -                    sTmpScreenDecorFrame /* stableFrame */); +                    sTmpScreenDecorFrame /* displayFrame */);              try {                  w.computeFrame(displayFrames);              } finally { @@ -1743,128 +1679,61 @@ public class DisplayPolicy {                      w.setSimulatedWindowFrames(null);                  }              } -            final Rect frame = windowFrames.mFrame; - -            if (frame.left <= 0 && frame.top <= 0) { -                // Docked at left or top. -                if (frame.bottom >= displayHeight) { -                    // Docked left. -                    dockFrame.left = Math.max(frame.right, dockFrame.left); -                } else if (frame.right >= displayWidth) { -                    // Docked top. -                    dockFrame.top = Math.max(frame.bottom, dockFrame.top); -                } else { -                    Slog.w(TAG, "layoutScreenDecorWindows: Ignoring decor win=" + w -                            + " not docked on left or top of display. frame=" + frame -                            + " displayWidth=" + displayWidth + " displayHeight=" + displayHeight); -                } -            } else if (frame.right >= displayWidth && frame.bottom >= displayHeight) { -                // Docked at right or bottom. -                if (frame.top <= 0) { -                    // Docked right. -                    dockFrame.right = Math.min(frame.left, dockFrame.right); -                } else if (frame.left <= 0) { -                    // Docked bottom. -                    dockFrame.bottom = Math.min(frame.top, dockFrame.bottom); -                } else { -                    Slog.w(TAG, "layoutScreenDecorWindows: Ignoring decor win=" + w -                            + " not docked on right or bottom" + " of display. frame=" + frame -                            + " displayWidth=" + displayWidth + " displayHeight=" + displayHeight); -                } -            } else { -                // Screen decor windows are required to be docked on one of the sides of the screen. -                Slog.w(TAG, "layoutScreenDecorWindows: Ignoring decor win=" + w -                        + " not docked on one of the sides of the display. frame=" + frame -                        + " displayWidth=" + displayWidth + " displayHeight=" + displayHeight); -            }          } - -        displayFrames.mRestricted.set(dockFrame); -        displayFrames.mCurrent.set(dockFrame); -        displayFrames.mVoiceContent.set(dockFrame); -        displayFrames.mSystem.set(dockFrame); -        displayFrames.mContent.set(dockFrame);      } -    private void layoutStatusBar(DisplayFrames displayFrames, int appearance, -            Rect simulatedContentFrame) { +    private void layoutStatusBar(DisplayFrames displayFrames, Rect simulatedContentFrame) {          // decide where the status bar goes ahead of time          if (mStatusBar == null) {              return;          }          // apply any status bar insets          getRotatedWindowBounds(displayFrames, mStatusBar, sTmpStatusFrame); -        sTmpRect.setEmpty();          final WindowFrames windowFrames = mStatusBar.getLayoutingWindowFrames();          windowFrames.setFrames(sTmpStatusFrame /* parentFrame */, -                sTmpStatusFrame /* displayFrame */, sTmpStatusFrame /* contentFrame */, -                sTmpStatusFrame /* visibleFrame */, sTmpRect /* decorFrame */, -                sTmpStatusFrame /* stableFrame */); +                sTmpStatusFrame /* displayFrame */);          // Let the status bar determine its size.          mStatusBar.computeFrame(displayFrames);          // For layout, the status bar is always at the top with our fixed height. -        displayFrames.mStable.top = displayFrames.mUnrestricted.top +        int statusBarBottom = displayFrames.mUnrestricted.top                  + mStatusBarHeightForRotation[displayFrames.mRotation];          // Make sure the status bar covers the entire cutout height -        displayFrames.mStable.top = Math.max(displayFrames.mStable.top, -                displayFrames.mDisplayCutoutSafe.top); +        statusBarBottom = Math.max(statusBarBottom, displayFrames.mDisplayCutoutSafe.top); + +        if (displayFrames.mDisplayCutoutSafe.top > displayFrames.mUnrestricted.top) { +            // Make sure that the zone we're avoiding for the cutout is at least as tall as the +            // status bar; otherwise fullscreen apps will end up cutting halfway into the status +            // bar. +            displayFrames.mDisplayCutoutSafe.top = Math.max(displayFrames.mDisplayCutoutSafe.top, +                    statusBarBottom); +        }          // Tell the bar controller where the collapsed status bar content is. -        sTmpRect.set(windowFrames.mContentFrame); +        sTmpRect.set(windowFrames.mFrame);          sTmpRect.intersect(displayFrames.mDisplayCutoutSafe); -        sTmpRect.top = windowFrames.mContentFrame.top; // Ignore top display cutout inset -        sTmpRect.bottom = displayFrames.mStable.top; // Use collapsed status bar size +        sTmpRect.top = windowFrames.mFrame.top; // Ignore top display cutout inset +        sTmpRect.bottom = statusBarBottom; // Use collapsed status bar size          if (simulatedContentFrame != null) {              simulatedContentFrame.set(sTmpRect);          } else {              mStatusBarController.setContentFrame(sTmpRect);          } - -        boolean statusBarTransient = -                mDisplayContent.getInsetsPolicy().isTransient(ITYPE_STATUS_BAR); -        boolean statusBarTranslucent = (appearance & APPEARANCE_OPAQUE_STATUS_BARS) == 0; - -        // If the status bar is hidden, we don't want to cause windows behind it to scroll. -        if (mStatusBar.isVisible() && !statusBarTransient) { -            // Status bar may go away, so the screen area it occupies is available to apps but just -            // covering them when the status bar is visible. -            final Rect dockFrame = displayFrames.mDock; -            dockFrame.top = displayFrames.mStable.top; -            displayFrames.mContent.set(dockFrame); -            displayFrames.mVoiceContent.set(dockFrame); -            displayFrames.mCurrent.set(dockFrame); - -            if (DEBUG_LAYOUT) Slog.v(TAG, "Status bar: " + String.format( -                    "dock=%s content=%s cur=%s", dockFrame.toString(), -                    displayFrames.mContent.toString(), displayFrames.mCurrent.toString())); - -            if (!statusBarTranslucent && !mStatusBar.isAnimatingLw()) { - -                // If the opaque status bar is currently requested to be visible, and not in the -                // process of animating on or off, then we can tell the app that it is covered by -                // it. -                displayFrames.mSystem.top = displayFrames.mStable.top; -            } -        }      } -    private void layoutNavigationBar(DisplayFrames displayFrames, int uiMode, boolean navVisible, -            boolean navTranslucent, boolean navAllowedHidden, Rect simulatedContentFrame) { +    private void layoutNavigationBar(DisplayFrames displayFrames, int uiMode, +            Rect simulatedContentFrame) {          if (mNavigationBar == null) {              return;          }          final Rect navigationFrame = sTmpNavFrame; -        boolean navBarTransient = -                mDisplayContent.getInsetsPolicy().isTransient(ITYPE_NAVIGATION_BAR);          // Force the navigation bar to its appropriate place and size. We need to do this directly,          // instead of relying on it to bubble up from the nav bar, because this needs to change          // atomically with screen rotations.          final int rotation = displayFrames.mRotation;          final int displayHeight = displayFrames.mDisplayHeight;          final int displayWidth = displayFrames.mDisplayWidth; -        final Rect dockFrame = displayFrames.mDock;          final int navBarPosition = navigationBarPosition(displayWidth, displayHeight, rotation);          getRotatedWindowBounds(displayFrames, mNavigationBar, navigationFrame); @@ -1875,73 +1744,31 @@ public class DisplayPolicy {          if (navBarPosition == NAV_BAR_BOTTOM) {              // It's a system nav bar or a portrait screen; nav bar goes on bottom. -            final int topNavBar = Math.min(cutoutSafeUnrestricted.bottom, navigationFrame.bottom) +            navigationFrame.top = Math.min(cutoutSafeUnrestricted.bottom, navigationFrame.bottom)                      - getNavigationBarFrameHeight(rotation, uiMode); -            final int top = mNavButtonForcedVisible ? topNavBar : -                    Math.min(cutoutSafeUnrestricted.bottom, navigationFrame.bottom) -                            - getNavigationBarHeight(rotation, uiMode); -            navigationFrame.top = topNavBar; -            displayFrames.mStable.bottom = displayFrames.mStableFullscreen.bottom = top; -            if (navVisible && !navBarTransient) { -                dockFrame.bottom = displayFrames.mRestricted.bottom = top; -            } -            if (navVisible && !navTranslucent && !navAllowedHidden -                    && !mNavigationBar.isAnimatingLw()) { -                // If the opaque nav bar is currently requested to be visible and not in the process -                // of animating on or off, then we can tell the app that it is covered by it. -                displayFrames.mSystem.bottom = top; -            }          } else if (navBarPosition == NAV_BAR_RIGHT) {              // Landscape screen; nav bar goes to the right. -            final int left = Math.min(cutoutSafeUnrestricted.right, navigationFrame.right) +            navigationFrame.left = Math.min(cutoutSafeUnrestricted.right, navigationFrame.right)                      - getNavigationBarWidth(rotation, uiMode); -            navigationFrame.left = left; -            displayFrames.mStable.right = displayFrames.mStableFullscreen.right = left; -            if (navVisible && !navBarTransient) { -                dockFrame.right = displayFrames.mRestricted.right = left; -            } -            if (navVisible && !navTranslucent && !navAllowedHidden -                    && !mNavigationBar.isAnimatingLw()) { -                // If the nav bar is currently requested to be visible, and not in the process of -                // animating on or off, then we can tell the app that it is covered by it. -                displayFrames.mSystem.right = left; -            }          } else if (navBarPosition == NAV_BAR_LEFT) {              // Seascape screen; nav bar goes to the left. -            final int right = Math.max(cutoutSafeUnrestricted.left, navigationFrame.left) +            navigationFrame.right = Math.max(cutoutSafeUnrestricted.left, navigationFrame.left)                      + getNavigationBarWidth(rotation, uiMode); -            navigationFrame.right = right; -            displayFrames.mStable.left = displayFrames.mStableFullscreen.left = right; -            if (navVisible && !navBarTransient) { -                dockFrame.left = displayFrames.mRestricted.left = right; -            } -            if (navVisible && !navTranslucent && !navAllowedHidden -                    && !mNavigationBar.isAnimatingLw()) { -                // If the nav bar is currently requested to be visible, and not in the process of -                // animating on or off, then we can tell the app that it is covered by it. -                displayFrames.mSystem.left = right; -            }          } -        // Make sure the content and current rectangles are updated to account for the restrictions -        // from the navigation bar. -        displayFrames.mCurrent.set(dockFrame); -        displayFrames.mVoiceContent.set(dockFrame); -        displayFrames.mContent.set(dockFrame); -        // And compute the final frame. -        sTmpRect.setEmpty(); +        // Compute the final frame.          final WindowFrames windowFrames = mNavigationBar.getLayoutingWindowFrames();          windowFrames.setFrames(navigationFrame /* parentFrame */, -                navigationFrame /* displayFrame */, -                displayFrames.mDisplayCutoutSafe /* contentFrame */, -                navigationFrame /* visibleFrame */, sTmpRect /* decorFrame */, -                navigationFrame /* stableFrame */); +                navigationFrame /* displayFrame */);          mNavigationBar.computeFrame(displayFrames); +        final Rect contentFrame =  sTmpRect; +        contentFrame.set(windowFrames.mFrame); +        contentFrame.intersect(displayFrames.mDisplayCutoutSafe);          if (simulatedContentFrame != null) { -            simulatedContentFrame.set(windowFrames.mContentFrame); +            simulatedContentFrame.set(contentFrame);          } else {              mNavigationBarPosition = navBarPosition; -            mNavigationBarController.setContentFrame(windowFrames.mContentFrame); +            mNavigationBarController.setContentFrame(contentFrame);          }          if (DEBUG_LAYOUT) Slog.i(TAG, "mNavigationBar frame: " + navigationFrame); @@ -2010,21 +1837,12 @@ public class DisplayPolicy {          sTmpLastParentFrame.set(windowFrames.mParentFrame);          final Rect pf = windowFrames.mParentFrame;          final Rect df = windowFrames.mDisplayFrame; -        final Rect cf = windowFrames.mContentFrame; -        final Rect vf = windowFrames.mVisibleFrame; -        final Rect dcf = windowFrames.mDecorFrame; -        final Rect sf = windowFrames.mStableFrame; -        dcf.setEmpty();          windowFrames.setParentFrameWasClippedByDisplayCutout(false); -        final int adjust = sim & SOFT_INPUT_MASK_ADJUST; -          final boolean layoutInScreen = (fl & FLAG_LAYOUT_IN_SCREEN) == FLAG_LAYOUT_IN_SCREEN;          final boolean layoutInsetDecor = (fl & FLAG_LAYOUT_INSET_DECOR) == FLAG_LAYOUT_INSET_DECOR; -        sf.set(displayFrames.mStable); - -        final InsetsState state = mDisplayContent.getInsetsPolicy().getInsetsForWindow(win); +        final InsetsState state = win.getInsetsState();          computeWindowBounds(attrs, state, df);          if (attached == null) {              pf.set(df); @@ -2034,15 +1852,9 @@ public class DisplayPolicy {                      pf.inset(source.calculateInsets(pf, false /* ignoreVisibility */));                  }              } -            vf.set(adjust != SOFT_INPUT_ADJUST_NOTHING -                    ? displayFrames.mCurrent : displayFrames.mDock);          } else {              pf.set((fl & FLAG_LAYOUT_IN_SCREEN) == 0 ? attached.getFrame() : df); -            vf.set(attached.getVisibleFrame());          } -        cf.set(adjust != SOFT_INPUT_ADJUST_RESIZE -                ? displayFrames.mDock : displayFrames.mContent); -        dcf.set(displayFrames.mSystem);          final int cutoutMode = attrs.layoutInDisplayCutoutMode;          // Ensure that windows with a DEFAULT or NEVER display cutout mode are laid out in @@ -2114,75 +1926,25 @@ public class DisplayPolicy {              df.intersectUnchecked(displayCutoutSafeExceptMaybeBars);          } -        // Content should never appear in the cutout. -        cf.intersectUnchecked(displayFrames.mDisplayCutoutSafe); -          // TYPE_SYSTEM_ERROR is above the NavigationBar so it can't be allowed to extend over it.          // Also, we don't allow windows in multi-window mode to extend out of the screen.          if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0 && type != TYPE_SYSTEM_ERROR                  && !win.inMultiWindowMode()) {              df.left = df.top = -10000;              df.right = df.bottom = 10000; -            if (type != TYPE_WALLPAPER) { -                cf.left = cf.top = vf.left = vf.top = -10000; -                cf.right = cf.bottom = vf.right = vf.bottom = 10000; -            }          }          if (DEBUG_LAYOUT) Slog.v(TAG, "Compute frame " + attrs.getTitle()                  + ": sim=#" + Integer.toHexString(sim)                  + " attach=" + attached + " type=" + type                  + String.format(" flags=0x%08x", fl) -                + " pf=" + pf.toShortString() + " df=" + df.toShortString() -                + " cf=" + cf.toShortString() + " vf=" + vf.toShortString() -                + " dcf=" + dcf.toShortString() -                + " sf=" + sf.toShortString()); +                + " pf=" + pf.toShortString() + " df=" + df.toShortString());          if (!sTmpLastParentFrame.equals(pf)) {              windowFrames.setContentChanged(true);          }          win.computeFrame(displayFrames); -        // Dock windows carve out the bottom of the screen, so normal windows -        // can't appear underneath them. -        if (type == TYPE_INPUT_METHOD && win.isVisible() && !win.mGivenInsetsPending) { -            offsetInputMethodWindowLw(win, displayFrames); -        } -        if (type == TYPE_VOICE_INTERACTION && win.isVisible() && !win.mGivenInsetsPending) { -            offsetVoiceInputWindowLw(win, displayFrames); -        } -    } - -    private void offsetInputMethodWindowLw(WindowState win, DisplayFrames displayFrames) { -        final int rotation = displayFrames.mRotation; -        final int navBarPosition = navigationBarPosition(displayFrames.mDisplayWidth, -                displayFrames.mDisplayHeight, rotation); - -        int top = Math.max(win.getDisplayFrame().top, win.getContentFrame().top); -        top += win.mGivenContentInsets.top; -        displayFrames.mContent.bottom = Math.min(displayFrames.mContent.bottom, top); -        if (navBarPosition == NAV_BAR_BOTTOM) { -            // Always account for the nav bar frame height on the bottom since in all navigation -            // modes we make room to show the dismiss-ime button, even if the IME does not report -            // insets (ie. when floating) -            final int uimode = mService.mPolicy.getUiMode(); -            final int navFrameHeight = getNavigationBarFrameHeight(rotation, uimode); -            displayFrames.mContent.bottom = Math.min(displayFrames.mContent.bottom, -                    displayFrames.mUnrestricted.bottom - navFrameHeight); -        } -        displayFrames.mVoiceContent.bottom = Math.min(displayFrames.mVoiceContent.bottom, top); -        top = win.getVisibleFrame().top; -        top += win.mGivenVisibleInsets.top; -        displayFrames.mCurrent.bottom = Math.min(displayFrames.mCurrent.bottom, top); -        if (DEBUG_LAYOUT) Slog.v(TAG, "Input method: mDockBottom=" -                + displayFrames.mDock.bottom + " mContentBottom=" -                + displayFrames.mContent.bottom + " mCurBottom=" + displayFrames.mCurrent.bottom); -    } - -    private void offsetVoiceInputWindowLw(WindowState win, DisplayFrames displayFrames) { -        int top = Math.max(win.getDisplayFrame().top, win.getContentFrame().top); -        top += win.mGivenContentInsets.top; -        displayFrames.mVoiceContent.bottom = Math.min(displayFrames.mVoiceContent.bottom, top);      }      WindowState getTopFullscreenOpaqueWindow() { diff --git a/services/core/java/com/android/server/wm/InsetsPolicy.java b/services/core/java/com/android/server/wm/InsetsPolicy.java index 73641f4d76ac..d308766b9fe5 100644 --- a/services/core/java/com/android/server/wm/InsetsPolicy.java +++ b/services/core/java/com/android/server/wm/InsetsPolicy.java @@ -492,10 +492,10 @@ class InsetsPolicy {                  }                  mAnimatingShown = show; +                final InsetsState state = getInsetsForWindow(mFocusedWin);                  mAnimationControl = new InsetsAnimationControlImpl(controls, -                        mFocusedWin.getDisplayContent().getBounds(), mFocusedWin.getInsetsState(), -                        mListener, typesReady, this, mListener.getDurationMs(), -                        InsetsController.SYSTEM_BARS_INTERPOLATOR, +                        state.getDisplayFrame(), state, mListener, typesReady, this, +                        mListener.getDurationMs(), InsetsController.SYSTEM_BARS_INTERPOLATOR,                          show ? ANIMATION_TYPE_SHOW : ANIMATION_TYPE_HIDE, null /* translator */);                  SurfaceAnimationThread.getHandler().post(                          () -> mListener.onReady(mAnimationControl, typesReady)); diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java index 2de4a7129ffe..0605ed800565 100644 --- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java @@ -548,8 +548,7 @@ class InsetsSourceProvider {          @Override          public void startAnimation(SurfaceControl animationLeash, Transaction t,                  @AnimationType int type, OnAnimationFinishedCallback finishCallback) { -            // TODO(b/118118435): We can remove the type check when implementing the transient bar -            //                    animation. +            // TODO(b/166736352): Check if we still need to control the IME visibility here.              if (mSource.getType() == ITYPE_IME) {                  // TODO: use 0 alpha and remove t.hide() once b/138459974 is fixed.                  t.setAlpha(animationLeash, 1 /* alpha */); diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java index 5f8b12eb5bc0..6d29a1d4eb93 100644 --- a/services/core/java/com/android/server/wm/RecentsAnimationController.java +++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java @@ -53,6 +53,7 @@ import android.view.InputWindowHandle;  import android.view.RemoteAnimationTarget;  import android.view.SurfaceControl;  import android.view.SurfaceControl.Transaction; +import android.view.WindowInsets.Type;  import com.android.internal.annotations.VisibleForTesting;  import com.android.internal.inputmethod.SoftInputShowHideReason; @@ -534,7 +535,10 @@ public class RecentsAnimationController implements DeathRecipient {                              : null;              final Rect contentInsets;              if (mTargetActivityRecord != null && mTargetActivityRecord.findMainWindow() != null) { -                contentInsets = mTargetActivityRecord.findMainWindow().getContentInsets(); +                contentInsets = mTargetActivityRecord.findMainWindow() +                        .getInsetsStateWithVisibilityOverride() +                        .calculateInsets(mTargetActivityRecord.getBounds(), Type.systemBars(), +                                false /* ignoreVisibility */);              } else {                  // If the window for the activity had not yet been created, use the display insets.                  mService.getStableInsets(mDisplayId, mTmpRect); @@ -969,8 +973,8 @@ public class RecentsAnimationController implements DeathRecipient {              if (mainWindow == null) {                  return null;              } -            final Rect insets = new Rect(); -            mainWindow.getContentInsets(insets); +            final Rect insets = mainWindow.getInsetsStateWithVisibilityOverride().calculateInsets( +                    mBounds, Type.systemBars(), false /* ignoreVisibility */);              InsetUtils.addInsets(insets, mainWindow.mActivityRecord.getLetterboxInsets());              final int mode = topApp.getActivityType() == mTargetActivityType                      ? MODE_OPENING diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 0e2c2f975f32..99e17917e0b7 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -448,6 +448,7 @@ class Task extends WindowContainer<WindowContainer> {      private final Rect mTmpBounds = new Rect();      private final Rect mTmpInsets = new Rect();      private final Rect mTmpFullBounds = new Rect(); +    private static final Rect sTmpBounds = new Rect();      // Last non-fullscreen bounds the task was launched in or resized to.      // The information is persisted and used to determine the appropriate stack to launch the @@ -3418,8 +3419,7 @@ class Task extends WindowContainer<WindowContainer> {       * a dialog that's different in size from the activity below, in which case we should       * be dimming the entire task area behind the dialog.       * -     * @param out Rect containing the max visible bounds. -     * @return true if the task has some visible app windows; false otherwise. +     * @param out the union of visible bounds.       */      private static void getMaxVisibleBounds(ActivityRecord token, Rect out, boolean[] foundTop) {          // skip hidden (or about to hide) apps @@ -3435,7 +3435,11 @@ class Task extends WindowContainer<WindowContainer> {              out.setEmpty();          } -        win.getMaxVisibleBounds(out); +        final Rect visibleFrame = sTmpBounds; +        visibleFrame.set(win.getFrame()); +        visibleFrame.inset(win.getInsetsStateWithVisibilityOverride().calculateVisibleInsets( +                visibleFrame, win.mAttrs.softInputMode)); +        out.union(visibleFrame);      }      /** Bounds of the task to be used for dimming, as well as touch related tests. */ diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java index 1809cdd712ef..6dc957c1d118 100644 --- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java +++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java @@ -85,6 +85,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {      private final ActivityTaskSupervisor mSupervisor;      private final Rect mTmpBounds = new Rect(); +    private final Rect mTmpStableBounds = new Rect();      private final int[] mTmpDirections = new int[2];      private StringBuilder mLogBuilder; @@ -425,7 +426,8 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {          // Use stable frame instead of raw frame to avoid launching freeform windows on top of          // stable insets, which usually are system widgets such as sysbar & navbar. -        final Rect displayStableBounds = display.mDisplayContent.mDisplayFrames.mStable; +        final Rect displayStableBounds = mTmpStableBounds; +        display.getStableRect(displayStableBounds);          final int defaultWidth = displayStableBounds.width();          final int defaultHeight = displayStableBounds.height(); @@ -636,7 +638,8 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {          // of default size is calculated to keep the same aspect ratio as the display's. Here we use          // stable bounds of displays because that indicates the area that isn't occupied by system          // widgets (e.g. sysbar and navbar). -        Rect displayStableBounds = display.mDisplayContent.mDisplayFrames.mStable; +        final Rect displayStableBounds = mTmpStableBounds; +        display.getStableRect(displayStableBounds);          final int portraitHeight =                  Math.min(displayStableBounds.width(), displayStableBounds.height());          final int otherDimension = @@ -676,7 +679,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {      private void centerBounds(@NonNull DisplayContent display, int width, int height,              @NonNull Rect inOutBounds) {          if (inOutBounds.isEmpty()) { -            inOutBounds.set(display.mDisplayContent.mDisplayFrames.mStable); +            display.getStableRect(inOutBounds);          }          final int left = inOutBounds.centerX() - width / 2;          final int top = inOutBounds.centerY() - height / 2; @@ -685,7 +688,8 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {      private void adjustBoundsToFitInDisplay(@NonNull DisplayContent display,              @NonNull Rect inOutBounds) { -        final Rect displayStableBounds = display.mDisplayContent.mDisplayFrames.mStable; +        final Rect displayStableBounds = mTmpStableBounds; +        display.getStableRect(displayStableBounds);          if (displayStableBounds.width() < inOutBounds.width()                  || displayStableBounds.height() < inOutBounds.height()) { diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java index 3ce04aff5301..3327300793d5 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotController.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java @@ -16,9 +16,7 @@  package com.android.server.wm; -import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;  import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; -import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;  import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;  import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME; @@ -39,12 +37,10 @@ import android.os.Environment;  import android.os.Handler;  import android.util.ArraySet;  import android.util.Slog; -import android.view.InsetsSource;  import android.view.InsetsState; -import android.view.InsetsState.InternalInsetsType;  import android.view.SurfaceControl;  import android.view.ThreadedRenderer; -import android.view.WindowInsets; +import android.view.WindowInsets.Type;  import android.view.WindowManager.LayoutParams;  import com.android.internal.annotations.VisibleForTesting; @@ -310,9 +306,13 @@ class TaskSnapshotController {              return false;          } +        final Rect contentInsets = getSystemBarInsets(task.getBounds(), +                mainWindow.getInsetsStateWithVisibilityOverride()); +        InsetUtils.addInsets(contentInsets, activity.getLetterboxInsets()); +          builder.setIsRealSnapshot(true);          builder.setId(System.currentTimeMillis()); -        builder.setContentInsets(getInsets(mainWindow)); +        builder.setContentInsets(contentInsets);          final boolean isWindowTranslucent = mainWindow.getAttrs().format != PixelFormat.OPAQUE;          final boolean isShowWallpaper = (mainWindow.getAttrs().flags & FLAG_SHOW_WALLPAPER) != 0; @@ -420,21 +420,6 @@ class TaskSnapshotController {          return mIsRunningOnWear || mIsRunningOnTv || mIsRunningOnIoT;      } -    private Rect getInsets(WindowState state) { -        // XXX(b/72757033): These are insets relative to the window frame, but we're really -        // interested in the insets relative to the task bounds. -        final Rect insets = minRect(state.getContentInsets(), state.getStableInsets()); -        InsetUtils.addInsets(insets, state.mActivityRecord.getLetterboxInsets()); -        return insets; -    } - -    private Rect minRect(Rect rect1, Rect rect2) { -        return new Rect(Math.min(rect1.left, rect2.left), -                Math.min(rect1.top, rect2.top), -                Math.min(rect1.right, rect2.right), -                Math.min(rect1.bottom, rect2.bottom)); -    } -      /**       * Retrieves all closing tasks based on the list of closing apps during an app transition.       */ @@ -488,13 +473,14 @@ class TaskSnapshotController {          final int color = ColorUtils.setAlphaComponent(                  task.getTaskDescription().getBackgroundColor(), 255);          final LayoutParams attrs = mainWindow.getAttrs(); -        final InsetsState insetsState = getInsetsStateWithVisibilityOverride(mainWindow); -        final Rect systemBarInsets = getSystemBarInsets(mainWindow.getFrame(), insetsState); +        final Rect taskBounds = task.getBounds(); +        final InsetsState insetsState = mainWindow.getInsetsStateWithVisibilityOverride(); +        final Rect systemBarInsets = getSystemBarInsets(taskBounds, insetsState);          final SystemBarBackgroundPainter decorPainter = new SystemBarBackgroundPainter(attrs.flags,                  attrs.privateFlags, attrs.insetsFlags.appearance, task.getTaskDescription(),                  mHighResTaskSnapshotScale, insetsState); -        final int taskWidth = task.getBounds().width(); -        final int taskHeight = task.getBounds().height(); +        final int taskWidth = taskBounds.width(); +        final int taskHeight = taskBounds.height();          final int width = (int) (taskWidth * mHighResTaskSnapshotScale);          final int height = (int) (taskHeight * mHighResTaskSnapshotScale); @@ -510,6 +496,8 @@ class TaskSnapshotController {          if (hwBitmap == null) {              return null;          } +        final Rect contentInsets = new Rect(systemBarInsets); +        InsetUtils.addInsets(contentInsets, topChild.getLetterboxInsets());          // Note, the app theme snapshot is never translucent because we enforce a non-translucent          // color above @@ -518,9 +506,8 @@ class TaskSnapshotController {                  topChild.mActivityComponent, hwBitmap.getHardwareBuffer(),                  hwBitmap.getColorSpace(), mainWindow.getConfiguration().orientation,                  mainWindow.getWindowConfiguration().getRotation(), new Point(taskWidth, taskHeight), -                getInsets(mainWindow), false /* isLowResolution */, -                false /* isRealSnapshot */, task.getWindowingMode(), -                getSystemUiVisibility(task), false); +                contentInsets, false /* isLowResolution */, false /* isRealSnapshot */, +                task.getWindowingMode(), getSystemUiVisibility(task), false);      }      /** @@ -611,26 +598,8 @@ class TaskSnapshotController {          return 0;      } -    static InsetsState getInsetsStateWithVisibilityOverride(WindowState win) { -        final InsetsState state = new InsetsState(win.getInsetsState()); -        for (@InternalInsetsType int type = 0; type < InsetsState.SIZE; type++) { -            final boolean requestedVisible = win.getRequestedVisibility(type); -            InsetsSource source = state.peekSource(type); -            if (source != null && source.isVisible() != requestedVisible) { -                source = new InsetsSource(source); -                source.setVisible(requestedVisible); -                state.addSource(source); -            } -        } -        return state; -    } -      static Rect getSystemBarInsets(Rect frame, InsetsState state) { -        return state.calculateInsets(frame, null /* ignoringVisibilityState */, -                false /* isScreenRound */, false /* alwaysConsumeSystemBars */, -                null /* displayCutout */, 0 /* legacySoftInputMode */, 0 /* legacyWindowFlags */, -                0 /* legacySystemUiFlags */, TYPE_APPLICATION, WINDOWING_MODE_UNDEFINED, -                null /* typeSideMap */).getInsets(WindowInsets.Type.systemBars()).toRect(); +        return state.calculateInsets(frame, Type.systemBars(), false /* ignoreVisibility */);      }      void dump(PrintWriter pw, String prefix) { diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java index 30f09ce9a3e6..d2cd1a1d9d61 100644 --- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java +++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java @@ -43,7 +43,6 @@ import static com.android.internal.policy.DecorView.NAVIGATION_BAR_COLOR_VIEW_AT  import static com.android.internal.policy.DecorView.STATUS_BAR_COLOR_VIEW_ATTRIBUTES;  import static com.android.internal.policy.DecorView.getNavigationBarRect;  import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_STARTING_WINDOW; -import static com.android.server.wm.TaskSnapshotController.getInsetsStateWithVisibilityOverride;  import static com.android.server.wm.TaskSnapshotController.getSystemBarInsets;  import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;  import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM; @@ -246,7 +245,7 @@ class TaskSnapshotSurface implements StartingSurface {              task.getBounds(taskBounds);              currentOrientation = topFullscreenOpaqueWindow.getConfiguration().orientation;              activityType = activity.getActivityType(); -            insetsState = getInsetsStateWithVisibilityOverride(topFullscreenOpaqueWindow); +            insetsState = topFullscreenOpaqueWindow.getInsetsStateWithVisibilityOverride();          }          int displayId = activity.getDisplayContent().getDisplayId(); diff --git a/services/core/java/com/android/server/wm/WindowFrames.java b/services/core/java/com/android/server/wm/WindowFrames.java index 81122ac334b5..7991ec6ad59e 100644 --- a/services/core/java/com/android/server/wm/WindowFrames.java +++ b/services/core/java/com/android/server/wm/WindowFrames.java @@ -17,23 +17,16 @@  package com.android.server.wm;  import static com.android.server.wm.WindowFramesProto.CONTAINING_FRAME; -import static com.android.server.wm.WindowFramesProto.CONTENT_FRAME; -import static com.android.server.wm.WindowFramesProto.CONTENT_INSETS;  import static com.android.server.wm.WindowFramesProto.CUTOUT; -import static com.android.server.wm.WindowFramesProto.DECOR_FRAME;  import static com.android.server.wm.WindowFramesProto.DISPLAY_FRAME;  import static com.android.server.wm.WindowFramesProto.FRAME;  import static com.android.server.wm.WindowFramesProto.PARENT_FRAME; -import static com.android.server.wm.WindowFramesProto.STABLE_INSETS; -import static com.android.server.wm.WindowFramesProto.VISIBLE_FRAME; -import static com.android.server.wm.WindowFramesProto.VISIBLE_INSETS;  import android.annotation.NonNull;  import android.graphics.Rect;  import android.util.proto.ProtoOutputStream;  import android.view.DisplayCutout; -import com.android.server.wm.utils.InsetUtils;  import com.android.server.wm.utils.WmDisplayCutout;  import java.io.PrintWriter; @@ -66,30 +59,6 @@ public class WindowFrames {      public final Rect mDisplayFrame = new Rect();      /** -     * Legacy stuff. Generally equal to the content frame expect when the IME for older apps -     * displays hint text. -     */ -    public final Rect mVisibleFrame = new Rect(); - -    /** -     * The area not occupied by the status and navigation bars. So, if both status and navigation -     * bars are visible, the decor frame is equal to the stable frame. -     */ -    public final Rect mDecorFrame = new Rect(); - -    /** -     * Equal to the decor frame if the IME (e.g. keyboard) is not present. Equal to the decor frame -     * minus the area occupied by the IME if the IME is present. -     */ -    public final Rect mContentFrame = new Rect(); - -    /** -     * The display frame minus the stable insets. This value is always constant regardless of if -     * the status bar or navigation bar is visible. -     */ -    public final Rect mStableFrame = new Rect(); - -    /**       * Similar to {@link #mDisplayFrame}       *       * TODO: Why is this different than mDisplayFrame @@ -139,52 +108,21 @@ public class WindowFrames {      private boolean mDisplayCutoutChanged; -    /** -     * Insets that determine the area covered by the stable system windows.  These are in the -     * application's coordinate space (without compatibility scale applied). -     */ -    final Rect mStableInsets = new Rect(); -    final Rect mLastStableInsets = new Rect(); -    private boolean mStableInsetsChanged; - -    /** -     * Insets that determine the actually visible area.  These are in the application's -     * coordinate space (without compatibility scale applied). -     */ -    final Rect mVisibleInsets = new Rect(); -    final Rect mLastVisibleInsets = new Rect(); -    private boolean mVisibleInsetsChanged; - -    /** -     * Insets that are covered by system windows (such as the status bar) and -     * transient docking windows (such as the IME).  These are in the application's -     * coordinate space (without compatibility scale applied). -     */ -    final Rect mContentInsets = new Rect(); -    final Rect mLastContentInsets = new Rect(); -    private boolean mContentInsetsChanged; - -    private final Rect mTmpRect = new Rect(); +    boolean mLastForceReportingResized = false; +    boolean mForceReportingResized = false;      private boolean mContentChanged;      public WindowFrames() {      } -    public WindowFrames(Rect parentFrame, Rect displayFrame, Rect contentFrame, -            Rect visibleFrame, Rect decorFrame, Rect stableFrame) { -        setFrames(parentFrame, displayFrame, contentFrame, visibleFrame, decorFrame, -                stableFrame); +    public WindowFrames(Rect parentFrame, Rect displayFrame) { +        setFrames(parentFrame, displayFrame);      } -    public void setFrames(Rect parentFrame, Rect displayFrame, -            Rect contentFrame, Rect visibleFrame, Rect decorFrame, Rect stableFrame) { +    public void setFrames(Rect parentFrame, Rect displayFrame) {          mParentFrame.set(parentFrame);          mDisplayFrame.set(displayFrame); -        mContentFrame.set(contentFrame); -        mVisibleFrame.set(visibleFrame); -        mDecorFrame.set(decorFrame); -        mStableFrame.set(stableFrame);      }      public void setParentFrameWasClippedByDisplayCutout( @@ -207,49 +145,8 @@ public class WindowFrames {          return (mLastFrame.width() != mFrame.width()) || (mLastFrame.height() != mFrame.height());      } -    /** -     * Calculate the insets for a window. -     * -     * @param windowsAreFloating    Whether the window is in a floating task such as pinned or -     *                              freeform -     * @param inFullscreenContainer Whether the window is in a container that takes up the screen's -     *                              entire space -     * @param windowBounds          The bounds for the window -     */ -    void calculateInsets(boolean windowsAreFloating, boolean inFullscreenContainer, -            Rect windowBounds) { -        // Override right and/or bottom insets in case if the frame doesn't fit the screen in -        // non-fullscreen mode. -        boolean overrideRightInset = !windowsAreFloating && !inFullscreenContainer -                && mFrame.right > windowBounds.right; -        boolean overrideBottomInset = !windowsAreFloating && !inFullscreenContainer -                && mFrame.bottom > windowBounds.bottom; - -        mTmpRect.set(mFrame.left, mFrame.top, -                overrideRightInset ? windowBounds.right : mFrame.right, -                overrideBottomInset ? windowBounds.bottom : mFrame.bottom); - -        InsetUtils.insetsBetweenFrames(mTmpRect, mContentFrame, mContentInsets); -        InsetUtils.insetsBetweenFrames(mTmpRect, mVisibleFrame, mVisibleInsets); -        InsetUtils.insetsBetweenFrames(mTmpRect, mStableFrame, mStableInsets); -    } - -    /** -     * Scales all the insets by a specific amount. -     * -     * @param scale The amount to scale the insets by. -     */ -    void scaleInsets(float scale) { -        mContentInsets.scale(scale); -        mVisibleInsets.scale(scale); -        mStableInsets.scale(scale); -    } -      void offsetFrames(int layoutXDiff, int layoutYDiff) {          mFrame.offset(layoutXDiff, layoutYDiff); -        mContentFrame.offset(layoutXDiff, layoutYDiff); -        mVisibleFrame.offset(layoutXDiff, layoutYDiff); -        mStableFrame.offset(layoutXDiff, layoutYDiff);      }      /** @@ -258,44 +155,35 @@ public class WindowFrames {       * @return true if info about size has changed since last reported.       */      boolean setReportResizeHints() { -        mContentInsetsChanged |= !mLastContentInsets.equals(mContentInsets); -        mVisibleInsetsChanged |= !mLastVisibleInsets.equals(mVisibleInsets); -        mStableInsetsChanged |= !mLastStableInsets.equals(mStableInsets); +        mLastForceReportingResized |= mForceReportingResized;          mFrameSizeChanged |= didFrameSizeChange();          mDisplayCutoutChanged |= !mLastDisplayCutout.equals(mDisplayCutout); -        return mContentInsetsChanged || mVisibleInsetsChanged -                || mStableInsetsChanged || mFrameSizeChanged -                || mDisplayCutoutChanged; +        return mLastForceReportingResized || mFrameSizeChanged || mDisplayCutoutChanged;      }      /** -     * Resets the insets changed flags so they're all set to false again. This should be called -     * after the insets are reported to client. +     * Resets the size changed flags so they're all set to false again. This should be called +     * after the frames are reported to client.       */ -    void resetInsetsChanged() { -        mContentInsetsChanged = false; -        mVisibleInsetsChanged = false; -        mStableInsetsChanged = false; +    void clearReportResizeHints() { +        mLastForceReportingResized = false;          mFrameSizeChanged = false;          mDisplayCutoutChanged = false;      }      /** -     * Copy over inset values as the last insets that were sent to the client. +     * Clears factors that would cause report-resize.       */ -    void updateLastInsetValues() { -        mLastContentInsets.set(mContentInsets); -        mLastVisibleInsets.set(mVisibleInsets); -        mLastStableInsets.set(mStableInsets); +    void onResizeHandled() { +        mForceReportingResized = false;          mLastDisplayCutout = mDisplayCutout;      }      /** -     * Sets the last content insets as (-1, -1, -1, -1) to force the next layout pass to update -     * the client. +     * Forces the next layout pass to update the client.       */ -    void resetLastContentInsets() { -        mLastContentInsets.set(-1, -1, -1, -1); +    void forceReportingResized() { +        mForceReportingResized = true;      }      /** @@ -316,16 +204,10 @@ public class WindowFrames {      public void dumpDebug(@NonNull ProtoOutputStream proto, long fieldId) {          final long token = proto.start(fieldId);          mParentFrame.dumpDebug(proto, PARENT_FRAME); -        mContentFrame.dumpDebug(proto, CONTENT_FRAME);          mDisplayFrame.dumpDebug(proto, DISPLAY_FRAME); -        mVisibleFrame.dumpDebug(proto, VISIBLE_FRAME); -        mDecorFrame.dumpDebug(proto, DECOR_FRAME);          mContainingFrame.dumpDebug(proto, CONTAINING_FRAME);          mFrame.dumpDebug(proto, FRAME);          mDisplayCutout.getDisplayCutout().dumpDebug(proto, CUTOUT); -        mContentInsets.dumpDebug(proto, CONTENT_INSETS); -        mVisibleInsets.dumpDebug(proto, VISIBLE_INSETS); -        mStableInsets.dumpDebug(proto, STABLE_INSETS);          proto.end(token);      } @@ -333,36 +215,16 @@ public class WindowFrames {      public void dump(PrintWriter pw, String prefix) {          pw.println(prefix + "Frames: containing="                  + mContainingFrame.toShortString(sTmpSB) -                + " parent=" + mParentFrame.toShortString(sTmpSB)); -        pw.println(prefix + "    display=" + mDisplayFrame.toShortString(sTmpSB)); -        pw.println(prefix + "    content=" + mContentFrame.toShortString(sTmpSB) -                + " visible=" + mVisibleFrame.toShortString(sTmpSB)); -        pw.println(prefix + "    decor=" + mDecorFrame.toShortString(sTmpSB)); +                + " parent=" + mParentFrame.toShortString(sTmpSB) +                + " display=" + mDisplayFrame.toShortString(sTmpSB));          pw.println(prefix + "mFrame=" + mFrame.toShortString(sTmpSB)                  + " last=" + mLastFrame.toShortString(sTmpSB));          pw.println(prefix + " cutout=" + mDisplayCutout.getDisplayCutout()                  + " last=" + mLastDisplayCutout.getDisplayCutout()); -        pw.print(prefix + "Cur insets: content=" + mContentInsets.toShortString(sTmpSB) -                + " visible=" + mVisibleInsets.toShortString(sTmpSB) -                + " stable=" + mStableInsets.toShortString(sTmpSB)); -        pw.println(prefix + "Lst insets: content=" + mLastContentInsets.toShortString(sTmpSB) -                + " visible=" + mLastVisibleInsets.toShortString(sTmpSB) -                + " stable=" + mLastStableInsets.toShortString(sTmpSB)); -    } - -    String getInsetsInfo() { -        return "ci=" + mContentInsets.toShortString() -                + " vi=" + mVisibleInsets.toShortString() -                + " si=" + mStableInsets.toShortString();      }      String getInsetsChangedInfo() { -        return "contentInsetsChanged=" + mContentInsetsChanged -                + " " + mContentInsets.toShortString() -                + " visibleInsetsChanged=" + mVisibleInsetsChanged -                + " " + mVisibleInsets.toShortString() -                + " stableInsetsChanged=" + mStableInsetsChanged -                + " " + mStableInsets.toShortString() +        return "forceReportingResized=" + mLastForceReportingResized                  + " displayCutoutChanged=" + mDisplayCutoutChanged;      }  } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 5b126b8aa29c..2e95fca0bcd1 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1916,7 +1916,9 @@ public class WindowManagerService extends IWindowManager.Stub          }          // We use the visible frame, because we want the animation to morph the window from what          // was visible to the user to the final destination of the new window. -        Rect frame = replacedWindow.getVisibleFrame(); +        final Rect frame = new Rect(replacedWindow.getFrame()); +        frame.inset(replacedWindow.getInsetsStateWithVisibilityOverride().calculateVisibleInsets( +                frame, replacedWindow.mAttrs.softInputMode));          // We treat this as if this activity was opening, so we can trigger the app transition          // animation and piggy-back on existing transition animation infrastructure.          final DisplayContent dc = activity.getDisplayContent(); @@ -2460,12 +2462,11 @@ public class WindowManagerService extends IWindowManager.Stub              win.setLastReportedMergedConfiguration(mergedConfiguration); -            // Update the last inset values here because the values are sent back to the client. -            // The last inset values represent the last client state -            win.updateLastInsetValues(); +            // Set resize-handled here because the values are sent back to the client. +            win.onResizeHandled();              win.fillClientWindowFrames(outFrames); -            outInsetsState.set(win.getInsetsState(), win.isClientLocal()); +            outInsetsState.set(win.getCompatInsetsState(), win.isClientLocal());              if (DEBUG) {                  Slog.v(TAG_WM, "Relayout given client " + client.asBinder()                          + ", requestedWidth=" + requestedWidth @@ -7564,7 +7565,7 @@ public class WindowManagerService extends IWindowManager.Stub          public int getInputMethodWindowVisibleHeight(int displayId) {              synchronized (mGlobalLock) {                  final DisplayContent dc = mRoot.getDisplayContent(displayId); -                return dc.mDisplayFrames.getInputMethodWindowVisibleHeight(); +                return dc.getInputMethodWindowVisibleHeight();              }          } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 04d777299ecc..d972a519cf17 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -30,13 +30,15 @@ import static android.os.IInputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;  import static android.os.PowerManager.DRAW_WAKE_LOCK;  import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;  import static android.view.InsetsState.ITYPE_IME; +import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;  import static android.view.SurfaceControl.Transaction; -import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; -import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;  import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT;  import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;  import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;  import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE; +import static android.view.WindowInsets.Type.displayCutout; +import static android.view.WindowInsets.Type.ime; +import static android.view.WindowInsets.Type.systemBars;  import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;  import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;  import static android.view.WindowManager.LayoutParams.FIRST_SYSTEM_WINDOW; @@ -798,11 +800,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP      }      boolean isImplicitlyExcludingAllSystemGestures() { -        final int immersiveStickyFlags = -                SYSTEM_UI_FLAG_HIDE_NAVIGATION | SYSTEM_UI_FLAG_IMMERSIVE_STICKY; -        final boolean immersiveSticky = -                (mSystemUiVisibility & immersiveStickyFlags) == immersiveStickyFlags; -        return immersiveSticky && mWmService.mConstants.mSystemGestureExcludedByPreQStickyImmersive +        final boolean stickyHideNav = +                mAttrs.insetsFlags.behavior == BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE +                        && !getRequestedVisibility(ITYPE_NAVIGATION_BAR); +        return stickyHideNav && mWmService.mConstants.mSystemGestureExcludedByPreQStickyImmersive                  && mActivityRecord != null && mActivityRecord.mTargetSdk < Build.VERSION_CODES.Q;      } @@ -1121,12 +1122,17 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP              if (isImeTarget) {                  if (inFreeformWindowingMode()) {                      // Push the freeform window up to make room for the IME. However, don't push -                    // it up past the top of the screen. -                    final int bottomOverlap = windowFrames.mContainingFrame.bottom -                            - windowFrames.mVisibleFrame.bottom; +                    // it up past the bottom of the top bar. +                    final InsetsState state = dc.getInsetsStateController().getRawInsetsState(); +                    final Rect visibleFrame = mTmpRect; +                    visibleFrame.set(state.getDisplayFrame()); +                    visibleFrame.inset(state.calculateInsets(visibleFrame, +                            systemBars() | ime() | displayCutout(), false /* ignoreVisibility */)); +                    final int bottomOverlap = +                            windowFrames.mContainingFrame.bottom - visibleFrame.bottom;                      if (bottomOverlap > 0) {                          final int distanceToTop = Math.max(windowFrames.mContainingFrame.top -                                - windowFrames.mContentFrame.top, 0); +                                - visibleFrame.top, 0);                          int offs = Math.min(bottomOverlap, distanceToTop);                          windowFrames.mContainingFrame.offset(0, -offs);                          mInsetFrame.offset(0, -offs); @@ -1145,7 +1151,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP                  // if it wasn't set already. No need to intersect it with the (visible)                  // "content frame" since it is allowed to be outside the visible desktop.                  if (windowFrames.mContainingFrame.isEmpty()) { -                    windowFrames.mContainingFrame.set(windowFrames.mContentFrame); +                    windowFrames.mContainingFrame.set(windowFrames.mDisplayFrame);                  }              } @@ -1180,52 +1186,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP          applyGravityAndUpdateFrame(windowFrames, layoutContainingFrame, layoutDisplayFrame); -        // Make sure the content and visible frames are inside of the -        // final window frame. -        if (windowsAreFloating && !windowFrames.mFrame.isEmpty()) { -            final int visBottom = windowFrames.mVisibleFrame.bottom; -            final int contentBottom = windowFrames.mContentFrame.bottom; -            windowFrames.mContentFrame.set(windowFrames.mFrame); -            windowFrames.mVisibleFrame.set(windowFrames.mContentFrame); -            windowFrames.mStableFrame.set(windowFrames.mContentFrame); -            if (isImeTarget && inFreeformWindowingMode()) { -                // After displacing a freeform window to make room for the ime, any part of -                // the window still covered by IME should be inset. -                if (contentBottom + layoutYDiff < windowFrames.mContentFrame.bottom) { -                    windowFrames.mContentFrame.bottom = contentBottom + layoutYDiff; -                } -                if (visBottom + layoutYDiff < windowFrames.mVisibleFrame.bottom) { -                    windowFrames.mVisibleFrame.bottom = visBottom + layoutYDiff; -                } -            } -        } else if (mAttrs.type == TYPE_DOCK_DIVIDER) { -            windowFrames.mContentFrame.set(windowFrames.mFrame); +        if (mAttrs.type == TYPE_DOCK_DIVIDER) {              if (!windowFrames.mFrame.equals(windowFrames.mLastFrame)) {                  mMovedByResize = true;              } -        } else { -            windowFrames.mContentFrame.set( -                    Math.max(windowFrames.mContentFrame.left, windowFrames.mFrame.left), -                    Math.max(windowFrames.mContentFrame.top, windowFrames.mFrame.top), -                    Math.min(windowFrames.mContentFrame.right, windowFrames.mFrame.right), -                    Math.min(windowFrames.mContentFrame.bottom, windowFrames.mFrame.bottom)); - -            windowFrames.mVisibleFrame.set( -                    Math.max(windowFrames.mVisibleFrame.left, windowFrames.mFrame.left), -                    Math.max(windowFrames.mVisibleFrame.top, windowFrames.mFrame.top), -                    Math.min(windowFrames.mVisibleFrame.right, windowFrames.mFrame.right), -                    Math.min(windowFrames.mVisibleFrame.bottom, windowFrames.mFrame.bottom)); - -            windowFrames.mStableFrame.set( -                    Math.max(windowFrames.mStableFrame.left, windowFrames.mFrame.left), -                    Math.max(windowFrames.mStableFrame.top, windowFrames.mFrame.top), -                    Math.min(windowFrames.mStableFrame.right, windowFrames.mFrame.right), -                    Math.min(windowFrames.mStableFrame.bottom, windowFrames.mFrame.bottom));          } -        windowFrames.calculateInsets(windowsAreFloating, isFullscreenAndFillsDisplay, -                getDisplayFrames(dc.mDisplayFrames).mUnrestricted); -          windowFrames.setDisplayCutout(                  windowFrames.mDisplayCutout.calculateRelativeTo(windowFrames.mFrame)); @@ -1234,11 +1200,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP          windowFrames.mCompatFrame.set(windowFrames.mFrame);          if (inSizeCompatMode()) { -            // If there is a size compatibility scale being applied to the -            // window, we need to apply this to its insets so that they are -            // reported to the app in its coordinate space. -            windowFrames.scaleInsets(mInvGlobalScale); -              // Also the scaled frame that we report to the app needs to be              // adjusted to be in its coordinate space.              windowFrames.mCompatFrame.scale(mInvGlobalScale); @@ -1270,7 +1231,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP                              + mRequestedWidth + ", mRequestedheight="                              + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph                              + "): frame=" + windowFrames.mFrame.toShortString() -                            + " " + windowFrames.getInsetsInfo()                              + " " + mAttrs.getTitle());          }      } @@ -1303,33 +1263,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP          return mWindowFrames.mDisplayFrame;      } -    /** -     * Retrieves the frame of the content area that this window was last laid out in. This is the -     * area in which the content of the window should be placed. It will be smaller than the display -     * frame to account for screen decorations such as a status bar or soft keyboard. -     */ -    Rect getContentFrame() { -        return mWindowFrames.mContentFrame; -    } - -    /** -     * Retrieves the frame of the visible area that this window was last laid out in. This is the -     * area of the screen in which the window will actually be fully visible. It will be smaller -     * than the content frame to account for transient UI elements blocking it such as an input -     * method's candidates UI. -     */ -    Rect getVisibleFrame() { -        return mWindowFrames.mVisibleFrame; -    } - -    Rect getStableFrame() { -        return mWindowFrames.mStableFrame; -    } - -    Rect getDecorFrame() { -        return mWindowFrames.mDecorFrame; -    } -      Rect getParentFrame() {          return mWindowFrames.mParentFrame;      } @@ -1342,10 +1275,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP          return mWindowFrames.mDisplayCutout;      } -    void getCompatFrame(Rect outFrame) { -        outFrame.set(mWindowFrames.mCompatFrame); -    } -      void getCompatFrameSize(Rect outFrame) {          outFrame.set(0, 0, mWindowFrames.mCompatFrame.width(), mWindowFrames.mCompatFrame.height());      } @@ -1433,7 +1362,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP                  return;              } -            updateLastInsetValues(); +            onResizeHandled();              mWmService.makeWindowFreezingScreenIfNeededLocked(this);              // If the orientation is changing, or we're starting or ending a drag resizing action, @@ -1534,11 +1463,19 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP      }      /** -     * Returns the insets state for the client. Its sources may be the copies with visibility +     * Returns the insets state for the window. Its sources may be the copies with visibility       * modification according to the state of transient bars.       */      InsetsState getInsetsState() { -        InsetsState state = getDisplayContent().getInsetsPolicy().getInsetsForWindow(this); +        return getDisplayContent().getInsetsPolicy().getInsetsForWindow(this); +    } + +    /** +     * Returns the insets state for the client and scales the frames if the client is in the size +     * compatible mode. +     */ +    InsetsState getCompatInsetsState() { +        InsetsState state = getInsetsState();          if (inSizeCompatMode()) {              state = new InsetsState(state, true);              state.scale(mInvGlobalScale); @@ -1546,6 +1483,23 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP          return state;      } +    /** +     * Returns the insets state for the window and applies the requested visibility. +     */ +    InsetsState getInsetsStateWithVisibilityOverride() { +        final InsetsState state = new InsetsState(getInsetsState()); +        for (@InternalInsetsType int type = 0; type < InsetsState.SIZE; type++) { +            final boolean requestedVisible = getRequestedVisibility(type); +            InsetsSource source = state.peekSource(type); +            if (source != null && source.isVisible() != requestedVisible) { +                source = new InsetsSource(source); +                source.setVisible(requestedVisible); +                state.addSource(source); +            } +        } +        return state; +    } +      int getDisplayId() {          final DisplayContent displayContent = getDisplayContent();          if (displayContent == null) { @@ -1625,18 +1579,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP              }          } -        bounds.set(mWindowFrames.mVisibleFrame); +        bounds.set(mWindowFrames.mFrame); +        bounds.inset(getInsetsStateWithVisibilityOverride().calculateVisibleInsets( +                bounds, mAttrs.softInputMode));          if (intersectWithStackBounds) {              bounds.intersect(mTmpRect);          } - -        if (bounds.isEmpty()) { -            bounds.set(mWindowFrames.mFrame); -            if (intersectWithStackBounds) { -                bounds.intersect(mTmpRect); -            } -            return; -        }      }      public long getInputDispatchingTimeoutMillis() { @@ -1958,7 +1906,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP          mWinAnimator.mDrawState = DRAW_PENDING;          // Force add to {@link WindowManagerService#mResizingWindows}. -        resetLastContentInsets(); +        forceReportingResized();          outWaitingForDrawn.add(this);      } @@ -3423,8 +3371,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP              // bottom right.              if (win.getFrame().left <= win.getDisplayFrame().left                      && win.getFrame().top <= win.getDisplayFrame().top -                    && win.getFrame().right >= win.getStableFrame().right -                    && win.getFrame().bottom >= win.getStableFrame().bottom) { +                    && win.getFrame().right >= win.getDisplayFrame().right +                    && win.getFrame().bottom >= win.getDisplayFrame().bottom) {                  // Is a fullscreen window, like the clock alarm. Show to everyone.                  return true;              } @@ -3623,7 +3571,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP          // that may cause WINDOW_FREEZE_TIMEOUT because resizing the client keeps failing.          mReportOrientationChanged = false;          mDragResizingChangeReported = true; -        mWindowFrames.resetInsetsChanged(); +        mWindowFrames.clearReportResizeHints();          final MergedConfiguration mergedConfiguration = mLastReportedConfiguration;          final boolean reportDraw = mWinAnimator.mDrawState == DRAW_PENDING || useBLASTSync() || !mRedrawForSyncReported; @@ -3692,7 +3640,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP      void notifyInsetsChanged() {          ProtoLog.d(WM_DEBUG_IME, "notifyInsetsChanged for %s ", this);          try { -            mClient.insetsChanged(getInsetsState()); +            mClient.insetsChanged(getCompatInsetsState());          } catch (RemoteException e) {              Slog.w(TAG, "Failed to deliver inset state change w=" + this, e);          } @@ -3707,7 +3655,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP          final InsetsStateController stateController =                  getDisplayContent().getInsetsStateController();          try { -            mClient.insetsControlChanged(getInsetsState(), +            mClient.insetsControlChanged(getCompatInsetsState(),                      stateController.getControlsForDispatch(this));          } catch (RemoteException e) {              Slog.w(TAG, "Failed to deliver inset state change to w=" + this, e); @@ -4917,24 +4865,6 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP          }      } -    private boolean skipDecorCrop() { -        // The decor frame is used to specify the region not covered by the system -        // decorations (nav bar, status bar). In case this is empty, for example with -        // FLAG_TRANSLUCENT_NAVIGATION, we don't need to do any cropping. -        if (mWindowFrames.mDecorFrame.isEmpty()) { -            return true; -        } - -        // But if we have a frame, and are an application window, then we must be cropped. -        if (mActivityRecord != null) { -            return false; -        } - -        // For non application windows, we may be allowed to extend over the decor bars -        // depending on our type and permissions assosciated with our token. -        return mToken.canLayerAboveSystemBars(); -    } -      /**       * Expand the given rectangle by this windows surface insets. This       * takes you from the 'window size' to the 'surface size'. @@ -5062,10 +4992,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP      }      /** -     * Updates the last inset values to the current ones. +     * Clears factors that would cause report-resize.       */ -    void updateLastInsetValues() { -        mWindowFrames.updateLastInsetValues(); +    void onResizeHandled() { +        mWindowFrames.onResizeHandled();      }      @Override @@ -5550,48 +5480,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP          mFrameNumber = frameNumber;      } -    public void getMaxVisibleBounds(Rect out) { -        if (out.isEmpty()) { -            out.set(mWindowFrames.mVisibleFrame); -            return; -        } - -        if (mWindowFrames.mVisibleFrame.left < out.left) { -            out.left = mWindowFrames.mVisibleFrame.left; -        } -        if (mWindowFrames.mVisibleFrame.top < out.top) { -            out.top = mWindowFrames.mVisibleFrame.top; -        } -        if (mWindowFrames.mVisibleFrame.right > out.right) { -            out.right = mWindowFrames.mVisibleFrame.right; -        } -        if (mWindowFrames.mVisibleFrame.bottom > out.bottom) { -            out.bottom = mWindowFrames.mVisibleFrame.bottom; -        } -    } - -    void getContentInsets(Rect outContentInsets) { -        outContentInsets.set(mWindowFrames.mContentInsets); -    } - -    Rect getContentInsets() { -        return mWindowFrames.mContentInsets; -    } - -    void getStableInsets(Rect outStableInsets) { -        outStableInsets.set(mWindowFrames.mStableInsets); -    } - -    Rect getStableInsets() { -        return mWindowFrames.mStableInsets; -    } - -    void resetLastContentInsets() { -        mWindowFrames.resetLastContentInsets(); -    } - -    Rect getVisibleInsets() { -        return mWindowFrames.mVisibleInsets; +    void forceReportingResized() { +        mWindowFrames.forceReportingResized();      }      /** Returns the {@link WindowFrames} associated with this {@link WindowState}. */ @@ -5719,10 +5609,11 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP              outFrame.set(getContainingFrame());          }          outSurfaceInsets.set(getAttrs().surfaceInsets); -        // TODO(b/72757033): These are insets relative to the window frame, but we're really -        // interested in the insets relative to the frame we chose in the if-blocks above. -        getContentInsets(outInsets); -        getStableInsets(outStableInsets); +        final InsetsState state = getInsetsStateWithVisibilityOverride(); +        outInsets.set(state.calculateInsets(outFrame, systemBars(), +                false /* ignoreVisibility */)); +        outStableInsets.set(state.calculateInsets(outFrame, systemBars(), +                true /* ignoreVisibility */));      }      /** diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java index c81f2715eb87..0f7a254ececf 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java @@ -30,11 +30,11 @@ import static android.view.Display.FLAG_PRIVATE;  import static android.view.DisplayCutout.BOUNDS_POSITION_LEFT;  import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;  import static android.view.DisplayCutout.fromBoundingRect; +import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; +import static android.view.InsetsState.ITYPE_STATUS_BAR;  import static android.view.Surface.ROTATION_0;  import static android.view.Surface.ROTATION_90; -import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN; -import static android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; -import static android.view.View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; +import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;  import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;  import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;  import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; @@ -101,6 +101,7 @@ import android.view.IDisplayWindowRotationCallback;  import android.view.IDisplayWindowRotationController;  import android.view.ISystemGestureExclusionListener;  import android.view.IWindowManager; +import android.view.InsetsState;  import android.view.MotionEvent;  import android.view.Surface;  import android.view.SurfaceControl.Transaction; @@ -1107,9 +1108,11 @@ public class DisplayContentTests extends WindowTestsBase {          win.getAttrs().flags |= FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR;          win.getAttrs().layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;          win.getAttrs().privateFlags |= PRIVATE_FLAG_NO_MOVE_ANIMATION; -        win.getAttrs().subtreeSystemUiVisibility = win.mSystemUiVisibility = -                SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_HIDE_NAVIGATION -                        | SYSTEM_UI_FLAG_IMMERSIVE_STICKY; +        win.getAttrs().insetsFlags.behavior = BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE; +        final InsetsState requestedState = new InsetsState(); +        requestedState.getSource(ITYPE_NAVIGATION_BAR).setVisible(false); +        requestedState.getSource(ITYPE_STATUS_BAR).setVisible(false); +        win.updateRequestedVisibility(requestedState);          win.mActivityRecord.mTargetSdk = P;          performLayout(dc); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java index 3598cd8d841d..378a0a82c12f 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java @@ -16,10 +16,6 @@  package com.android.server.wm; -import static android.view.Gravity.BOTTOM; -import static android.view.Gravity.LEFT; -import static android.view.Gravity.RIGHT; -import static android.view.Gravity.TOP;  import static android.view.InsetsState.ITYPE_CLIMATE_BAR;  import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR;  import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; @@ -32,12 +28,10 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;  import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;  import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;  import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; -import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;  import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;  import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER;  import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;  import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME; -import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR;  import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;  import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;  import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; @@ -58,7 +52,6 @@ import static org.junit.Assert.assertNotEquals;  import static org.junit.Assert.assertThat;  import static org.mockito.ArgumentMatchers.eq;  import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn;  import static org.mockito.Mockito.spy;  import static org.testng.Assert.expectThrows; @@ -106,7 +99,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {      private int mRotation = ROTATION_0;      private boolean mHasDisplayCutout;      private boolean mIsLongEdgeDisplayCutout; -    private static final int DECOR_WINDOW_INSET = 50;      private final Rect mDisplayBounds = new Rect(); @@ -282,12 +274,8 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); -        assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);          assertInsetByTopBottom(mWindow.getDisplayFrame(), STATUS_BAR_HEIGHT, 0);          assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0); -        assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);      }      @Test @@ -298,12 +286,8 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); -        assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);          assertInsetByTopBottom(mWindow.getDisplayFrame(), 0, NAV_BAR_HEIGHT);          assertInsetByTopBottom(mWindow.getParentFrame(), 0, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);      }      @Test @@ -314,12 +298,8 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); -        assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);          assertInsetByTopBottom(mWindow.getDisplayFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);          assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);      }      @Test @@ -330,18 +310,13 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); -        assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);          assertInsetByTopBottom(mWindow.getDisplayFrame(), STATUS_BAR_HEIGHT, 0);          assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0); -        assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);      }      @Test      public void layoutWindowLw_fitInsetsIgnoringVisibility() { -        final InsetsState state = -                mDisplayContent.getInsetsPolicy().getInsetsForWindow(mWindow); +        final InsetsState state = mWindow.getInsetsState();          state.getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false);          state.getSource(InsetsState.ITYPE_NAVIGATION_BAR).setVisible(false);          mWindow.mAttrs.setFitInsetsIgnoringVisibility(true); @@ -350,18 +325,13 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); -        assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);          assertInsetByTopBottom(mWindow.getDisplayFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);          assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);      }      @Test      public void layoutWindowLw_fitInsetsNotIgnoringVisibility() { -        final InsetsState state = -                mDisplayContent.getInsetsPolicy().getInsetsForWindow(mWindow); +        final InsetsState state = mWindow.getInsetsState();          state.getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false);          state.getSource(InsetsState.ITYPE_NAVIGATION_BAR).setVisible(false);          mWindow.mAttrs.setFitInsetsIgnoringVisibility(false); @@ -370,12 +340,8 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); -        assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);          assertInsetByTopBottom(mWindow.getDisplayFrame(), 0, 0);          assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0); -        assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);      }      @Test @@ -407,12 +373,8 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */);          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); -        assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);          assertInsetByTopBottom(mWindow.getDisplayFrame(), DISPLAY_CUTOUT_HEIGHT, 0);          assertInsetByTopBottom(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0); -        assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);      }      @Test @@ -428,9 +390,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);          assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0); -        assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);          assertInsetByTopBottom(mWindow.getDisplayFrame(), 0, 0);      } @@ -448,9 +407,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);          assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0); -        assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);          assertInsetByTopBottom(mWindow.getDisplayFrame(), STATUS_BAR_HEIGHT, 0);      } @@ -468,9 +424,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);          assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0); -        assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT); -        assertInsetBy(mWindow.getContentFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT); -        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);          assertInsetBy(mWindow.getDisplayFrame(), 0, 0, 0, 0);      } @@ -488,9 +441,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);          assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0); -        assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT); -        assertInsetBy(mWindow.getContentFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT); -        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);          assertInsetBy(mWindow.getDisplayFrame(), 0, 0, 0, 0);      } @@ -509,9 +459,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);          assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0); -        assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);          assertInsetByTopBottom(mWindow.getDisplayFrame(), 0, 0);      } @@ -522,8 +469,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mWindow.mAttrs.flags =                  FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;          mWindow.mAttrs.setFitInsetsTypes(0 /* types */); -        mDisplayContent.getInsetsPolicy().getInsetsForWindow(mWindow) -                .getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false); +        mWindow.getInsetsState().getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false);          final InsetsState requestedState = new InsetsState();          requestedState.getSource(ITYPE_STATUS_BAR).setVisible(false);          mWindow.updateRequestedVisibility(requestedState); @@ -533,9 +479,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);          assertInsetByTopBottom(mWindow.getParentFrame(), STATUS_BAR_HEIGHT, 0); -        assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);          assertInsetByTopBottom(mWindow.getDisplayFrame(), STATUS_BAR_HEIGHT, 0);      } @@ -546,8 +489,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mWindow.mAttrs.flags =                  FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS;          mWindow.mAttrs.setFitInsetsTypes(0 /* types */); -        mDisplayContent.getInsetsPolicy().getInsetsForWindow(mWindow) -                .getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false); +        mWindow.getInsetsState().getSource(InsetsState.ITYPE_STATUS_BAR).setVisible(false);          final InsetsState requestedState = new InsetsState();          requestedState.getSource(ITYPE_STATUS_BAR).setVisible(false);          mWindow.updateRequestedVisibility(requestedState); @@ -558,9 +500,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);          assertInsetByTopBottom(mWindow.getParentFrame(), 0, 0); -        assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getDecorFrame(), 0, 0);          assertInsetByTopBottom(mWindow.getDisplayFrame(), 0, 0);      } @@ -578,10 +517,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);          assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0); -        assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); -        assertInsetBy(mWindow.getContentFrame(), -                DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); -        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);          assertInsetBy(mWindow.getDisplayFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);      } @@ -599,10 +534,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);          assertInsetBy(mWindow.getParentFrame(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0); -        assertInsetBy(mWindow.getStableFrame(), NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, 0, 0); -        assertInsetBy(mWindow.getContentFrame(), -                NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, 0); -        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);          assertInsetBy(mWindow.getDisplayFrame(), 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);      } @@ -622,10 +553,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);          assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0); -        assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); -        assertInsetBy(mWindow.getContentFrame(), -                DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); -        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);      }      @Test @@ -663,10 +590,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);          assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0); -        assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); -        assertInsetBy(mWindow.getContentFrame(), -                DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0); -        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);      }      @Test @@ -682,10 +605,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);          assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0); -        assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT); -        assertInsetBy(mWindow.getContentFrame(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0, -                NAV_BAR_HEIGHT); -        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);          assertInsetBy(mWindow.getDisplayFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);      } @@ -703,11 +622,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);          assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0); -        assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, 0, -                NAV_BAR_HEIGHT); -        assertInsetBy(mWindow.getContentFrame(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0, -                NAV_BAR_HEIGHT); -        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);          assertInsetBy(mWindow.getDisplayFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);      } @@ -725,10 +639,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);          assertInsetBy(mWindow.getParentFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0); -        assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT); -        assertInsetBy(mWindow.getContentFrame(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0, -                NAV_BAR_HEIGHT); -        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);          assertInsetBy(mWindow.getDisplayFrame(), DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);      } @@ -746,10 +656,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);          assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0); -        assertInsetBy(mWindow.getStableFrame(), 0, STATUS_BAR_HEIGHT, 0, NAV_BAR_HEIGHT); -        assertInsetBy(mWindow.getContentFrame(), DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, 0, -                NAV_BAR_HEIGHT); -        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);          assertInsetBy(mWindow.getDisplayFrame(), 0, 0, 0, 0);      } @@ -767,10 +673,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames);          assertInsetBy(mWindow.getParentFrame(), 0, 0, 0, 0); -        assertInsetByTopBottom(mWindow.getStableFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetByTopBottom(mWindow.getVisibleFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -        assertInsetBy(mWindow.getDecorFrame(), 0, 0, 0, 0);          assertInsetBy(mWindow.getDisplayFrame(), 0, 0, 0, 0);      } @@ -832,10 +734,16 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          // Initialize DisplayFrames          mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); +        final InsetsState state = +                mDisplayContent.getInsetsStateController().getRawInsetsState(); +        final Rect contentFrame = new Rect(state.getDisplayFrame()); +        contentFrame.inset(state.calculateInsets(contentFrame, Type.systemBars(), +                false /* ignoreVisibility */)); +          // Task is in the nav bar area (usually does not happen, but this is similar enough to          // the possible overlap with the IME) -        final Rect taskBounds = new Rect(100, mFrames.mContent.bottom + 1, -                200, mFrames.mContent.bottom + 10); +        final Rect taskBounds = new Rect(100, contentFrame.bottom + 1, +                200, contentFrame.bottom + 10);          final Task task = mWindow.getTask();          // Make the task floating. @@ -915,59 +823,6 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase {          assertEquals(DISPLAY_HEIGHT, rotatedFrame.width());      } -    @Test -    public void testScreenDecorWindows() { -        final WindowState decorWindow = spy( -                createWindow(null, TYPE_APPLICATION_OVERLAY, "decorWindow")); -        mWindow.mAttrs.flags = FLAG_NOT_FOCUSABLE | FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR -                | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; -        decorWindow.mAttrs.privateFlags |= PRIVATE_FLAG_IS_SCREEN_DECOR; -        addWindow(decorWindow); -        addWindow(mWindow); -        doReturn(new Rect(0, 0, mFrames.mDisplayWidth, mFrames.mDisplayHeight)) -                .when(decorWindow).getBounds(); - -        // Decor on top -        updateDecorWindow(decorWindow, MATCH_PARENT, DECOR_WINDOW_INSET, TOP); -        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); -        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); -        assertInsetByTopBottom(mWindow.getContentFrame(), DECOR_WINDOW_INSET, NAV_BAR_HEIGHT); - -        // Decor on bottom -        updateDecorWindow(decorWindow, MATCH_PARENT, DECOR_WINDOW_INSET, BOTTOM); -        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); -        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); -        assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, -                DECOR_WINDOW_INSET); - -        // Decor on the left -        updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, MATCH_PARENT, LEFT); -        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); -        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); -        assertInsetBy(mWindow.getContentFrame(), DECOR_WINDOW_INSET, STATUS_BAR_HEIGHT, 0, -                NAV_BAR_HEIGHT); - -        // Decor on the right -        updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, MATCH_PARENT, RIGHT); -        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); -        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); -        assertInsetBy(mWindow.getContentFrame(), 0, STATUS_BAR_HEIGHT, DECOR_WINDOW_INSET, -                NAV_BAR_HEIGHT); - -        // Decor not allowed as inset -        updateDecorWindow(decorWindow, DECOR_WINDOW_INSET, DECOR_WINDOW_INSET, TOP); -        mDisplayPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); -        mDisplayPolicy.layoutWindowLw(mWindow, null, mFrames); -        assertInsetByTopBottom(mWindow.getContentFrame(), STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); -    } - -    private void updateDecorWindow(WindowState decorWindow, int width, int height, int gravity) { -        decorWindow.mAttrs.width = width; -        decorWindow.mAttrs.height = height; -        decorWindow.mAttrs.gravity = gravity; -        decorWindow.setRequestedSize(width, height); -    } -      /**       * Asserts that {@code actual} is inset by the given amounts from the full display rect.       * diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java index bbe811d15258..e0fd3796f2aa 100644 --- a/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java +++ b/services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java @@ -356,7 +356,7 @@ public class InsetsPolicyTest extends WindowTestsBase {              assertNull(controls[i].getLeash());          } -        final InsetsState state = policy.getInsetsForWindow(mAppWindow); +        final InsetsState state = mAppWindow.getInsetsState();          state.setSourceVisible(ITYPE_STATUS_BAR, true);          state.setSourceVisible(ITYPE_NAVIGATION_BAR, true); diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java index a1097d26fbbb..98520bb7a20b 100644 --- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java @@ -28,6 +28,10 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;  import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;  import static android.util.DisplayMetrics.DENSITY_DEFAULT;  import static android.view.Display.DEFAULT_DISPLAY; +import static android.view.InsetsState.ITYPE_CLIMATE_BAR; +import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR; +import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; +import static android.view.InsetsState.ITYPE_STATUS_BAR;  import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;  import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; @@ -36,6 +40,8 @@ import static com.android.server.wm.LaunchParamsController.LaunchParamsModifier.  import static org.junit.Assert.assertEquals;  import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt;  import android.app.ActivityOptions;  import android.content.pm.ActivityInfo; @@ -45,6 +51,7 @@ import android.graphics.Rect;  import android.os.Build;  import android.platform.test.annotations.Presubmit;  import android.view.Gravity; +import android.view.InsetsState;  import androidx.test.filters.SmallTest; @@ -1114,8 +1121,9 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {          // This test case requires a relatively big app bounds to ensure the default size calculated          // by letterbox won't be too small to hold the minimum width/height. -        freeformDisplay.mDisplayContent.mDisplayFrames.mStable.set(/* left */ 10, /* top */ 10, -                /* right */ 1910, /* top */ 1070); +        configInsetsState( +                freeformDisplay.getInsetsStateController().getRawInsetsState(), +                DISPLAY_BOUNDS, new Rect(10, 10, 1910, 1070));          final ActivityOptions options = ActivityOptions.makeBasic();          options.setLaunchDisplayId(freeformDisplay.mDisplayId); @@ -1339,15 +1347,45 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {          display.setBounds(DISPLAY_BOUNDS);          display.getConfiguration().densityDpi = DENSITY_DEFAULT;          display.getConfiguration().orientation = ORIENTATION_LANDSCAPE; -        display.mDisplayContent.mDisplayFrames.mStable.set(DISPLAY_STABLE_BOUNDS); -        spyOn(display.mDisplayContent.mDisplayFrames); +        configInsetsState(display.getInsetsStateController().getRawInsetsState(), +                DISPLAY_BOUNDS, DISPLAY_STABLE_BOUNDS);          // We didn't set up the overall environment for this test, so we need to mute the side          // effect of layout passes that loosen the stable frame. -        doNothing().when(display.mDisplayContent.mDisplayFrames).onBeginLayout(); +        final DisplayPolicy policy = display.getDisplayPolicy(); +        spyOn(policy); +        doNothing().when(policy).beginLayoutLw(any(), anyInt());          return display;      } +    /** +     * Creates insets sources so that we can get the expected stable frame. +     */ +    private static void configInsetsState(InsetsState state, Rect displayFrame, Rect stableFrame) { +        final int dl = displayFrame.left; +        final int dt = displayFrame.top; +        final int dr = displayFrame.right; +        final int db = displayFrame.bottom; +        final int sl = stableFrame.left; +        final int st = stableFrame.top; +        final int sr = stableFrame.right; +        final int sb = stableFrame.bottom; + +        state.setDisplayFrame(displayFrame); +        if (sl > dl) { +            state.getSource(ITYPE_CLIMATE_BAR).setFrame(dl, dt, sl, db); +        } +        if (st > dt) { +            state.getSource(ITYPE_STATUS_BAR).setFrame(dl, dt, dr, st); +        } +        if (sr < dr) { +            state.getSource(ITYPE_EXTRA_NAVIGATION_BAR).setFrame(sr, dt, dr, db); +        } +        if (sb < db) { +            state.getSource(ITYPE_NAVIGATION_BAR).setFrame(dl, sb, dr, db); +        } +    } +      private ActivityRecord createSourceActivity(TestDisplayContent display) {          final Task stack = display.getDefaultTaskDisplayArea()                  .createStack(display.getWindowingMode(), ACTIVITY_TYPE_STANDARD, true); diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java index 0cf63f4ff21d..d2be50d02ef3 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowFrameTests.java @@ -21,9 +21,10 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;  import static android.app.WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_SECONDARY;  import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;  import static android.view.DisplayCutout.fromBoundingRect; +import static android.view.InsetsState.ITYPE_IME; +import static android.view.InsetsState.ITYPE_STATUS_BAR;  import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;  import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;  import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; @@ -34,6 +35,8 @@ import android.graphics.Rect;  import android.platform.test.annotations.Presubmit;  import android.view.DisplayInfo;  import android.view.Gravity; +import android.view.InsetsSource; +import android.view.InsetsState;  import android.view.WindowManager;  import androidx.test.filters.FlakyTest; @@ -57,7 +60,6 @@ import org.mockito.Mockito;  @RunWith(WindowTestRunner.class)  public class WindowFrameTests extends WindowTestsBase { -    private final Rect mEmptyRect = new Rect();      private DisplayContent mTestDisplayContent;      @Before @@ -76,18 +78,6 @@ public class WindowFrameTests extends WindowTestsBase {          assertEquals(bottom, rect.bottom);      } -    private void assertContentInset(WindowState w, int left, int top, int right, int bottom) { -        assertRect(w.getContentInsets(), left, top, right, bottom); -    } - -    private void assertVisibleInset(WindowState w, int left, int top, int right, int bottom) { -        assertRect(w.getVisibleInsets(), left, top, right, bottom); -    } - -    private void assertStableInset(WindowState w, int left, int top, int right, int bottom) { -        assertRect(w.getStableInsets(), left, top, right, bottom); -    } -      private void assertFrame(WindowState w, Rect frame) {          assertEquals(w.getFrame(), frame);      } @@ -100,82 +90,8 @@ public class WindowFrameTests extends WindowTestsBase {          assertRect(w.getRelativeFrame(), left, top, right, bottom);      } -    private void assertContentFrame(WindowState w, Rect expectedRect) { -        assertRect(w.getContentFrame(), expectedRect.left, expectedRect.top, expectedRect.right, -                expectedRect.bottom); -    } - -    private void assertVisibleFrame(WindowState w, Rect expectedRect) { -        assertRect(w.getVisibleFrame(), expectedRect.left, expectedRect.top, expectedRect.right, -                expectedRect.bottom); -    } - -    private void assertStableFrame(WindowState w, Rect expectedRect) { -        assertRect(w.getStableFrame(), expectedRect.left, expectedRect.top, expectedRect.right, -                expectedRect.bottom); -    } -      @Test -    public void testLayoutInFullscreenTaskInsets() { -        // fullscreen task doesn't use bounds for computeFrame -        WindowState w = createWindow(); -        w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP; - -        final int bottomContentInset = 100; -        final int topContentInset = 50; -        final int bottomVisibleInset = 30; -        final int topVisibleInset = 70; -        final int leftStableInset = 20; -        final int rightStableInset = 90; - -        // With no insets or system decor all the frames incoming from PhoneWindowManager -        // are identical. -        final Rect pf = new Rect(0, 0, 1000, 1000); -        final Rect df = pf; -        final Rect of = df; -        final Rect cf = new Rect(pf); -        // Produce some insets -        cf.top += 50; -        cf.bottom -= 100; -        final Rect vf = new Rect(pf); -        vf.top += topVisibleInset; -        vf.bottom -= bottomVisibleInset; -        final Rect sf = new Rect(pf); -        sf.left += leftStableInset; -        sf.right -= rightStableInset; - -        final Rect dcf = pf; -        // When mFrame extends past cf, the content insets are -        // the difference between mFrame and ContentFrame. Visible -        // and stable frames work the same way. -        w.getWindowFrames().setFrames(pf, df, cf, vf, dcf, sf); -        w.computeFrame(); -        assertFrame(w, 0, 0, 1000, 1000); -        assertRelFrame(w, 0, 0, 1000, 1000); -        assertContentInset(w, 0, topContentInset, 0, bottomContentInset); -        assertVisibleInset(w, 0, topVisibleInset, 0, bottomVisibleInset); -        assertStableInset(w, leftStableInset, 0, rightStableInset, 0); -        assertContentFrame(w, cf); -        assertVisibleFrame(w, vf); -        assertStableFrame(w, sf); -        // On the other hand getFrame() doesn't extend past cf we won't get any insets -        w.mAttrs.x = 100; -        w.mAttrs.y = 100; -        w.mAttrs.width = 100; w.mAttrs.height = 100; //have to clear MATCH_PARENT -        w.mRequestedWidth = 100; -        w.mRequestedHeight = 100; -        w.computeFrame(); -        assertFrame(w, 100, 100, 200, 200); -        assertRelFrame(w, 100, 100, 200, 200); -        assertContentInset(w, 0, 0, 0, 0); -        // In this case the frames are shrunk to the window frame. -        assertContentFrame(w, w.getFrame()); -        assertVisibleFrame(w, w.getFrame()); -        assertStableFrame(w, w.getFrame()); -    } - -    @Test -    public void testLayoutInFullscreenTaskNoInsets() { +    public void testLayoutInFullscreenTask() {          // fullscreen task doesn't use bounds for computeFrame          WindowState w = createWindow();          w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP; @@ -186,7 +102,7 @@ public class WindowFrameTests extends WindowTestsBase {          // Here the window has FILL_PARENT, FILL_PARENT          // so we expect it to fill the entire available frame. -        w.getWindowFrames().setFrames(pf, pf, pf, pf, pf, pf); +        w.getWindowFrames().setFrames(pf, pf);          w.computeFrame();          assertFrame(w, 0, 0, 1000, 1000);          assertRelFrame(w, 0, 0, 1000, 1000); @@ -278,76 +194,24 @@ public class WindowFrameTests extends WindowTestsBase {          final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);          final WindowFrames windowFrames = w.getWindowFrames(); -        windowFrames.setFrames(pf, pf, pf, pf, pf, pf); +        windowFrames.setFrames(pf, pf);          w.computeFrame();          // For non fullscreen tasks the containing frame is based off the          // task bounds not the parent frame.          assertEquals(resolvedTaskBounds, w.getFrame());          assertEquals(0, w.getRelativeFrame().left);          assertEquals(0, w.getRelativeFrame().top); -        assertContentFrame(w, resolvedTaskBounds); -        assertContentInset(w, 0, 0, 0, 0);          pf.set(0, 0, logicalWidth, logicalHeight);          // We still produce insets against the containing frame the same way.          final int cfRight = logicalWidth / 2;          final int cfBottom = logicalHeight / 2;          final Rect cf = new Rect(0, 0, cfRight, cfBottom); -        windowFrames.setFrames(pf, pf, cf, cf, pf, cf); +        windowFrames.setFrames(pf, pf);          w.computeFrame();          assertEquals(resolvedTaskBounds, w.getFrame());          assertEquals(0, w.getRelativeFrame().left);          assertEquals(0, w.getRelativeFrame().top); -        int contentInsetRight = resolvedTaskBounds.right - cfRight; -        int contentInsetBottom = resolvedTaskBounds.bottom - cfBottom; -        assertContentInset(w, 0, 0, contentInsetRight, contentInsetBottom); -        assertContentFrame(w, new Rect(resolvedTaskBounds.left, resolvedTaskBounds.top, -                resolvedTaskBounds.right - contentInsetRight, -                resolvedTaskBounds.bottom - contentInsetBottom)); -    } - -    @Test -    @FlakyTest(bugId = 130388666) -    public void testCalculatePolicyCrop() { -        final WindowState w = createWindow(); -        w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP; - -        final DisplayInfo displayInfo = w.getDisplayContent().getDisplayInfo(); -        final int logicalWidth = displayInfo.logicalWidth; -        final int logicalHeight = displayInfo.logicalHeight; -        final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight); -        final Rect df = pf; -        final Rect cf = new Rect(pf); -        // Produce some insets -        cf.top += displayInfo.logicalWidth / 10; -        cf.bottom -= displayInfo.logicalWidth / 5; -        final Rect vf = cf; -        final Rect sf = vf; -        // We use a decor content frame with insets to produce cropping. -        Rect dcf = new Rect(cf); - -        final WindowFrames windowFrames = w.getWindowFrames(); -        windowFrames.setFrames(pf, df, cf, vf, dcf, sf); -        w.computeFrame(); - -        windowFrames.mDecorFrame.setEmpty(); -        // Likewise with no decor frame we would get no crop -        w.computeFrame(); - -        // Now we set up a window which doesn't fill the entire decor frame. -        // Normally it would be cropped to it's frame but in the case of docked resizing -        // we need to account for the fact the windows surface will be made -        // fullscreen and thus also make the crop fullscreen. - -        windowFrames.setFrames(pf, pf, pf, pf, pf, pf); -        w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP; -        w.mAttrs.width = logicalWidth / 2; -        w.mAttrs.height = logicalHeight / 2; -        w.mRequestedWidth = logicalWidth / 2; -        w.mRequestedHeight = logicalHeight / 2; -        w.computeFrame(); - -        doReturn(true).when(w).isDockedResizing();      }      @Test @@ -372,13 +236,11 @@ public class WindowFrameTests extends WindowTestsBase {          final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);          final WindowFrames windowFrames = w.getWindowFrames(); -        windowFrames.setFrames(pf, pf, pf, pf, pf, pf); +        windowFrames.setFrames(pf, pf);          w.computeFrame();          // For non fullscreen tasks the containing frame is based off the          // task bounds not the parent frame.          assertFrame(w, taskLeft, taskTop, taskRight, taskBottom); -        assertContentFrame(w, taskBounds); -        assertContentInset(w, 0, 0, 0, 0);          // Now simulate switch to fullscreen for letterboxed app.          final int xInset = logicalWidth / 10; @@ -390,11 +252,9 @@ public class WindowFrameTests extends WindowTestsBase {          pf.set(0, 0, logicalWidth, logicalHeight);          task.setWindowingMode(WINDOWING_MODE_FULLSCREEN);          task.setBounds(null); -        windowFrames.setFrames(pf, pf, cf, cf, pf, cf); +        windowFrames.setFrames(pf, pf);          w.computeFrame();          assertFrame(w, cf); -        assertContentFrame(w, cf); -        assertContentInset(w, 0, 0, 0, 0);      }      @Test @@ -411,7 +271,7 @@ public class WindowFrameTests extends WindowTestsBase {                  pf.width(), pf.height());          final WindowFrames windowFrames = w.getWindowFrames(); -        windowFrames.setFrames(pf, pf, pf, pf, pf, pf); +        windowFrames.setFrames(pf, pf);          windowFrames.setDisplayCutout(cutout);          w.computeFrame(); @@ -430,51 +290,52 @@ public class WindowFrameTests extends WindowTestsBase {          w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;          task.setWindowingMode(WINDOWING_MODE_FREEFORM); -        DisplayContent dc = mTestDisplayContent; +        // Make IME attach to the window and can produce insets. +        final DisplayContent dc = mTestDisplayContent;          dc.mInputMethodTarget = w;          WindowState mockIme = mock(WindowState.class);          Mockito.doReturn(true).when(mockIme).isVisibleNow();          dc.mInputMethodWindow = mockIme; +        final InsetsState state = dc.getInsetsStateController().getRawInsetsState(); +        final InsetsSource imeSource = state.getSource(ITYPE_IME); +        final Rect imeFrame = new Rect(state.getDisplayFrame()); +        imeFrame.top = 400; +        imeSource.setFrame(imeFrame); +        imeSource.setVisible(true); +        w.updateRequestedVisibility(state); +        w.mBehindIme = true;          // With no insets or system decor all the frames incoming from PhoneWindowManager          // are identical.          final Rect pf = new Rect(0, 0, 1000, 800); -        final Rect df = pf; -        final Rect of = df; -        final Rect cf = new Rect(pf); -        cf.bottom -= 400; -        final Rect vf = new Rect(cf); -        final Rect sf = new Rect(pf); -        final Rect dcf = pf;          // First check that it only gets moved up enough to show window.          final Rect winRect = new Rect(200, 200, 300, 500); -          task.setBounds(winRect); -        w.getWindowFrames().setFrames(pf, df, cf, vf, dcf, sf); +        w.getWindowFrames().setFrames(pf, pf);          w.computeFrame(); +        assertFrame(w, winRect.left, imeFrame.top - winRect.height(), winRect.right, imeFrame.top); -        final Rect expected = new Rect(winRect.left, cf.bottom - winRect.height(), -                winRect.right, cf.bottom); -        assertEquals(expected, w.getFrame()); -        assertEquals(expected, w.getContentFrame()); -        assertEquals(expected, w.getVisibleFrame()); - -        // Now check that it won't get moved beyond the top and then has appropriate insets -        winRect.bottom = 600; +        // Now check that it won't get moved beyond the top +        winRect.bottom = 650;          task.setBounds(winRect);          w.setBounds(winRect); -        w.getWindowFrames().setFrames(pf, df, cf, vf, dcf, sf); +        w.getWindowFrames().setFrames(pf, pf);          w.computeFrame(); -          assertFrame(w, winRect.left, 0, winRect.right, winRect.height()); -        expected.top = 0; -        expected.bottom = cf.bottom; -        assertContentFrame(w, expected); -        assertVisibleFrame(w, expected); + +        // Now we have status bar. Check that it won't go into the status bar area. +        final Rect statusBarFrame = new Rect(state.getDisplayFrame()); +        statusBarFrame.bottom = 60; +        state.getSource(ITYPE_STATUS_BAR).setFrame(statusBarFrame); +        w.getWindowFrames().setFrames(pf, pf); +        w.computeFrame(); +        assertFrame(w, winRect.left, statusBarFrame.bottom, winRect.right, +                statusBarFrame.bottom + winRect.height());          // Check that it's moved back without ime insets -        w.getWindowFrames().setFrames(pf, df, pf, pf, dcf, sf); +        state.removeSource(ITYPE_IME); +        w.getWindowFrames().setFrames(pf, pf);          w.computeFrame();          assertEquals(winRect, w.getFrame());      } diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java index 7470cd898396..b78f0e237bc5 100644 --- a/tests/net/java/com/android/server/ConnectivityServiceTest.java +++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java @@ -158,7 +158,7 @@ import android.net.INetworkPolicyListener;  import android.net.INetworkPolicyManager;  import android.net.INetworkStatsService;  import android.net.InetAddresses; -import android.net.InterfaceConfiguration; +import android.net.InterfaceConfigurationParcel;  import android.net.IpPrefix;  import android.net.IpSecManager;  import android.net.IpSecManager.UdpEncapsulationSocket; @@ -6084,12 +6084,13 @@ public class ConnectivityServiceTest {      }      /** -     * Make simulated InterfaceConfig for Nat464Xlat to query clat lower layer info. +     * Make simulated InterfaceConfigParcel for Nat464Xlat to query clat lower layer info.       */ -    private InterfaceConfiguration getClatInterfaceConfig(LinkAddress la) { -        InterfaceConfiguration cfg = new InterfaceConfiguration(); -        cfg.setHardwareAddress("11:22:33:44:55:66"); -        cfg.setLinkAddress(la); +    private InterfaceConfigurationParcel getClatInterfaceConfigParcel(LinkAddress la) { +        final InterfaceConfigurationParcel cfg = new InterfaceConfigurationParcel(); +        cfg.hwAddr = "11:22:33:44:55:66"; +        cfg.ipv4Addr = la.getAddress().getHostAddress(); +        cfg.prefixLength = la.getPrefixLength();          return cfg;      } @@ -6180,8 +6181,8 @@ public class ConnectivityServiceTest {          reset(mNetworkManagementService);          reset(mMockNetd);          reset(mMockDnsResolver); -        when(mNetworkManagementService.getInterfaceConfig(CLAT_PREFIX + MOBILE_IFNAME)) -                .thenReturn(getClatInterfaceConfig(myIpv4)); +        when(mMockNetd.interfaceGetCfg(CLAT_PREFIX + MOBILE_IFNAME)) +                .thenReturn(getClatInterfaceConfigParcel(myIpv4));          // Remove IPv4 address. Expect prefix discovery to be started again.          cellLp.removeLinkAddress(myIpv4); @@ -6230,7 +6231,8 @@ public class ConnectivityServiceTest {                      TYPE_MOBILE);          }          reset(mMockNetd); - +        when(mMockNetd.interfaceGetCfg(CLAT_PREFIX + MOBILE_IFNAME)) +                .thenReturn(getClatInterfaceConfigParcel(myIpv4));          // Change the NAT64 prefix without first removing it.          // Expect clatd to be stopped and started with the new prefix.          mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, true /* added */, @@ -6279,8 +6281,8 @@ public class ConnectivityServiceTest {          reset(mNetworkManagementService);          reset(mMockNetd);          reset(mMockDnsResolver); -        when(mNetworkManagementService.getInterfaceConfig(CLAT_PREFIX + MOBILE_IFNAME)) -                .thenReturn(getClatInterfaceConfig(myIpv4)); +        when(mMockNetd.interfaceGetCfg(CLAT_PREFIX + MOBILE_IFNAME)) +                .thenReturn(getClatInterfaceConfigParcel(myIpv4));          // Stopping prefix discovery causes netd to tell us that the NAT64 prefix is gone.          mService.mNetdEventCallback.onNat64PrefixEvent(cellNetId, false /* added */, @@ -6320,6 +6322,7 @@ public class ConnectivityServiceTest {          networkCallback.expectLinkPropertiesThat(mCellNetworkAgent,                  (lp) -> lp.getStackedLinks().size() == 0);          verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME); +        verify(mMockNetd, times(1)).interfaceGetCfg(CLAT_PREFIX + MOBILE_IFNAME);          verifyNoMoreInteractions(mMockNetd);          // Clean up.          mCellNetworkAgent.disconnect(); diff --git a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java index 5046b6586fb0..4f65b67fa3da 100644 --- a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java +++ b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java @@ -29,7 +29,7 @@ import static org.mockito.Mockito.when;  import android.net.ConnectivityManager;  import android.net.IDnsResolver;  import android.net.INetd; -import android.net.InterfaceConfiguration; +import android.net.InterfaceConfigurationParcel;  import android.net.IpPrefix;  import android.net.LinkAddress;  import android.net.LinkProperties; @@ -68,7 +68,6 @@ public class Nat464XlatTest {      @Mock IDnsResolver mDnsResolver;      @Mock INetd mNetd;      @Mock INetworkManagementService mNms; -    @Mock InterfaceConfiguration mConfig;      @Mock NetworkAgentInfo mNai;      TestLooper mLooper; @@ -106,9 +105,10 @@ public class Nat464XlatTest {          when(mNai.connService()).thenReturn(mConnectivity);          when(mNai.netAgentConfig()).thenReturn(mAgentConfig);          when(mNai.handler()).thenReturn(mHandler); - -        when(mNms.getInterfaceConfig(eq(STACKED_IFACE))).thenReturn(mConfig); -        when(mConfig.getLinkAddress()).thenReturn(ADDR); +        final InterfaceConfigurationParcel mConfig = new InterfaceConfigurationParcel(); +        when(mNetd.interfaceGetCfg(eq(STACKED_IFACE))).thenReturn(mConfig); +        mConfig.ipv4Addr = ADDR.getAddress().getHostAddress(); +        mConfig.prefixLength =  ADDR.getPrefixLength();      }      private void assertRequiresClat(boolean expected, NetworkAgentInfo nai) { @@ -213,7 +213,7 @@ public class Nat464XlatTest {          nat.interfaceLinkStateChanged(STACKED_IFACE, true);          mLooper.dispatchNext(); -        verify(mNms).getInterfaceConfig(eq(STACKED_IFACE)); +        verify(mNetd).interfaceGetCfg(eq(STACKED_IFACE));          verify(mConnectivity).handleUpdateLinkProperties(eq(mNai), c.capture());          assertFalse(c.getValue().getStackedLinks().isEmpty());          assertTrue(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE)); @@ -353,7 +353,7 @@ public class Nat464XlatTest {          nat.interfaceLinkStateChanged(STACKED_IFACE, true);          mLooper.dispatchNext(); -        verify(mNms).getInterfaceConfig(eq(STACKED_IFACE)); +        verify(mNetd).interfaceGetCfg(eq(STACKED_IFACE));          verify(mConnectivity, times(1)).handleUpdateLinkProperties(eq(mNai), c.capture());          assertFalse(c.getValue().getStackedLinks().isEmpty());          assertTrue(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));  |