diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index a037675029..c3816ccf0c 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -18,7 +18,6 @@ package com.android.launcher3; import static android.animation.ValueAnimator.areAnimatorsEnabled; -import static com.android.launcher3.Utilities.getBoundsForViewInDragLayer; import static com.android.launcher3.anim.Interpolators.DEACCEL_1_5; import android.animation.Animator; @@ -194,7 +193,6 @@ public class CellLayout extends ViewGroup { private static final int INVALID_DIRECTION = -100; private final Rect mTempRect = new Rect(); - private final RectF mTempRectF = new RectF(); private static final Paint sPaint = new Paint(); @@ -1069,16 +1067,11 @@ public class CellLayout extends ViewGroup { // Apply local extracted color if the DragView is an AppWidgetHostViewDrawable. View view = dragObject.dragView.getContentView(); if (view instanceof LauncherAppWidgetHostView) { - Launcher launcher = Launcher.getLauncher(dragObject.dragView.getContext()); - Workspace workspace = launcher.getWorkspace(); + Workspace workspace = + Launcher.getLauncher(dragObject.dragView.getContext()).getWorkspace(); int screenId = workspace.getIdForScreen(this); int pageId = workspace.getPageIndexForScreenId(screenId); cellToRect(targetCell[0], targetCell[1], spanX, spanY, mTempRect); - - // Now get the rect in drag layer coordinates. - getBoundsForViewInDragLayer(launcher.getDragLayer(), workspace, mTempRect, false, - mTempRectF); - Utilities.setRect(mTempRectF, mTempRect); ((LauncherAppWidgetHostView) view).handleDrag(mTempRect, pageId); } } diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 073a46c0e0..a799b4a33a 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -33,7 +33,6 @@ import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.pm.ShortcutInfo; -import android.content.res.Configuration; import android.content.res.Resources; import android.database.ContentObserver; import android.graphics.Bitmap; @@ -85,7 +84,6 @@ import com.android.launcher3.shortcuts.ShortcutKey; import com.android.launcher3.shortcuts.ShortcutRequest; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.PackageManagerHelper; -import com.android.launcher3.views.BaseDragLayer; import com.android.launcher3.widget.PendingAddShortcutInfo; import java.lang.reflect.Method; @@ -106,8 +104,6 @@ public final class Utilities { private static final Pattern sTrimPattern = Pattern.compile("^[\\s|\\p{javaSpaceChar}]*(.*)[\\s|\\p{javaSpaceChar}]*$"); - private static final float[] sTmpFloatArray = new float[4]; - private static final int[] sLoc0 = new int[2]; private static final int[] sLoc1 = new int[2]; private static final Matrix sMatrix = new Matrix(); @@ -137,15 +133,6 @@ public final class Utilities { Build.TYPE.toLowerCase(Locale.ROOT).contains("debug") || Build.TYPE.toLowerCase(Locale.ROOT).equals("eng"); - /** - * Returns true if theme is dark. - */ - public static boolean isDarkTheme(Context context) { - Configuration configuration = context.getResources().getConfiguration(); - int nightMode = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK; - return nightMode == Configuration.UI_MODE_NIGHT_YES; - } - public static boolean isDevelopersOptionsEnabled(Context context) { return Settings.Global.getInt(context.getApplicationContext().getContentResolver(), Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0; @@ -231,33 +218,6 @@ public final class Utilities { return scale; } - /** - * Returns bounds for a child view of DragLayer, in drag layer coordinates. - * - * see {@link com.android.launcher3.dragndrop.DragLayer}. - * - * @param viewBounds Bounds of the view wanted in drag layer coordinates, relative to the view - * itself. eg. (0, 0, view.getWidth, view.getHeight) - * @param ignoreTransform If true, view transform is ignored - * @param outRect The out rect where we return the bounds of {@param view} in drag layer coords. - */ - public static void getBoundsForViewInDragLayer(BaseDragLayer dragLayer, View view, - Rect viewBounds, boolean ignoreTransform, RectF outRect) { - float[] points = sTmpFloatArray; - points[0] = viewBounds.left; - points[1] = viewBounds.top; - points[2] = viewBounds.right; - points[3] = viewBounds.bottom; - - Utilities.getDescendantCoordRelativeToAncestor(view, dragLayer, points, - false, ignoreTransform); - outRect.set( - Math.min(points[0], points[2]), - Math.min(points[1], points[3]), - Math.max(points[0], points[2]), - Math.max(points[1], points[3])); - } - /** * Inverse of {@link #getDescendantCoordRelativeToAncestor(View, View, float[], boolean)}. */ @@ -313,16 +273,6 @@ public final class Utilities { return new int[] {sLoc1[0] - sLoc0[0], sLoc1[1] - sLoc0[1]}; } - /** - * Helper method to set rectOut with rectFSrc. - */ - public static void setRect(RectF rectFSrc, Rect rectOut) { - rectOut.left = (int) rectFSrc.left; - rectOut.top = (int) rectFSrc.top; - rectOut.right = (int) rectFSrc.right; - rectOut.bottom = (int) rectFSrc.bottom; - } - public static void scaleRectFAboutCenter(RectF r, float scale) { if (scale != 1.0f) { float cx = r.centerX(); diff --git a/src/com/android/launcher3/graphics/PreloadIconDrawable.java b/src/com/android/launcher3/graphics/PreloadIconDrawable.java index e45b8f7918..13ae866efb 100644 --- a/src/com/android/launcher3/graphics/PreloadIconDrawable.java +++ b/src/com/android/launcher3/graphics/PreloadIconDrawable.java @@ -21,6 +21,7 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.content.Context; +import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; @@ -33,7 +34,6 @@ import android.util.Property; import android.util.SparseArray; import android.view.ContextThemeWrapper; -import com.android.launcher3.Utilities; import com.android.launcher3.anim.Interpolators; import com.android.launcher3.icons.FastBitmapDrawable; import com.android.launcher3.icons.GraphicsUtils; @@ -119,7 +119,9 @@ public class PreloadIconDrawable extends FastBitmapDrawable { info, IconPalette.getPreloadProgressColor(context, info.bitmap.color), getPreloadColors(context), - Utilities.isDarkTheme(context)); + (context.getResources().getConfiguration().uiMode + & Configuration.UI_MODE_NIGHT_MASK + & Configuration.UI_MODE_NIGHT_YES) != 0) /* isDarkMode */; } public PreloadIconDrawable( diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java index 48c5d0a854..c19dfe9300 100644 --- a/src/com/android/launcher3/popup/ArrowPopup.java +++ b/src/com/android/launcher3/popup/ArrowPopup.java @@ -16,9 +16,9 @@ package com.android.launcher3.popup; +import static com.android.launcher3.AbstractFloatingView.getTopOpenViewWithType; import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; import static com.android.launcher3.popup.PopupPopulator.MAX_SHORTCUTS; -import static com.android.launcher3.util.ColorExtractionUtils.getColorExtractionRect; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -31,7 +31,6 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Outline; import android.graphics.Rect; -import android.graphics.RectF; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; @@ -42,21 +41,17 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewOutlineProvider; -import android.view.ViewTreeObserver; import android.widget.FrameLayout; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.InsettableFrameLayout; -import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.LauncherState; import com.android.launcher3.R; import com.android.launcher3.Utilities; -import com.android.launcher3.Workspace; import com.android.launcher3.anim.RevealOutlineAnimation; import com.android.launcher3.anim.RoundedRectRevealOutlineProvider; import com.android.launcher3.dragndrop.DragLayer; @@ -64,11 +59,9 @@ import com.android.launcher3.shortcuts.DeepShortcutView; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.util.Themes; import com.android.launcher3.views.BaseDragLayer; -import com.android.launcher3.widget.LocalColorExtractor; import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; /** * A container for shortcuts to deep links and notifications associated with an app. @@ -80,9 +73,6 @@ public abstract class ArrowPopup> // +1 for system shortcut view private static final int MAX_NUM_CHILDREN = MAX_SHORTCUTS + 1; - // Index used to get background color when using local wallpaper color extraction, - private static final int LIGHT_COLOR_EXTRACTION_INDEX = android.R.color.system_accent2_50; - private static final int DARK_COLOR_EXTRACTION_INDEX = android.R.color.system_accent2_800; private final Rect mTempRect = new Rect(); @@ -114,14 +104,8 @@ public abstract class ArrowPopup> private Runnable mOnCloseCallback = () -> { }; - // The rect string of the view that the arrow is attached to, in screen reference frame. - private String mArrowColorRectString; private int mArrowColor; private final int[] mColors; - private final HashMap mViewForRect = new HashMap<>(); - - private final int mColorExtractionIndex; - @Nullable private LocalColorExtractor mColorExtractor; public ArrowPopup(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); @@ -129,9 +113,7 @@ public abstract class ArrowPopup> mOutlineRadius = Themes.getDialogCornerRadius(context); mLauncher = BaseDraggingActivity.fromContext(context); mIsRtl = Utilities.isRtl(getResources()); - mColorExtractionIndex = Utilities.isDarkTheme(context) - ? DARK_COLOR_EXTRACTION_INDEX - : LIGHT_COLOR_EXTRACTION_INDEX; + setClipToOutline(true); setOutlineProvider(new ViewOutlineProvider() { @Override @@ -176,10 +158,6 @@ public abstract class ArrowPopup> mColors[i] = (int) argb.evaluate((i + 1) * step, primaryColor, secondaryColor); } - - if (Utilities.ATLEAST_S) { - setupColorExtraction(); - } } } @@ -364,15 +342,6 @@ public abstract class ArrowPopup> // so we centered it instead. In that case we don't want to showDefaultOptions the arrow. mArrow.setVisibility(INVISIBLE); } else { - updateArrowColor(); - } - - mArrow.setPivotX(mArrowWidth / 2.0f); - mArrow.setPivotY(mIsAboveIcon ? mArrowHeight : 0); - } - - private void updateArrowColor() { - if (!Gravity.isVertical(mGravity)) { mArrow.setBackground(new RoundedArrowDrawable( mArrowWidth, mArrowHeight, mArrowPointRadius, mOutlineRadius, getMeasuredWidth(), getMeasuredHeight(), @@ -381,6 +350,9 @@ public abstract class ArrowPopup> mArrowColor)); mArrow.setElevation(getElevation()); } + + mArrow.setPivotX(mArrowWidth / 2.0f); + mArrow.setPivotY(mIsAboveIcon ? mArrowHeight : 0); } /** @@ -699,11 +671,6 @@ public abstract class ArrowPopup> getPopupContainer().removeView(this); getPopupContainer().removeView(mArrow); mOnCloseCallback.run(); - mArrowColorRectString = null; - mViewForRect.clear(); - if (mColorExtractor != null) { - mColorExtractor.removeLocations(); - } } /** @@ -713,68 +680,6 @@ public abstract class ArrowPopup> mOnCloseCallback = callback; } - private void setupColorExtraction() { - Workspace workspace = mLauncher.findViewById(R.id.workspace); - if (workspace == null) { - return; - } - - mColorExtractor = LocalColorExtractor.newInstance(mLauncher); - mColorExtractor.setListener((rect, extractedColors) -> { - String rectString = rect.toShortString(); - View v = mViewForRect.get(rectString); - if (v != null) { - int newColor = extractedColors.get(mColorExtractionIndex); - setChildColor(v, newColor); - if (rectString.equals(mArrowColorRectString)) { - mArrowColor = newColor; - updateArrowColor(); - } - } - }); - - getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { - @Override - public boolean onPreDraw() { - getViewTreeObserver().removeOnPreDrawListener(this); - - ArrayList locations = new ArrayList<>(); - Rect r = new Rect(); - - int count = getChildCount(); - int numVisibleChild = 0; - for (int i = 0; i < count; i++) { - View view = getChildAt(i); - if (view.getVisibility() == VISIBLE) { - RectF rf = new RectF(); - getColorExtractionRect(Launcher.getLauncher(getContext()), - workspace.getCurrentPage(), view, rf); - if (rf.isEmpty()) { - numVisibleChild++; - continue; - } - - locations.add(rf); - String rectString = rf.toShortString(); - mViewForRect.put(rectString, view); - - // Arrow color matches the first child or the last child. - if (!mIsAboveIcon && numVisibleChild == 0) { - mArrowColorRectString = rectString; - } else if (mIsAboveIcon) { - mArrowColorRectString = rectString; - } - - numVisibleChild++; - } - } - - mColorExtractor.addLocation(locations); - return false; - } - }); - } - protected BaseDragLayer getPopupContainer() { return mLauncher.getDragLayer(); } diff --git a/src/com/android/launcher3/util/ColorExtractionUtils.java b/src/com/android/launcher3/util/ColorExtractionUtils.java deleted file mode 100644 index b377ded44a..0000000000 --- a/src/com/android/launcher3/util/ColorExtractionUtils.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (C) 2021 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.launcher3.util; - -import android.content.res.Resources; -import android.graphics.Rect; -import android.graphics.RectF; -import android.view.View; - -import com.android.launcher3.DeviceProfile; -import com.android.launcher3.Launcher; -import com.android.launcher3.Utilities; - -/** - * Utility class used to map launcher views to wallpaper rect. - */ -public class ColorExtractionUtils { - - public static final String TAG = "ColorExtractionUtils"; - - private static final Rect sTempRect = new Rect(); - private static final RectF sTempRectF = new RectF(); - - /** - * Takes a view and returns its rect that can be used by the wallpaper local color extractor. - * - * @param launcher Launcher class class. - * @param pageId The page the workspace item is on. - * @param v The view. - * @param colorExtractionRectOut The location rect, but converted to a format expected by the - * wallpaper local color extractor. - */ - public static void getColorExtractionRect(Launcher launcher, int pageId, View v, - RectF colorExtractionRectOut) { - Rect viewRect = sTempRect; - viewRect.set(0, 0, v.getWidth(), v.getHeight()); - Utilities.getBoundsForViewInDragLayer(launcher.getDragLayer(), v, viewRect, false, - sTempRectF); - Utilities.setRect(sTempRectF, viewRect); - getColorExtractionRect(launcher, pageId, viewRect, colorExtractionRectOut); - } - - /** - * Takes a rect in drag layer coordinates and returns the rect that can be used by the wallpaper - * local color extractor. - * - * @param launcher Launcher class. - * @param pageId The page the workspace item is on. - * @param rectInDragLayer The relevant bounds of the view in drag layer coordinates. - * @param colorExtractionRectOut The location rect, but converted to a format expected by the - * wallpaper local color extractor. - */ - public static void getColorExtractionRect(Launcher launcher, int pageId, Rect rectInDragLayer, - RectF colorExtractionRectOut) { - // If the view hasn't been measured and laid out, we cannot do this. - if (rectInDragLayer.isEmpty()) { - colorExtractionRectOut.setEmpty(); - return; - } - - Resources res = launcher.getResources(); - DeviceProfile dp = launcher.getDeviceProfile().inv.getDeviceProfile(launcher); - float screenWidth = dp.widthPx; - float screenHeight = dp.heightPx; - int numScreens = launcher.getWorkspace().getNumPagesForWallpaperParallax(); - pageId = Utilities.isRtl(res) ? numScreens - pageId - 1 : pageId; - float relativeScreenWidth = 1f / numScreens; - - int[] dragLayerBounds = new int[2]; - launcher.getDragLayer().getLocationOnScreen(dragLayerBounds); - // Translate from drag layer coordinates to screen coordinates. - int screenLeft = rectInDragLayer.left + dragLayerBounds[0]; - int screenTop = rectInDragLayer.top + dragLayerBounds[1]; - int screenRight = rectInDragLayer.right + dragLayerBounds[0]; - int screenBottom = rectInDragLayer.bottom + dragLayerBounds[1]; - - // This is the position of the view relative to the wallpaper, as expected by the - // local color extraction of the WallpaperManager. - // The coordinate system is such that, on the horizontal axis, each screen has a - // distinct range on the [0,1] segment. So if there are 3 screens, they will have the - // ranges [0, 1/3], [1/3, 2/3] and [2/3, 1]. The position on the subrange should be - // the position of the view relative to the screen. For the vertical axis, this is - // simply the location of the view relative to the screen. - // Translate from drag layer coordinates to screen coordinates - colorExtractionRectOut.left = (screenLeft / screenWidth + pageId) * relativeScreenWidth; - colorExtractionRectOut.right = (screenRight / screenWidth + pageId) * relativeScreenWidth; - colorExtractionRectOut.top = screenTop / screenHeight; - colorExtractionRectOut.bottom = screenBottom / screenHeight; - - if (colorExtractionRectOut.left < 0 - || colorExtractionRectOut.right > 1 - || colorExtractionRectOut.top < 0 - || colorExtractionRectOut.bottom > 1) { - colorExtractionRectOut.setEmpty(); - } - } -} diff --git a/src/com/android/launcher3/util/Themes.java b/src/com/android/launcher3/util/Themes.java index 06cac08aec..99942aa56d 100644 --- a/src/com/android/launcher3/util/Themes.java +++ b/src/com/android/launcher3/util/Themes.java @@ -22,6 +22,7 @@ import static android.app.WallpaperColors.HINT_SUPPORTS_DARK_THEME; import android.app.WallpaperColors; import android.app.WallpaperManager; import android.content.Context; +import android.content.res.Configuration; import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.ColorMatrix; @@ -53,12 +54,16 @@ public class Themes { } public static int getActivityThemeRes(Context context, int wallpaperColorHints) { + Configuration configuration = context.getResources().getConfiguration(); + int nightMode = configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK; + boolean darkTheme = nightMode == Configuration.UI_MODE_NIGHT_YES; + boolean supportsDarkText = Utilities.ATLEAST_S && (wallpaperColorHints & HINT_SUPPORTS_DARK_TEXT) != 0; boolean isMainColorDark = Utilities.ATLEAST_S && (wallpaperColorHints & HINT_SUPPORTS_DARK_THEME) != 0; - if (Utilities.isDarkTheme(context)) { + if (darkTheme) { return supportsDarkText ? R.style.AppTheme_Dark_DarkText : isMainColorDark ? R.style.AppTheme_Dark_DarkMainColor : R.style.AppTheme_Dark; } else { diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java index 1ddd1ba89f..d49320b073 100644 --- a/src/com/android/launcher3/views/FloatingIconView.java +++ b/src/com/android/launcher3/views/FloatingIconView.java @@ -233,8 +233,15 @@ public class FloatingIconView extends FrameLayout implements outViewBounds.set(0, 0, v.getWidth(), v.getHeight()); } - Utilities.getBoundsForViewInDragLayer(launcher.getDragLayer(), v, outViewBounds, - ignoreTransform, outRect); + float[] points = new float[] {outViewBounds.left, outViewBounds.top, outViewBounds.right, + outViewBounds.bottom}; + Utilities.getDescendantCoordRelativeToAncestor(v, launcher.getDragLayer(), points, + false, ignoreTransform); + outRect.set( + Math.min(points[0], points[2]), + Math.min(points[1], points[3]), + Math.max(points[0], points[2]), + Math.max(points[1], points[3])); } /** diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java index 697c4531c2..620604a4d1 100644 --- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java +++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java @@ -16,10 +16,6 @@ package com.android.launcher3.widget; -import static com.android.launcher3.Utilities.getBoundsForViewInDragLayer; -import static com.android.launcher3.Utilities.setRect; -import static com.android.launcher3.util.ColorExtractionUtils.getColorExtractionRect; - import android.appwidget.AppWidgetProviderInfo; import android.content.Context; import android.content.res.Configuration; @@ -29,6 +25,7 @@ import android.graphics.Rect; import android.graphics.RectF; import android.os.Handler; import android.os.SystemClock; +import android.util.Log; import android.util.SparseBooleanArray; import android.util.SparseIntArray; import android.view.LayoutInflater; @@ -98,11 +95,11 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView private RectF mLastLocationRegistered = null; @Nullable private AppWidgetHostViewDragListener mDragListener; - // Used to store the widget sizes in drag layer coordinates. + // Used to store the widget size during onLayout. private final Rect mCurrentWidgetSize = new Rect(); private final Rect mWidgetSizeAtDrag = new Rect(); - private final RectF mTempRectF = new RectF(); + private final boolean mIsRtl; private final Rect mEnforcedRectangle = new Rect(); private final float mEnforcedCornerRadius; private final ViewOutlineProvider mCornerRadiusEnforcementOutline = new ViewOutlineProvider() { @@ -132,6 +129,7 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView if (Utilities.ATLEAST_Q && Themes.getAttrBoolean(mLauncher, R.attr.isWorkspaceDarkText)) { setOnLightBackground(true); } + mIsRtl = Utilities.isRtl(context.getResources()); mColorExtractor = LocalColorExtractor.newInstance(getContext()); mColorExtractor.setListener(this); @@ -321,12 +319,13 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView mIsScrollable = checkScrollableRecursively(this); if (!mIsInDragMode && getTag() instanceof LauncherAppWidgetInfo) { + mCurrentWidgetSize.left = left; + mCurrentWidgetSize.top = top; + mCurrentWidgetSize.right = right; + mCurrentWidgetSize.bottom = bottom; LauncherAppWidgetInfo info = (LauncherAppWidgetInfo) getTag(); - getBoundsForViewInDragLayer(mLauncher.getDragLayer(), this, mCurrentWidgetSize, true, - mTempRectF); - setRect(mTempRectF, mCurrentWidgetSize); - updateColorExtraction(mCurrentWidgetSize, - mWorkspace.getPageIndexForScreenId(info.screenId)); + int pageId = mWorkspace.getPageIndexForScreenId(info.screenId); + updateColorExtraction(mCurrentWidgetSize, pageId); } enforceRoundedCorners(); @@ -339,8 +338,8 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView } /** Handles a drag event occurred on a workspace page, {@code pageId}. */ - public void handleDrag(Rect rectInDragLayer, int pageId) { - mWidgetSizeAtDrag.set(rectInDragLayer); + public void handleDrag(Rect rect, int pageId) { + mWidgetSizeAtDrag.set(rect); updateColorExtraction(mWidgetSizeAtDrag, pageId); } @@ -352,14 +351,53 @@ public class LauncherAppWidgetHostView extends NavigableAppWidgetHostView requestLayout(); } - /** - * @param rectInDragLayer Rect of widget in drag layer coordinates. - * @param pageId The workspace page the widget is on. - */ - private void updateColorExtraction(Rect rectInDragLayer, int pageId) { - getColorExtractionRect(mLauncher, pageId, rectInDragLayer, mTempRectF); - - if (mTempRectF.isEmpty()) { + private void updateColorExtraction(Rect widgetLocation, int pageId) { + // If the widget hasn't been measured and laid out, we cannot do this. + if (widgetLocation.isEmpty()) { + return; + } + int screenWidth = mLauncher.getDeviceProfile().widthPx; + int screenHeight = mLauncher.getDeviceProfile().heightPx; + int numScreens = mWorkspace.getNumPagesForWallpaperParallax(); + pageId = mIsRtl ? numScreens - pageId - 1 : pageId; + float relativeScreenWidth = 1f / numScreens; + float absoluteTop = widgetLocation.top; + float absoluteBottom = widgetLocation.bottom; + View v = this; + while (v.getParent() instanceof View) { + v = (View) v.getParent(); + if (v.getId() != R.id.launcher) { + break; + } + absoluteBottom += v.getTop(); + absoluteTop += v.getTop(); + } + float xOffset = 0; + View parentView = (View) getParent(); + // The layout depends on the orientation. + if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { + int parentViewWidth = parentView == null ? 0 : parentView.getWidth(); + xOffset = screenWidth - mWorkspace.getPaddingRight() - parentViewWidth; + } else { + int parentViewPaddingLeft = parentView == null ? 0 : parentView.getPaddingLeft(); + xOffset = mWorkspace.getPaddingLeft() + parentViewPaddingLeft; + } + // This is the position of the widget relative to the wallpaper, as expected by the + // local color extraction of the WallpaperManager. + // The coordinate system is such that, on the horizontal axis, each screen has a + // distinct range on the [0,1] segment. So if there are 3 screens, they will have the + // ranges [0, 1/3], [1/3, 2/3] and [2/3, 1]. The position on the subrange should be + // the position of the widget relative to the screen. For the vertical axis, this is + // simply the location of the widget relative to the screen. + mTempRectF.left = ((widgetLocation.left + xOffset) / screenWidth + pageId) + * relativeScreenWidth; + mTempRectF.right = ((widgetLocation.right + xOffset) / screenWidth + pageId) + * relativeScreenWidth; + mTempRectF.top = absoluteTop / screenHeight; + mTempRectF.bottom = absoluteBottom / screenHeight; + if (mTempRectF.left < 0 || mTempRectF.right > 1 || mTempRectF.top < 0 + || mTempRectF.bottom > 1) { + Log.e(LOG_TAG, " Error, invalid relative position"); return; } if (!mTempRectF.equals(mLastLocationRegistered)) { diff --git a/src/com/android/launcher3/widget/LocalColorExtractor.java b/src/com/android/launcher3/widget/LocalColorExtractor.java index 2121bc288b..097158b072 100644 --- a/src/com/android/launcher3/widget/LocalColorExtractor.java +++ b/src/com/android/launcher3/widget/LocalColorExtractor.java @@ -43,10 +43,7 @@ public class LocalColorExtractor implements ResourceBasedOverride { void onColorsChanged(RectF rect, SparseIntArray extractedColors); } - /** - * Returns a new instance of the LocalColorExtractor. - */ - public static LocalColorExtractor newInstance(Context context) { + static LocalColorExtractor newInstance(Context context) { return Overrides.getObject(LocalColorExtractor.class, context.getApplicationContext(), R.string.local_colors_extraction_class); }