Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f3a62fbc authored by Wale Ogunwale's avatar Wale Ogunwale
Browse files

Added support for resizing background color for an app window

R.styleable.Window_windowResizingBackground allows an activity to
specify the background drawable that should be used when it is being
resized in multi-window mode. If unset, the system will try to use
R.styleable.Window_windowBackground if set, then
R.styleable.Window_windowBackgroundFallback if set. Otherwise, the
system default resizing background color set by
R.integer.config_windowResizingBackgroundColorARGB.

Also, use decor title color as caption background color when resizing
instead of black.

Bug: 24534744
Change-Id: I83313865b4044b976ebc78d598e14e17e0f37212
parent d4f2b641
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1420,6 +1420,7 @@ package android {
    field public static final int windowNoTitle = 16842838; // 0x1010056
    field public static final int windowOverscan = 16843727; // 0x10103cf
    field public static final int windowReenterTransition = 16843951; // 0x10104af
    field public static final int windowResizingBackground = 16844035; // 0x1010503
    field public static final int windowReturnTransition = 16843950; // 0x10104ae
    field public static final int windowSharedElementEnterTransition = 16843833; // 0x1010439
    field public static final int windowSharedElementExitTransition = 16843834; // 0x101043a
+1 −0
Original line number Diff line number Diff line
@@ -1516,6 +1516,7 @@ package android {
    field public static final int windowNoTitle = 16842838; // 0x1010056
    field public static final int windowOverscan = 16843727; // 0x10103cf
    field public static final int windowReenterTransition = 16843951; // 0x10104af
    field public static final int windowResizingBackground = 16844035; // 0x1010503
    field public static final int windowReturnTransition = 16843950; // 0x10104ae
    field public static final int windowSharedElementEnterTransition = 16843833; // 0x1010439
    field public static final int windowSharedElementExitTransition = 16843834; // 0x101043a
+11 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.internal.policy;

import android.content.Context;
import android.content.res.TypedArray;
import android.view.ContextThemeWrapper;
import android.view.WindowManager;
import android.view.WindowManagerImpl;
@@ -30,6 +31,7 @@ import android.view.WindowManagerImpl;
class DecorContext extends ContextThemeWrapper {
    private PhoneWindow mPhoneWindow;
    private WindowManager mWindowManager;
    private TypedArray mWindowStyle;

    public DecorContext(Context context) {
        super(context, null);
@@ -52,4 +54,13 @@ class DecorContext extends ContextThemeWrapper {
        }
        return super.getSystemService(name);
    }

    public TypedArray getWindowStyle() {
        synchronized (this) {
            if (mWindowStyle == null) {
                mWindowStyle = obtainStyledAttributes(com.android.internal.R.styleable.Window);
            }
            return mWindowStyle;
        }
    }
}
+44 −5
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ package com.android.internal.policy;
import static android.app.ActivityManager.FIRST_DYNAMIC_STACK_ID;
import static android.app.ActivityManager.FREEFORM_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.FULLSCREEN_WORKSPACE_STACK_ID;
import static android.app.ActivityManager.HOME_STACK_ID;
import static android.app.ActivityManager.INVALID_STACK_ID;
import static android.view.View.MeasureSpec.AT_MOST;
import static android.view.View.MeasureSpec.EXACTLY;
@@ -32,8 +31,7 @@ import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.app.ActivityManagerNative;
import android.app.SearchManager;
import android.content.ContextWrapper;
import android.content.res.Resources;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.UserHandle;

@@ -4228,7 +4226,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
                }
            }
            nonClientDecorView.setPhoneWindow(this, hasNonClientDecor(mWorkspaceId),
                    nonClientDecorHasShadow(mWorkspaceId));
                    nonClientDecorHasShadow(mWorkspaceId), getResizingBackgroundDrawable(),
                    mDecor.getContext().getDrawable(R.drawable.non_client_decor_title_focused));
        }
        // Tell the decor if it has a visible non client decor.
        mDecor.enableNonClientDecor(nonClientDecorView != null && hasNonClientDecor(mWorkspaceId));
