Fixed bug with caption not showing for some apps that handle config changes

We currently decide when to show the decor caption onConfigurationChanged
However, if the app handles configuration changes or the threshold isn't
big enough for the configuration change to be reported to the app, we don't
display the caption in some cases when transitioning from fullscreen mode
to freeform mode.
We now also use the onMultiWindowModeChanged call to also determine if
the caption should be visible.

Change-Id: I237437f04ad90f904912ebac0253245f547b0e3e
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 93c6bef..ef84ab0 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -1733,9 +1733,13 @@
      *
      * @param multiWindowMode True if the activity is in multi-window mode.
      */
+    @CallSuper
     public void onMultiWindowModeChanged(boolean multiWindowMode) {
         if (DEBUG_LIFECYCLE) Slog.v(TAG,
                 "onMultiWindowModeChanged " + this + ": " + multiWindowMode);
+        if (mWindow != null) {
+            mWindow.onMultiWindowModeChanged();
+        }
     }
 
     /**
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 53490b4..d7a98ab 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -2106,4 +2106,10 @@
      * to better match your application.
      */
     public abstract void setResizingCaptionDrawable(Drawable drawable);
+
+    /**
+     * Called when the activity changes from fullscreen mode to multi-window mode and visa-versa.
+     * @hide
+     */
+    public abstract void onMultiWindowModeChanged();
 }
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index e405564..447c213 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -67,6 +67,7 @@
 import android.widget.FrameLayout;
 import android.widget.PopupWindow;
 
+import static android.app.ActivityManager.StackId;
 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
 import static android.view.View.MeasureSpec.AT_MOST;
@@ -1188,7 +1189,7 @@
         invalidate();
 
         int opacity = PixelFormat.OPAQUE;
-        if (ActivityManager.StackId.hasWindowShadow(mStackId)) {
+        if (StackId.hasWindowShadow(mStackId)) {
             // If the window has a shadow, it must be translucent.
             opacity = PixelFormat.TRANSLUCENT;
         } else{
@@ -1571,13 +1572,25 @@
 
     void onConfigurationChanged() {
         int workspaceId = getStackId();
-        if (mDecorCaptionView != null) {
-            if (mStackId != workspaceId) {
-                mStackId = workspaceId;
+        if (mStackId != workspaceId) {
+            mStackId = workspaceId;
+            if (mDecorCaptionView == null && StackId.hasWindowDecor(mStackId)) {
+                // Configuration now requires a caption.
+                final LayoutInflater inflater = mWindow.getLayoutInflater();
+                mDecorCaptionView = createDecorCaptionView(inflater);
+                if (mDecorCaptionView != null) {
+                    if (mDecorCaptionView.getParent() == null) {
+                        addView(mDecorCaptionView, 0,
+                                new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT));
+                    }
+                    removeView(mContentRoot);
+                    mDecorCaptionView.addView(mContentRoot,
+                            new ViewGroup.MarginLayoutParams(MATCH_PARENT, MATCH_PARENT));
+                }
+            } else if (mDecorCaptionView != null) {
                 // We might have to change the kind of surface before we do anything else.
-                mDecorCaptionView.onConfigurationChanged(
-                        ActivityManager.StackId.hasWindowDecor(mStackId));
-                enableCaption(ActivityManager.StackId.hasWindowDecor(workspaceId));
+                mDecorCaptionView.onConfigurationChanged(StackId.hasWindowDecor(mStackId));
+                enableCaption(StackId.hasWindowDecor(workspaceId));
             }
         }
         initializeElevation();
@@ -1630,8 +1643,7 @@
         final boolean isApplication = attrs.type == TYPE_BASE_APPLICATION ||
                 attrs.type == TYPE_APPLICATION;
         // Only a non floating application window on one of the allowed workspaces can get a caption
-        if (!mWindow.isFloating() && isApplication
-                && ActivityManager.StackId.hasWindowDecor(mStackId)) {
+        if (!mWindow.isFloating() && isApplication && StackId.hasWindowDecor(mStackId)) {
             // Dependent on the brightness of the used title we either use the
             // dark or the light button frame.
             if (decorCaptionView == null) {
@@ -1854,7 +1866,7 @@
         final boolean wasAdjustedForStack = mElevationAdjustedForStack;
         // Do not use a shadow when we are in resizing mode (mBackdropFrameRenderer not null)
         // since the shadow is bound to the content size and not the target size.
-        if (ActivityManager.StackId.hasWindowShadow(mStackId) && !isResizing()) {
+        if (StackId.hasWindowShadow(mStackId) && !isResizing()) {
             elevation = hasWindowFocus() ?
                     DECOR_SHADOW_FOCUSED_HEIGHT_IN_DIP : DECOR_SHADOW_UNFOCUSED_HEIGHT_IN_DIP;
             // TODO(skuhne): Remove this if clause once b/22668382 got fixed.
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 86bd782..8853527 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -662,6 +662,13 @@
         }
     }
 
+    @Override
+    public void onMultiWindowModeChanged() {
+        if (mDecor != null) {
+            mDecor.onConfigurationChanged();
+        }
+    }
+
     private static void clearMenuViews(PanelFeatureState st) {
         // This can be called on config changes, so we should make sure
         // the views will be reconstructed based on the new orientation, etc.