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

Commit a8bbfd4c authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 10017868 from 1464c5f0 to udc-qpr1-release

Change-Id: Iae9acd483e4e6b2a71ebe690fc151dffec258fd6
parents 7f187096 1464c5f0
Loading
Loading
Loading
Loading
+0 −98
Original line number Diff line number Diff line
package com.android.launcher3.icons;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.Drawable;

/**
 * Factory for creating app badge icons that are shown on bubbles.
 */
public class BubbleBadgeIconFactory extends BaseIconFactory {

    final int mRingColor;
    final int mRingWidth;

    public BubbleBadgeIconFactory(Context context, int badgeSize, int ringColor, int ringWidth) {
        super(context, context.getResources().getConfiguration().densityDpi, badgeSize);
        mRingColor = ringColor;
        mRingWidth = ringWidth;
    }

    /**
     * Returns a {@link BitmapInfo} for the app-badge that is shown on top of each bubble. This
     * will include the workprofile indicator on the badge if appropriate.
     */
    public BitmapInfo getBadgeBitmap(Drawable userBadgedAppIcon, boolean isImportantConversation) {
        if (userBadgedAppIcon instanceof AdaptiveIconDrawable) {
            AdaptiveIconDrawable ad = (AdaptiveIconDrawable) userBadgedAppIcon;
            userBadgedAppIcon = new BubbleBadgeIconFactory.CircularAdaptiveIcon(ad.getBackground(),
                    ad.getForeground());
        }
        if (isImportantConversation) {
            userBadgedAppIcon = new BubbleBadgeIconFactory.CircularRingDrawable(userBadgedAppIcon);
        }
        Bitmap userBadgedBitmap = createIconBitmap(
                userBadgedAppIcon, 1, MODE_WITH_SHADOW);
        return createIconBitmap(userBadgedBitmap);
    }

    private class CircularRingDrawable extends BubbleBadgeIconFactory.CircularAdaptiveIcon {
        final Rect mInnerBounds = new Rect();

        final Drawable mDr;

        CircularRingDrawable(Drawable dr) {
            super(null, null);
            mDr = dr;
        }

        @Override
        public void draw(Canvas canvas) {
            int save = canvas.save();
            canvas.clipPath(getIconMask());
            canvas.drawColor(mRingColor);
            mInnerBounds.set(getBounds());
            mInnerBounds.inset(mRingWidth, mRingWidth);
            canvas.translate(mInnerBounds.left, mInnerBounds.top);
            mDr.setBounds(0, 0, mInnerBounds.width(), mInnerBounds.height());
            mDr.draw(canvas);
            canvas.restoreToCount(save);
        }
    }

    private static class CircularAdaptiveIcon extends AdaptiveIconDrawable {

        final Path mPath = new Path();

        CircularAdaptiveIcon(Drawable bg, Drawable fg) {
            super(bg, fg);
        }

        @Override
        public Path getIconMask() {
            mPath.reset();
            Rect bounds = getBounds();
            mPath.addOval(bounds.left, bounds.top, bounds.right, bounds.bottom, Path.Direction.CW);
            return mPath;
        }

        @Override
        public void draw(Canvas canvas) {
            int save = canvas.save();
            canvas.clipPath(getIconMask());

            Drawable d;
            if ((d = getBackground()) != null) {
                d.draw(canvas);
            }
            if ((d = getForeground()) != null) {
                d.draw(canvas);
            }
            canvas.restoreToCount(save);
        }
    }
}
+106 −6
Original line number Diff line number Diff line
package com.android.launcher3.icons;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.content.Context;
import android.content.Intent;
import android.content.pm.LauncherApps;
import android.content.pm.ShortcutInfo;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.os.Build;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

/**
 * Factory for creating normalized bubble icons.
 * Factory for creating normalized bubble icons and app badges.
 */
public class BubbleIconFactory extends BaseIconFactory {

