Loading src/com/android/launcher3/allapps/AlphabeticalAppsList.java +41 −15 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_NOTHING; import android.content.Context; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.recyclerview.widget.DiffUtil; import com.android.launcher3.Flags; Loading Loading @@ -338,26 +339,14 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement hasPrivateApps = appList.stream(). allMatch(mPrivateProviderManager.getItemInfoMatcher()); } int privateAppCount = 0; int numberOfColumns = mActivityContext.getDeviceProfile().numShownAllAppsColumns; int numberOfAppRows = (int) Math.ceil((double) appList.size() / numberOfColumns); for (AppInfo info : appList) { for (int i = 0; i < appList.size(); i++) { AppInfo info = appList.get(i); // Apply decorator to private apps. if (hasPrivateApps) { int roundRegion = ROUND_NOTHING; if ((privateAppCount / numberOfColumns) == numberOfAppRows - 1) { if ((privateAppCount % numberOfColumns) == 0) { // App is the first column roundRegion = ROUND_BOTTOM_LEFT; } else if ((privateAppCount % numberOfColumns) == numberOfColumns-1) { roundRegion = ROUND_BOTTOM_RIGHT; } } mAdapterItems.add(AdapterItem.asAppWithDecorationInfo(info, new SectionDecorationInfo(mActivityContext.getApplicationContext(), roundRegion, getRoundRegions(i, appList.size()), true /* decorateTogether */))); privateAppCount += 1; } else { mAdapterItems.add(AdapterItem.asApp(info)); } Loading @@ -372,6 +361,43 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement } } /** * Determines the corner regions that should be rounded for a specific app icon based on its * position in a grid. Apps that should only be cared about rounding are the apps in the last * row. In the last row on the first column, the app should only be rounded on the bottom left. * Apps in the middle would not be rounded and the last app on the last row will ALWAYS have a * {@link SectionDecorationInfo#ROUND_BOTTOM_RIGHT}. * * @param appIndex The index of the app icon within the app list. * @param appListSize The total number of apps within the app list. * @return An integer representing the corner regions to be rounded, using bitwise flags: * - {@link SectionDecorationInfo#ROUND_NOTHING}: No corners should be rounded. * - {@link SectionDecorationInfo#ROUND_TOP_LEFT}: Round the top-left corner. * - {@link SectionDecorationInfo#ROUND_TOP_RIGHT}: Round the top-right corner. * - {@link SectionDecorationInfo#ROUND_BOTTOM_LEFT}: Round the bottom-left corner. * - {@link SectionDecorationInfo#ROUND_BOTTOM_RIGHT}: Round the bottom-right corner. */ @VisibleForTesting int getRoundRegions(int appIndex, int appListSize) { int numberOfAppRows = (int) Math.ceil((double) appListSize / mNumAppsPerRowAllApps); int roundRegion = ROUND_NOTHING; // App is in the last row. if ((appIndex / mNumAppsPerRowAllApps) == numberOfAppRows - 1) { if ((appIndex % mNumAppsPerRowAllApps) == 0) { // App is the first column. roundRegion = ROUND_BOTTOM_LEFT; } else if ((appIndex % mNumAppsPerRowAllApps) == mNumAppsPerRowAllApps-1) { // App is in the last column. roundRegion = ROUND_BOTTOM_RIGHT; } // Ensure the last private app is rounded on the bottom right. if (appIndex == appListSize - 1) { roundRegion |= ROUND_BOTTOM_RIGHT; } } return roundRegion; } private static class MyDiffCallback extends DiffUtil.Callback { private final List<AdapterItem> mOldList; Loading src/com/android/launcher3/allapps/SectionDecorationInfo.java +5 −5 Original line number Diff line number Diff line Loading @@ -22,11 +22,11 @@ import androidx.annotation.NonNull; public class SectionDecorationInfo { public static final int ROUND_NOTHING = 1 << 1; public static final int ROUND_TOP_LEFT = 1 << 2; public static final int ROUND_TOP_RIGHT = 1 << 3; public static final int ROUND_BOTTOM_LEFT = 1 << 4; public static final int ROUND_BOTTOM_RIGHT = 1 << 5; public static final int ROUND_NOTHING = 0; public static final int ROUND_TOP_LEFT = 1 << 1; public static final int ROUND_TOP_RIGHT = 1 << 2; public static final int ROUND_BOTTOM_LEFT = 1 << 3; public static final int ROUND_BOTTOM_RIGHT = 1 << 4; public static final int DECORATOR_ALPHA = 255; protected boolean mShouldDecorateItemsTogether; Loading tests/src/com/android/launcher3/allapps/AlphabeticalAppsListTest.java +94 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ package com.android.launcher3.allapps; import static androidx.test.core.app.ApplicationProvider.getApplicationContext; import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_PRIVATE_SPACE_HEADER; import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_BOTTOM_LEFT; import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_BOTTOM_RIGHT; import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_NOTHING; import static com.android.launcher3.allapps.UserProfileManager.STATE_DISABLED; import static com.android.launcher3.allapps.UserProfileManager.STATE_ENABLED; import static com.android.launcher3.allapps.UserProfileManager.STATE_TRANSITION; Loading Loading @@ -61,6 +64,8 @@ public class AlphabeticalAppsListTest { private static final int PRIVATE_SPACE_HEADER_ITEM_COUNT = 1; private static final int MAIN_USER_APP_COUNT = 2; private static final int PRIVATE_USER_APP_COUNT = 1; private static final int NUM_APP_COLS = 4; private static final int NUM_APP_ROWS = 3; private AlphabeticalAppsList<?> mAlphabeticalAppsList; @Mock Loading @@ -81,6 +86,7 @@ public class AlphabeticalAppsListTest { info != null && info.user.equals(PRIVATE_HANDLE)); mAlphabeticalAppsList = new AlphabeticalAppsList<>(mContext, mAllAppsStore, null, mPrivateProfileManager); mAlphabeticalAppsList.setNumAppsPerRowAllApps(NUM_APP_COLS); } @Test Loading Loading @@ -182,6 +188,94 @@ public class AlphabeticalAppsListTest { .toList().size()); } @Test public void getRoundRegions_whenIndexIsMiddleOfLastRow_roundNothing() { int index = 3; int roundRegions = mAlphabeticalAppsList.getRoundRegions(index, NUM_APP_COLS * NUM_APP_ROWS); assertEquals(ROUND_NOTHING, roundRegions); } @Test public void getRoundRegions_whenIndexIsInEndOfLastRow_roundBottomRight() { int index = 11; int roundRegions = mAlphabeticalAppsList.getRoundRegions(index, NUM_APP_COLS * NUM_APP_ROWS); assertEquals(ROUND_BOTTOM_RIGHT, roundRegions); } @Test public void getRoundRegions_whenIndexIsInBeginningOfLastRow_roundBottomLeft() { int index = 8; int roundRegions = mAlphabeticalAppsList.getRoundRegions(index, NUM_APP_COLS * NUM_APP_ROWS); assertEquals(ROUND_BOTTOM_LEFT, roundRegions); } @Test public void getRoundRegions_whenIndexIsInMiddleOfLastRow_roundNothing() { int index = 9; int roundRegions = mAlphabeticalAppsList.getRoundRegions(index, NUM_APP_COLS * NUM_APP_ROWS); assertEquals(ROUND_NOTHING, roundRegions); } @Test public void getRoundRegions_whenIndexIsInMiddleRow_roundNothing() { int index = 5; int roundRegions = mAlphabeticalAppsList.getRoundRegions(index, NUM_APP_COLS * NUM_APP_ROWS); assertEquals(ROUND_NOTHING, roundRegions); } @Test public void getRoundRegions_whenIndexIsInBeginningOfTopRow_roundNothing() { int index = 0; int roundRegions = mAlphabeticalAppsList.getRoundRegions(index, NUM_APP_COLS * NUM_APP_ROWS); assertEquals(ROUND_NOTHING, roundRegions); } @Test public void getRoundRegions_whenIndexIsInLastOfTopRow_roundNothing() { int index = 3; int roundRegions = mAlphabeticalAppsList.getRoundRegions(index, NUM_APP_COLS * NUM_APP_ROWS); assertEquals(ROUND_NOTHING, roundRegions); } @Test public void getRoundRegions_whenIndexIsInMiddleOfLastRowLastItem_roundBottomRight() { int index = 9; int roundRegions = mAlphabeticalAppsList.getRoundRegions(index, index+1); assertEquals(ROUND_BOTTOM_RIGHT, roundRegions); } @Test public void getRoundRegions_whenIndexIsInBeginningOfLastRowLastItem_roundBottomRight() { int index = 8; int roundRegions = mAlphabeticalAppsList.getRoundRegions(index, index+1); assertEquals(ROUND_BOTTOM_RIGHT | ROUND_BOTTOM_LEFT, roundRegions); } private int addPrivateSpaceHeader(List<BaseAllAppsAdapter.AdapterItem> adapterItemList) { adapterItemList.add(new BaseAllAppsAdapter.AdapterItem(VIEW_TYPE_PRIVATE_SPACE_HEADER)); return adapterItemList.size(); Loading Loading
src/com/android/launcher3/allapps/AlphabeticalAppsList.java +41 −15 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_NOTHING; import android.content.Context; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.recyclerview.widget.DiffUtil; import com.android.launcher3.Flags; Loading Loading @@ -338,26 +339,14 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement hasPrivateApps = appList.stream(). allMatch(mPrivateProviderManager.getItemInfoMatcher()); } int privateAppCount = 0; int numberOfColumns = mActivityContext.getDeviceProfile().numShownAllAppsColumns; int numberOfAppRows = (int) Math.ceil((double) appList.size() / numberOfColumns); for (AppInfo info : appList) { for (int i = 0; i < appList.size(); i++) { AppInfo info = appList.get(i); // Apply decorator to private apps. if (hasPrivateApps) { int roundRegion = ROUND_NOTHING; if ((privateAppCount / numberOfColumns) == numberOfAppRows - 1) { if ((privateAppCount % numberOfColumns) == 0) { // App is the first column roundRegion = ROUND_BOTTOM_LEFT; } else if ((privateAppCount % numberOfColumns) == numberOfColumns-1) { roundRegion = ROUND_BOTTOM_RIGHT; } } mAdapterItems.add(AdapterItem.asAppWithDecorationInfo(info, new SectionDecorationInfo(mActivityContext.getApplicationContext(), roundRegion, getRoundRegions(i, appList.size()), true /* decorateTogether */))); privateAppCount += 1; } else { mAdapterItems.add(AdapterItem.asApp(info)); } Loading @@ -372,6 +361,43 @@ public class AlphabeticalAppsList<T extends Context & ActivityContext> implement } } /** * Determines the corner regions that should be rounded for a specific app icon based on its * position in a grid. Apps that should only be cared about rounding are the apps in the last * row. In the last row on the first column, the app should only be rounded on the bottom left. * Apps in the middle would not be rounded and the last app on the last row will ALWAYS have a * {@link SectionDecorationInfo#ROUND_BOTTOM_RIGHT}. * * @param appIndex The index of the app icon within the app list. * @param appListSize The total number of apps within the app list. * @return An integer representing the corner regions to be rounded, using bitwise flags: * - {@link SectionDecorationInfo#ROUND_NOTHING}: No corners should be rounded. * - {@link SectionDecorationInfo#ROUND_TOP_LEFT}: Round the top-left corner. * - {@link SectionDecorationInfo#ROUND_TOP_RIGHT}: Round the top-right corner. * - {@link SectionDecorationInfo#ROUND_BOTTOM_LEFT}: Round the bottom-left corner. * - {@link SectionDecorationInfo#ROUND_BOTTOM_RIGHT}: Round the bottom-right corner. */ @VisibleForTesting int getRoundRegions(int appIndex, int appListSize) { int numberOfAppRows = (int) Math.ceil((double) appListSize / mNumAppsPerRowAllApps); int roundRegion = ROUND_NOTHING; // App is in the last row. if ((appIndex / mNumAppsPerRowAllApps) == numberOfAppRows - 1) { if ((appIndex % mNumAppsPerRowAllApps) == 0) { // App is the first column. roundRegion = ROUND_BOTTOM_LEFT; } else if ((appIndex % mNumAppsPerRowAllApps) == mNumAppsPerRowAllApps-1) { // App is in the last column. roundRegion = ROUND_BOTTOM_RIGHT; } // Ensure the last private app is rounded on the bottom right. if (appIndex == appListSize - 1) { roundRegion |= ROUND_BOTTOM_RIGHT; } } return roundRegion; } private static class MyDiffCallback extends DiffUtil.Callback { private final List<AdapterItem> mOldList; Loading
src/com/android/launcher3/allapps/SectionDecorationInfo.java +5 −5 Original line number Diff line number Diff line Loading @@ -22,11 +22,11 @@ import androidx.annotation.NonNull; public class SectionDecorationInfo { public static final int ROUND_NOTHING = 1 << 1; public static final int ROUND_TOP_LEFT = 1 << 2; public static final int ROUND_TOP_RIGHT = 1 << 3; public static final int ROUND_BOTTOM_LEFT = 1 << 4; public static final int ROUND_BOTTOM_RIGHT = 1 << 5; public static final int ROUND_NOTHING = 0; public static final int ROUND_TOP_LEFT = 1 << 1; public static final int ROUND_TOP_RIGHT = 1 << 2; public static final int ROUND_BOTTOM_LEFT = 1 << 3; public static final int ROUND_BOTTOM_RIGHT = 1 << 4; public static final int DECORATOR_ALPHA = 255; protected boolean mShouldDecorateItemsTogether; Loading
tests/src/com/android/launcher3/allapps/AlphabeticalAppsListTest.java +94 −0 Original line number Diff line number Diff line Loading @@ -19,6 +19,9 @@ package com.android.launcher3.allapps; import static androidx.test.core.app.ApplicationProvider.getApplicationContext; import static com.android.launcher3.allapps.BaseAllAppsAdapter.VIEW_TYPE_PRIVATE_SPACE_HEADER; import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_BOTTOM_LEFT; import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_BOTTOM_RIGHT; import static com.android.launcher3.allapps.SectionDecorationInfo.ROUND_NOTHING; import static com.android.launcher3.allapps.UserProfileManager.STATE_DISABLED; import static com.android.launcher3.allapps.UserProfileManager.STATE_ENABLED; import static com.android.launcher3.allapps.UserProfileManager.STATE_TRANSITION; Loading Loading @@ -61,6 +64,8 @@ public class AlphabeticalAppsListTest { private static final int PRIVATE_SPACE_HEADER_ITEM_COUNT = 1; private static final int MAIN_USER_APP_COUNT = 2; private static final int PRIVATE_USER_APP_COUNT = 1; private static final int NUM_APP_COLS = 4; private static final int NUM_APP_ROWS = 3; private AlphabeticalAppsList<?> mAlphabeticalAppsList; @Mock Loading @@ -81,6 +86,7 @@ public class AlphabeticalAppsListTest { info != null && info.user.equals(PRIVATE_HANDLE)); mAlphabeticalAppsList = new AlphabeticalAppsList<>(mContext, mAllAppsStore, null, mPrivateProfileManager); mAlphabeticalAppsList.setNumAppsPerRowAllApps(NUM_APP_COLS); } @Test Loading Loading @@ -182,6 +188,94 @@ public class AlphabeticalAppsListTest { .toList().size()); } @Test public void getRoundRegions_whenIndexIsMiddleOfLastRow_roundNothing() { int index = 3; int roundRegions = mAlphabeticalAppsList.getRoundRegions(index, NUM_APP_COLS * NUM_APP_ROWS); assertEquals(ROUND_NOTHING, roundRegions); } @Test public void getRoundRegions_whenIndexIsInEndOfLastRow_roundBottomRight() { int index = 11; int roundRegions = mAlphabeticalAppsList.getRoundRegions(index, NUM_APP_COLS * NUM_APP_ROWS); assertEquals(ROUND_BOTTOM_RIGHT, roundRegions); } @Test public void getRoundRegions_whenIndexIsInBeginningOfLastRow_roundBottomLeft() { int index = 8; int roundRegions = mAlphabeticalAppsList.getRoundRegions(index, NUM_APP_COLS * NUM_APP_ROWS); assertEquals(ROUND_BOTTOM_LEFT, roundRegions); } @Test public void getRoundRegions_whenIndexIsInMiddleOfLastRow_roundNothing() { int index = 9; int roundRegions = mAlphabeticalAppsList.getRoundRegions(index, NUM_APP_COLS * NUM_APP_ROWS); assertEquals(ROUND_NOTHING, roundRegions); } @Test public void getRoundRegions_whenIndexIsInMiddleRow_roundNothing() { int index = 5; int roundRegions = mAlphabeticalAppsList.getRoundRegions(index, NUM_APP_COLS * NUM_APP_ROWS); assertEquals(ROUND_NOTHING, roundRegions); } @Test public void getRoundRegions_whenIndexIsInBeginningOfTopRow_roundNothing() { int index = 0; int roundRegions = mAlphabeticalAppsList.getRoundRegions(index, NUM_APP_COLS * NUM_APP_ROWS); assertEquals(ROUND_NOTHING, roundRegions); } @Test public void getRoundRegions_whenIndexIsInLastOfTopRow_roundNothing() { int index = 3; int roundRegions = mAlphabeticalAppsList.getRoundRegions(index, NUM_APP_COLS * NUM_APP_ROWS); assertEquals(ROUND_NOTHING, roundRegions); } @Test public void getRoundRegions_whenIndexIsInMiddleOfLastRowLastItem_roundBottomRight() { int index = 9; int roundRegions = mAlphabeticalAppsList.getRoundRegions(index, index+1); assertEquals(ROUND_BOTTOM_RIGHT, roundRegions); } @Test public void getRoundRegions_whenIndexIsInBeginningOfLastRowLastItem_roundBottomRight() { int index = 8; int roundRegions = mAlphabeticalAppsList.getRoundRegions(index, index+1); assertEquals(ROUND_BOTTOM_RIGHT | ROUND_BOTTOM_LEFT, roundRegions); } private int addPrivateSpaceHeader(List<BaseAllAppsAdapter.AdapterItem> adapterItemList) { adapterItemList.add(new BaseAllAppsAdapter.AdapterItem(VIEW_TYPE_PRIVATE_SPACE_HEADER)); return adapterItemList.size(); Loading