use of com.android.launcher3.tapl.Background in project Neo-Launcher by NeoApplications.
the class AdaptiveIconGenerator method loop.
private void loop() {
if (Utilities.ATLEAST_OREO && shouldWrap) {
if (roundIcon != null && roundIcon instanceof AdaptiveIconCompat) {
icon = roundIcon;
}
Drawable extractee = icon;
if (icon instanceof AdaptiveIconCompat) {
if (!treatWhite) {
onExitLoop();
return;
}
AdaptiveIconCompat aid = (AdaptiveIconCompat) extractee;
// we still check this seperately as this is the only information we need from the background
if (!isSingleColor(aid.getBackground(), Color.WHITE)) {
onExitLoop();
return;
}
isBackgroundWhite = true;
extractee = aid.getForeground();
}
if (extractee == null) {
Log.e("AdaptiveIconGenerator", "extractee is null, skipping.");
onExitLoop();
return;
}
LauncherIcons li = LauncherIcons.obtain(context);
IconNormalizer normalizer = li.getNormalizer();
li.recycle();
boolean[] outShape = new boolean[1];
RectF bounds = new RectF();
initTmpIfNeeded();
// scale = normalizer.getScale(extractee, bounds, tmp.getIconMask(), outShape);
scale = normalizer.getScale(extractee, bounds, tmp.getIconMask(), outShape, MIN_VISIBLE_ALPHA);
matchesMaskShape = outShape[0];
if (extractee instanceof ColorDrawable) {
isFullBleed = true;
fullBleedChecked = true;
}
width = extractee.getIntrinsicWidth();
height = extractee.getIntrinsicHeight();
aWidth = width * (1 - (bounds.left + bounds.right));
aHeight = height * (1 - (bounds.top + bounds.bottom));
// Check if the icon is squareish
final float ratio = aHeight / aWidth;
boolean isSquareish = 0.999 < ratio && ratio < 1.0001;
boolean almostSquarish = isSquareish || (0.97 < ratio && ratio < 1.005);
if (!isSquareish) {
isFullBleed = false;
fullBleedChecked = true;
}
final Bitmap bitmap = Utilities.drawableToBitmap(extractee);
if (bitmap == null) {
onExitLoop();
return;
}
if (!bitmap.hasAlpha()) {
isFullBleed = true;
fullBleedChecked = true;
}
final int size = height * width;
SparseIntArray rgbScoreHistogram = new SparseIntArray(NUMBER_OF_COLORS_GUESSTIMATION);
final int[] pixels = new int[size];
bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
/*
* Calculate the number of padding pixels around the actual icon (i)
* +----------------+
* | top |
* +---+--------+---+
* | | | |
* | l | i | r |
* | | | |
* +---+--------+---+
* | bottom |
* +----------------+
*/
float adjHeight = height - bounds.top - bounds.bottom;
float l = bounds.left * width * adjHeight;
float top = bounds.top * height * width;
float r = bounds.right * width * adjHeight;
float bottom = bounds.bottom * height * width;
int addPixels = Math.round(l + top + r + bottom);
// Any icon with less than 10% transparent pixels (padding excluded) is considered "full-bleed-ish"
final int maxTransparent = (int) (round(size * .10) + addPixels);
// Any icon with less than 27% transparent pixels (padding excluded) doesn't need a color mix-in
final int noMixinScore = (int) (round(size * .27) + addPixels);
int highScore = 0;
int bestRGB = 0;
int transparentScore = 0;
for (int pixel : pixels) {
int alpha = 0xFF & (pixel >> 24);
if (alpha < MIN_VISIBLE_ALPHA) {
// Drop mostly-transparent pixels.
transparentScore++;
if (transparentScore > maxTransparent) {
isFullBleed = false;
fullBleedChecked = true;
if (!extractColor && transparentScore > noMixinScore) {
break;
}
}
continue;
}
// Reduce color complexity.
int rgb = ColorExtractor.posterize(pixel);
if (rgb < 0) {
// Defensively avoid array bounds violations.
continue;
}
int currentScore = rgbScoreHistogram.get(rgb) + 1;
rgbScoreHistogram.append(rgb, currentScore);
if (currentScore > highScore) {
highScore = currentScore;
bestRGB = rgb;
}
}
// add back the alpha channel
bestRGB |= 0xff << 24;
// not yet checked = not set to false = has to be full bleed, isBackgroundWhite = true = is adaptive
isFullBleed |= !fullBleedChecked && !isBackgroundWhite;
// return early if a mix-in isnt needed
noMixinNeeded = !isFullBleed && !isBackgroundWhite && almostSquarish && transparentScore <= noMixinScore;
if (isFullBleed || noMixinNeeded) {
backgroundColor = bestRGB;
onExitLoop();
return;
}
if (!extractColor) {
backgroundColor = Color.WHITE;
onExitLoop();
return;
}
// "single color"
final int numColors = rgbScoreHistogram.size();
boolean singleColor = numColors <= SINGLE_COLOR_LIMIT;
// Convert to HSL to get the lightness and adjust the color
final float[] hsl = new float[3];
ColorUtils.colorToHSL(bestRGB, hsl);
float lightness = hsl[2];
boolean light = lightness > .5;
// Apply dark background to mostly white icons
boolean veryLight = lightness > .75 && singleColor;
// Apply light background to mostly dark icons
boolean veryDark = lightness < .35 && singleColor;
// Adjust color to reach suitable contrast depending on the relationship between the colors
final int opaqueSize = size - transparentScore;
final float pxPerColor = opaqueSize / (float) numColors;
float mixRatio = min(max(pxPerColor / highScore, .15f), .7f);
// Vary color mix-in based on lightness and amount of colors
int fill = (light && !veryLight) || veryDark ? 0xFFFFFFFF : 0xFF333333;
backgroundColor = ColorUtils.blendARGB(bestRGB, fill, mixRatio);
// backgroundColor = Utilities.findDominantColorByHue(bitmap, 20);
}
onExitLoop();
}
use of com.android.launcher3.tapl.Background in project android_packages_apps_Launcher3 by ArrowOS.
the class Workspace method manageFolderFeedback.
private void manageFolderFeedback(float distance, DragObject dragObject) {
if (distance > mDragTargetLayout.getFolderCreationRadius(mTargetCell)) {
if ((mDragMode == DRAG_MODE_ADD_TO_FOLDER || mDragMode == DRAG_MODE_CREATE_FOLDER)) {
setDragMode(DRAG_MODE_NONE);
}
return;
}
final View dragOverView = mDragTargetLayout.getChildAt(mTargetCell[0], mTargetCell[1]);
ItemInfo info = dragObject.dragInfo;
boolean userFolderPending = willCreateUserFolder(info, dragOverView, false);
if (mDragMode == DRAG_MODE_NONE && userFolderPending) {
mFolderCreateBg = new PreviewBackground();
mFolderCreateBg.setup(mLauncher, mLauncher, null, dragOverView.getMeasuredWidth(), dragOverView.getPaddingTop());
// The full preview background should appear behind the icon
mFolderCreateBg.isClipping = false;
mFolderCreateBg.animateToAccept(mDragTargetLayout, mTargetCell[0], mTargetCell[1]);
mDragTargetLayout.clearDragOutlines();
setDragMode(DRAG_MODE_CREATE_FOLDER);
if (dragObject.stateAnnouncer != null) {
dragObject.stateAnnouncer.announce(WorkspaceAccessibilityHelper.getDescriptionForDropOver(dragOverView, getContext()));
}
return;
}
boolean willAddToFolder = willAddToExistingUserFolder(info, dragOverView);
if (willAddToFolder && mDragMode == DRAG_MODE_NONE) {
mDragOverFolderIcon = ((FolderIcon) dragOverView);
mDragOverFolderIcon.onDragEnter(info);
if (mDragTargetLayout != null) {
mDragTargetLayout.clearDragOutlines();
}
setDragMode(DRAG_MODE_ADD_TO_FOLDER);
if (dragObject.stateAnnouncer != null) {
dragObject.stateAnnouncer.announce(WorkspaceAccessibilityHelper.getDescriptionForDropOver(dragOverView, getContext()));
}
return;
}
if (mDragMode == DRAG_MODE_ADD_TO_FOLDER && !willAddToFolder) {
setDragMode(DRAG_MODE_NONE);
}
if (mDragMode == DRAG_MODE_CREATE_FOLDER && !userFolderPending) {
setDragMode(DRAG_MODE_NONE);
}
}
use of com.android.launcher3.tapl.Background in project android_packages_apps_Launcher3 by ArrowOS.
the class ClipIconView method setIcon.
/**
* Sets the icon for this view as part of initial setup
*/
public void setIcon(@Nullable Drawable drawable, int iconOffset, MarginLayoutParams lp, boolean isOpening, boolean isVerticalBarLayout, DeviceProfile dp) {
mIsAdaptiveIcon = drawable instanceof AdaptiveIconDrawable;
if (mIsAdaptiveIcon) {
boolean isFolderIcon = drawable instanceof FolderAdaptiveIcon;
AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) drawable;
Drawable background = adaptiveIcon.getBackground();
if (background == null) {
background = new ColorDrawable(Color.TRANSPARENT);
}
mBackground = background;
Drawable foreground = adaptiveIcon.getForeground();
if (foreground == null) {
foreground = new ColorDrawable(Color.TRANSPARENT);
}
mForeground = foreground;
final int originalHeight = lp.height;
final int originalWidth = lp.width;
int blurMargin = mBlurSizeOutline / 2;
mFinalDrawableBounds.set(0, 0, originalWidth, originalHeight);
if (!isFolderIcon) {
mFinalDrawableBounds.inset(iconOffset - blurMargin, iconOffset - blurMargin);
}
mForeground.setBounds(mFinalDrawableBounds);
mBackground.setBounds(mFinalDrawableBounds);
mStartRevealRect.set(0, 0, originalWidth, originalHeight);
if (!isFolderIcon) {
Utilities.scaleRectAboutCenter(mStartRevealRect, IconShape.getNormalizationScale());
}
if (isVerticalBarLayout) {
lp.width = (int) Math.max(lp.width, lp.height * dp.aspectRatio);
} else {
lp.height = (int) Math.max(lp.height, lp.width * dp.aspectRatio);
}
int left = mIsRtl ? dp.widthPx - lp.getMarginStart() - lp.width : lp.leftMargin;
layout(left, lp.topMargin, left + lp.width, lp.topMargin + lp.height);
float scale = Math.max((float) lp.height / originalHeight, (float) lp.width / originalWidth);
float bgDrawableStartScale;
if (isOpening) {
bgDrawableStartScale = 1f;
mOutline.set(0, 0, originalWidth, originalHeight);
} else {
bgDrawableStartScale = scale;
mOutline.set(0, 0, lp.width, lp.height);
}
setBackgroundDrawableBounds(bgDrawableStartScale, isVerticalBarLayout);
mEndRevealRect.set(0, 0, lp.width, lp.height);
setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
outline.setRoundRect(mOutline, mTaskCornerRadius);
}
});
setClipToOutline(true);
} else {
setBackground(drawable);
setClipToOutline(false);
}
invalidate();
invalidateOutline();
}
use of com.android.launcher3.tapl.Background in project android_packages_apps_Launcher3 by ArrowOS.
the class FloatingWidgetView method getFloatingWidgetView.
/**
* Configures and returns a an instance of {@link FloatingWidgetView} matching the appearance of
* {@param originalView}.
*
* @param widgetBackgroundPosition a {@link RectF} that will be updated with the widget's
* background bounds
* @param windowSize the size of the window when launched
* @param windowCornerRadius the corner radius of the window
*/
public static FloatingWidgetView getFloatingWidgetView(Launcher launcher, LauncherAppWidgetHostView originalView, RectF widgetBackgroundPosition, Size windowSize, float windowCornerRadius, boolean appTargetsAreTranslucent, int fallbackBackgroundColor) {
final DragLayer dragLayer = launcher.getDragLayer();
ViewGroup parent = (ViewGroup) dragLayer.getParent();
FloatingWidgetView floatingView = launcher.getViewCache().getView(R.layout.floating_widget_view, launcher, parent);
floatingView.recycle();
floatingView.init(dragLayer, originalView, widgetBackgroundPosition, windowSize, windowCornerRadius, appTargetsAreTranslucent, fallbackBackgroundColor);
parent.addView(floatingView);
return floatingView;
}
use of com.android.launcher3.tapl.Background in project android_packages_apps_Launcher3 by ArrowOS.
the class AddWorkspaceItemsTask method execute.
@Override
public void execute(LauncherAppState app, BgDataModel dataModel, AllAppsList apps) {
if (mItemList.isEmpty()) {
return;
}
final ArrayList<ItemInfo> addedItemsFinal = new ArrayList<>();
final IntArray addedWorkspaceScreensFinal = new IntArray();
synchronized (dataModel) {
IntArray workspaceScreens = dataModel.collectWorkspaceScreens();
List<ItemInfo> filteredItems = new ArrayList<>();
for (Pair<ItemInfo, Object> entry : mItemList) {
ItemInfo item = entry.first;
if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION || item.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT) {
// Short-circuit this logic if the icon exists somewhere on the workspace
if (shortcutExists(dataModel, item.getIntent(), item.user)) {
continue;
}
// b/139663018 Short-circuit this logic if the icon is a system app
if (PackageManagerHelper.isSystemApp(app.getContext(), item.getIntent())) {
continue;
}
}
if (item.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION) {
if (item instanceof AppInfo) {
item = ((AppInfo) item).makeWorkspaceItem();
}
}
if (item != null) {
filteredItems.add(item);
}
}
InstallSessionHelper packageInstaller = InstallSessionHelper.INSTANCE.get(app.getContext());
LauncherApps launcherApps = app.getContext().getSystemService(LauncherApps.class);
for (ItemInfo item : filteredItems) {
// Find appropriate space for the item.
int[] coords = findSpaceForItem(app, dataModel, workspaceScreens, addedWorkspaceScreensFinal, item.spanX, item.spanY);
int screenId = coords[0];
ItemInfo itemInfo;
if (item instanceof WorkspaceItemInfo || item instanceof FolderInfo || item instanceof LauncherAppWidgetInfo) {
itemInfo = item;
} else if (item instanceof AppInfo) {
itemInfo = ((AppInfo) item).makeWorkspaceItem();
} else {
throw new RuntimeException("Unexpected info type");
}
if (item instanceof WorkspaceItemInfo && ((WorkspaceItemInfo) item).isPromise()) {
WorkspaceItemInfo workspaceInfo = (WorkspaceItemInfo) item;
String packageName = item.getTargetComponent() != null ? item.getTargetComponent().getPackageName() : null;
if (packageName == null) {
continue;
}
SessionInfo sessionInfo = packageInstaller.getActiveSessionInfo(item.user, packageName);
if (!packageInstaller.verifySessionInfo(sessionInfo)) {
FileLog.d(LOG, "Item info failed session info verification. " + "Skipping : " + workspaceInfo);
continue;
}
List<LauncherActivityInfo> activities = launcherApps.getActivityList(packageName, item.user);
boolean hasActivity = activities != null && !activities.isEmpty();
if (sessionInfo == null) {
if (!hasActivity) {
// Session was cancelled, do not add.
continue;
}
} else {
workspaceInfo.setProgressLevel((int) (sessionInfo.getProgress() * 100), PackageInstallInfo.STATUS_INSTALLING);
}
if (hasActivity) {
// App was installed while launcher was in the background,
// or app was already installed for another user.
itemInfo = new AppInfo(app.getContext(), activities.get(0), item.user).makeWorkspaceItem();
if (shortcutExists(dataModel, itemInfo.getIntent(), itemInfo.user)) {
// Icon already exists on the workspace and should not be auto-added.
continue;
}
WorkspaceItemInfo wii = (WorkspaceItemInfo) itemInfo;
wii.title = "";
wii.bitmap = app.getIconCache().getDefaultIcon(item.user);
app.getIconCache().getTitleAndIcon(wii, ((WorkspaceItemInfo) itemInfo).usingLowResIcon());
}
}
// Add the shortcut to the db
getModelWriter().addItemToDatabase(itemInfo, LauncherSettings.Favorites.CONTAINER_DESKTOP, screenId, coords[1], coords[2]);
// Save the WorkspaceItemInfo for binding in the workspace
addedItemsFinal.add(itemInfo);
// log bitmap and label
FileLog.d(LOG, "Adding item info to workspace: " + itemInfo);
}
}
if (!addedItemsFinal.isEmpty()) {
scheduleCallbackTask(new CallbackTask() {
@Override
public void execute(Callbacks callbacks) {
final ArrayList<ItemInfo> addAnimated = new ArrayList<>();
final ArrayList<ItemInfo> addNotAnimated = new ArrayList<>();
if (!addedItemsFinal.isEmpty()) {
ItemInfo info = addedItemsFinal.get(addedItemsFinal.size() - 1);
int lastScreenId = info.screenId;
for (ItemInfo i : addedItemsFinal) {
if (i.screenId == lastScreenId) {
addAnimated.add(i);
} else {
addNotAnimated.add(i);
}
}
}
callbacks.bindAppsAdded(addedWorkspaceScreensFinal, addNotAnimated, addAnimated);
}
});
}
}
Aggregations