    public BubbleIconFactory(Context context, int iconSize) {
    private final int mRingColor;
    private final int mRingWidth;

    private final BaseIconFactory mBadgeFactory;

    /**
     * Creates a bubble icon factory.
     *
     * @param context the context for the factory.
     * @param iconSize the size of the bubble icon (i.e. the large icon for the bubble).
     * @param badgeSize the size of the badge (i.e. smaller icon shown on top of the large icon).
     * @param ringColor the color of the ring optionally shown around the badge.
     * @param ringWidth the width of the ring optionally shown around the badge.
     */
    public BubbleIconFactory(Context context, int iconSize, int badgeSize, int ringColor,
            int ringWidth) {
        super(context, context.getResources().getConfiguration().densityDpi, iconSize);
        mRingColor = ringColor;
        mRingWidth = ringWidth;

        mBadgeFactory = new BaseIconFactory(context,
                context.getResources().getConfiguration().densityDpi,
                badgeSize);
    }

    /**
@@ -45,9 +71,9 @@ public class BubbleIconFactory extends BaseIconFactory {

    /**
     * Creates the bitmap for the provided drawable and returns the scale used for
     * drawing the actual drawable.
     * drawing the actual drawable. This is used for the larger icon shown for the bubble.
     */
    public Bitmap createIconBitmap(@NonNull Drawable icon, float[] outScale) {
    public Bitmap getBubbleBitmap(@NonNull Drawable icon, float[] outScale) {
        if (outScale == null) {
            outScale = new float[1];
        }
@@ -57,4 +83,78 @@ public class BubbleIconFactory extends BaseIconFactory {
                outScale);
        return createIconBitmap(icon, outScale[0], MODE_WITH_SHADOW);
    }

    /**
     * Returns a {@link BitmapInfo} for the app-badge that is shown on top of each bubble. This
     * will include the workprofile indicator on the badge if appropriate.
     */
    public BitmapInfo getBadgeBitmap(Drawable userBadgedAppIcon, boolean isImportantConversation) {
        if (userBadgedAppIcon instanceof AdaptiveIconDrawable) {
            AdaptiveIconDrawable ad = (AdaptiveIconDrawable) userBadgedAppIcon;
            userBadgedAppIcon = new CircularAdaptiveIcon(ad.getBackground(),
                    ad.getForeground());
        }
        if (isImportantConversation) {
            userBadgedAppIcon = new CircularRingDrawable(userBadgedAppIcon);
        }
        Bitmap userBadgedBitmap = mBadgeFactory.createIconBitmap(
                userBadgedAppIcon, 1, MODE_WITH_SHADOW);
        return mBadgeFactory.createIconBitmap(userBadgedBitmap);
    }

    private class CircularRingDrawable extends CircularAdaptiveIcon {
        final Rect mInnerBounds = new Rect();

        final Drawable mDr;

        CircularRingDrawable(Drawable dr) {
            super(null, null);
            mDr = dr;
        }

        @Override
        public void draw(Canvas canvas) {
            int save = canvas.save();
            canvas.clipPath(getIconMask());
            canvas.drawColor(mRingColor);
            mInnerBounds.set(getBounds());
            mInnerBounds.inset(mRingWidth, mRingWidth);
            canvas.translate(mInnerBounds.left, mInnerBounds.top);
            mDr.setBounds(0, 0, mInnerBounds.width(), mInnerBounds.height());
            mDr.draw(canvas);
            canvas.restoreToCount(save);
        }
    }

    private static class CircularAdaptiveIcon extends AdaptiveIconDrawable {

        final Path mPath = new Path();

        CircularAdaptiveIcon(Drawable bg, Drawable fg) {
            super(bg, fg);
        }

        @Override
        public Path getIconMask() {
            mPath.reset();
            Rect bounds = getBounds();
            mPath.addOval(bounds.left, bounds.top, bounds.right, bounds.bottom, Path.Direction.CW);
            return mPath;
        }

        @Override
        public void draw(Canvas canvas) {
            int save = canvas.save();
            canvas.clipPath(getIconMask());

            Drawable d;
            if ((d = getBackground()) != null) {
                d.draw(canvas);
            }
            if ((d = getForeground()) != null) {
                d.draw(canvas);
            }
            canvas.restoreToCount(save);
        }
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -100,6 +100,9 @@ public class LayoutType {
    // Layout for a quick settings tile
    public static final String QS_TILE = "qs_tile";

    // Layout for a quick settings tile container
    public static final String QS_TILE_CONTAINER = "qs_tile_container";

    // Placeholder for web suggest.
    public static final String PLACEHOLDER = "placeholder";

+26 −7
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static com.android.app.search.SearchTargetExtras.isRichAnswer;
import android.app.search.SearchTarget;
import android.content.ComponentName;
import android.os.Process;
import android.os.UserHandle;

import androidx.annotation.Nullable;

@@ -72,21 +73,24 @@ public class SearchTargetEventHelper {
    }

    /**
     * Generate application target id similar to AiAi targetId for logging only 0-state.
     * For n-state, AiAi already populates the target id in right format.
     * AiAi target id is of format "resultType:userId:packageName:extraInfo"
     * Generate application target id that matches the AiAi targetId for only 0-state.
     * For n-state, AiAi already populates the target id in right format and it's unnecessary for
     * Launcher to generate it itself.
     * AiAi target id is of format "resultType:userHandle.Id:packageName:extraInfo"
     *
     * When the apps from AiAi's AppPredictionService are converted to {@link SearchTarget}, we need
     * to construct the targetId using componentName.
     * When the apps from AiAi's AppPredictionService are converted to {@link SearchTarget},
     * we need to construct the targetId using {@link ComponentName} and {@link UserHandle}.
     * Both are required to create a unique id for the SearchTarget.
     *
     * @return string appTargetId
     * Example appTargetId for
     * maps - APPLICATION:0:com.google.android.apps.maps:com.google.android.maps.MapsActivity
     * clock - APPLICATION:0:com.google.android.deskclock:com.android.deskclock.DeskClock
     */
    public static String generateAppTargetIdForLogging(@Nullable ComponentName appComponentName) {
    public static String generateAppTargetId(@Nullable ComponentName appComponentName,
            UserHandle userHandle) {
        StringBuilder appTargetId = new StringBuilder(
                "APPLICATION" + ":" + Process.myUserHandle().getIdentifier() + ":");
                "APPLICATION" + ":" + userHandle.getIdentifier() + ":");
        if (appComponentName == null) return appTargetId.append(" : ").toString();
        return appTargetId + appComponentName.getPackageName() + ":"
                + appComponentName.getClassName();
@@ -103,4 +107,19 @@ public class SearchTargetEventHelper {
    public static String generatePlayTargetIdForLogging(String appPackage) {
        return "PLAY" + ":" + Process.myUserHandle().getIdentifier() + ":" + appPackage + ":Gms";
    }

    /**
     * Generate target id similar to AiAi targetId for logging Toast session based on surface
     * visible and invisible.
     * AiAi target id is of format "resultType:userId:packageName:extraInfo"
     *
     * @return string TargetId for Toast session
     * Example of Toast session target Id
     * targetId=SESSION_INFO:0:toast:SURFACE_VISIBLE
     * targetId=SESSION_INFO:0:toast:SURFACE_INVISIBLE
     */
    public static String generateToastSessionTargetIdForLogging(String surfaceVisibility) {
        return "SESSION_INFO:" + Process.myUserHandle().getIdentifier()
                + ":toast:" + surfaceVisibility;
    }
}
+9 −2
Original line number Diff line number Diff line
@@ -123,9 +123,16 @@ public class SearchTargetExtras {
            "tall_card_image_description";
    public static final String BUNDLE_EXTRA_BITMAP_URL = "bitmap_url";

    // Used for web suggestions count for both AA+ and QSB entry point.
    // Used for web suggestions count in n-state for both AA+ and QSB entry point.
    // Returns the number of web suggestions to be shown.
    public static final String WEB_SUG_COUNT = "web_sug_count";
    public static final String BUNDLE_EXTRA_NSTATE_WEB_SUG_COUNT = "web_sug_count";

    // Used for web suggestions count in 0-state for QSB entry point.
    public static final String BUNDLE_EXTRA_ZERO_STATE_QSB_WEB_SUGGEST_COUNT =
            "zero_state_qsb_web_suggest_count";
    // Used for web suggestions count in 0-state for AA+ entry point.
    public static final String BUNDLE_EXTRA_ZERO_STATE_ALL_APPS_WEB_SUGGEST_COUNT =
            "zero_state_all_apps_web_suggest_count";

    /**
     *  Replaced with thumbnail crop type