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

Commit 079f33bc authored by Abodunrinwa Toki's avatar Abodunrinwa Toki
Browse files

Enforce FloatingToolbar themes.

This ensures that theme attribute values that affect the look and
feel of the FloatingToolbar views are the ones specified in the
framework.
The aim is to avoid apps modifying the toolbar's look and feel in
unexpected ways by overriding Theme attributes.

Bug: 21957785

Change-Id: Idd472b4e8511f0a039cd07f98b1fd3ce93ae97fa
parent e71c6e38
Loading
Loading
Loading
Loading
+26 −21
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.animation.ObjectAnimator;
import android.content.ComponentCallbacks;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
@@ -30,6 +31,7 @@ import android.graphics.Region;
import android.graphics.drawable.ColorDrawable;
import android.text.TextUtils;
import android.util.Size;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -108,8 +110,10 @@ public final class FloatingToolbar {
     * Initializes a floating toolbar.
     */
    public FloatingToolbar(Context context, Window window) {
        mContext = Preconditions.checkNotNull(context);
        mPopup = new FloatingToolbarPopup(window.getDecorView());
        Preconditions.checkNotNull(context);
        Preconditions.checkNotNull(window);
        mContext = applyDefaultTheme(context);
        mPopup = new FloatingToolbarPopup(mContext, window.getDecorView());
    }

    /**
@@ -276,6 +280,7 @@ public final class FloatingToolbar {
        public static final int OVERFLOW_DIRECTION_UP = 0;
        public static final int OVERFLOW_DIRECTION_DOWN = 1;

        private final Context mContext;
        private final View mParent;
        private final PopupWindow mPopupWindow;
        private final ViewGroup mContentContainer;
@@ -375,9 +380,10 @@ public final class FloatingToolbar {
         * @param parent  A parent view to get the {@link android.view.View#getWindowToken()} token
         *      from.
         */
        public FloatingToolbarPopup(View parent) {
        public FloatingToolbarPopup(Context context, View parent) {
            mParent = Preconditions.checkNotNull(parent);
            mContentContainer = createContentContainer(parent.getContext());
            mContext = Preconditions.checkNotNull(context);
            mContentContainer = createContentContainer(context);
            mPopupWindow = createPopupWindow(mContentContainer);
            mDismissAnimation = createExitAnimation(
                    mContentContainer,
@@ -415,7 +421,7 @@ public final class FloatingToolbar {

            mContentContainer.removeAllViews();
            if (mMainPanel == null) {
                mMainPanel = new FloatingToolbarMainPanel(mParent.getContext(), mOpenOverflow);
                mMainPanel = new FloatingToolbarMainPanel(mContext, mOpenOverflow);
            }
            List<MenuItem> overflowMenuItems =
                    mMainPanel.layoutMenuItems(menuItems, getToolbarWidth(suggestedWidth));
@@ -423,7 +429,7 @@ public final class FloatingToolbar {
            if (!overflowMenuItems.isEmpty()) {
                if (mOverflowPanel == null) {
                    mOverflowPanel =
                            new FloatingToolbarOverflowPanel(mParent.getContext(), mCloseOverflow);
                            new FloatingToolbarOverflowPanel(mContext, mCloseOverflow);
                }
                mOverflowPanel.setMenuItems(overflowMenuItems);
                mOverflowPanel.setOnMenuItemClickListener(menuItemClickListener);
@@ -540,7 +546,7 @@ public final class FloatingToolbar {
         * Returns the context this popup is running in.
         */
        public Context getContext() {
            return mContentContainer.getContext();
            return mContext;
        }

        private void refreshCoordinatesAndOverflowDirection(Rect contentRect) {
@@ -562,7 +568,7 @@ public final class FloatingToolbar {
                } else if (availableHeightBelowContent >= getToolbarHeightWithVerticalMargin()) {
                    // There is enough space at the bottom of the content.
                    y = contentRect.bottom;
                } else if (availableHeightBelowContent >= getEstimatedToolbarHeight(getContext())) {
                } else if (availableHeightBelowContent >= getEstimatedToolbarHeight(mContext)) {
                    // Just enough space to fit the toolbar with no vertical margins.
                    y = contentRect.bottom - mMarginVertical;
                } else {
@@ -621,7 +627,7 @@ public final class FloatingToolbar {
        }

        private int getToolbarHeightWithVerticalMargin() {
            return getEstimatedToolbarHeight(mParent.getContext()) + mMarginVertical * 2;
            return getEstimatedToolbarHeight(mContext) + mMarginVertical * 2;
        }

        /**
@@ -1477,6 +1483,17 @@ public final class FloatingToolbar {
        return animation;
    }

    /**
     * Returns a re-themed context with controlled look and feel for views.
     */
    private static Context applyDefaultTheme(Context originalContext) {
        TypedArray a = originalContext.obtainStyledAttributes(new int[]{R.attr.isLightTheme});
        boolean isLightTheme = a.getBoolean(0, true);
        int themeId = isLightTheme ? R.style.Theme_Material_Light : R.style.Theme_Material;
        a.recycle();
        return new ContextThemeWrapper(originalContext, themeId);
    }

    private static int getEstimatedToolbarHeight(Context context) {
        return context.getResources().getDimensionPixelSize(R.dimen.floating_toolbar_height);
    }
@@ -1486,18 +1503,6 @@ public final class FloatingToolbar {
                .getDimensionPixelSize(R.dimen.floating_toolbar_menu_button_minimum_width);
    }

    private static int getAdjustedToolbarWidth(Context context, int width) {
        int maximumWidth = getScreenWidth(context) - 2 * context.getResources()
                .getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin);

        if (width <= 0 || width > maximumWidth) {
            int defaultWidth = context.getResources()
                    .getDimensionPixelSize(R.dimen.floating_toolbar_preferred_width);
            width = Math.min(defaultWidth, maximumWidth);
        }
        return width;
    }

    /**
     * Returns the device's screen width.
     */
+2 −1
Original line number Diff line number Diff line
@@ -18,7 +18,8 @@
<Button xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="match_parent"
    android:minWidth="@dimen/floating_toolbar_menu_button_side_padding"
    android:minWidth="@dimen/floating_toolbar_menu_button_minimum_width"
    android:minHeight="@dimen/floating_toolbar_height"
    android:paddingStart="@dimen/floating_toolbar_menu_button_side_padding"
    android:paddingEnd="@dimen/floating_toolbar_menu_button_side_padding"
    android:paddingTop="0dp"
+3 −0
Original line number Diff line number Diff line
@@ -27,6 +27,9 @@
        <!-- ============== -->
        <eat-comment />

        <!-- Specifies that a theme has a light background with dark text on top.  -->
        <attr name="isLightTheme" format="boolean" />

        <!-- Default color of foreground imagery. -->
        <attr name="colorForeground" format="color" />
        <!-- Default color of foreground imagery on an inverted background. -->
+1 −0
Original line number Diff line number Diff line
@@ -240,6 +240,7 @@
  <java-symbol type="attr" name="windowFixedHeightMajor" />
  <java-symbol type="attr" name="windowFixedHeightMinor" />
  <java-symbol type="attr" name="accessibilityFocusedDrawable"/>
  <java-symbol type="attr" name="isLightTheme"/>

  <java-symbol type="bool" name="action_bar_embed_tabs" />
  <java-symbol type="bool" name="action_bar_embed_tabs_pre_jb" />
+2 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ please see themes_device_defaults.xml.
    -->
    <style name="Theme">

        <item name="isLightTheme">false</item>
        <item name="colorForeground">@color/bright_foreground_dark</item>
        <item name="colorForegroundInverse">@color/bright_foreground_dark_inverse</item>
        <item name="colorBackground">@color/background_dark</item>
@@ -472,6 +473,7 @@ please see themes_device_defaults.xml.
         background will be a light color.
         <p>This is designed for API level 10 and lower.</p>-->
    <style name="Theme.Light">
        <item name="isLightTheme">true</item>
        <item name="windowBackground">@drawable/screen_background_selector_light</item>
        <item name="windowClipToOutline">false</item>