Merge "Check if ThumbnailData's bitmap is null in TaskThumbnailCache" into sc-v2-dev
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index e48c9e8..4e6b7b9 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -28,6 +28,7 @@
<dimen name="task_menu_item_corner_radius">4dp</dimen>
<dimen name="task_menu_spacing">2dp</dimen>
<dimen name="task_menu_width_grid">234dp</dimen>
+ <dimen name="task_menu_horizontal_padding">8dp</dimen>
<dimen name="overview_proactive_row_height">48dp</dimen>
<dimen name="overview_proactive_row_bottom_margin">16dp</dimen>
diff --git a/quickstep/src/com/android/quickstep/KtR.java b/quickstep/src/com/android/quickstep/KtR.java
index 57dad08..a768ef5 100644
--- a/quickstep/src/com/android/quickstep/KtR.java
+++ b/quickstep/src/com/android/quickstep/KtR.java
@@ -30,6 +30,7 @@
public static final class dimen {
public static int task_menu_spacing = R.dimen.task_menu_spacing;
+ public static int task_menu_horizontal_padding = R.dimen.task_menu_horizontal_padding;
}
public static final class layout {
diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt
index 5059f8b..179fd68 100644
--- a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt
@@ -23,14 +23,18 @@
import android.graphics.drawable.ShapeDrawable
import android.graphics.drawable.shapes.RectShape
import android.util.AttributeSet
+import android.view.Gravity
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
+import android.widget.FrameLayout
import android.widget.LinearLayout
import com.android.launcher3.BaseDraggingActivity
import com.android.launcher3.DeviceProfile
+import com.android.launcher3.InsettableFrameLayout
import com.android.launcher3.R
import com.android.launcher3.popup.ArrowPopup
+import com.android.launcher3.popup.RoundedArrowDrawable
import com.android.launcher3.popup.SystemShortcut
import com.android.launcher3.util.Themes
import com.android.quickstep.KtR
@@ -43,9 +47,13 @@
fun showForTask(taskContainer: TaskIdAttributeContainer): Boolean {
val activity = BaseDraggingActivity
- .fromContext<BaseDraggingActivity>(taskContainer.taskView.context)
+ .fromContext<BaseDraggingActivity>(taskContainer.taskView.context)
val taskMenuViewWithArrow = activity.layoutInflater
- .inflate(KtR.layout.task_menu_with_arrow, activity.dragLayer, false) as TaskMenuViewWithArrow<*>
+ .inflate(
+ KtR.layout.task_menu_with_arrow,
+ activity.dragLayer,
+ false
+ ) as TaskMenuViewWithArrow<*>
return taskMenuViewWithArrow.populateAndShowForTask(taskContainer)
}
@@ -53,10 +61,21 @@
constructor(context: Context) : super(context)
constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
- constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
+ constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
+ context,
+ attrs,
+ defStyleAttr
+ )
init {
clipToOutline = true
+
+ shouldScaleArrow = true
+ // This synchronizes the arrow and menu to open at the same time
+ OPEN_CHILD_FADE_START_DELAY = OPEN_FADE_START_DELAY
+ OPEN_CHILD_FADE_DURATION = OPEN_FADE_DURATION
+ CLOSE_FADE_START_DELAY = CLOSE_CHILD_FADE_START_DELAY
+ CLOSE_FADE_DURATION = CLOSE_CHILD_FADE_DURATION
}
private val menuWidth = context.resources.getDimensionPixelSize(R.dimen.task_menu_width_grid)
@@ -65,6 +84,13 @@
private lateinit var optionLayout: LinearLayout
private lateinit var taskContainer: TaskIdAttributeContainer
+ private var optionMeasuredHeight = 0
+ private val arrowHorizontalPadding: Int
+ get() = if (taskView.isFocusedTask)
+ resources.getDimensionPixelSize(KtR.dimen.task_menu_horizontal_padding)
+ else
+ 0
+
override fun isOfType(type: Int): Boolean = type and TYPE_TASK_MENU != 0
override fun getTargetObjectLocation(outPos: Rect?) {
@@ -147,7 +173,10 @@
}
override fun assignMarginsAndBackgrounds(viewGroup: ViewGroup) {
- assignMarginsAndBackgrounds(this, Themes.getAttrColor(context, com.android.internal.R.attr.colorSurface))
+ assignMarginsAndBackgrounds(
+ this,
+ Themes.getAttrColor(context, com.android.internal.R.attr.colorSurface)
+ )
}
override fun onCreateOpenAnimation(anim: AnimatorSet) {
@@ -164,4 +193,90 @@
ObjectAnimator.ofFloat(taskContainer.thumbnailView, TaskThumbnailView.DIM_ALPHA, 0f)
)
}
+
+ /**
+ * Orients this container to the left or right of the given icon, aligning with the first option
+ * or second.
+ *
+ * These are the preferred orientations, in order (RTL prefers right-aligned over left):
+ * - Right and first option aligned
+ * - Right and second option aligned
+ * - Left and first option aligned
+ * - Left and second option aligned
+ *
+ * So we always align right if there is enough horizontal space
+ */
+ override fun orientAboutObject() {
+ measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
+ // Needed for offsets later
+ optionMeasuredHeight = optionLayout.getChildAt(0).measuredHeight
+ val extraHorizontalSpace = (mArrowHeight + mArrowOffsetVertical + arrowHorizontalPadding)
+
+ val widthWithArrow = measuredWidth + paddingLeft + paddingRight + extraHorizontalSpace
+ getTargetObjectLocation(mTempRect)
+ val dragLayer: InsettableFrameLayout = popupContainer
+ val insets = dragLayer.insets
+
+ // Put to the right of the icon if there is space, which means left aligned with the menu
+ val rightAlignedMenuStartX = mTempRect.left - widthWithArrow
+ val leftAlignedMenuStartX = mTempRect.right + extraHorizontalSpace
+ mIsLeftAligned = if (mIsRtl) {
+ rightAlignedMenuStartX + insets.left < 0
+ } else {
+ leftAlignedMenuStartX + (widthWithArrow - extraHorizontalSpace) + insets.left <
+ dragLayer.width - insets.right
+ }
+
+ var menuStartX = if (mIsLeftAligned) leftAlignedMenuStartX else rightAlignedMenuStartX
+
+ // Offset y so that the arrow and first row are center-aligned with the original icon.
+ val iconHeight = mTempRect.height()
+ val optionHeight = optionMeasuredHeight
+ val yOffset = (optionHeight - iconHeight) / 2
+ var menuStartY = mTempRect.top - yOffset
+
+ // Insets are added later, so subtract them now.
+ menuStartX -= insets.left
+ menuStartY -= insets.top
+
+ setX(menuStartX.toFloat())
+ setY(menuStartY.toFloat())
+
+ val lp = layoutParams as FrameLayout.LayoutParams
+ val arrowLp = mArrow.layoutParams as FrameLayout.LayoutParams
+ lp.gravity = Gravity.TOP
+ arrowLp.gravity = lp.gravity
+ }
+
+ override fun addArrow() {
+ popupContainer.addView(mArrow)
+ mArrow.x = getArrowX()
+ mArrow.y = y + (optionMeasuredHeight / 2) - (mArrowHeight / 2)
+
+ updateArrowColor()
+
+ // This is inverted (x = height, y = width) because the arrow is rotated
+ mArrow.pivotX = if (mIsLeftAligned) 0f else mArrowHeight.toFloat()
+ mArrow.pivotY = 0f
+ }
+
+ private fun getArrowX(): Float {
+ return if (mIsLeftAligned)
+ x - mArrowHeight
+ else
+ x + measuredWidth + mArrowOffsetVertical
+ }
+
+ override fun updateArrowColor() {
+ mArrow.background = RoundedArrowDrawable(
+ mArrowWidth.toFloat(),
+ mArrowHeight.toFloat(),
+ mArrowPointRadius.toFloat(),
+ mIsLeftAligned,
+ mArrowColor
+ )
+ elevation = mElevation
+ mArrow.elevation = mElevation
+ }
+
}
\ No newline at end of file
diff --git a/res/layout/widget_cell_content.xml b/res/layout/widget_cell_content.xml
index b27b505..0f6fc6c 100644
--- a/res/layout/widget_cell_content.xml
+++ b/res/layout/widget_cell_content.xml
@@ -33,6 +33,14 @@
android:layout_height="match_parent"
android:importantForAccessibility="no"
android:layout_gravity="fill"/>
+
+ <ImageView
+ android:id="@+id/widget_badge"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:importantForAccessibility="no"
+ android:layout_gravity="end|bottom"
+ android:layout_margin="@dimen/profile_badge_margin"/>
</com.android.launcher3.widget.WidgetCellPreview>
<!-- The name of the widget. -->
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 3758093..0235ef0 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -36,8 +36,8 @@
<string name="add_item_request_drag_hint" msgid="5653291305078645405">"Tocca e tieni premuto il widget per spostarlo nella schermata Home"</string>
<string name="add_to_home_screen" msgid="8631549138215492708">"Aggiungi a schermata Home"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> aggiunto alla schermata Home"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widget}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# scorciatoia}other{# scorciatoie}}"</string>
+ <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}one{# widget}other{# widget}}"</string>
+ <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# scorciatoia}one{# scorciatoia}other{# scorciatoie}}"</string>
<string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
<string name="widget_button_text" msgid="2880537293434387943">"Widget"</string>
<string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Cerca"</string>
@@ -86,7 +86,7 @@
<string name="uninstall_system_app_text" msgid="4172046090762920660">"Questa è un\'app di sistema e non può essere disinstallata."</string>
<string name="folder_hint_text" msgid="5174843001373488816">"Modifica nome"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"App <xliff:g id="APP_NAME">%1$s</xliff:g> disattivata"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} ha # notifica}other{{app_name} ha # notifiche}}"</string>
+ <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{{app_name} ha # notifica}one{{app_name} ha # notifica}other{{app_name} ha # notifiche}}"</string>
<string name="default_scroll_format" msgid="7475544710230993317">"Pagina %1$d di %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Schermata Home %1$d di %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nuova pagina Schermata Home"</string>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 09a1200..a3c225a 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -36,8 +36,8 @@
<string name="add_item_request_drag_hint" msgid="5653291305078645405">"Toque sem soltar no widget para o mover à volta do ecrã principal"</string>
<string name="add_to_home_screen" msgid="8631549138215492708">"Adicionar ao ecrã principal"</string>
<string name="added_to_home_screen_accessibility_text" msgid="4451545765448884415">"Widget <xliff:g id="WIDGET_NAME">%1$s</xliff:g> adicionado ao ecrã principal"</string>
- <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}other{# widgets}}"</string>
- <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# atalho}other{# atalhos}}"</string>
+ <string name="widgets_count" msgid="6467746476364652096">"{count,plural, =1{# widget}one{# widget(s)}other{# widgets}}"</string>
+ <string name="shortcuts_count" msgid="8471715556199592381">"{count,plural, =1{# atalho}one{# atalho(s)}other{# atalhos}}"</string>
<string name="widgets_and_shortcuts_count" msgid="7209136747878365116">"<xliff:g id="WIDGETS_COUNT">%1$s</xliff:g>, <xliff:g id="SHORTCUTS_COUNT">%2$s</xliff:g>"</string>
<string name="widget_button_text" msgid="2880537293434387943">"Widgets"</string>
<string name="widgets_full_sheet_search_bar_hint" msgid="8484659090860596457">"Pesquisar"</string>
@@ -86,7 +86,7 @@
<string name="uninstall_system_app_text" msgid="4172046090762920660">"É uma app de sistema e não pode ser desinstalada."</string>
<string name="folder_hint_text" msgid="5174843001373488816">"Edite o nome"</string>
<string name="disabled_app_label" msgid="6673129024321402780">"<xliff:g id="APP_NAME">%1$s</xliff:g> desativado"</string>
- <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{A app {app_name} tem # notificação}other{A app {app_name} tem # notificações}}"</string>
+ <string name="dotted_app_label" msgid="1704091277755818896">"{count,plural,offset:1 =1{A app {app_name} tem # notificação}one{A app {app_name} tem # notificação(ões)}other{A app {app_name} tem # notificações}}"</string>
<string name="default_scroll_format" msgid="7475544710230993317">"Página %1$d de %2$d"</string>
<string name="workspace_scroll_format" msgid="8458889198184077399">"Ecrã principal %1$d de %2$d"</string>
<string name="workspace_new_page" msgid="257366611030256142">"Nova página do ecrã principal"</string>
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index c4d8166..98cb5ae 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -72,6 +72,7 @@
"PROMISE_APPS_NEW_INSTALLS", true,
"Adds a promise icon to the home screen for new install sessions.");
+ // TODO: b/206508141: Long pressing on some icons on home screen cause launcher to crash.
public static final BooleanFlag ENABLE_LOCAL_COLOR_POPUPS = getDebugFlag(
"ENABLE_LOCAL_COLOR_POPUPS", false, "Enable local color extraction for popups.");
diff --git a/src/com/android/launcher3/popup/ArrowPopup.java b/src/com/android/launcher3/popup/ArrowPopup.java
index 5a1e4bf..b1a4109 100644
--- a/src/com/android/launcher3/popup/ArrowPopup.java
+++ b/src/com/android/launcher3/popup/ArrowPopup.java
@@ -77,44 +77,45 @@
extends AbstractFloatingView {
// Duration values (ms) for popup open and close animations.
- private static final int OPEN_DURATION = 276;
- private static final int OPEN_FADE_START_DELAY = 0;
- private static final int OPEN_FADE_DURATION = 38;
- private static final int OPEN_CHILD_FADE_START_DELAY = 38;
- private static final int OPEN_CHILD_FADE_DURATION = 76;
+ protected int OPEN_DURATION = 276;
+ protected int OPEN_FADE_START_DELAY = 0;
+ protected int OPEN_FADE_DURATION = 38;
+ protected int OPEN_CHILD_FADE_START_DELAY = 38;
+ protected int OPEN_CHILD_FADE_DURATION = 76;
- private static final int CLOSE_DURATION = 200;
- private static final int CLOSE_FADE_START_DELAY = 140;
- private static final int CLOSE_FADE_DURATION = 50;
- private static final int CLOSE_CHILD_FADE_START_DELAY = 0;
- private static final int CLOSE_CHILD_FADE_DURATION = 140;
+ protected int CLOSE_DURATION = 200;
+ protected int CLOSE_FADE_START_DELAY = 140;
+ protected int CLOSE_FADE_DURATION = 50;
+ protected int CLOSE_CHILD_FADE_START_DELAY = 0;
+ protected int CLOSE_CHILD_FADE_DURATION = 140;
// Index used to get background color when using local wallpaper color extraction,
private static final int DARK_COLOR_EXTRACTION_INDEX = android.R.color.system_neutral2_800;
private static final int LIGHT_COLOR_EXTRACTION_INDEX = android.R.color.system_accent2_50;
- private final Rect mTempRect = new Rect();
+ protected final Rect mTempRect = new Rect();
protected final LayoutInflater mInflater;
- private final float mOutlineRadius;
+ protected final float mOutlineRadius;
protected final T mActivityContext;
protected final boolean mIsRtl;
- private final int mArrowOffsetVertical;
- private final int mArrowOffsetHorizontal;
- private final int mArrowWidth;
- private final int mArrowHeight;
- private final int mArrowPointRadius;
- private final View mArrow;
+ protected final int mArrowOffsetVertical;
+ protected final int mArrowOffsetHorizontal;
+ protected final int mArrowWidth;
+ protected final int mArrowHeight;
+ protected final int mArrowPointRadius;
+ protected final View mArrow;
private final int mMargin;
protected boolean mIsLeftAligned;
protected boolean mIsAboveIcon;
- private int mGravity;
+ protected int mGravity;
protected AnimatorSet mOpenCloseAnimator;
protected boolean mDeferContainerRemoval;
+ protected boolean shouldScaleArrow = false;
private final GradientDrawable mRoundedTop;
private final GradientDrawable mRoundedBottom;
@@ -122,10 +123,10 @@
private Runnable mOnCloseCallback = () -> { };
// The rect string of the view that the arrow is attached to, in screen reference frame.
- private int mArrowColor;
+ protected int mArrowColor;
protected final List<LocalColorExtractor> mColorExtractors;
- private final float mElevation;
+ protected final float mElevation;
private final int mBackgroundColor;
private final String mIterateChildrenTag;
@@ -729,6 +730,14 @@
scale.setInterpolator(interpolator);
animatorSet.play(scale);
+ if (shouldScaleArrow) {
+ Animator arrowScaleAnimator = ObjectAnimator.ofFloat(mArrow, View.SCALE_Y,
+ scaleValues);
+ arrowScaleAnimator.setDuration(totalDuration);
+ arrowScaleAnimator.setInterpolator(interpolator);
+ animatorSet.play(arrowScaleAnimator);
+ }
+
fadeInChildViews(this, alphaValues, childFadeStartDelay, childFadeDuration, animatorSet);
return animatorSet;
diff --git a/src/com/android/launcher3/popup/RoundedArrowDrawable.java b/src/com/android/launcher3/popup/RoundedArrowDrawable.java
index e662d5c..436aa51 100644
--- a/src/com/android/launcher3/popup/RoundedArrowDrawable.java
+++ b/src/com/android/launcher3/popup/RoundedArrowDrawable.java
@@ -78,6 +78,32 @@
mPath.transform(pathTransform);
}
+ /**
+ * Constructor for an arrow that points to the left or right.
+ *
+ * @param width of the arrow.
+ * @param height of the arrow.
+ * @param radius of the tip of the arrow.
+ * @param isPointingLeft or not.
+ * @param color to draw the triangle.
+ */
+ public RoundedArrowDrawable(float width, float height, float radius, boolean isPointingLeft,
+ int color) {
+ mPath = new Path();
+ mPaint = new Paint();
+ mPaint.setColor(color);
+ mPaint.setStyle(Paint.Style.FILL);
+ mPaint.setAntiAlias(true);
+
+ // Make the drawable with the triangle pointing down...
+ addDownPointingRoundedTriangleToPath(width, height, radius, mPath);
+
+ // ... then rotate it to the side it needs to point.
+ Matrix pathTransform = new Matrix();
+ pathTransform.setRotate(isPointingLeft ? 90 : -90, width * 0.5f, height * 0.5f);
+ mPath.transform(pathTransform);
+ }
+
@Override
public void draw(Canvas canvas) {
canvas.drawPath(mPath, mPaint);
diff --git a/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java b/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java
index aacb9c5..784f4f0 100644
--- a/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java
+++ b/src/com/android/launcher3/widget/DatabaseWidgetPreviewLoader.java
@@ -25,11 +25,15 @@
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
import android.graphics.RectF;
+import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Process;
+import android.os.UserHandle;
+import android.util.ArrayMap;
import android.util.Log;
import android.util.Size;
@@ -40,6 +44,7 @@
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.icons.BitmapRenderer;
+import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.icons.ShadowGenerator;
import com.android.launcher3.icons.cache.HandlerRunnable;
@@ -60,6 +65,9 @@
private final Context mContext;
private final float mPreviewBoxCornerRadius;
+ private final UserHandle mMyUser = Process.myUserHandle();
+ private final ArrayMap<UserHandle, Bitmap> mUserBadges = new ArrayMap<>();
+
public DatabaseWidgetPreviewLoader(Context context) {
mContext = context;
float previewCornerRadius = RoundedCornerEnforcement.computeEnforcedRadius(context);
@@ -101,6 +109,52 @@
}
/**
+ * Returns a drawable that can be used as a badge for the user or null.
+ */
+ // @UiThread
+ public Drawable getBadgeForUser(UserHandle user, int badgeSize) {
+ if (mMyUser.equals(user)) {
+ return null;
+ }
+
+ Bitmap badgeBitmap = getUserBadge(user, badgeSize);
+ FastBitmapDrawable d = new FastBitmapDrawable(badgeBitmap);
+ d.setFilterBitmap(true);
+ d.setBounds(0, 0, badgeBitmap.getWidth(), badgeBitmap.getHeight());
+ return d;
+ }
+
+ private Bitmap getUserBadge(UserHandle user, int badgeSize) {
+ synchronized (mUserBadges) {
+ Bitmap badgeBitmap = mUserBadges.get(user);
+ if (badgeBitmap != null) {
+ return badgeBitmap;
+ }
+
+ final Resources res = mContext.getResources();
+ badgeBitmap = Bitmap.createBitmap(badgeSize, badgeSize, Bitmap.Config.ARGB_8888);
+
+ Drawable drawable = mContext.getPackageManager().getUserBadgedDrawableForDensity(
+ new BitmapDrawable(res, badgeBitmap), user,
+ new Rect(0, 0, badgeSize, badgeSize),
+ 0);
+ if (drawable instanceof BitmapDrawable) {
+ badgeBitmap = ((BitmapDrawable) drawable).getBitmap();
+ } else {
+ badgeBitmap.eraseColor(Color.TRANSPARENT);
+ Canvas c = new Canvas(badgeBitmap);
+ drawable.setBounds(0, 0, badgeSize, badgeSize);
+ drawable.draw(c);
+ c.setBitmap(null);
+ }
+
+ mUserBadges.put(user, badgeBitmap);
+ return badgeBitmap;
+ }
+ }
+
+
+ /**
* Generates the widget preview from either the {@link WidgetManagerHelper} or cache
* and add badge at the bottom right corner.
*
diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java
index f1ac656..c92fe5a 100644
--- a/src/com/android/launcher3/widget/WidgetCell.java
+++ b/src/com/android/launcher3/widget/WidgetCell.java
@@ -36,6 +36,7 @@
import android.view.ViewPropertyAnimator;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
+import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RemoteViews;
import android.widget.TextView;
@@ -47,6 +48,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
+import com.android.launcher3.icons.BaseIconFactory;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.icons.RoundDrawableWrapper;
import com.android.launcher3.icons.cache.HandlerRunnable;
@@ -111,6 +113,7 @@
private FrameLayout mWidgetImageContainer;
private WidgetImageView mWidgetImage;
+ private ImageView mWidgetBadge;
private TextView mWidgetName;
private TextView mWidgetDims;
private TextView mWidgetDescription;
@@ -166,6 +169,7 @@
mWidgetImageContainer = findViewById(R.id.widget_preview_container);
mWidgetImage = findViewById(R.id.widget_preview);
+ mWidgetBadge = findViewById(R.id.widget_badge);
mWidgetName = findViewById(R.id.widget_name);
mWidgetDims = findViewById(R.id.widget_dims);
mWidgetDescription = findViewById(R.id.widget_description);
@@ -195,6 +199,8 @@
mWidgetImage.animate().cancel();
mWidgetImage.setDrawable(null);
mWidgetImage.setVisibility(View.VISIBLE);
+ mWidgetBadge.setImageDrawable(null);
+ mWidgetBadge.setVisibility(View.GONE);
mWidgetName.setText(null);
mWidgetDims.setText(null);
mWidgetDescription.setText(null);
@@ -349,6 +355,7 @@
mAppWidgetHostViewPreview = null;
}
}
+
if (mAnimatePreview) {
mWidgetImageContainer.setAlpha(0f);
ViewPropertyAnimator anim = mWidgetImageContainer.animate();
@@ -362,6 +369,20 @@
}
}
+ /** Used to show the badge when the widget is in the recommended section
+ */
+ public void showBadge() {
+ Drawable badge = mWidgetPreviewLoader.getBadgeForUser(mItem.user,
+ BaseIconFactory.getBadgeSizeForIconSize(
+ mActivity.getDeviceProfile().allAppsIconSizePx));
+ if (badge == null) {
+ mWidgetBadge.setVisibility(View.GONE);
+ } else {
+ mWidgetBadge.setVisibility(View.VISIBLE);
+ mWidgetBadge.setImageDrawable(badge);
+ }
+ }
+
private void setContainerSize(int width, int height) {
LayoutParams layoutParams = (LayoutParams) mWidgetImageContainer.getLayoutParams();
layoutParams.width = width;
diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java b/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
index c986007..06cc65e 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsRecommendationTableLayout.java
@@ -109,6 +109,7 @@
for (WidgetItem widgetItem : widgetItems) {
WidgetCell widgetCell = addItemCell(tableRow);
widgetCell.applyFromCellItem(widgetItem, data.mPreviewScale);
+ widgetCell.showBadge();
}
addView(tableRow);
}