Window Manager Flag Migration (4/n)

Wire up the appearance and the transient state of system bars between
WMS and System UI. The derived classes of CommandQueue.Callbacks no
longer listen to setSystemUiVisibility, but listen to showTransient,
abortTransient, and onSystemBarAppearanceChanged instead.

Bug: 118118435
Test: atest InsetsSourceProviderTest InsetsStateControllerTest
            InsetsPolicyTest WindowStateTests CommandQueueTest
            RegisterStatusBarResultTest InsetsFlagsTest
            LightBarControllerTest
Test: build on specific target
Change-Id: Ie35f4b4468bce7ef8c76f091e306610c069fba85
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 35cfe9e..7f717a7 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -306,6 +306,11 @@
     oneway void statusBarVisibilityChanged(int displayId, int visibility);
 
     /**
+     * Called by System UI to notify Window Manager to hide transient bars.
+     */
+    oneway void hideTransientBars(int displayId);
+
+    /**
     * When set to {@code true} the system bars will always be shown. This is true even if an app
     * requests to be fullscreen by setting the system ui visibility flags. The
     * functionality was added for the automotive case as a way to guarantee required content stays
diff --git a/core/java/android/view/InsetsAnimationControlImpl.java b/core/java/android/view/InsetsAnimationControlImpl.java
index e4deffa..0fb1c33 100644
--- a/core/java/android/view/InsetsAnimationControlImpl.java
+++ b/core/java/android/view/InsetsAnimationControlImpl.java
@@ -146,20 +146,11 @@
         }
         final Insets offset = Insets.subtract(mShownInsets, mPendingInsets);
         ArrayList<SurfaceParams> params = new ArrayList<>();
-        if (offset.left != 0) {
-            updateLeashesForSide(INSET_SIDE_LEFT, offset.left, mPendingInsets.left, params, state);
-        }
-        if (offset.top != 0) {
-            updateLeashesForSide(INSET_SIDE_TOP, offset.top, mPendingInsets.top, params, state);
-        }
-        if (offset.right != 0) {
-            updateLeashesForSide(INSET_SIDE_RIGHT, offset.right, mPendingInsets.right, params,
-                    state);
-        }
-        if (offset.bottom != 0) {
-            updateLeashesForSide(INSET_SIDE_BOTTOM, offset.bottom, mPendingInsets.bottom, params,
-                    state);
-        }
+        updateLeashesForSide(INSET_SIDE_LEFT, offset.left, mPendingInsets.left, params, state);
+        updateLeashesForSide(INSET_SIDE_TOP, offset.top, mPendingInsets.top, params, state);
+        updateLeashesForSide(INSET_SIDE_RIGHT, offset.right, mPendingInsets.right, params, state);
+        updateLeashesForSide(INSET_SIDE_BOTTOM, offset.bottom, mPendingInsets.bottom, params,
+                state);
         SyncRtSurfaceTransactionApplier applier = mTransactionApplierSupplier.get();
         applier.scheduleApply(params.toArray(new SurfaceParams[params.size()]));
         mCurrentInsets = mPendingInsets;
@@ -224,6 +215,9 @@
     private void updateLeashesForSide(@InsetSide int side, int offset, int inset,
             ArrayList<SurfaceParams> surfaceParams, InsetsState state) {
         ArraySet<InsetsSourceConsumer> items = mSideSourceMap.get(side);
+        if (items == null) {
+            return;
+        }
         // TODO: Implement behavior when inset spans over multiple types
         for (int i = items.size() - 1; i >= 0; i--) {
             final InsetsSourceConsumer consumer = items.valueAt(i);
@@ -274,9 +268,15 @@
             SparseSetArray<InsetsSourceConsumer> sideSourcesMap,
             SparseArray<InsetsSourceConsumer> consumers) {
         for (int i = typeSideMap.size() - 1; i >= 0; i--) {
-            int type = typeSideMap.keyAt(i);
-            int side = typeSideMap.valueAt(i);
-            sideSourcesMap.add(side, consumers.get(type));
+            final int type = typeSideMap.keyAt(i);
+            final int side = typeSideMap.valueAt(i);
+            final InsetsSourceConsumer consumer = consumers.get(type);
+            if (consumer == null) {
+                // If the types that we are controlling are less than the types that the system has,
+                // there can be some null consumers.
+                continue;
+            }
+            sideSourcesMap.add(side, consumer);
         }
     }
 }
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 5bb4f63..eca6dcb 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -67,9 +67,9 @@
      * Translation animation evaluator.
      */
     private static TypeEvaluator<Insets> sEvaluator = (fraction, startValue, endValue) -> Insets.of(
-            0,
+            (int) (startValue.left + fraction * (endValue.left - startValue.left)),
             (int) (startValue.top + fraction * (endValue.top - startValue.top)),
-            0,
+            (int) (startValue.right + fraction * (endValue.right - startValue.right)),
             (int) (startValue.bottom + fraction * (endValue.bottom - startValue.bottom)));
 
     /**
diff --git a/core/java/android/view/InsetsFlags.java b/core/java/android/view/InsetsFlags.java
index 276e80a..6e459b2 100644
--- a/core/java/android/view/InsetsFlags.java
+++ b/core/java/android/view/InsetsFlags.java
@@ -16,10 +16,18 @@
 
 package android.view;
 
+import static android.view.View.NAVIGATION_BAR_TRANSLUCENT;
+import static android.view.View.NAVIGATION_BAR_TRANSPARENT;
+import static android.view.View.STATUS_BAR_TRANSLUCENT;
+import static android.view.View.STATUS_BAR_TRANSPARENT;
+import static android.view.View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
+import static android.view.View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+import static android.view.View.SYSTEM_UI_FLAG_LOW_PROFILE;
 import static android.view.WindowInsetsController.APPEARANCE_LIGHT_SIDE_BARS;
 import static android.view.WindowInsetsController.APPEARANCE_LIGHT_TOP_BAR;
 import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
-import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_SIDE_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_TOP_BAR;
 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE;
 import static android.view.WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE;
 
@@ -35,9 +43,13 @@
 
     @ViewDebug.ExportedProperty(flagMapping = {
             @ViewDebug.FlagToString(
-                    mask = APPEARANCE_OPAQUE_BARS,
-                    equals = APPEARANCE_OPAQUE_BARS,
-                    name = "OPAQUE_BARS"),
+                    mask = APPEARANCE_OPAQUE_TOP_BAR,
+                    equals = APPEARANCE_OPAQUE_TOP_BAR,
+                    name = "OPAQUE_TOP_BAR"),
+            @ViewDebug.FlagToString(
+                    mask = APPEARANCE_OPAQUE_SIDE_BARS,
+                    equals = APPEARANCE_OPAQUE_SIDE_BARS,
+                    name = "OPAQUE_SIDE_BARS"),
             @ViewDebug.FlagToString(
                     mask = APPEARANCE_LOW_PROFILE_BARS,
                     equals = APPEARANCE_LOW_PROFILE_BARS,
@@ -64,4 +76,44 @@
                     name = "SHOW_TRANSIENT_BARS_BY_SWIPE")
     })
     public @Behavior int behavior;
+
+    /**
+     * Converts system UI visibility to appearance.
+     *
+     * @param systemUiVisibility the system UI visibility to be converted.
+     * @return the outcome {@link Appearance}
+     */
+    public static @Appearance int getAppearance(int systemUiVisibility) {
+        int appearance = 0;
+        appearance |= convertFlag(systemUiVisibility, SYSTEM_UI_FLAG_LOW_PROFILE,
+                APPEARANCE_LOW_PROFILE_BARS);
+        appearance |= convertFlag(systemUiVisibility, SYSTEM_UI_FLAG_LIGHT_STATUS_BAR,
+                APPEARANCE_LIGHT_TOP_BAR);
+        appearance |= convertFlag(systemUiVisibility, SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR,
+                APPEARANCE_LIGHT_SIDE_BARS);
+        appearance |= convertNoFlag(systemUiVisibility,
+                STATUS_BAR_TRANSLUCENT | STATUS_BAR_TRANSPARENT, APPEARANCE_OPAQUE_TOP_BAR);
+        appearance |= convertNoFlag(systemUiVisibility,
+                NAVIGATION_BAR_TRANSLUCENT | NAVIGATION_BAR_TRANSPARENT,
+                APPEARANCE_OPAQUE_SIDE_BARS);
+        return appearance;
+    }
+
+    /**
+     * Converts the system UI visibility into an appearance flag if the given visibility contains
+     * the given system UI flag.
+     */
+    private static @Appearance int convertFlag(int systemUiVisibility, int systemUiFlag,
+            @Appearance int appearance) {
+        return (systemUiVisibility & systemUiFlag) != 0 ? appearance : 0;
+    }
+
+    /**
+     * Converts the system UI visibility into an appearance flag if the given visibility doesn't
+     * contains the given system UI flag.
+     */
+    private static @Appearance int convertNoFlag(int systemUiVisibility, int systemUiFlag,
+            @Appearance int appearance) {
+        return (systemUiVisibility & systemUiFlag) == 0 ? appearance : 0;
+    }
 }
