From 4d7b244f3fad4ba09494bebe40bc5608dd1eb81f Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Mon, 9 Dec 2019 13:42:57 -0800 Subject: [PATCH] Render user's actual workspace in ThemePicker preview (Part 2) With this change, we can also render folders in preview. It's built on top of part 1. Test: Go to grid options, choose a different grid option, and see user's workspace rendered in the preview Bug: 144052839 Change-Id: Iaf6d8af6b909ece4147ea250d95dec3d2c0019d3 --- .../uioverrides/PredictedAppIcon.java | 4 +- src/com/android/launcher3/Launcher.java | 10 +++- src/com/android/launcher3/Workspace.java | 3 +- .../android/launcher3/folder/FolderIcon.java | 59 +++++++++++-------- .../launcher3/folder/PreviewItemManager.java | 9 +-- .../graphics/LauncherPreviewRenderer.java | 10 +++- 6 files changed, 60 insertions(+), 35 deletions(-) diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/PredictedAppIcon.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/PredictedAppIcon.java index 27ac284037..bd8962652c 100644 --- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/PredictedAppIcon.java +++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/PredictedAppIcon.java @@ -47,7 +47,7 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView { private static final float RING_EFFECT_RATIO = 0.11f; - private DeviceProfile mDeviceProfile; + private final DeviceProfile mDeviceProfile; private final Paint mIconRingPaint = new Paint(Paint.ANTI_ALIAS_FLAG); private boolean mIsPinned = false; private int mNormalizedIconRadius; @@ -65,7 +65,7 @@ public class PredictedAppIcon extends DoubleShadowBubbleTextView { mDeviceProfile = Launcher.getLauncher(context).getDeviceProfile(); mNormalizedIconRadius = IconNormalizer.getNormalizedCircleSize(getIconSize()) / 2; setOnClickListener(ItemClickHandler.INSTANCE); - setOnFocusChangeListener(Launcher.getLauncher(context).mFocusHandler); + setOnFocusChangeListener(Launcher.getLauncher(context).getFocusHandler()); } @Override diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index d8c4c5cc16..a7bb9ee259 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -307,7 +307,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, // Request id for any pending activity result protected int mPendingActivityRequestCode = -1; - public ViewGroupFocusHelper mFocusHandler; + private ViewGroupFocusHelper mFocusHandler; private RotationHelper mRotationHelper; @@ -617,6 +617,10 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, return mRotationHelper; } + public ViewGroupFocusHelper getFocusHandler() { + return mFocusHandler; + } + public LauncherStateManager getStateManager() { return mStateManager; } @@ -1740,7 +1744,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, getModelWriter().addItemToDatabase(folderInfo, container, screenId, cellX, cellY); // Create the view - FolderIcon newFolder = FolderIcon.fromXml(R.layout.folder_icon, this, layout, folderInfo); + FolderIcon newFolder = FolderIcon.inflateFolderAndIcon(R.layout.folder_icon, this, layout, folderInfo); mWorkspace.addInScreen(newFolder, folderInfo); // Force measure the new folder icon CellLayout parent = mWorkspace.getParentCellLayoutForView(newFolder); @@ -2101,7 +2105,7 @@ public class Launcher extends BaseDraggingActivity implements LauncherExterns, break; } case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: { - view = FolderIcon.fromXml(R.layout.folder_icon, this, + view = FolderIcon.inflateFolderAndIcon(R.layout.folder_icon, this, (ViewGroup) workspace.getChildAt(workspace.getCurrentPage()), (FolderInfo) item); break; diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index f96e73552a..9a3a379697 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -83,7 +83,6 @@ import com.android.launcher3.logging.UserEventDispatcher; import com.android.launcher3.pageindicators.WorkspacePageIndicator; import com.android.launcher3.popup.PopupContainerWithArrow; import com.android.launcher3.shortcuts.ShortcutDragPreviewProvider; -import com.android.launcher3.testing.TestProtocol; import com.android.launcher3.touch.WorkspaceTouchListener; import com.android.launcher3.userevent.nano.LauncherLogProto.Action; import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType; @@ -2547,7 +2546,7 @@ public class Workspace extends PagedView view = mLauncher.createShortcut(cellLayout, (WorkspaceItemInfo) info); break; case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: - view = FolderIcon.fromXml(R.layout.folder_icon, mLauncher, cellLayout, + view = FolderIcon.inflateFolderAndIcon(R.layout.folder_icon, mLauncher, cellLayout, (FolderInfo) info); break; default: diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java index f322061d59..8c56823a4a 100644 --- a/src/com/android/launcher3/folder/FolderIcon.java +++ b/src/com/android/launcher3/folder/FolderIcon.java @@ -67,6 +67,7 @@ import com.android.launcher3.icons.DotRenderer; import com.android.launcher3.touch.ItemClickHandler; import com.android.launcher3.util.Executors; import com.android.launcher3.util.Thunk; +import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.IconLabelDotView; import com.android.launcher3.widget.PendingAddShortcutInfo; @@ -79,7 +80,7 @@ import java.util.function.Predicate; */ public class FolderIcon extends FrameLayout implements FolderListener, IconLabelDotView { - @Thunk Launcher mLauncher; + @Thunk ActivityContext mActivity; @Thunk Folder mFolder; private FolderInfo mInfo; @@ -153,7 +154,21 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel mDotParams = new DotRenderer.DrawParams(); } - public static FolderIcon fromXml(int resId, Launcher launcher, ViewGroup group, + public static FolderIcon inflateFolderAndIcon(int resId, Launcher launcher, ViewGroup group, + FolderInfo folderInfo) { + Folder folder = Folder.fromXml(launcher); + folder.setDragController(launcher.getDragController()); + + FolderIcon icon = inflateIcon(resId, launcher, group, folderInfo); + folder.setFolderIcon(icon); + folder.bind(folderInfo); + icon.setFolder(folder); + + icon.setOnFocusChangeListener(launcher.getFocusHandler()); + return icon; + } + + public static FolderIcon inflateIcon(int resId, ActivityContext activity, ViewGroup group, FolderInfo folderInfo) { @SuppressWarnings("all") // suppress dead code warning final boolean error = INITIAL_ITEM_ANIMATION_DURATION >= DROP_IN_ANIMATION_DURATION; @@ -163,7 +178,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel "is dependent on this"); } - DeviceProfile grid = launcher.getWallpaperDeviceProfile(); + DeviceProfile grid = activity.getWallpaperDeviceProfile(); FolderIcon icon = (FolderIcon) LayoutInflater.from(group.getContext()) .inflate(resId, group, false); @@ -177,27 +192,27 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel icon.setTag(folderInfo); icon.setOnClickListener(ItemClickHandler.INSTANCE); icon.mInfo = folderInfo; - icon.mLauncher = launcher; + icon.mActivity = activity; icon.mDotRenderer = grid.mDotRendererWorkSpace; - icon.setContentDescription(launcher.getString(R.string.folder_name_format, folderInfo.title)); + + icon.setContentDescription( + group.getContext().getString(R.string.folder_name_format, folderInfo.title)); // Keep the notification dot up to date with the sum of all the content's dots. FolderDotInfo folderDotInfo = new FolderDotInfo(); for (WorkspaceItemInfo si : folderInfo.contents) { - folderDotInfo.addDotInfo(launcher.getDotInfoForItem(si)); + folderDotInfo.addDotInfo(activity.getDotInfoForItem(si)); } icon.setDotInfo(folderDotInfo); - Folder folder = Folder.fromXml(launcher); - folder.setDragController(launcher.getDragController()); - folder.setFolderIcon(icon); - folder.bind(folderInfo); - icon.setFolder(folder); - icon.setAccessibilityDelegate(launcher.getAccessibilityDelegate()); + icon.setAccessibilityDelegate(activity.getAccessibilityDelegate()); + + icon.mPreviewVerifier = new FolderGridOrganizer(activity.getDeviceProfile().inv); + icon.mPreviewVerifier.setFolderInfo(folderInfo); + icon.updatePreviewItems(false); folderInfo.addListener(icon); - icon.setOnFocusChangeListener(launcher.mFocusHandler); return icon; } @@ -225,9 +240,6 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel private void setFolder(Folder folder) { mFolder = folder; - mPreviewVerifier = new FolderGridOrganizer(mLauncher.getDeviceProfile().inv); - mPreviewVerifier.setFolderInfo(mFolder.getInfo()); - updatePreviewItems(false); } private boolean willAcceptItem(ItemInfo item) { @@ -309,14 +321,15 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel // Typically, the animateView corresponds to the DragView; however, if this is being done // after a configuration activity (ie. for a Shortcut being dragged from AllApps) we // will not have a view to animate - if (animateView != null) { - DragLayer dragLayer = mLauncher.getDragLayer(); + if (animateView != null && mActivity instanceof Launcher) { + final Launcher launcher = (Launcher) mActivity; + DragLayer dragLayer = launcher.getDragLayer(); Rect from = new Rect(); dragLayer.getViewRectRelativeToSelf(animateView, from); Rect to = finalRect; if (to == null) { to = new Rect(); - Workspace workspace = mLauncher.getWorkspace(); + Workspace workspace = launcher.getWorkspace(); // Set cellLayout and this to it's final state to compute final animation locations workspace.setFinalTransitionTransform(); float scaleX = getScaleX(); @@ -382,7 +395,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel String[] suggestedNameOut = new String[FolderNameProvider.SUGGEST_MAX]; if (FeatureFlags.FOLDER_NAME_SUGGEST.get()) { Executors.UI_HELPER_EXECUTOR.post(() -> { - mLauncher.getFolderNameProvider().getSuggestedFolderName( + launcher.getFolderNameProvider().getSuggestedFolderName( getContext(), mInfo.contents, suggestedNameOut); showFinalView(finalIndex, item, suggestedNameOut); }); @@ -547,7 +560,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel if (!mForceHideDot && ((mDotInfo != null && mDotInfo.hasDot()) || mDotScale > 0)) { Rect iconBounds = mDotParams.iconBounds; BubbleTextView.getIconBounds(this, iconBounds, - mLauncher.getWallpaperDeviceProfile().iconSizePx); + mActivity.getWallpaperDeviceProfile().iconSizePx); float iconScale = (float) mBackground.previewSize / iconBounds.width(); Utilities.scaleRectAboutCenter(iconBounds, iconScale); @@ -605,7 +618,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel @Override public void onAdd(WorkspaceItemInfo item, int rank) { boolean wasDotted = mDotInfo.hasDot(); - mDotInfo.addDotInfo(mLauncher.getDotInfoForItem(item)); + mDotInfo.addDotInfo(mActivity.getDotInfoForItem(item)); boolean isDotted = mDotInfo.hasDot(); updateDotScale(wasDotted, isDotted); invalidate(); @@ -615,7 +628,7 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel @Override public void onRemove(WorkspaceItemInfo item) { boolean wasDotted = mDotInfo.hasDot(); - mDotInfo.subtractDotInfo(mLauncher.getDotInfoForItem(item)); + mDotInfo.subtractDotInfo(mActivity.getDotInfoForItem(item)); boolean isDotted = mDotInfo.hasDot(); updateDotScale(wasDotted, isDotted); invalidate(); diff --git a/src/com/android/launcher3/folder/PreviewItemManager.java b/src/com/android/launcher3/folder/PreviewItemManager.java index 5b3a05ef10..27aa43ef3d 100644 --- a/src/com/android/launcher3/folder/PreviewItemManager.java +++ b/src/com/android/launcher3/folder/PreviewItemManager.java @@ -37,10 +37,10 @@ import android.widget.TextView; import androidx.annotation.NonNull; -import com.android.launcher3.Launcher; import com.android.launcher3.Utilities; import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.graphics.PreloadIconDrawable; +import com.android.launcher3.views.ActivityContext; import java.util.ArrayList; import java.util.List; @@ -94,7 +94,8 @@ public class PreviewItemManager { public PreviewItemManager(FolderIcon icon) { mContext = icon.getContext(); mIcon = icon; - mIconSize = Launcher.getLauncher(mContext).getDeviceProfile().folderChildIconSizePx; + mIconSize = ActivityContext.lookupContext( + mContext).getDeviceProfile().folderChildIconSizePx; } /** @@ -132,7 +133,7 @@ public class PreviewItemManager { mTotalWidth = totalSize; mPrevTopPadding = mIcon.getPaddingTop(); - mIcon.mBackground.setup(mIcon.mLauncher, mIcon.mLauncher, mIcon, mTotalWidth, + mIcon.mBackground.setup(mIcon.getContext(), mIcon.mActivity, mIcon, mTotalWidth, mIcon.getPaddingTop()); mIcon.mPreviewLayoutRule.init(mIcon.mBackground.previewSize, mIntrinsicIconSize, Utilities.isRtl(mIcon.getResources())); @@ -152,7 +153,7 @@ public class PreviewItemManager { } private PreviewItemDrawingParams getFinalIconParams(PreviewItemDrawingParams params) { - float iconSize = mIcon.mLauncher.getDeviceProfile().iconSizePx; + float iconSize = mIcon.mActivity.getDeviceProfile().iconSizePx; final float scale = iconSize / mReferenceDrawable.getIntrinsicWidth(); final float trans = (mIcon.mBackground.previewSize - iconSize) / 2; diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java index 0c5535ffe0..bfe7351c0a 100644 --- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java @@ -49,6 +49,7 @@ import android.widget.TextClock; import com.android.launcher3.BubbleTextView; import com.android.launcher3.CellLayout; import com.android.launcher3.DeviceProfile; +import com.android.launcher3.FolderInfo; import com.android.launcher3.Hotseat; import com.android.launcher3.InsettableFrameLayout; import com.android.launcher3.InvariantDeviceProfile; @@ -63,6 +64,7 @@ import com.android.launcher3.WorkspaceItemInfo; import com.android.launcher3.WorkspaceLayoutManager; import com.android.launcher3.allapps.SearchUiManager; import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.folder.FolderIcon; import com.android.launcher3.icons.BaseIconFactory; import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.icons.BitmapRenderer; @@ -239,6 +241,12 @@ public class LauncherPreviewRenderer implements Callable { addInScreenFromBind(icon, info); } + private void inflateAndAddFolder(FolderInfo info) { + FolderIcon folderIcon = FolderIcon.inflateIcon(R.layout.folder_icon, this, mWorkspace, + info); + addInScreenFromBind(folderIcon, info); + } + private void dispatchVisibilityAggregated(View view, boolean isVisible) { // Similar to View.dispatchVisibilityAggregated implementation. final boolean thisVisible = view.getVisibility() == VISIBLE; @@ -288,7 +296,7 @@ public class LauncherPreviewRenderer implements Callable { inflateAndAddIcon((WorkspaceItemInfo) itemInfo); break; case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: - // TODO: for folder implementation here. + inflateAndAddFolder((FolderInfo) itemInfo); break; default: break;