Loading quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java +5 −4 Original line number Original line Diff line number Diff line Loading @@ -29,11 +29,11 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ObjectAnimator; import android.content.ComponentName; import android.content.Context; import android.content.Context; import android.graphics.Rect; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.RectF; import android.graphics.Region; import android.graphics.Region; import android.os.UserHandle; import android.view.MotionEvent; import android.view.MotionEvent; import android.view.View; import android.view.View; import android.view.animation.Interpolator; import android.view.animation.Interpolator; Loading Loading @@ -102,9 +102,10 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe final RecentsView recentsView = activity.getOverviewPanel(); final RecentsView recentsView = activity.getOverviewPanel(); final TaskView runningTaskView = recentsView.getRunningTaskView(); final TaskView runningTaskView = recentsView.getRunningTaskView(); final View workspaceView; final View workspaceView; if (runningTaskView != null) { if (runningTaskView != null && runningTaskView.getTask().key.getComponent() != null) { ComponentName component = runningTaskView.getTask().key.sourceComponent; workspaceView = activity.getWorkspace().getFirstMatchForAppClose( workspaceView = activity.getWorkspace().getFirstMatchForAppClose(component); runningTaskView.getTask().key.getComponent().getPackageName(), UserHandle.of(runningTaskView.getTask().key.userId)); } else { } else { workspaceView = null; workspaceView = null; } } Loading src/com/android/launcher3/Workspace.java +54 −74 Original line number Original line Diff line number Diff line Loading @@ -19,9 +19,13 @@ package com.android.launcher3; import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS; import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS; import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY; import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY; import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_TRANSITION_MS; import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_TRANSITION_MS; import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT; import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.SPRING_LOADED; import static com.android.launcher3.LauncherState.SPRING_LOADED; import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM; import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_OVERLAY; import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_OVERLAY; import android.animation.Animator; import android.animation.Animator; Loading @@ -34,7 +38,6 @@ import android.annotation.SuppressLint; import android.app.WallpaperManager; import android.app.WallpaperManager; import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetProviderInfo; import android.appwidget.AppWidgetProviderInfo; import android.content.ComponentName; import android.content.Context; import android.content.Context; import android.content.res.Resources; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Bitmap; Loading @@ -47,6 +50,7 @@ import android.os.IBinder; import android.os.Message; import android.os.Message; import android.os.Parcelable; import android.os.Parcelable; import android.os.UserHandle; import android.os.UserHandle; import android.text.TextUtils; import android.util.AttributeSet; import android.util.AttributeSet; import android.util.Log; import android.util.Log; import android.util.SparseArray; import android.util.SparseArray; Loading Loading @@ -99,8 +103,6 @@ import com.android.launcher3.widget.PendingAppWidgetHostView; import java.util.ArrayList; import java.util.ArrayList; import java.util.HashSet; import java.util.HashSet; import java.util.Objects; import java.util.Set; import java.util.function.Predicate; import java.util.function.Predicate; /** /** Loading Loading @@ -1612,7 +1614,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator> boolean aboveShortcut = (dropOverView.getTag() instanceof ShortcutInfo); boolean aboveShortcut = (dropOverView.getTag() instanceof ShortcutInfo); boolean willBecomeShortcut = boolean willBecomeShortcut = (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION || (info.itemType == ITEM_TYPE_APPLICATION || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT); info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT); Loading Loading @@ -2520,7 +2522,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator> View view; View view; switch (info.itemType) { switch (info.itemType) { case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: case ITEM_TYPE_APPLICATION: case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT: case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT: if (info.container == NO_ID && info instanceof AppInfo) { if (info.container == NO_ID && info instanceof AppInfo) { Loading Loading @@ -2895,52 +2897,30 @@ public class Workspace extends PagedView<WorkspacePageIndicator> return layouts; return layouts; } } /** * Returns a list of all the CellLayouts on the Homescreen, starting with * {@param startPage}, then going outward alternating between pages prior to the startPage, * and then the pages after the startPage. * ie. if there are 5 pages [0, 1, 2, 3, 4] and startPage is 1, we return [1, 0, 2, 3, 4]. */ private CellLayout[] getWorkspaceCellLayouts(int startPage) { int screenCount = getChildCount(); final CellLayout[] layouts = new CellLayout[screenCount]; int screen = 0; layouts[screen] = (CellLayout) getChildAt(startPage); screen++; for (int i = 1; screen < screenCount; ++i) { CellLayout prevPage = (CellLayout) getChildAt(startPage - i); CellLayout nextPage = (CellLayout) getChildAt(startPage + i); if (prevPage != null) { layouts[screen] = prevPage; screen++; } if (nextPage != null) { layouts[screen] = nextPage; screen++; } } return layouts; } /** /** * Similar to {@link #getFirstMatch} but optimized to finding a suitable view for the app close * Similar to {@link #getFirstMatch} but optimized to finding a suitable view for the app close * animation. * animation. * * * @param component The component of the task being dismissed. * @param packageName The package name of the app to match. * @param user The user of the app to match. */ */ public View getFirstMatchForAppClose(ComponentName component) { public View getFirstMatchForAppClose(String packageName, UserHandle user) { final int curPage = getCurrentPage(); final int curPage = getCurrentPage(); final CellLayout currentPage = (CellLayout) getPageAt(curPage); final CellLayout currentPage = (CellLayout) getPageAt(curPage); final Workspace.ItemOperator isItemComponent = (info, view) -> final Workspace.ItemOperator packageAndUser = (ItemInfo info, View view) -> info != null info != null && Objects.equals(info.getTargetComponent(), component); && info.getTargetComponent() != null final Workspace.ItemOperator isItemInFolder = (info, view) -> { && TextUtils.equals(info.getTargetComponent().getPackageName(), packageName) && info.user.equals(user); final Workspace.ItemOperator packageAndUserAndApp = (ItemInfo info, View view) -> packageAndUser.evaluate(info, view) && info.itemType == ITEM_TYPE_APPLICATION; final Workspace.ItemOperator packageAndUserAndShortcut = (ItemInfo info, View view) -> packageAndUser.evaluate(info, view) && (info.itemType == ITEM_TYPE_SHORTCUT || info.itemType == ITEM_TYPE_DEEP_SHORTCUT); final Workspace.ItemOperator packageAndUserInFolder = (info, view) -> { if (info instanceof FolderInfo) { if (info instanceof FolderInfo) { FolderInfo folderInfo = (FolderInfo) info; FolderInfo folderInfo = (FolderInfo) info; for (ShortcutInfo shortcutInfo : folderInfo.contents) { for (ShortcutInfo shortcutInfo : folderInfo.contents) { if (Objects.equals(shortcutInfo.getTargetComponent(), component)) { if (packageAndUser.evaluate(shortcutInfo, view)) { return true; return true; } } } } Loading @@ -2948,33 +2928,16 @@ public class Workspace extends PagedView<WorkspacePageIndicator> return false; return false; }; }; CellLayout[] hotseatAndCurrentPage = new CellLayout[] { getHotseat(), currentPage }; // Order: App icons, shortcuts, app/shortcut in folder. Items in hotseat get returned first. // First we look if the app itself is in the hotseat or on the current workspace page. if (ADAPTIVE_ICON_WINDOW_ANIM.get()) { View icon = getFirstMatch(hotseatAndCurrentPage, isItemComponent); return getFirstMatch(new CellLayout[] { getHotseat(), currentPage }, if (icon != null) { packageAndUserAndApp, packageAndUserAndShortcut, packageAndUserInFolder); return icon; } else { } // Do not use Folder as a criteria, since it'll cause a crash when trying to draw // Then we look if the app is in a folder on the hotseat or current workspace page. // FolderAdaptiveIcon as the background. icon = getFirstMatch(hotseatAndCurrentPage, isItemInFolder); return getFirstMatch(new CellLayout[] { getHotseat(), currentPage }, if (icon != null) { packageAndUserAndApp, packageAndUserAndShortcut); return icon; } // Continue searching for the app or for a folder with the app on other pages of the // workspace. We skip the current page, since we already searched above. CellLayout[] allPages = getWorkspaceCellLayouts(curPage); CellLayout[] page = new CellLayout[1]; for (int i = 1; i < allPages.length; ++i) { page[0] = allPages[i]; icon = getFirstMatch(page, isItemComponent); if (icon != null) { return icon; } icon = getFirstMatch(page, isItemInFolder); if (icon != null) { return icon; } } } return null; } } public View getHomescreenIconByItemId(final int id) { public View getHomescreenIconByItemId(final int id) { Loading Loading @@ -3002,21 +2965,38 @@ public class Workspace extends PagedView<WorkspacePageIndicator> return value[0]; return value[0]; } } private View getFirstMatch(CellLayout[] cellLayouts, final ItemOperator operator) { /** final View[] value = new View[1]; * @param cellLayouts List of CellLayouts to scan, in order of preference. * @param operators List of operators, in order starting from best matching operator. * @return */ private View getFirstMatch(CellLayout[] cellLayouts, final ItemOperator... operators) { // This array is filled with the first match for each operator. final View[] matches = new View[operators.length]; // For efficiency, the outer loop should be CellLayout. for (CellLayout cellLayout : cellLayouts) { for (CellLayout cellLayout : cellLayouts) { mapOverCellLayout(MAP_NO_RECURSE, cellLayout, (info, v) -> { mapOverCellLayout(MAP_NO_RECURSE, cellLayout, (info, v) -> { if (operator.evaluate(info, v)) { for (int i = 0; i < operators.length; ++i) { value[0] = v; if (matches[i] == null && operators[i].evaluate(info, v)) { matches[i] = v; if (i == 0) { // We can return since this is the best match possible. return true; return true; } } } } return false; return false; }); }); if (value[0] != null) { if (matches[0] != null) { break; break; } } } } return value[0]; for (View match : matches) { if (match != null) { return match; } } return null; } } void clearDropTargets() { void clearDropTargets() { Loading src/com/android/launcher3/config/BaseFlags.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -102,7 +102,7 @@ abstract class BaseFlags { false, "Enable springs for quickstep animations"); false, "Enable springs for quickstep animations"); public static final TogglableFlag ADAPTIVE_ICON_WINDOW_ANIM = new TogglableFlag( public static final TogglableFlag ADAPTIVE_ICON_WINDOW_ANIM = new TogglableFlag( "ADAPTIVE_ICON_WINDOW_ANIM", false, "ADAPTIVE_ICON_WINDOW_ANIM", true, "Use adaptive icons for window animations."); "Use adaptive icons for window animations."); public static final TogglableFlag ENABLE_QUICKSTEP_LIVE_TILE = new TogglableFlag( public static final TogglableFlag ENABLE_QUICKSTEP_LIVE_TILE = new TogglableFlag( Loading src/com/android/launcher3/views/FloatingIconView.java +19 −7 Original line number Original line Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.view.ViewOutlineProvider; import com.android.launcher3.BubbleTextView; import com.android.launcher3.InsettableFrameLayout.LayoutParams; import com.android.launcher3.InsettableFrameLayout.LayoutParams; import com.android.launcher3.ItemInfo; import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; import com.android.launcher3.Launcher; Loading Loading @@ -81,7 +82,7 @@ public class FloatingIconView extends View implements Animator.AnimatorListener, private final Rect mFinalDrawableBounds = new Rect(); private final Rect mFinalDrawableBounds = new Rect(); private final Rect mBgDrawableBounds = new Rect(); private final Rect mBgDrawableBounds = new Rect(); private final float mBgDrawableStartScale = 5f; // Magic number that can be tuned later. private float mBgDrawableStartScale = 1f; private FloatingIconView(Context context) { private FloatingIconView(Context context) { super(context); super(context); Loading Loading @@ -188,12 +189,19 @@ public class FloatingIconView extends View implements Animator.AnimatorListener, private void getIcon(Launcher launcher, View v, ItemInfo info, boolean useDrawableAsIs, private void getIcon(Launcher launcher, View v, ItemInfo info, boolean useDrawableAsIs, float aspectRatio) { float aspectRatio) { final LayoutParams lp = (LayoutParams) getLayoutParams(); final LayoutParams lp = (LayoutParams) getLayoutParams(); mDrawable = Utilities.getFullDrawable(launcher, info, lp.width, lp.height, useDrawableAsIs, new Object[1]); if (ADAPTIVE_ICON_WINDOW_ANIM.get() && !useDrawableAsIs boolean supportsAdaptiveIcons = ADAPTIVE_ICON_WINDOW_ANIM.get() && !useDrawableAsIs && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O; && mDrawable instanceof AdaptiveIconDrawable) { if (!supportsAdaptiveIcons && v instanceof BubbleTextView) { // Similar to DragView, we simply use the BubbleTextView icon here. mDrawable = ((BubbleTextView) v).getIcon(); } if (mDrawable == null) { mDrawable = Utilities.getFullDrawable(launcher, info, lp.width, lp.height, useDrawableAsIs, new Object[1]); } if (supportsAdaptiveIcons && mDrawable instanceof AdaptiveIconDrawable) { mIsAdaptiveIcon = true; mIsAdaptiveIcon = true; AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) mDrawable; AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) mDrawable; Loading Loading @@ -227,8 +235,9 @@ public class FloatingIconView extends View implements Animator.AnimatorListener, lp.height = (int) Math.max(lp.height, lp.width * aspectRatio); lp.height = (int) Math.max(lp.height, lp.width * aspectRatio); layout(lp.leftMargin, lp.topMargin, lp.leftMargin + lp.width, lp.topMargin layout(lp.leftMargin, lp.topMargin, lp.leftMargin + lp.width, lp.topMargin + lp.height); + lp.height); setBackgroundDrawableBounds(mBgDrawableStartScale); } } mBgDrawableStartScale = (float) lp.height / mOriginalHeight; setBackgroundDrawableBounds(mBgDrawableStartScale); // Set up outline // Set up outline mOutline.set(0, 0, lp.width, lp.height); mOutline.set(0, 0, lp.width, lp.height); Loading @@ -252,6 +261,9 @@ public class FloatingIconView extends View implements Animator.AnimatorListener, private void setBackgroundDrawableBounds(float scale) { private void setBackgroundDrawableBounds(float scale) { mBgDrawableBounds.set(mFinalDrawableBounds); mBgDrawableBounds.set(mFinalDrawableBounds); Utilities.scaleRectAboutCenter(mBgDrawableBounds, scale); Utilities.scaleRectAboutCenter(mBgDrawableBounds, scale); // Since the drawable is at the top of the view, we need to offset to keep it centered. mBgDrawableBounds.offsetTo(mBgDrawableBounds.left, (int) (mFinalDrawableBounds.top * scale)); mBackground.setBounds(mBgDrawableBounds); mBackground.setBounds(mBgDrawableBounds); } } Loading Loading
quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityControllerHelper.java +5 −4 Original line number Original line Diff line number Diff line Loading @@ -29,11 +29,11 @@ import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorSet; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ObjectAnimator; import android.content.ComponentName; import android.content.Context; import android.content.Context; import android.graphics.Rect; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.RectF; import android.graphics.Region; import android.graphics.Region; import android.os.UserHandle; import android.view.MotionEvent; import android.view.MotionEvent; import android.view.View; import android.view.View; import android.view.animation.Interpolator; import android.view.animation.Interpolator; Loading Loading @@ -102,9 +102,10 @@ public final class LauncherActivityControllerHelper implements ActivityControlHe final RecentsView recentsView = activity.getOverviewPanel(); final RecentsView recentsView = activity.getOverviewPanel(); final TaskView runningTaskView = recentsView.getRunningTaskView(); final TaskView runningTaskView = recentsView.getRunningTaskView(); final View workspaceView; final View workspaceView; if (runningTaskView != null) { if (runningTaskView != null && runningTaskView.getTask().key.getComponent() != null) { ComponentName component = runningTaskView.getTask().key.sourceComponent; workspaceView = activity.getWorkspace().getFirstMatchForAppClose( workspaceView = activity.getWorkspace().getFirstMatchForAppClose(component); runningTaskView.getTask().key.getComponent().getPackageName(), UserHandle.of(runningTaskView.getTask().key.userId)); } else { } else { workspaceView = null; workspaceView = null; } } Loading
src/com/android/launcher3/Workspace.java +54 −74 Original line number Original line Diff line number Diff line Loading @@ -19,9 +19,13 @@ package com.android.launcher3; import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS; import static com.android.launcher3.LauncherAnimUtils.OVERVIEW_TRANSITION_MS; import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY; import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY; import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_TRANSITION_MS; import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_TRANSITION_MS; import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT; import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT; import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.SPRING_LOADED; import static com.android.launcher3.LauncherState.SPRING_LOADED; import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM; import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_OVERLAY; import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_OVERLAY; import android.animation.Animator; import android.animation.Animator; Loading @@ -34,7 +38,6 @@ import android.annotation.SuppressLint; import android.app.WallpaperManager; import android.app.WallpaperManager; import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetProviderInfo; import android.appwidget.AppWidgetProviderInfo; import android.content.ComponentName; import android.content.Context; import android.content.Context; import android.content.res.Resources; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Bitmap; Loading @@ -47,6 +50,7 @@ import android.os.IBinder; import android.os.Message; import android.os.Message; import android.os.Parcelable; import android.os.Parcelable; import android.os.UserHandle; import android.os.UserHandle; import android.text.TextUtils; import android.util.AttributeSet; import android.util.AttributeSet; import android.util.Log; import android.util.Log; import android.util.SparseArray; import android.util.SparseArray; Loading Loading @@ -99,8 +103,6 @@ import com.android.launcher3.widget.PendingAppWidgetHostView; import java.util.ArrayList; import java.util.ArrayList; import java.util.HashSet; import java.util.HashSet; import java.util.Objects; import java.util.Set; import java.util.function.Predicate; import java.util.function.Predicate; /** /** Loading Loading @@ -1612,7 +1614,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator> boolean aboveShortcut = (dropOverView.getTag() instanceof ShortcutInfo); boolean aboveShortcut = (dropOverView.getTag() instanceof ShortcutInfo); boolean willBecomeShortcut = boolean willBecomeShortcut = (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_APPLICATION || (info.itemType == ITEM_TYPE_APPLICATION || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT || info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT); info.itemType == LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT); Loading Loading @@ -2520,7 +2522,7 @@ public class Workspace extends PagedView<WorkspacePageIndicator> View view; View view; switch (info.itemType) { switch (info.itemType) { case LauncherSettings.Favorites.ITEM_TYPE_APPLICATION: case ITEM_TYPE_APPLICATION: case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: case LauncherSettings.Favorites.ITEM_TYPE_SHORTCUT: case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT: case LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT: if (info.container == NO_ID && info instanceof AppInfo) { if (info.container == NO_ID && info instanceof AppInfo) { Loading Loading @@ -2895,52 +2897,30 @@ public class Workspace extends PagedView<WorkspacePageIndicator> return layouts; return layouts; } } /** * Returns a list of all the CellLayouts on the Homescreen, starting with * {@param startPage}, then going outward alternating between pages prior to the startPage, * and then the pages after the startPage. * ie. if there are 5 pages [0, 1, 2, 3, 4] and startPage is 1, we return [1, 0, 2, 3, 4]. */ private CellLayout[] getWorkspaceCellLayouts(int startPage) { int screenCount = getChildCount(); final CellLayout[] layouts = new CellLayout[screenCount]; int screen = 0; layouts[screen] = (CellLayout) getChildAt(startPage); screen++; for (int i = 1; screen < screenCount; ++i) { CellLayout prevPage = (CellLayout) getChildAt(startPage - i); CellLayout nextPage = (CellLayout) getChildAt(startPage + i); if (prevPage != null) { layouts[screen] = prevPage; screen++; } if (nextPage != null) { layouts[screen] = nextPage; screen++; } } return layouts; } /** /** * Similar to {@link #getFirstMatch} but optimized to finding a suitable view for the app close * Similar to {@link #getFirstMatch} but optimized to finding a suitable view for the app close * animation. * animation. * * * @param component The component of the task being dismissed. * @param packageName The package name of the app to match. * @param user The user of the app to match. */ */ public View getFirstMatchForAppClose(ComponentName component) { public View getFirstMatchForAppClose(String packageName, UserHandle user) { final int curPage = getCurrentPage(); final int curPage = getCurrentPage(); final CellLayout currentPage = (CellLayout) getPageAt(curPage); final CellLayout currentPage = (CellLayout) getPageAt(curPage); final Workspace.ItemOperator isItemComponent = (info, view) -> final Workspace.ItemOperator packageAndUser = (ItemInfo info, View view) -> info != null info != null && Objects.equals(info.getTargetComponent(), component); && info.getTargetComponent() != null final Workspace.ItemOperator isItemInFolder = (info, view) -> { && TextUtils.equals(info.getTargetComponent().getPackageName(), packageName) && info.user.equals(user); final Workspace.ItemOperator packageAndUserAndApp = (ItemInfo info, View view) -> packageAndUser.evaluate(info, view) && info.itemType == ITEM_TYPE_APPLICATION; final Workspace.ItemOperator packageAndUserAndShortcut = (ItemInfo info, View view) -> packageAndUser.evaluate(info, view) && (info.itemType == ITEM_TYPE_SHORTCUT || info.itemType == ITEM_TYPE_DEEP_SHORTCUT); final Workspace.ItemOperator packageAndUserInFolder = (info, view) -> { if (info instanceof FolderInfo) { if (info instanceof FolderInfo) { FolderInfo folderInfo = (FolderInfo) info; FolderInfo folderInfo = (FolderInfo) info; for (ShortcutInfo shortcutInfo : folderInfo.contents) { for (ShortcutInfo shortcutInfo : folderInfo.contents) { if (Objects.equals(shortcutInfo.getTargetComponent(), component)) { if (packageAndUser.evaluate(shortcutInfo, view)) { return true; return true; } } } } Loading @@ -2948,33 +2928,16 @@ public class Workspace extends PagedView<WorkspacePageIndicator> return false; return false; }; }; CellLayout[] hotseatAndCurrentPage = new CellLayout[] { getHotseat(), currentPage }; // Order: App icons, shortcuts, app/shortcut in folder. Items in hotseat get returned first. // First we look if the app itself is in the hotseat or on the current workspace page. if (ADAPTIVE_ICON_WINDOW_ANIM.get()) { View icon = getFirstMatch(hotseatAndCurrentPage, isItemComponent); return getFirstMatch(new CellLayout[] { getHotseat(), currentPage }, if (icon != null) { packageAndUserAndApp, packageAndUserAndShortcut, packageAndUserInFolder); return icon; } else { } // Do not use Folder as a criteria, since it'll cause a crash when trying to draw // Then we look if the app is in a folder on the hotseat or current workspace page. // FolderAdaptiveIcon as the background. icon = getFirstMatch(hotseatAndCurrentPage, isItemInFolder); return getFirstMatch(new CellLayout[] { getHotseat(), currentPage }, if (icon != null) { packageAndUserAndApp, packageAndUserAndShortcut); return icon; } // Continue searching for the app or for a folder with the app on other pages of the // workspace. We skip the current page, since we already searched above. CellLayout[] allPages = getWorkspaceCellLayouts(curPage); CellLayout[] page = new CellLayout[1]; for (int i = 1; i < allPages.length; ++i) { page[0] = allPages[i]; icon = getFirstMatch(page, isItemComponent); if (icon != null) { return icon; } icon = getFirstMatch(page, isItemInFolder); if (icon != null) { return icon; } } } return null; } } public View getHomescreenIconByItemId(final int id) { public View getHomescreenIconByItemId(final int id) { Loading Loading @@ -3002,21 +2965,38 @@ public class Workspace extends PagedView<WorkspacePageIndicator> return value[0]; return value[0]; } } private View getFirstMatch(CellLayout[] cellLayouts, final ItemOperator operator) { /** final View[] value = new View[1]; * @param cellLayouts List of CellLayouts to scan, in order of preference. * @param operators List of operators, in order starting from best matching operator. * @return */ private View getFirstMatch(CellLayout[] cellLayouts, final ItemOperator... operators) { // This array is filled with the first match for each operator. final View[] matches = new View[operators.length]; // For efficiency, the outer loop should be CellLayout. for (CellLayout cellLayout : cellLayouts) { for (CellLayout cellLayout : cellLayouts) { mapOverCellLayout(MAP_NO_RECURSE, cellLayout, (info, v) -> { mapOverCellLayout(MAP_NO_RECURSE, cellLayout, (info, v) -> { if (operator.evaluate(info, v)) { for (int i = 0; i < operators.length; ++i) { value[0] = v; if (matches[i] == null && operators[i].evaluate(info, v)) { matches[i] = v; if (i == 0) { // We can return since this is the best match possible. return true; return true; } } } } return false; return false; }); }); if (value[0] != null) { if (matches[0] != null) { break; break; } } } } return value[0]; for (View match : matches) { if (match != null) { return match; } } return null; } } void clearDropTargets() { void clearDropTargets() { Loading
src/com/android/launcher3/config/BaseFlags.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -102,7 +102,7 @@ abstract class BaseFlags { false, "Enable springs for quickstep animations"); false, "Enable springs for quickstep animations"); public static final TogglableFlag ADAPTIVE_ICON_WINDOW_ANIM = new TogglableFlag( public static final TogglableFlag ADAPTIVE_ICON_WINDOW_ANIM = new TogglableFlag( "ADAPTIVE_ICON_WINDOW_ANIM", false, "ADAPTIVE_ICON_WINDOW_ANIM", true, "Use adaptive icons for window animations."); "Use adaptive icons for window animations."); public static final TogglableFlag ENABLE_QUICKSTEP_LIVE_TILE = new TogglableFlag( public static final TogglableFlag ENABLE_QUICKSTEP_LIVE_TILE = new TogglableFlag( Loading
src/com/android/launcher3/views/FloatingIconView.java +19 −7 Original line number Original line Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.ViewGroup; import android.view.ViewOutlineProvider; import android.view.ViewOutlineProvider; import com.android.launcher3.BubbleTextView; import com.android.launcher3.InsettableFrameLayout.LayoutParams; import com.android.launcher3.InsettableFrameLayout.LayoutParams; import com.android.launcher3.ItemInfo; import com.android.launcher3.ItemInfo; import com.android.launcher3.Launcher; import com.android.launcher3.Launcher; Loading Loading @@ -81,7 +82,7 @@ public class FloatingIconView extends View implements Animator.AnimatorListener, private final Rect mFinalDrawableBounds = new Rect(); private final Rect mFinalDrawableBounds = new Rect(); private final Rect mBgDrawableBounds = new Rect(); private final Rect mBgDrawableBounds = new Rect(); private final float mBgDrawableStartScale = 5f; // Magic number that can be tuned later. private float mBgDrawableStartScale = 1f; private FloatingIconView(Context context) { private FloatingIconView(Context context) { super(context); super(context); Loading Loading @@ -188,12 +189,19 @@ public class FloatingIconView extends View implements Animator.AnimatorListener, private void getIcon(Launcher launcher, View v, ItemInfo info, boolean useDrawableAsIs, private void getIcon(Launcher launcher, View v, ItemInfo info, boolean useDrawableAsIs, float aspectRatio) { float aspectRatio) { final LayoutParams lp = (LayoutParams) getLayoutParams(); final LayoutParams lp = (LayoutParams) getLayoutParams(); mDrawable = Utilities.getFullDrawable(launcher, info, lp.width, lp.height, useDrawableAsIs, new Object[1]); if (ADAPTIVE_ICON_WINDOW_ANIM.get() && !useDrawableAsIs boolean supportsAdaptiveIcons = ADAPTIVE_ICON_WINDOW_ANIM.get() && !useDrawableAsIs && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O; && mDrawable instanceof AdaptiveIconDrawable) { if (!supportsAdaptiveIcons && v instanceof BubbleTextView) { // Similar to DragView, we simply use the BubbleTextView icon here. mDrawable = ((BubbleTextView) v).getIcon(); } if (mDrawable == null) { mDrawable = Utilities.getFullDrawable(launcher, info, lp.width, lp.height, useDrawableAsIs, new Object[1]); } if (supportsAdaptiveIcons && mDrawable instanceof AdaptiveIconDrawable) { mIsAdaptiveIcon = true; mIsAdaptiveIcon = true; AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) mDrawable; AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) mDrawable; Loading Loading @@ -227,8 +235,9 @@ public class FloatingIconView extends View implements Animator.AnimatorListener, lp.height = (int) Math.max(lp.height, lp.width * aspectRatio); lp.height = (int) Math.max(lp.height, lp.width * aspectRatio); layout(lp.leftMargin, lp.topMargin, lp.leftMargin + lp.width, lp.topMargin layout(lp.leftMargin, lp.topMargin, lp.leftMargin + lp.width, lp.topMargin + lp.height); + lp.height); setBackgroundDrawableBounds(mBgDrawableStartScale); } } mBgDrawableStartScale = (float) lp.height / mOriginalHeight; setBackgroundDrawableBounds(mBgDrawableStartScale); // Set up outline // Set up outline mOutline.set(0, 0, lp.width, lp.height); mOutline.set(0, 0, lp.width, lp.height); Loading @@ -252,6 +261,9 @@ public class FloatingIconView extends View implements Animator.AnimatorListener, private void setBackgroundDrawableBounds(float scale) { private void setBackgroundDrawableBounds(float scale) { mBgDrawableBounds.set(mFinalDrawableBounds); mBgDrawableBounds.set(mFinalDrawableBounds); Utilities.scaleRectAboutCenter(mBgDrawableBounds, scale); Utilities.scaleRectAboutCenter(mBgDrawableBounds, scale); // Since the drawable is at the top of the view, we need to offset to keep it centered. mBgDrawableBounds.offsetTo(mBgDrawableBounds.left, (int) (mFinalDrawableBounds.top * scale)); mBackground.setBounds(mBgDrawableBounds); mBackground.setBounds(mBgDrawableBounds); } } Loading