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

Commit 433f5b42 authored by Jonathan Miranda's avatar Jonathan Miranda Committed by Android (Google) Code Review
Browse files

Merge changes from topic "extractor-utils" into sc-dev

* changes:
  Move color extraction utils to extractor class so each instance can have its own set of temp variables.
  Revert "Revert "Use color extraction for arrow popup.""
parents 4d5c7334 88b7f6a0
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ 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;
@@ -193,6 +194,8 @@ 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 final float[] mTmpFloatArray = new float[4];

    private static final Paint sPaint = new Paint();

@@ -1070,11 +1073,16 @@ public class CellLayout extends ViewGroup {
        // Apply local extracted color if the DragView is an AppWidgetHostViewDrawable.
        View view = dragObject.dragView.getContentView();
        if (view instanceof LauncherAppWidgetHostView) {
            Workspace workspace =
                    Launcher.getLauncher(dragObject.dragView.getContext()).getWorkspace();
            Launcher launcher = Launcher.getLauncher(dragObject.dragView.getContext());
            Workspace workspace = launcher.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,
                    mTmpFloatArray, mTempRectF);
            Utilities.setRect(mTempRectF, mTempRect);
            ((LauncherAppWidgetHostView) view).handleDrag(mTempRect, pageId);
        }
    }
+50 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ 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;
@@ -84,6 +85,7 @@ 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;
@@ -104,6 +106,8 @@ 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();
@@ -133,6 +137,15 @@ 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;
@@ -218,6 +231,33 @@ 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, float[] recycle, RectF outRect) {
        float[] points = recycle == null ? new float[4] : recycle;
        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)}.
     */
@@ -273,6 +313,16 @@ 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();
+2 −4
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@ 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;
@@ -34,6 +33,7 @@ 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,9 +119,7 @@ public class PreloadIconDrawable extends FastBitmapDrawable {
                info,
                IconPalette.getPreloadProgressColor(context, info.bitmap.color),
                getPreloadColors(context),
            (context.getResources().getConfiguration().uiMode
                    & Configuration.UI_MODE_NIGHT_MASK
                    & Configuration.UI_MODE_NIGHT_YES) != 0) /* isDarkMode */;
                Utilities.isDarkTheme(context));
    }

    public PreloadIconDrawable(
+100 −5
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

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;

@@ -31,6 +30,7 @@ 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;
@@ -41,17 +41,21 @@ 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;
@@ -59,9 +63,11 @@ 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.
@@ -73,6 +79,9 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>

    // +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();

@@ -104,8 +113,14 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>

    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<String, View> mViewForRect = new HashMap<>();

    private final int mColorExtractionIndex;
    @Nullable private LocalColorExtractor mColorExtractor;

    public ArrowPopup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
@@ -113,7 +128,9 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
        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
@@ -158,6 +175,10 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
                mColors[i] =
                        (int) argb.evaluate((i + 1) * step, primaryColor, secondaryColor);
            }

            if (Utilities.ATLEAST_S) {
                setupColorExtraction();
            }
        }
    }

@@ -342,6 +363,15 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
            // 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(),
@@ -350,9 +380,6 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
                    mArrowColor));
            mArrow.setElevation(getElevation());
        }

        mArrow.setPivotX(mArrowWidth / 2.0f);
        mArrow.setPivotY(mIsAboveIcon ? mArrowHeight : 0);
    }

    /**
@@ -671,6 +698,12 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
        getPopupContainer().removeView(this);
        getPopupContainer().removeView(mArrow);
        mOnCloseCallback.run();
        mArrowColorRectString = null;
        mViewForRect.clear();
        if (mColorExtractor != null) {
            mColorExtractor.removeLocations();
            mColorExtractor.setListener(null);
        }
    }

    /**
@@ -680,6 +713,68 @@ public abstract class ArrowPopup<T extends StatefulActivity<LauncherState>>
        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<RectF> 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();
                        mColorExtractor.getExtractedRectForView(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();
    }
+1 −6
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@ 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;
@@ -54,16 +53,12 @@ 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 (darkTheme) {
        if (Utilities.isDarkTheme(context)) {
            return supportsDarkText ? R.style.AppTheme_Dark_DarkText
                    : isMainColorDark ? R.style.AppTheme_Dark_DarkMainColor : R.style.AppTheme_Dark;
        } else {
Loading