@@ -5409,7 +5408,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
     * @param workspaceId The Id of the workspace which contains this window.
     * @Return Returns true if the window should show a non client decor.
     **/
    private boolean hasNonClientDecor(int workspaceId) {
    private static boolean hasNonClientDecor(int workspaceId) {
        return workspaceId == FREEFORM_WORKSPACE_STACK_ID;
    }

@@ -5432,4 +5431,44 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
            }
        }
    }

    /**
     * Returns the color used to fill areas the app has not rendered content to yet when the user
     * is resizing the window of an activity in multi-window mode.
     * */
    private Drawable getResizingBackgroundDrawable() {
        final Context context = mDecor.getContext();
        final TypedArray windowStyle;
        if (context instanceof DecorContext) {
            windowStyle = ((DecorContext) context).getWindowStyle();
        } else {
            windowStyle = getWindowStyle();
        }
        final int resourceId =
                windowStyle.getResourceId(R.styleable.Window_windowResizingBackground, 0);
        if (resourceId != 0) {
            return context.getDrawable(resourceId);
        }

        // The app didn't set a resizing background color. In this case we try to use the app's
        // background drawable for the resizing background.
        if (mBackgroundResource != 0) {
            final Drawable drawable = context.getDrawable(mBackgroundResource);
            if (drawable != null) {
                return drawable;
            }
        }

        // The app background drawable isn't currently set. This might be because the app cleared
        // it. In this case we try to use the app's background fallback drawable.
        if (mBackgroundFallbackResource != 0) {
            final Drawable fallbackDrawable = context.getDrawable(mBackgroundFallbackResource);
            if (fallbackDrawable != null) {
                return fallbackDrawable;
            }
        }

        return new ColorDrawable(context.getResources().getInteger(
                com.android.internal.R.integer.config_windowResizingBackgroundColorARGB));
    }
}
+13 −6
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.internal.widget;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Looper;
import android.os.RemoteException;
import android.util.AttributeSet;
@@ -52,7 +53,7 @@ import com.android.internal.policy.PhoneWindow;
 * <li>The resize handles which allow to resize the window.</li>
 * </ul>
 * After creating the view, the function
 * {@link #setPhoneWindow(PhoneWindow owner, boolean windowHasShadow)} needs to be called to make
 * {@link #setPhoneWindow} needs to be called to make
 * the connection to it's owning PhoneWindow.
 * Note: At this time the application can change various attributes of the DecorView which
 * will break things (in settle/unexpected ways):
@@ -97,6 +98,9 @@ public class NonClientDecorView extends LinearLayout
    // The resize frame renderer.
    private ResizeFrameThread mFrameRendererThread = null;

    private Drawable mResizingBackgroundDrawable;
    private Drawable mCaptionBackgroundDrawable;

    public NonClientDecorView(Context context) {
        super(context);
    }
@@ -133,10 +137,13 @@ public class NonClientDecorView extends LinearLayout
        }
    }

    public void setPhoneWindow(PhoneWindow owner, boolean showDecor, boolean windowHasShadow) {
    public void setPhoneWindow(PhoneWindow owner, boolean showDecor, boolean windowHasShadow,
            Drawable resizingBackgroundDrawable, Drawable captionBackgroundDrawableDrawable) {
        mOwner = owner;
        mWindowHasShadow = windowHasShadow;
        mShowDecor = showDecor;
        mResizingBackgroundDrawable = resizingBackgroundDrawable;
        mCaptionBackgroundDrawable = captionBackgroundDrawableDrawable;
        updateCaptionVisibility();
        if (mWindowHasShadow) {
            initializeElevation();
@@ -624,7 +631,8 @@ public class NonClientDecorView extends LinearLayout
            // barely show while the entire screen is moving.
            mFrameNode.setLeftTopRightBottom(left, top, left + width, top + mLastCaptionHeight);
            DisplayListCanvas canvas = mFrameNode.start(width, height);
            canvas.drawColor(Color.BLACK);
            mCaptionBackgroundDrawable.setBounds(0, 0, left + width, top + mLastCaptionHeight);
            mCaptionBackgroundDrawable.draw(canvas);
            mFrameNode.end(canvas);

            mBackdropNode.setLeftTopRightBottom(left, top + mLastCaptionHeight, left + width,
@@ -632,9 +640,8 @@ public class NonClientDecorView extends LinearLayout

            // The backdrop: clear everything with the background. Clipping is done elsewhere.
            canvas = mBackdropNode.start(width, height - mLastCaptionHeight);
            // TODO(skuhne): mOwner.getDecorView().mBackgroundFallback.draw(..) - or similar.
            // Note: This might not work (calculator for example uses a transparent background).
            canvas.drawColor(0xff808080);
            mResizingBackgroundDrawable.setBounds(0, 0, left + width, top + height);
            mResizingBackgroundDrawable.draw(canvas);
            mBackdropNode.end(canvas);

            // We need to render both rendered nodes explicitly.
Loading