From 079f33bca029c440ec6e788d6b3185f850f57973 Mon Sep 17 00:00:00 2001 From: Abodunrinwa Toki Date: Tue, 23 Jun 2015 20:36:52 -0700 Subject: [PATCH] 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 --- .../internal/widget/FloatingToolbar.java | 47 ++++++++++--------- .../res/layout/floating_popup_menu_button.xml | 3 +- core/res/res/values/attrs.xml | 3 ++ core/res/res/values/symbols.xml | 1 + core/res/res/values/themes.xml | 2 + 5 files changed, 34 insertions(+), 22 deletions(-) diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java index 523663c0e6e45..32a145c7c1c91 100644 --- a/core/java/com/android/internal/widget/FloatingToolbar.java +++ b/core/java/com/android/internal/widget/FloatingToolbar.java @@ -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 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. */ diff --git a/core/res/res/layout/floating_popup_menu_button.xml b/core/res/res/layout/floating_popup_menu_button.xml index 1b58ce530c1f6..482f91f5ab9ef 100644 --- a/core/res/res/layout/floating_popup_menu_button.xml +++ b/core/res/res/layout/floating_popup_menu_button.xml @@ -18,7 +18,8 @@