Loading src/com/android/launcher3/config/FeatureFlags.java +4 −0 Original line number Diff line number Diff line Loading @@ -126,6 +126,10 @@ public final class FeatureFlags { public static final TogglableFlag ENABLE_DEEP_SHORTCUT_ICON_CACHE = new TogglableFlag( "ENABLE_DEEP_SHORTCUT_ICON_CACHE", true, "R/W deep shortcut in IconCache"); public static final TogglableFlag ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER = new TogglableFlag( "ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER", false, "Show launcher preview in grid picker"); public static void initialize(Context context) { // Avoid the disk read for user builds if (Utilities.IS_DEBUG_DEVICE) { Loading src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +105 −15 Original line number Diff line number Diff line Loading @@ -19,6 +19,10 @@ import static android.view.View.MeasureSpec.EXACTLY; import static android.view.View.MeasureSpec.makeMeasureSpec; import static android.view.View.VISIBLE; import static com.android.launcher3.config.FeatureFlags.ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER; import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems; import static com.android.launcher3.model.ModelUtils.sortWorkspaceItemsSpatially; import android.annotation.TargetApi; import android.app.Fragment; import android.content.Context; Loading Loading @@ -48,6 +52,10 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.Hotseat; import com.android.launcher3.InsettableFrameLayout; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.ItemInfo; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherModel; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.R; import com.android.launcher3.Utilities; Loading @@ -58,11 +66,20 @@ import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.icons.BaseIconFactory; import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.icons.BitmapRenderer; import com.android.launcher3.model.AllAppsList; import com.android.launcher3.model.BgDataModel; import com.android.launcher3.model.LoaderResults; import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.BaseDragLayer; import java.util.ArrayList; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** * Utility class for generating the preview of Launcher for a given InvariantDeviceProfile. Loading Loading @@ -241,6 +258,43 @@ public class LauncherPreviewRenderer implements Callable<Bitmap> { } private void renderScreenShot(Canvas canvas) { if (ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER.get()) { final LauncherModel launcherModel = LauncherAppState.getInstance( mContext).getModel(); final WorkspaceItemsInfoFetcher fetcher = new WorkspaceItemsInfoFetcher(); launcherModel.enqueueModelUpdateTask(fetcher); ArrayList<ItemInfo> workspaceItems; try { workspaceItems = fetcher.mTask.get(5, TimeUnit.SECONDS); } catch (InterruptedException | ExecutionException | TimeoutException e) { Log.d(TAG, "Error fetching workspace items info", e); return; } // Separate the items that are on the current screen, and all the other remaining // items ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<>(); ArrayList<ItemInfo> otherWorkspaceItems = new ArrayList<>(); filterCurrentWorkspaceItems(0 /* currentScreenId */, workspaceItems, currentWorkspaceItems, otherWorkspaceItems); sortWorkspaceItemsSpatially(mIdp, currentWorkspaceItems); for (ItemInfo itemInfo : currentWorkspaceItems) { switch (itemInfo.itemType) { case Favorites.ITEM_TYPE_APPLICATION: case Favorites.ITEM_TYPE_SHORTCUT: case Favorites.ITEM_TYPE_DEEP_SHORTCUT: inflateAndAddIcon((WorkspaceItemInfo) itemInfo); break; case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: // TODO: for folder implementation here. break; default: break; } } } else { // Add hotseat icons for (int i = 0; i < mIdp.numHotseatIcons; i++) { WorkspaceItemInfo info = new WorkspaceItemInfo(mWorkspaceItemInfo); Loading @@ -248,7 +302,6 @@ public class LauncherPreviewRenderer implements Callable<Bitmap> { info.screenId = i; inflateAndAddIcon(info); } // Add workspace icons for (int i = 0; i < mIdp.numColumns; i++) { WorkspaceItemInfo info = new WorkspaceItemInfo(mWorkspaceItemInfo); Loading @@ -258,6 +311,7 @@ public class LauncherPreviewRenderer implements Callable<Bitmap> { info.cellY = mIdp.numRows - 1; inflateAndAddIcon(info); } } // Add first page QSB if (FeatureFlags.QSB_ON_FIRST_SCREEN) { Loading Loading @@ -286,6 +340,42 @@ public class LauncherPreviewRenderer implements Callable<Bitmap> { } } private static class WorkspaceItemsInfoFetcher implements Callable<ArrayList<ItemInfo>>, LauncherModel.ModelUpdateTask { private final FutureTask<ArrayList<ItemInfo>> mTask = new FutureTask<>(this); private LauncherAppState mApp; private LauncherModel mModel; private BgDataModel mBgDataModel; private AllAppsList mAllAppsList; @Override public void init(LauncherAppState app, LauncherModel model, BgDataModel dataModel, AllAppsList allAppsList, Executor uiExecutor) { mApp = app; mModel = model; mBgDataModel = dataModel; mAllAppsList = allAppsList; } @Override public void run() { mTask.run(); } @Override public ArrayList<ItemInfo> call() throws Exception { if (!mModel.isModelLoaded()) { Log.d(TAG, "Workspace not loaded, loading now"); mModel.startLoaderForResults( new LoaderResults(mApp, mBgDataModel, mAllAppsList, 0, null)); return new ArrayList<>(); } return mBgDataModel.workspaceItems; } } private static void measureView(View view, int width, int height) { view.measure(makeMeasureSpec(width, EXACTLY), makeMeasureSpec(height, EXACTLY)); view.layout(0, 0, width, height); Loading src/com/android/launcher3/model/BaseLoaderResults.java +5 −90 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.launcher3.model; import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems; import static com.android.launcher3.model.ModelUtils.sortWorkspaceItemsSpatially; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import android.os.Looper; Loading @@ -27,20 +29,15 @@ import com.android.launcher3.ItemInfo; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherModel.CallbackTask; import com.android.launcher3.LauncherSettings; import com.android.launcher3.PagedView; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.BgDataModel.Callbacks; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.IntSet; import com.android.launcher3.util.LooperIdleLock; import com.android.launcher3.util.ViewOnDrawExecutor; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.concurrent.Executor; /** Loading Loading @@ -123,8 +120,9 @@ public abstract class BaseLoaderResults { otherWorkspaceItems); filterCurrentWorkspaceItems(currentScreenId, appWidgets, currentAppWidgets, otherAppWidgets); sortWorkspaceItemsSpatially(currentWorkspaceItems); sortWorkspaceItemsSpatially(otherWorkspaceItems); final InvariantDeviceProfile idp = mApp.getInvariantDeviceProfile(); sortWorkspaceItemsSpatially(idp, currentWorkspaceItems); sortWorkspaceItemsSpatially(idp, otherWorkspaceItems); // Tell the workspace that we're about to start binding items executeCallbacksTask(c -> { Loading Loading @@ -169,89 +167,6 @@ public abstract class BaseLoaderResults { } } /** Filters the set of items who are directly or indirectly (via another container) on the * specified screen. */ public static <T extends ItemInfo> void filterCurrentWorkspaceItems(int currentScreenId, ArrayList<T> allWorkspaceItems, ArrayList<T> currentScreenItems, ArrayList<T> otherScreenItems) { // Purge any null ItemInfos Iterator<T> iter = allWorkspaceItems.iterator(); while (iter.hasNext()) { ItemInfo i = iter.next(); if (i == null) { iter.remove(); } } // Order the set of items by their containers first, this allows use to walk through the // list sequentially, build up a list of containers that are in the specified screen, // as well as all items in those containers. IntSet itemsOnScreen = new IntSet(); Collections.sort(allWorkspaceItems, (lhs, rhs) -> Integer.compare(lhs.container, rhs.container)); for (T info : allWorkspaceItems) { if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { if (info.screenId == currentScreenId) { currentScreenItems.add(info); itemsOnScreen.add(info.id); } else { otherScreenItems.add(info); } } else if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { currentScreenItems.add(info); itemsOnScreen.add(info.id); } else { if (itemsOnScreen.contains(info.container)) { currentScreenItems.add(info); itemsOnScreen.add(info.id); } else { otherScreenItems.add(info); } } } } /** Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to * right) */ protected void sortWorkspaceItemsSpatially(ArrayList<ItemInfo> workspaceItems) { final InvariantDeviceProfile profile = mApp.getInvariantDeviceProfile(); final int screenCols = profile.numColumns; final int screenCellCount = profile.numColumns * profile.numRows; Collections.sort(workspaceItems, new Comparator<ItemInfo>() { @Override public int compare(ItemInfo lhs, ItemInfo rhs) { if (lhs.container == rhs.container) { // Within containers, order by their spatial position in that container switch (lhs.container) { case LauncherSettings.Favorites.CONTAINER_DESKTOP: { int lr = (lhs.screenId * screenCellCount + lhs.cellY * screenCols + lhs.cellX); int rr = (rhs.screenId * screenCellCount + rhs.cellY * screenCols + rhs.cellX); return Integer.compare(lr, rr); } case LauncherSettings.Favorites.CONTAINER_HOTSEAT: { // We currently use the screen id as the rank return Integer.compare(lhs.screenId, rhs.screenId); } default: if (FeatureFlags.IS_DOGFOOD_BUILD) { throw new RuntimeException("Unexpected container type when " + "sorting workspace items."); } return 0; } } else { // Between containers, order by hotseat, desktop return Integer.compare(lhs.container, rhs.container); } } }); } protected void bindWorkspaceItems(final ArrayList<ItemInfo> workspaceItems, final Executor executor) { // Bind the workspace items Loading src/com/android/launcher3/model/LoaderTask.java +1 −1 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ package com.android.launcher3.model; import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_LOCKED_USER; import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SAFEMODE; import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SUSPENDED; import static com.android.launcher3.model.LoaderResults.filterCurrentWorkspaceItems; import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems; import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; import static com.android.launcher3.util.PackageManagerHelper.isSystemApp; Loading src/com/android/launcher3/model/ModelUtils.java 0 → 100644 +112 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.launcher3.model; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.ItemInfo; import com.android.launcher3.LauncherSettings; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.util.IntSet; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; /** * Utils class for {@link com.android.launcher3.LauncherModel}. */ public class ModelUtils { /** * Filters the set of items who are directly or indirectly (via another container) on the * specified screen. */ public static <T extends ItemInfo> void filterCurrentWorkspaceItems(int currentScreenId, ArrayList<T> allWorkspaceItems, ArrayList<T> currentScreenItems, ArrayList<T> otherScreenItems) { // Purge any null ItemInfos Iterator<T> iter = allWorkspaceItems.iterator(); while (iter.hasNext()) { ItemInfo i = iter.next(); if (i == null) { iter.remove(); } } // Order the set of items by their containers first, this allows use to walk through the // list sequentially, build up a list of containers that are in the specified screen, // as well as all items in those containers. IntSet itemsOnScreen = new IntSet(); Collections.sort(allWorkspaceItems, (lhs, rhs) -> Integer.compare(lhs.container, rhs.container)); for (T info : allWorkspaceItems) { if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { if (info.screenId == currentScreenId) { currentScreenItems.add(info); itemsOnScreen.add(info.id); } else { otherScreenItems.add(info); } } else if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { currentScreenItems.add(info); itemsOnScreen.add(info.id); } else { if (itemsOnScreen.contains(info.container)) { currentScreenItems.add(info); itemsOnScreen.add(info.id); } else { otherScreenItems.add(info); } } } } /** * Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to right) */ public static void sortWorkspaceItemsSpatially(InvariantDeviceProfile profile, ArrayList<ItemInfo> workspaceItems) { final int screenCols = profile.numColumns; final int screenCellCount = profile.numColumns * profile.numRows; Collections.sort(workspaceItems, (lhs, rhs) -> { if (lhs.container == rhs.container) { // Within containers, order by their spatial position in that container switch (lhs.container) { case LauncherSettings.Favorites.CONTAINER_DESKTOP: { int lr = (lhs.screenId * screenCellCount + lhs.cellY * screenCols + lhs.cellX); int rr = (rhs.screenId * screenCellCount + +rhs.cellY * screenCols + rhs.cellX); return Integer.compare(lr, rr); } case LauncherSettings.Favorites.CONTAINER_HOTSEAT: { // We currently use the screen id as the rank return Integer.compare(lhs.screenId, rhs.screenId); } default: if (FeatureFlags.IS_DOGFOOD_BUILD) { throw new RuntimeException( "Unexpected container type when sorting workspace items."); } return 0; } } else { // Between containers, order by hotseat, desktop return Integer.compare(lhs.container, rhs.container); } }); } } Loading
src/com/android/launcher3/config/FeatureFlags.java +4 −0 Original line number Diff line number Diff line Loading @@ -126,6 +126,10 @@ public final class FeatureFlags { public static final TogglableFlag ENABLE_DEEP_SHORTCUT_ICON_CACHE = new TogglableFlag( "ENABLE_DEEP_SHORTCUT_ICON_CACHE", true, "R/W deep shortcut in IconCache"); public static final TogglableFlag ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER = new TogglableFlag( "ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER", false, "Show launcher preview in grid picker"); public static void initialize(Context context) { // Avoid the disk read for user builds if (Utilities.IS_DEBUG_DEVICE) { Loading
src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +105 −15 Original line number Diff line number Diff line Loading @@ -19,6 +19,10 @@ import static android.view.View.MeasureSpec.EXACTLY; import static android.view.View.MeasureSpec.makeMeasureSpec; import static android.view.View.VISIBLE; import static com.android.launcher3.config.FeatureFlags.ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER; import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems; import static com.android.launcher3.model.ModelUtils.sortWorkspaceItemsSpatially; import android.annotation.TargetApi; import android.app.Fragment; import android.content.Context; Loading Loading @@ -48,6 +52,10 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.Hotseat; import com.android.launcher3.InsettableFrameLayout; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.ItemInfo; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherModel; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.R; import com.android.launcher3.Utilities; Loading @@ -58,11 +66,20 @@ import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.icons.BaseIconFactory; import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.icons.BitmapRenderer; import com.android.launcher3.model.AllAppsList; import com.android.launcher3.model.BgDataModel; import com.android.launcher3.model.LoaderResults; import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.BaseDragLayer; import java.util.ArrayList; import java.util.concurrent.Callable; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor; import java.util.concurrent.FutureTask; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; /** * Utility class for generating the preview of Launcher for a given InvariantDeviceProfile. Loading Loading @@ -241,6 +258,43 @@ public class LauncherPreviewRenderer implements Callable<Bitmap> { } private void renderScreenShot(Canvas canvas) { if (ENABLE_LAUNCHER_PREVIEW_IN_GRID_PICKER.get()) { final LauncherModel launcherModel = LauncherAppState.getInstance( mContext).getModel(); final WorkspaceItemsInfoFetcher fetcher = new WorkspaceItemsInfoFetcher(); launcherModel.enqueueModelUpdateTask(fetcher); ArrayList<ItemInfo> workspaceItems; try { workspaceItems = fetcher.mTask.get(5, TimeUnit.SECONDS); } catch (InterruptedException | ExecutionException | TimeoutException e) { Log.d(TAG, "Error fetching workspace items info", e); return; } // Separate the items that are on the current screen, and all the other remaining // items ArrayList<ItemInfo> currentWorkspaceItems = new ArrayList<>(); ArrayList<ItemInfo> otherWorkspaceItems = new ArrayList<>(); filterCurrentWorkspaceItems(0 /* currentScreenId */, workspaceItems, currentWorkspaceItems, otherWorkspaceItems); sortWorkspaceItemsSpatially(mIdp, currentWorkspaceItems); for (ItemInfo itemInfo : currentWorkspaceItems) { switch (itemInfo.itemType) { case Favorites.ITEM_TYPE_APPLICATION: case Favorites.ITEM_TYPE_SHORTCUT: case Favorites.ITEM_TYPE_DEEP_SHORTCUT: inflateAndAddIcon((WorkspaceItemInfo) itemInfo); break; case LauncherSettings.Favorites.ITEM_TYPE_FOLDER: // TODO: for folder implementation here. break; default: break; } } } else { // Add hotseat icons for (int i = 0; i < mIdp.numHotseatIcons; i++) { WorkspaceItemInfo info = new WorkspaceItemInfo(mWorkspaceItemInfo); Loading @@ -248,7 +302,6 @@ public class LauncherPreviewRenderer implements Callable<Bitmap> { info.screenId = i; inflateAndAddIcon(info); } // Add workspace icons for (int i = 0; i < mIdp.numColumns; i++) { WorkspaceItemInfo info = new WorkspaceItemInfo(mWorkspaceItemInfo); Loading @@ -258,6 +311,7 @@ public class LauncherPreviewRenderer implements Callable<Bitmap> { info.cellY = mIdp.numRows - 1; inflateAndAddIcon(info); } } // Add first page QSB if (FeatureFlags.QSB_ON_FIRST_SCREEN) { Loading Loading @@ -286,6 +340,42 @@ public class LauncherPreviewRenderer implements Callable<Bitmap> { } } private static class WorkspaceItemsInfoFetcher implements Callable<ArrayList<ItemInfo>>, LauncherModel.ModelUpdateTask { private final FutureTask<ArrayList<ItemInfo>> mTask = new FutureTask<>(this); private LauncherAppState mApp; private LauncherModel mModel; private BgDataModel mBgDataModel; private AllAppsList mAllAppsList; @Override public void init(LauncherAppState app, LauncherModel model, BgDataModel dataModel, AllAppsList allAppsList, Executor uiExecutor) { mApp = app; mModel = model; mBgDataModel = dataModel; mAllAppsList = allAppsList; } @Override public void run() { mTask.run(); } @Override public ArrayList<ItemInfo> call() throws Exception { if (!mModel.isModelLoaded()) { Log.d(TAG, "Workspace not loaded, loading now"); mModel.startLoaderForResults( new LoaderResults(mApp, mBgDataModel, mAllAppsList, 0, null)); return new ArrayList<>(); } return mBgDataModel.workspaceItems; } } private static void measureView(View view, int width, int height) { view.measure(makeMeasureSpec(width, EXACTLY), makeMeasureSpec(height, EXACTLY)); view.layout(0, 0, width, height); Loading
src/com/android/launcher3/model/BaseLoaderResults.java +5 −90 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.launcher3.model; import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems; import static com.android.launcher3.model.ModelUtils.sortWorkspaceItemsSpatially; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import android.os.Looper; Loading @@ -27,20 +29,15 @@ import com.android.launcher3.ItemInfo; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherAppWidgetInfo; import com.android.launcher3.LauncherModel.CallbackTask; import com.android.launcher3.LauncherSettings; import com.android.launcher3.PagedView; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.BgDataModel.Callbacks; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.IntSet; import com.android.launcher3.util.LooperIdleLock; import com.android.launcher3.util.ViewOnDrawExecutor; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.concurrent.Executor; /** Loading Loading @@ -123,8 +120,9 @@ public abstract class BaseLoaderResults { otherWorkspaceItems); filterCurrentWorkspaceItems(currentScreenId, appWidgets, currentAppWidgets, otherAppWidgets); sortWorkspaceItemsSpatially(currentWorkspaceItems); sortWorkspaceItemsSpatially(otherWorkspaceItems); final InvariantDeviceProfile idp = mApp.getInvariantDeviceProfile(); sortWorkspaceItemsSpatially(idp, currentWorkspaceItems); sortWorkspaceItemsSpatially(idp, otherWorkspaceItems); // Tell the workspace that we're about to start binding items executeCallbacksTask(c -> { Loading Loading @@ -169,89 +167,6 @@ public abstract class BaseLoaderResults { } } /** Filters the set of items who are directly or indirectly (via another container) on the * specified screen. */ public static <T extends ItemInfo> void filterCurrentWorkspaceItems(int currentScreenId, ArrayList<T> allWorkspaceItems, ArrayList<T> currentScreenItems, ArrayList<T> otherScreenItems) { // Purge any null ItemInfos Iterator<T> iter = allWorkspaceItems.iterator(); while (iter.hasNext()) { ItemInfo i = iter.next(); if (i == null) { iter.remove(); } } // Order the set of items by their containers first, this allows use to walk through the // list sequentially, build up a list of containers that are in the specified screen, // as well as all items in those containers. IntSet itemsOnScreen = new IntSet(); Collections.sort(allWorkspaceItems, (lhs, rhs) -> Integer.compare(lhs.container, rhs.container)); for (T info : allWorkspaceItems) { if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { if (info.screenId == currentScreenId) { currentScreenItems.add(info); itemsOnScreen.add(info.id); } else { otherScreenItems.add(info); } } else if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { currentScreenItems.add(info); itemsOnScreen.add(info.id); } else { if (itemsOnScreen.contains(info.container)) { currentScreenItems.add(info); itemsOnScreen.add(info.id); } else { otherScreenItems.add(info); } } } } /** Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to * right) */ protected void sortWorkspaceItemsSpatially(ArrayList<ItemInfo> workspaceItems) { final InvariantDeviceProfile profile = mApp.getInvariantDeviceProfile(); final int screenCols = profile.numColumns; final int screenCellCount = profile.numColumns * profile.numRows; Collections.sort(workspaceItems, new Comparator<ItemInfo>() { @Override public int compare(ItemInfo lhs, ItemInfo rhs) { if (lhs.container == rhs.container) { // Within containers, order by their spatial position in that container switch (lhs.container) { case LauncherSettings.Favorites.CONTAINER_DESKTOP: { int lr = (lhs.screenId * screenCellCount + lhs.cellY * screenCols + lhs.cellX); int rr = (rhs.screenId * screenCellCount + rhs.cellY * screenCols + rhs.cellX); return Integer.compare(lr, rr); } case LauncherSettings.Favorites.CONTAINER_HOTSEAT: { // We currently use the screen id as the rank return Integer.compare(lhs.screenId, rhs.screenId); } default: if (FeatureFlags.IS_DOGFOOD_BUILD) { throw new RuntimeException("Unexpected container type when " + "sorting workspace items."); } return 0; } } else { // Between containers, order by hotseat, desktop return Integer.compare(lhs.container, rhs.container); } } }); } protected void bindWorkspaceItems(final ArrayList<ItemInfo> workspaceItems, final Executor executor) { // Bind the workspace items Loading
src/com/android/launcher3/model/LoaderTask.java +1 −1 Original line number Diff line number Diff line Loading @@ -19,7 +19,7 @@ package com.android.launcher3.model; import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_LOCKED_USER; import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SAFEMODE; import static com.android.launcher3.ItemInfoWithIcon.FLAG_DISABLED_SUSPENDED; import static com.android.launcher3.model.LoaderResults.filterCurrentWorkspaceItems; import static com.android.launcher3.model.ModelUtils.filterCurrentWorkspaceItems; import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; import static com.android.launcher3.util.PackageManagerHelper.isSystemApp; Loading
src/com/android/launcher3/model/ModelUtils.java 0 → 100644 +112 −0 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.launcher3.model; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.ItemInfo; import com.android.launcher3.LauncherSettings; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.util.IntSet; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; /** * Utils class for {@link com.android.launcher3.LauncherModel}. */ public class ModelUtils { /** * Filters the set of items who are directly or indirectly (via another container) on the * specified screen. */ public static <T extends ItemInfo> void filterCurrentWorkspaceItems(int currentScreenId, ArrayList<T> allWorkspaceItems, ArrayList<T> currentScreenItems, ArrayList<T> otherScreenItems) { // Purge any null ItemInfos Iterator<T> iter = allWorkspaceItems.iterator(); while (iter.hasNext()) { ItemInfo i = iter.next(); if (i == null) { iter.remove(); } } // Order the set of items by their containers first, this allows use to walk through the // list sequentially, build up a list of containers that are in the specified screen, // as well as all items in those containers. IntSet itemsOnScreen = new IntSet(); Collections.sort(allWorkspaceItems, (lhs, rhs) -> Integer.compare(lhs.container, rhs.container)); for (T info : allWorkspaceItems) { if (info.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) { if (info.screenId == currentScreenId) { currentScreenItems.add(info); itemsOnScreen.add(info.id); } else { otherScreenItems.add(info); } } else if (info.container == LauncherSettings.Favorites.CONTAINER_HOTSEAT) { currentScreenItems.add(info); itemsOnScreen.add(info.id); } else { if (itemsOnScreen.contains(info.container)) { currentScreenItems.add(info); itemsOnScreen.add(info.id); } else { otherScreenItems.add(info); } } } } /** * Sorts the set of items by hotseat, workspace (spatially from top to bottom, left to right) */ public static void sortWorkspaceItemsSpatially(InvariantDeviceProfile profile, ArrayList<ItemInfo> workspaceItems) { final int screenCols = profile.numColumns; final int screenCellCount = profile.numColumns * profile.numRows; Collections.sort(workspaceItems, (lhs, rhs) -> { if (lhs.container == rhs.container) { // Within containers, order by their spatial position in that container switch (lhs.container) { case LauncherSettings.Favorites.CONTAINER_DESKTOP: { int lr = (lhs.screenId * screenCellCount + lhs.cellY * screenCols + lhs.cellX); int rr = (rhs.screenId * screenCellCount + +rhs.cellY * screenCols + rhs.cellX); return Integer.compare(lr, rr); } case LauncherSettings.Favorites.CONTAINER_HOTSEAT: { // We currently use the screen id as the rank return Integer.compare(lhs.screenId, rhs.screenId); } default: if (FeatureFlags.IS_DOGFOOD_BUILD) { throw new RuntimeException( "Unexpected container type when sorting workspace items."); } return 0; } } else { // Between containers, order by hotseat, desktop return Integer.compare(lhs.container, rhs.container); } }); } }