diff --git a/core/java/android/view/InsetsState.java b/core/java/android/view/InsetsState.java
index a04c39b..99502a6 100644
--- a/core/java/android/view/InsetsState.java
+++ b/core/java/android/view/InsetsState.java
@@ -270,10 +270,23 @@
      *
      * @param type The {@link InternalInsetType} of the source to remove
      */
-    public void removeSource(int type) {
+    public void removeSource(@InternalInsetType int type) {
         mSources.remove(type);
     }
 
+    /**
+     * A shortcut for setting the visibility of the source.
+     *
+     * @param type The {@link InternalInsetType} of the source to set the visibility
+     * @param visible {@code true} for visible
+     */
+    public void setSourceVisible(@InternalInsetType int type, boolean visible) {
+        InsetsSource source = mSources.get(type);
+        if (source != null) {
+            source.setVisible(visible);
+        }
+    }
+
     public void set(InsetsState other) {
         set(other, false /* copySources */);
     }
@@ -357,6 +370,19 @@
         }
     }
 
+    public static boolean containsType(@InternalInsetType int[] types,
+            @InternalInsetType int type) {
+        if (types == null) {
+            return false;
+        }
+        for (int t : types) {
+            if (t == type) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     public void dump(String prefix, PrintWriter pw) {
         pw.println(prefix + "InsetsState");
         for (int i = mSources.size() - 1; i >= 0; i--) {
@@ -364,7 +390,7 @@
         }
     }
 
-    public static String typeToString(int type) {
+    public static String typeToString(@InternalInsetType int type) {
         switch (type) {
             case TYPE_TOP_BAR:
                 return "TYPE_TOP_BAR";
diff --git a/core/java/android/view/WindowInsetsController.java b/core/java/android/view/WindowInsetsController.java
index 396422e..b415319 100644
--- a/core/java/android/view/WindowInsetsController.java
+++ b/core/java/android/view/WindowInsetsController.java
@@ -35,33 +35,39 @@
 public interface WindowInsetsController {
 
     /**
-     * Makes system bars become opaque with solid dark background and light foreground.
+     * Makes the top bars become opaque with solid dark background and light foreground.
      * @hide
      */
-    int APPEARANCE_OPAQUE_BARS = 1;
+    int APPEARANCE_OPAQUE_TOP_BAR = 1;
+
+    /**
+     * Makes the side bars become opaque with solid dark background and light foreground.
+     * @hide
+     */
+    int APPEARANCE_OPAQUE_SIDE_BARS = 1 << 1;
 
     /**
      * Makes items on system bars become less noticeable without changing the layout of the bars.
      * @hide
      */
-    int APPEARANCE_LOW_PROFILE_BARS = 1 << 1;
+    int APPEARANCE_LOW_PROFILE_BARS = 1 << 2;
 
     /**
      * Changes the foreground color for the light top bar so that the items on the bar can be read
      * clearly.
      */
-    int APPEARANCE_LIGHT_TOP_BAR = 1 << 2;
+    int APPEARANCE_LIGHT_TOP_BAR = 1 << 3;
 
     /**
      * Changes the foreground color for the light side bars so that the items on the bar can be read
      * clearly.
      */
-    int APPEARANCE_LIGHT_SIDE_BARS = 1 << 3;
+    int APPEARANCE_LIGHT_SIDE_BARS = 1 << 4;
 
     /** Determines the appearance of system bars. */
     @Retention(RetentionPolicy.SOURCE)
-    @IntDef(flag = true, value = {APPEARANCE_OPAQUE_BARS, APPEARANCE_LOW_PROFILE_BARS,
-            APPEARANCE_LIGHT_TOP_BAR, APPEARANCE_LIGHT_SIDE_BARS})
+    @IntDef(flag = true, value = {APPEARANCE_OPAQUE_TOP_BAR, APPEARANCE_OPAQUE_SIDE_BARS,
+            APPEARANCE_LOW_PROFILE_BARS, APPEARANCE_LIGHT_TOP_BAR, APPEARANCE_LIGHT_SIDE_BARS})
     @interface Appearance {
     }
 
diff --git a/core/java/com/android/internal/statusbar/IStatusBar.aidl b/core/java/com/android/internal/statusbar/IStatusBar.aidl
index c8ba52a..d9e2ba3 100644
--- a/core/java/com/android/internal/statusbar/IStatusBar.aidl
+++ b/core/java/com/android/internal/statusbar/IStatusBar.aidl
@@ -23,6 +23,7 @@
 import android.service.notification.StatusBarNotification;
 
 import com.android.internal.statusbar.StatusBarIcon;
+import com.android.internal.view.AppearanceRegion;
 
 /** @hide */
 oneway interface IStatusBar
@@ -56,7 +57,7 @@
             int mask, in Rect fullscreenBounds, in Rect dockedBounds,
             boolean navbarColorManagedByIme);
 
-    void topAppWindowChanged(int displayId, boolean menuVisible);
+    void topAppWindowChanged(int displayId, boolean isFullscreen, boolean isImmersive);
     void setImeWindowStatus(int displayId, in IBinder token, int vis, int backDisposition,
             boolean showImeSwitcher, boolean isMultiClientImeEnabled);
     void setWindowState(int display, int window, int state);
@@ -172,4 +173,38 @@
      * Notifies System UI whether the recents animation is running or not.
      */
     void onRecentsAnimationStateChanged(boolean running);
+
+    /**
+     * Notifies System UI side of system bar appearance change on the specified display.
+     *
+     * @param displayId the ID of the display to notify
+     * @param appearance the appearance of the focused window. The light top bar appearance is not
+     *                   controlled here, but primaryAppearance and secondaryAppearance.
+     * @param appearanceRegions a set of appearances which will be only applied in their own bounds.
+     *                         This is for system bars which across multiple stack, e.g., status
+     *                         bar, that the bar can have partial appearances in corresponding
+     *                         stacks.
+     * @param navbarColorManagedByIme {@code true} if navigation bar color is managed by IME.
+     */
+    void onSystemBarAppearanceChanged(int displayId, int appearance,
+            in AppearanceRegion[] appearanceRegions, boolean navbarColorManagedByIme);
+
+    /**
+     * Notifies System UI to show transient bars. The transient bars are system bars, e.g., status
+     * bar and navigation bar which are temporarily visible to the user.
+     *
+     * @param displayId the ID of the display to notify.
+     * @param types the internal insets types of the bars are about to show transiently.
+     */
+    void showTransient(int displayId, in int[] types);
+
+    /**
+     * Notifies System UI to abort the transient state of system bars, which prevents the bars being
+     * hidden automatically. This is usually called when the app wants to show the permanent system
+     * bars again.
+     *
+     * @param displayId the ID of the display to notify.
+     * @param types the internal insets types of the bars are about to abort the transient state.
+     */
+    void abortTransient(int displayId, in int[] types);
 }
diff --git a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java
index 6b0f8b2..4c3f04b 100644
--- a/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java
+++ b/core/java/com/android/internal/statusbar/RegisterStatusBarResult.java
@@ -29,7 +29,6 @@
     public final ArrayMap<String, StatusBarIcon> mIcons;
     public final int mDisabledFlags1;                  // switch[0]
     public final int mSystemUiVisibility;              // switch[1]
-    public final boolean mMenuVisible;                 // switch[2]
     public final int mImeWindowVis;                    // switch[3]
     public final int mImeBackDisposition;              // switch[4]
     public final boolean mShowImeSwitcher;             // switch[5]
@@ -40,16 +39,18 @@
     public final Rect mFullscreenStackBounds;
     public final Rect mDockedStackBounds;
     public final boolean mNavbarColorManagedByIme;
+    public final boolean mAppFullscreen;
+    public final boolean mAppImmersive;
 
     public RegisterStatusBarResult(ArrayMap<String, StatusBarIcon> icons, int disabledFlags1,
-            int systemUiVisibility, boolean menuVisible, int imeWindowVis, int imeBackDisposition,
+            int systemUiVisibility, int imeWindowVis, int imeBackDisposition,
             boolean showImeSwitcher, int disabledFlags2, int fullscreenStackSysUiVisibility,
             int dockedStackSysUiVisibility, IBinder imeToken, Rect fullscreenStackBounds,
-            Rect dockedStackBounds, boolean navbarColorManagedByIme) {
+            Rect dockedStackBounds, boolean navbarColorManagedByIme, boolean appFullscreen,
+            boolean appImmersive) {
         mIcons = new ArrayMap<>(icons);
         mDisabledFlags1 = disabledFlags1;
         mSystemUiVisibility = systemUiVisibility;
-        mMenuVisible = menuVisible;
         mImeWindowVis = imeWindowVis;
         mImeBackDisposition = imeBackDisposition;
         mShowImeSwitcher = showImeSwitcher;
@@ -60,6 +61,8 @@
         mFullscreenStackBounds = fullscreenStackBounds;
         mDockedStackBounds = dockedStackBounds;
         mNavbarColorManagedByIme = navbarColorManagedByIme;
+        mAppFullscreen = appFullscreen;
+        mAppImmersive = appImmersive;
     }
 
     @Override
@@ -72,7 +75,6 @@
         dest.writeTypedArrayMap(mIcons, flags);
         dest.writeInt(mDisabledFlags1);
         dest.writeInt(mSystemUiVisibility);
-        dest.writeBoolean(mMenuVisible);
         dest.writeInt(mImeWindowVis);
         dest.writeInt(mImeBackDisposition);
         dest.writeBoolean(mShowImeSwitcher);
@@ -83,6 +85,8 @@
         dest.writeTypedObject(mFullscreenStackBounds, flags);
         dest.writeTypedObject(mDockedStackBounds, flags);
         dest.writeBoolean(mNavbarColorManagedByIme);
+        dest.writeBoolean(mAppFullscreen);
+        dest.writeBoolean(mAppImmersive);
     }
 
     /**
@@ -96,7 +100,6 @@
                             source.createTypedArrayMap(StatusBarIcon.CREATOR);
                     final int disabledFlags1 = source.readInt();
                     final int systemUiVisibility = source.readInt();
-                    final boolean menuVisible = source.readBoolean();
                     final int imeWindowVis = source.readInt();
                     final int imeBackDisposition = source.readInt();
                     final boolean showImeSwitcher = source.readBoolean();
@@ -107,11 +110,13 @@
                     final Rect fullscreenStackBounds = source.readTypedObject(Rect.CREATOR);
                     final Rect dockedStackBounds = source.readTypedObject(Rect.CREATOR);
                     final boolean navbarColorManagedByIme = source.readBoolean();
+                    final boolean appFullscreen = source.readBoolean();
+                    final boolean appImmersive = source.readBoolean();
                     return new RegisterStatusBarResult(icons, disabledFlags1, systemUiVisibility,
-                            menuVisible, imeWindowVis, imeBackDisposition, showImeSwitcher,
-                            disabledFlags2, fullscreenStackSysUiVisibility,
-                            dockedStackSysUiVisibility, imeToken, fullscreenStackBounds,
-                            dockedStackBounds, navbarColorManagedByIme);
+                            imeWindowVis, imeBackDisposition, showImeSwitcher, disabledFlags2,
+                            fullscreenStackSysUiVisibility, dockedStackSysUiVisibility, imeToken,
+                            fullscreenStackBounds, dockedStackBounds, navbarColorManagedByIme,
+                            appFullscreen, appImmersive);
                 }
 
                 @Override
diff --git a/core/java/com/android/internal/view/AppearanceRegion.aidl b/core/java/com/android/internal/view/AppearanceRegion.aidl
new file mode 100644
index 0000000..1638bf5
--- /dev/null
+++ b/core/java/com/android/internal/view/AppearanceRegion.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2019 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.internal.view;
+
+parcelable AppearanceRegion;
diff --git a/core/java/com/android/internal/view/AppearanceRegion.java b/core/java/com/android/internal/view/AppearanceRegion.java
new file mode 100644
index 0000000..1a0cb4b
--- /dev/null
+++ b/core/java/com/android/internal/view/AppearanceRegion.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2019 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.internal.view;
+
+import android.annotation.NonNull;
+import android.graphics.Rect;
+import android.os.Parcelable;
+import android.view.InsetsFlags;
+import android.view.ViewDebug;
+
+import com.android.internal.util.DataClass;
+
+/**
+ * Specifies which region applies which appearance.
+ */
+@DataClass
+public class AppearanceRegion implements Parcelable {
+
+    private int mAppearance;
+    private @NonNull Rect mBounds;
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        final AppearanceRegion sa = (AppearanceRegion) o;
+        return mAppearance == sa.mAppearance && mBounds.equals(sa.mBounds);
+    }
+
+    @Override
+    public String toString() {
+        final String appearanceString =
+                ViewDebug.flagsToString(InsetsFlags.class, "appearance", mAppearance);
+        return "AppearanceRegion{" + appearanceString + " bounds=" + mBounds.toShortString() + "}";
+    }
+
+
+
+    // Code below generated by codegen v1.0.7.
+    //
+    // DO NOT MODIFY!
+    // CHECKSTYLE:OFF Generated code
+    //
+    // To regenerate run:
+    // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/com/android/internal/view/AppearanceRegion.java
+
+
+    @DataClass.Generated.Member
+    public AppearanceRegion(
+            int appearance,
+            @NonNull Rect bounds) {
+        this.mAppearance = appearance;
+        this.mBounds = bounds;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mBounds);
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    @DataClass.Generated.Member
+    public int getAppearance() {
+        return mAppearance;
+    }
+
+    @DataClass.Generated.Member
+    public @NonNull Rect getBounds() {
+        return mBounds;
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public void writeToParcel(android.os.Parcel dest, int flags) {
+        // You can override field parcelling by defining methods like:
+        // void parcelFieldName(Parcel dest, int flags) { ... }
+
+        dest.writeInt(mAppearance);
+        dest.writeTypedObject(mBounds, flags);
+    }
+
+    @Override
+    @DataClass.Generated.Member
+    public int describeContents() { return 0; }
+
+    /** @hide */
+    @SuppressWarnings({"unchecked", "RedundantCast"})
+    @DataClass.Generated.Member
+    protected AppearanceRegion(android.os.Parcel in) {
+        // You can override field unparcelling by defining methods like:
+        // static FieldType unparcelFieldName(Parcel in) { ... }
+
+        int appearance = in.readInt();
+        Rect bounds = (Rect) in.readTypedObject(Rect.CREATOR);
+
+        this.mAppearance = appearance;
+        this.mBounds = bounds;
+        com.android.internal.util.AnnotationValidations.validate(
+                NonNull.class, null, mBounds);
+
+        // onConstructed(); // You can define this method to get a callback
+    }
+
+    @DataClass.Generated.Member
+    public static final @NonNull Parcelable.Creator<AppearanceRegion> CREATOR
+            = new Parcelable.Creator<AppearanceRegion>() {
+        @Override
+        public AppearanceRegion[] newArray(int size) {
+            return new AppearanceRegion[size];
+        }
+
+        @Override
+        public AppearanceRegion createFromParcel(android.os.Parcel in) {
+            return new AppearanceRegion(in);
+        }
+    };
+
+    @DataClass.Generated(
+            time = 1570909617357L,
+            codegenVersion = "1.0.7",
+            sourceFile = "frameworks/base/core/java/com/android/internal/view/AppearanceRegion.java",
+            inputSignatures = "private  int mAppearance\nprivate @android.annotation.NonNull android.graphics.Rect mBounds\npublic @java.lang.Override boolean equals(java.lang.Object)\npublic @java.lang.Override java.lang.String toString()\nclass AppearanceRegion extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass")
+    @Deprecated
+    private void __metadata() {}
+
+}
diff --git a/core/tests/coretests/src/android/view/InsetsFlagsTest.java b/core/tests/coretests/src/android/view/InsetsFlagsTest.java
new file mode 100644
index 0000000..7d4445b
--- /dev/null
+++ b/core/tests/coretests/src/android/view/InsetsFlagsTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2019 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.view;
+
+
+import static android.view.InsetsFlags.getAppearance;
+import static android.view.View.NAVIGATION_BAR_TRANSLUCENT;
+import static android.view.View.NAVIGATION_BAR_TRANSPARENT;
+import static android.view.View.STATUS_BAR_TRANSLUCENT;
+import static android.view.View.STATUS_BAR_TRANSPARENT;
+import static android.view.View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR;
+import static android.view.View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
+import static android.view.View.SYSTEM_UI_FLAG_LOW_PROFILE;
+import static android.view.WindowInsetsController.APPEARANCE_LIGHT_SIDE_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_LIGHT_TOP_BAR;
+import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_SIDE_BARS;
+import static android.view.WindowInsetsController.APPEARANCE_OPAQUE_TOP_BAR;
+
+import static org.junit.Assert.assertTrue;
+
+import android.platform.test.annotations.Presubmit;
+import android.view.WindowInsetsController.Appearance;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for {@link InsetsFlags}.
+ *
+ * <p>Build/Install/Run:
+ *  atest FrameworksCoreTests:InsetsFlagsTest
+ *
+ * <p>This test class is a part of Window Manager Service tests and specified in
+ * {@link com.android.server.wm.test.filters.FrameworksTestsFilter}.
+ */
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class InsetsFlagsTest {
+
+    @Test
+    public void testGetAppearance() {
+        assertContainsAppearance(APPEARANCE_LOW_PROFILE_BARS, SYSTEM_UI_FLAG_LOW_PROFILE);
+        assertContainsAppearance(APPEARANCE_LIGHT_TOP_BAR, SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
+        assertContainsAppearance(APPEARANCE_LIGHT_SIDE_BARS, SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR);
+        assertContainsAppearance(APPEARANCE_OPAQUE_TOP_BAR,
+                0xffffffff & ~(STATUS_BAR_TRANSLUCENT | STATUS_BAR_TRANSPARENT));
+        assertContainsAppearance(APPEARANCE_OPAQUE_SIDE_BARS,
+                0xffffffff & ~(NAVIGATION_BAR_TRANSLUCENT | NAVIGATION_BAR_TRANSPARENT));
+    }
+
+    void assertContainsAppearance(@Appearance int appearance, int systemUiVisibility) {
+        assertTrue((getAppearance(systemUiVisibility) & appearance) == appearance);
+    }
+}
diff --git a/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java b/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java
index b93c3a7..0be5009 100644
--- a/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java
+++ b/core/tests/coretests/src/com/android/internal/statusbar/RegisterStatusBarResultTest.java
@@ -48,7 +48,6 @@
         final RegisterStatusBarResult original = new RegisterStatusBarResult(iconMap,
                 0x2 /* disabledFlags1 */,
                 0x4 /* systemUiVisibility */,
-                true /* menuVisible */,
                 0x8 /* imeWindowVis */,
                 0x10 /* imeBackDisposition */,
                 false /* showImeSwitcher */,
@@ -58,7 +57,9 @@
                 new Binder() /* imeToken */,
                 new Rect(0x100, 0x200, 0x400, 0x800) /* fullscreenStackBounds */,
                 new Rect(0x1000, 0x2000, 0x4000, 0x8000) /* dockedStackBounds */,
-                true /* navbarColorManagedByIme */);
+                true /* navbarColorManagedByIme */,
+                true /* appFullscreen */,
+                true /* appImmersive */);
 
         final RegisterStatusBarResult copy = clone(original);
 
@@ -69,7 +70,6 @@
 
         assertThat(copy.mDisabledFlags1).isEqualTo(original.mDisabledFlags1);
         assertThat(copy.mSystemUiVisibility).isEqualTo(original.mSystemUiVisibility);
-        assertThat(copy.mMenuVisible).isEqualTo(original.mMenuVisible);
         assertThat(copy.mImeWindowVis).isEqualTo(original.mImeWindowVis);
         assertThat(copy.mImeBackDisposition).isEqualTo(original.mImeBackDisposition);
         assertThat(copy.mShowImeSwitcher).isEqualTo(original.mShowImeSwitcher);
@@ -82,6 +82,8 @@
         assertThat(copy.mFullscreenStackBounds).isEqualTo(original.mFullscreenStackBounds);
         assertThat(copy.mDockedStackBounds).isEqualTo(original.mDockedStackBounds);
         assertThat(copy.mNavbarColorManagedByIme).isEqualTo(original.mNavbarColorManagedByIme);
+        assertThat(copy.mAppFullscreen).isEqualTo(original.mAppFullscreen);
+        assertThat(copy.mAppImmersive).isEqualTo(original.mAppImmersive);
     }
 
     private RegisterStatusBarResult clone(RegisterStatusBarResult original) {