Merge branch 'android15-release' into merge-aosp15

This commit is contained in:
MrSluffy
2024-09-14 17:29:57 +08:00
1401 changed files with 86072 additions and 39248 deletions
+163 -52
View File
@@ -21,6 +21,13 @@ package com.android.launcher3;
import static com.android.launcher3.config.FeatureFlags.ENABLE_DOWNLOAD_APP_UX_V2;
import static com.android.launcher3.config.FeatureFlags.ENABLE_ICON_LABEL_AUTO_SCALING;
import static com.android.launcher3.graphics.PreloadIconDrawable.newPendingIcon;
import static android.text.Layout.Alignment.ALIGN_NORMAL;
import static com.android.launcher3.Flags.enableCursorHoverStates;
import static com.android.launcher3.graphics.PreloadIconDrawable.newPendingIcon;
import static com.android.launcher3.icons.BitmapInfo.FLAG_NO_BADGE;
import static com.android.launcher3.icons.BitmapInfo.FLAG_SKIP_USER_BADGE;
import static com.android.launcher3.icons.BitmapInfo.FLAG_THEMED;
import static com.android.launcher3.icons.GraphicsUtils.setColorAlphaBound;
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_INCREMENTAL_DOWNLOAD_ACTIVE;
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_INSTALL_SESSION_ACTIVE;
@@ -38,11 +45,13 @@ import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.icu.text.MessageFormat;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.TextUtils.TruncateAt;
import android.util.AttributeSet;
import android.util.Property;
import android.util.Size;
import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -55,7 +64,6 @@ import androidx.annotation.UiThread;
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.accessibility.BaseAccessibilityDelegate;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dot.DotInfo;
import com.android.launcher3.dragndrop.DragOptions.PreDragCondition;
import com.android.launcher3.dragndrop.DraggableView;
@@ -67,13 +75,13 @@ import com.android.launcher3.icons.DotRenderer;
import com.android.launcher3.icons.FastBitmapDrawable;
import com.android.launcher3.icons.IconCache.ItemInfoUpdateReceiver;
import com.android.launcher3.icons.PlaceHolderIconDrawable;
import com.android.launcher3.icons.cache.HandlerRunnable;
import com.android.launcher3.model.data.AppInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.ItemInfoWithIcon;
import com.android.launcher3.model.data.WorkspaceItemInfo;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.search.StringMatcherUtility;
import com.android.launcher3.util.CancellableTask;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.MultiTranslateDelegate;
import com.android.launcher3.util.SafeCloseable;
@@ -99,10 +107,10 @@ import app.lawnchair.util.LawnchairUtilsKt;
public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
IconLabelDotView, DraggableView, Reorderable {
private static final int DISPLAY_WORKSPACE = 0;
public static final int DISPLAY_WORKSPACE = 0;
public static final int DISPLAY_ALL_APPS = 1;
private static final int DISPLAY_FOLDER = 2;
protected static final int DISPLAY_TASKBAR = 5;
public static final int DISPLAY_FOLDER = 2;
public static final int DISPLAY_TASKBAR = 5;
public static final int DISPLAY_SEARCH_RESULT = 6;
public static final int DISPLAY_SEARCH_RESULT_SMALL = 7;
public static final int DISPLAY_PREDICTION_ROW = 8;
@@ -152,6 +160,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
private final MultiTranslateDelegate mTranslateDelegate = new MultiTranslateDelegate(this);
private final ActivityContext mActivity;
private FastBitmapDrawable mIcon;
private DeviceProfile mDeviceProfile;
private boolean mCenterVertically;
protected int mDisplay;
@@ -165,6 +174,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mHideBadge = false;
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mSkipUserBadge = false;
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mIsIconVisible = true;
@ViewDebug.ExportedProperty(category = "launcher")
private int mTextColor;
@@ -176,11 +187,30 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
@ViewDebug.ExportedProperty(category = "launcher")
private DotInfo mDotInfo;
private DotRenderer mDotRenderer;
private Locale mCurrentLocale;
@ViewDebug.ExportedProperty(category = "launcher", deepExport = true)
protected DotRenderer.DrawParams mDotParams;
private Animator mDotScaleAnim;
private boolean mForceHideDot;
// These fields, related to showing running apps, are only used for Taskbar.
private final Size mRunningAppIndicatorSize;
private final int mRunningAppIndicatorTopMargin;
private final Size mMinimizedAppIndicatorSize;
private final int mMinimizedAppIndicatorTopMargin;
private final Paint mRunningAppIndicatorPaint;
private final Rect mRunningAppIconBounds = new Rect();
private RunningAppState mRunningAppState;
/**
* Various options for the running state of an app.
*/
public enum RunningAppState {
NOT_RUNNING,
RUNNING,
MINIMIZED,
}
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mStayPressed;
@ViewDebug.ExportedProperty(category = "launcher")
@@ -188,7 +218,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
@ViewDebug.ExportedProperty(category = "launcher")
private boolean mDisableRelayout = false;
private HandlerRunnable mIconLoadRequest;
private CancellableTask mIconLoadRequest;
private boolean mEnableIconUpdateAnimation = false;
@@ -203,20 +233,22 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
public BubbleTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mActivity = ActivityContext.lookupContext(context);
FastBitmapDrawable.setFlagHoverEnabled(enableCursorHoverStates());
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.BubbleTextView, defStyle, 0);
mLayoutHorizontal = a.getBoolean(R.styleable.BubbleTextView_layoutHorizontal, false);
mIsRtl = (getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL);
DeviceProfile grid = mActivity.getDeviceProfile();
mDeviceProfile = mActivity.getDeviceProfile();
mCenterVertically = a.getBoolean(R.styleable.BubbleTextView_centerVertically, false);
mDisplay = a.getInteger(R.styleable.BubbleTextView_iconDisplay, DISPLAY_WORKSPACE);
final int defaultIconSize;
if (mDisplay == DISPLAY_WORKSPACE) {
setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.iconTextSizePx);
setCompoundDrawablePadding(grid.iconDrawablePaddingPx);
defaultIconSize = grid.iconSizePx;
setCenterVertically(grid.iconCenterVertically);
setTextSize(TypedValue.COMPLEX_UNIT_PX, mDeviceProfile.iconTextSizePx);
setCompoundDrawablePadding(mDeviceProfile.iconDrawablePaddingPx);
defaultIconSize = mDeviceProfile.iconSizePx;
setCenterVertically(mDeviceProfile.iconCenterVertically);
} else if (mDisplay == DISPLAY_ALL_APPS || mDisplay == DISPLAY_PREDICTION_ROW
|| mDisplay == DISPLAY_SEARCH_RESULT_APP_ROW) {
setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.allAppsIconTextSizePx);
@@ -224,33 +256,47 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
defaultIconSize = grid.allAppsIconSizePx;
LawnchairUtilsKt.overrideAllAppsTextColor(this);
} else if (mDisplay == DISPLAY_FOLDER) {
setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.folderChildTextSizePx);
setCompoundDrawablePadding(grid.folderChildDrawablePaddingPx);
defaultIconSize = grid.folderChildIconSizePx;
setTextSize(TypedValue.COMPLEX_UNIT_PX, mDeviceProfile.folderChildTextSizePx);
setCompoundDrawablePadding(mDeviceProfile.folderChildDrawablePaddingPx);
defaultIconSize = mDeviceProfile.folderChildIconSizePx;
} else if (mDisplay == DISPLAY_SEARCH_RESULT) {
setTextSize(TypedValue.COMPLEX_UNIT_PX, grid.allAppsIconTextSizePx);
setTextSize(TypedValue.COMPLEX_UNIT_PX, mDeviceProfile.allAppsIconTextSizePx);
defaultIconSize = getResources().getDimensionPixelSize(R.dimen.search_row_icon_size);
} else if (mDisplay == DISPLAY_SEARCH_RESULT_SMALL) {
defaultIconSize = getResources().getDimensionPixelSize(
R.dimen.search_row_small_icon_size);
} else if (mDisplay == DISPLAY_TASKBAR) {
defaultIconSize = grid.iconSizePx;
defaultIconSize = mDeviceProfile.taskbarIconSize;
} else {
// widget_selection or shortcut_popup
defaultIconSize = grid.iconSizePx;
defaultIconSize = mDeviceProfile.iconSizePx;
}
FontManager.INSTANCE.get(context).overrideFont(this, attrs);
mCenterVertically = a.getBoolean(R.styleable.BubbleTextView_centerVertically, false);
mIconSize = a.getDimensionPixelSize(R.styleable.BubbleTextView_iconSizeOverride,
defaultIconSize);
a.recycle();
mRunningAppIndicatorSize = new Size(
getResources().getDimensionPixelSize(R.dimen.taskbar_running_app_indicator_width),
getResources().getDimensionPixelSize(R.dimen.taskbar_running_app_indicator_height));
mMinimizedAppIndicatorSize = new Size(
getResources().getDimensionPixelSize(R.dimen.taskbar_minimized_app_indicator_width),
getResources().getDimensionPixelSize(
R.dimen.taskbar_minimized_app_indicator_height));
mRunningAppIndicatorTopMargin = getResources().getDimensionPixelSize(
R.dimen.taskbar_running_app_indicator_top_margin);
mMinimizedAppIndicatorTopMargin = getResources().getDimensionPixelSize(
R.dimen.taskbar_minimized_app_indicator_top_margin);
mRunningAppIndicatorPaint = new Paint();
mRunningAppIndicatorPaint.setColor(getResources().getColor(
R.color.taskbar_running_app_indicator_color, context.getTheme()));
mLongPressHelper = new CheckLongPressHelper(this);
mDotParams = new DotRenderer.DrawParams();
mCurrentLocale = context.getResources().getConfiguration().locale;
setEllipsize(TruncateAt.END);
setAccessibilityDelegate(mActivity.getAccessibilityDelegate());
setTextAlpha(1f);
@@ -268,6 +314,10 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
mHideBadge = hideBadge;
}
public void setSkipUserBadge(boolean skipUserBadge) {
mSkipUserBadge = skipUserBadge;
}
/**
* Resets the view so it can be recycled.
*/
@@ -289,6 +339,13 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
mIconLoadRequest.cancel();
mIconLoadRequest = null;
}
// Reset any shifty arrangements in case animation is disrupted.
setPivotY(0);
setAlpha(1);
setScaleY(1);
setTranslationY(0);
setMaxLines(1);
setVisibility(VISIBLE);
}
private void cancelDotScaleAnim() {
@@ -297,7 +354,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
}
}
private void animateDotScale(float... dotScales) {
public void animateDotScale(float... dotScales) {
cancelDotScaleAnim();
mDotScaleAnim = ObjectAnimator.ofFloat(this, DOT_SCALE_PROPERTY, dotScales);
mDotScaleAnim.addListener(new AnimatorListenerAdapter() {
@@ -385,10 +442,17 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
setDownloadStateContentDescription(info, info.getProgressLevel());
}
/** Updates whether the app this view represents is currently running. */
@UiThread
public void updateRunningState(RunningAppState runningAppState) {
mRunningAppState = runningAppState;
}
protected void setItemInfo(ItemInfoWithIcon itemInfo) {
setTag(itemInfo);
}
@VisibleForTesting
@UiThread
protected void applyIconAndLabel(ItemInfoWithIcon info) {
boolean useTheme = shouldUseTheme();
@@ -407,17 +471,17 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
}
/**
* Only if actual text can be displayed in two line, the {@code true} value will be effective.
* Only if actual text can be displayed in two line, the {@code true} value will
* be effective.
*/
protected boolean shouldUseTwoLine() {
return (FeatureFlags.twoLineAllApps(this.getContext()) && mDisplay == DISPLAY_ALL_APPS)
return (FeatureFlags.twoLineAllApps(this.getContext()) && mDisplay == DISPLAY_ALL_APPS)
|| (FeatureFlags.ENABLE_TWOLINE_DEVICESEARCH.get()
&& mDisplay == DISPLAY_SEARCH_RESULT);
&& mDisplay == DISPLAY_SEARCH_RESULT);
}
@UiThread
@VisibleForTesting
public void applyLabel(ItemInfoWithIcon info) {
public void applyLabel(ItemInfo info) {
CharSequence label = info.title;
if (label != null) {
mLastOriginalText = label;
@@ -542,9 +606,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
}
private void checkForEllipsis() {
if (!ENABLE_ICON_LABEL_AUTO_SCALING.get()) {
return;
}
float width = getWidth() - getCompoundPaddingLeft() - getCompoundPaddingRight();
if (width <= 0) {
return;
@@ -565,13 +626,12 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
/**
* Find the appropriate text spacing to display the provided text
*
*
* @param paint the paint used by the text view
* @param text the text to display
* @param allowedWidthPx available space to render the text
* @param minSpacingEm minimum spacing allowed between characters
* @return the final textSpacing value
*
* @see #setLetterSpacing(float)
*/
private float findBestSpacingValue(TextPaint paint, String text, float allowedWidthPx,
@@ -608,6 +668,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawDotIfNecessary(canvas);
drawRunningAppIndicatorIfNecessary(canvas);
}
/**
@@ -619,7 +680,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
if (!mForceHideDot && (hasDot() || mDotParams.scale > 0)) {
getIconBounds(mDotParams.iconBounds);
Utilities.scaleRectAboutCenter(mDotParams.iconBounds,
IconShape.getNormalizationScale());
IconShape.INSTANCE.get(getContext()).getNormalizationScale());
final int scrollX = getScrollX();
final int scrollY = getScrollY();
canvas.translate(scrollX, scrollY);
@@ -628,6 +689,25 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
}
}
/**
* Draws a line under the app icon if this is representing a running app in
* Desktop Mode.
*/
protected void drawRunningAppIndicatorIfNecessary(Canvas canvas) {
if (mRunningAppState == RunningAppState.NOT_RUNNING || mDisplay != DISPLAY_TASKBAR) {
return;
}
getIconBounds(mRunningAppIconBounds);
// TODO(b/333872717): update color, shape, and size of indicator
boolean isMinimized = mRunningAppState == RunningAppState.MINIMIZED;
int indicatorTop = mRunningAppIconBounds.bottom + (isMinimized ? mMinimizedAppIndicatorTopMargin
: mRunningAppIndicatorTopMargin);
final Size indicatorSize = isMinimized ? mMinimizedAppIndicatorSize : mRunningAppIndicatorSize;
canvas.drawRect(mRunningAppIconBounds.centerX() - indicatorSize.getWidth() / 2,
indicatorTop, mRunningAppIconBounds.centerX() + indicatorSize.getWidth() / 2,
indicatorTop + indicatorSize.getHeight(), mRunningAppIndicatorPaint);
}
@Override
public void setForceHideDot(boolean forceHideDot) {
if (mForceHideDot == forceHideDot) {
@@ -647,7 +727,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
return mForceHideDot;
}
private boolean hasDot() {
public boolean hasDot() {
return mDotInfo != null;
}
@@ -696,21 +776,28 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int height = MeasureSpec.getSize(heightMeasureSpec);
if (mCenterVertically) {
Paint.FontMetrics fm = getPaint().getFontMetrics();
int cellHeightPx = mIconSize + getCompoundDrawablePadding() +
(int) Math.ceil(fm.bottom - fm.top);
int height = MeasureSpec.getSize(heightMeasureSpec);
setPadding(getPaddingLeft(), (height - cellHeightPx) / 2, getPaddingRight(),
getPaddingBottom());
}
// Only apply two line for all_apps and device search only if necessary.
if (shouldUseTwoLine() && (mLastOriginalText != null)) {
int allowedVerticalSpace = height - getPaddingTop() - getPaddingBottom()
- mDeviceProfile.allAppsIconSizePx
- mDeviceProfile.allAppsIconDrawablePaddingPx;
CharSequence modifiedString = modifyTitleToSupportMultiLine(
MeasureSpec.getSize(widthMeasureSpec) - getCompoundPaddingLeft()
- getCompoundPaddingRight(),
allowedVerticalSpace,
mLastOriginalText,
getPaint(), mBreakPointsIntArray);
getPaint(),
mBreakPointsIntArray,
getLineSpacingMultiplier(),
getLineSpacingExtra());
if (!TextUtils.equals(modifiedString, mLastModifiedText)) {
mLastModifiedText = modifiedString;
setText(modifiedString);
@@ -795,7 +882,10 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
* new string is by
* iterating through the list of break points and determining if the strings
* between the break
* points can fit within the line it is in.
* points can fit within the line it is in. We will show the modified string if
* there is enough
* horizontal and vertical space, otherwise this method will just return the
* original string.
* Example assuming each character takes up one spot:
* title = "Battery Stats", breakpoint = [6], stringPtr = 0, limitedWidth = 7
* We get the current word -> from sublist(0, breakpoint[i]+1) so sublist (0,7)
@@ -808,8 +898,9 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
* would be
* "Battery\nStats"
*/
public static CharSequence modifyTitleToSupportMultiLine(int limitedWidth, CharSequence title,
TextPaint paint, IntArray breakPoints) {
public static CharSequence modifyTitleToSupportMultiLine(int limitedWidth, int limitedHeight,
CharSequence title, TextPaint paint, IntArray breakPoints, float spacingMultiplier,
float spacingExtra) {
// current title is less than the width allowed so we can just skip
if (title == null || paint.measureText(title, 0, title.length()) <= limitedWidth) {
return title;
@@ -817,6 +908,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
float currentWordWidth, runningWidth = 0;
CharSequence currentWord;
StringBuilder newString = new StringBuilder();
paint.setLetterSpacing(MIN_LETTER_SPACING);
int stringPtr = 0;
for (int i = 0; i < breakPoints.size() + 1; i++) {
if (i < breakPoints.size()) {
@@ -830,11 +922,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
if (runningWidth <= limitedWidth) {
newString.append(currentWord);
} else {
// there is no more space
if (i == 0) {
// if the first words exceeds width, just return as the first line will ellipse
return title;
} else {
if (i != 0) {
// If putting word onto a new line, make sure there is no space or new line
// character in the beginning of the current word and just put in the rest of
// the characters.
@@ -847,8 +935,14 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
: EMPTY;
}
newString.append(NEW_LINE).append(lastCharacters);
return newString.toString();
StaticLayout staticLayout = new StaticLayout(newString, paint, limitedWidth,
ALIGN_NORMAL, spacingMultiplier, spacingExtra, false);
if (staticLayout.getHeight() < limitedHeight) {
return newString.toString();
}
}
// if the first words exceeds width, just return as the first line will ellipse
return title;
}
if (i >= breakPoints.size()) {
// no need to look forward into the string if we've already finished processing
@@ -880,7 +974,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
if ((info.runtimeStatusFlags & FLAG_INCREMENTAL_DOWNLOAD_ACTIVE) != 0
|| info.hasPromiseIconUi()
|| (info.runtimeStatusFlags & FLAG_INSTALL_SESSION_ACTIVE) != 0
|| (ENABLE_DOWNLOAD_APP_UX_V2.get() && icon != null)) {
|| (icon != null)) {
updateProgressBarUi(info.getProgressLevel() == 100 ? icon : null);
}
}
@@ -897,7 +991,8 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
/** Applies the given progress level to the this icon's progress bar. */
@Nullable
public PreloadIconDrawable applyProgressLevel() {
if (!(getTag() instanceof ItemInfoWithIcon)) {
if (!(getTag() instanceof ItemInfoWithIcon)
|| ((ItemInfoWithIcon) getTag()).isInactiveArchive()) {
return null;
}
@@ -918,9 +1013,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
if (mIcon instanceof PreloadIconDrawable) {
preloadIconDrawable = (PreloadIconDrawable) mIcon;
preloadIconDrawable.setLevel(progressLevel);
preloadIconDrawable.setIsDisabled(ENABLE_DOWNLOAD_APP_UX_V2.get()
? info.getProgressLevel() == 0
: !info.isAppStartable());
preloadIconDrawable.setIsDisabled(isIconDisabled(info));
} else {
preloadIconDrawable = makePreloadIcon();
setIcon(preloadIconDrawable);
@@ -946,12 +1039,19 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
final PreloadIconDrawable preloadDrawable = newPendingIcon(getContext(), info);
preloadDrawable.setLevel(progressLevel);
preloadDrawable.setIsDisabled(ENABLE_DOWNLOAD_APP_UX_V2.get()
? info.getProgressLevel() == 0
: !info.isAppStartable());
preloadDrawable.setIsDisabled(isIconDisabled(info));
return preloadDrawable;
}
/**
* Returns true to grey the icon if the icon is either suspended or if the icon
* is pending
* download
*/
public boolean isIconDisabled(ItemInfoWithIcon info) {
return info.isDisabled() || info.isPendingDownload();
}
public void applyDotState(ItemInfo itemInfo, boolean animate) {
if (mIcon instanceof FastBitmapDrawable) {
boolean wasDotted = mDotInfo != null;
@@ -989,7 +1089,9 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
}
private void setDownloadStateContentDescription(ItemInfoWithIcon info, int progressLevel) {
if ((info.runtimeStatusFlags & ItemInfoWithIcon.FLAG_SHOW_DOWNLOAD_PROGRESS_MASK) != 0) {
if ((info.runtimeStatusFlags & ItemInfoWithIcon.FLAG_ARCHIVED) != 0 && progressLevel == 0) {
setContentDescription(getContext().getString(R.string.app_archived_title, info.title));
} else if ((info.runtimeStatusFlags & ItemInfoWithIcon.FLAG_SHOW_DOWNLOAD_PROGRESS_MASK) != 0) {
String percentageString = NumberFormat.getPercentInstance()
.format(progressLevel * 0.01);
if ((info.runtimeStatusFlags & FLAG_INSTALL_SESSION_ACTIVE) != 0) {
@@ -1212,4 +1314,13 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
public boolean canShowLongPressPopup() {
return getTag() instanceof ItemInfo && ShortcutUtil.supportsShortcuts((ItemInfo) getTag());
}
/** Returns the package name of the app this icon represents. */
public String getTargetPackageName() {
Object tag = getTag();
if (tag instanceof ItemInfo itemInfo) {
return itemInfo.getTargetPackage();
}
return null;
}
}