summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/InvariantDeviceProfile.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/launcher3/InvariantDeviceProfile.java')
-rw-r--r--src/com/android/launcher3/InvariantDeviceProfile.java202
1 files changed, 132 insertions, 70 deletions
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index bde87cb50..d66ba7317 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -18,6 +18,8 @@ package com.android.launcher3;
import static com.android.launcher3.Utilities.getDevicePrefs;
import static com.android.launcher3.config.FeatureFlags.APPLY_CONFIG_AT_RUNTIME;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
+import static com.android.launcher3.settings.SettingsActivity.GRID_OPTIONS_PREFERENCE_KEY;
import static com.android.launcher3.util.PackageManagerHelper.getPackageFilter;
import android.annotation.TargetApi;
@@ -39,11 +41,13 @@ import android.util.Log;
import android.util.SparseArray;
import android.util.TypedValue;
import android.util.Xml;
-import android.view.Display;
-import android.view.WindowManager;
+
+import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.util.ConfigMonitor;
+import com.android.launcher3.util.DefaultDisplay;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.Themes;
@@ -54,9 +58,7 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
-
-import androidx.annotation.Nullable;
-import androidx.annotation.VisibleForTesting;
+import java.util.Comparator;
public class InvariantDeviceProfile {
@@ -102,6 +104,8 @@ public class InvariantDeviceProfile {
public int iconBitmapSize;
public int fillResIconDpi;
public float iconTextSize;
+ public float allAppsIconSize;
+ public float allAppsIconTextSize;
private SparseArray<TypedValue> mExtraAttrs;
@@ -110,6 +114,11 @@ public class InvariantDeviceProfile {
*/
public int numHotseatIcons;
+ /**
+ * Number of columns in the all apps list.
+ */
+ public int numAllAppsColumns;
+
public int defaultLayoutId;
int demoModeLayoutId;
@@ -136,6 +145,9 @@ public class InvariantDeviceProfile {
landscapeIconSize = p.landscapeIconSize;
iconTextSize = p.iconTextSize;
numHotseatIcons = p.numHotseatIcons;
+ numAllAppsColumns = p.numAllAppsColumns;
+ allAppsIconSize = p.allAppsIconSize;
+ allAppsIconTextSize = p.allAppsIconTextSize;
defaultLayoutId = p.defaultLayoutId;
demoModeLayoutId = p.demoModeLayoutId;
mExtraAttrs = p.mExtraAttrs;
@@ -144,7 +156,10 @@ public class InvariantDeviceProfile {
@TargetApi(23)
private InvariantDeviceProfile(Context context) {
- initGrid(context, Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null));
+ String gridName = Utilities.getPrefs(context).getBoolean(GRID_OPTIONS_PREFERENCE_KEY, false)
+ ? Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null)
+ : null;
+ initGrid(context, gridName);
mConfigMonitor = new ConfigMonitor(context,
APPLY_CONFIG_AT_RUNTIME.get() ? this::onConfigChanged : this::killProcess);
mOverlayMonitor = new OverlayMonitor(context);
@@ -172,64 +187,82 @@ public class InvariantDeviceProfile {
}
private String initGrid(Context context, String gridName) {
- WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
- Display display = wm.getDefaultDisplay();
- DisplayMetrics dm = new DisplayMetrics();
- display.getMetrics(dm);
+ DefaultDisplay.Info displayInfo = DefaultDisplay.INSTANCE.get(context).getInfo();
- Point smallestSize = new Point();
- Point largestSize = new Point();
- display.getCurrentSizeRange(smallestSize, largestSize);
+ Point smallestSize = new Point(displayInfo.smallestSize);
+ Point largestSize = new Point(displayInfo.largestSize);
- ArrayList<DisplayOption> allOptions = getPredefinedDeviceProfiles(context, gridName);
// This guarantees that width < height
- float minWidthDps = Utilities.dpiFromPx(Math.min(smallestSize.x, smallestSize.y), dm);
- float minHeightDps = Utilities.dpiFromPx(Math.min(largestSize.x, largestSize.y), dm);
+ float minWidthDps = Utilities.dpiFromPx(Math.min(smallestSize.x, smallestSize.y),
+ displayInfo.metrics);
+ float minHeightDps = Utilities.dpiFromPx(Math.min(largestSize.x, largestSize.y),
+ displayInfo.metrics);
+
+ Point realSize = new Point(displayInfo.realSize);
+ // The real size never changes. smallSide and largeSide will remain the
+ // same in any orientation.
+ int smallSide = Math.min(realSize.x, realSize.y);
+ int largeSide = Math.max(realSize.x, realSize.y);
+
+ // We want a list of all options as well as the list of filtered options. This allows us
+ // to have a consistent UI for areas that the grid size change should not affect
+ // ie. All Apps should be consistent between grid sizes.
+ ArrayList<DisplayOption> allOptions = new ArrayList<>();
+ ArrayList<DisplayOption> filteredOptions = new ArrayList<>();
+ getPredefinedDeviceProfiles(context, gridName, filteredOptions, allOptions);
+
+ if (allOptions.isEmpty() && filteredOptions.isEmpty()) {
+ throw new RuntimeException("No display option with canBeDefault=true");
+ }
+
// Sort the profiles based on the closeness to the device size
- Collections.sort(allOptions, (a, b) ->
- Float.compare(dist(minWidthDps, minHeightDps, a.minWidthDps, a.minHeightDps),
- dist(minWidthDps, minHeightDps, b.minWidthDps, b.minHeightDps)));
+ Comparator<DisplayOption> comparator = (a, b) -> Float.compare(dist(minWidthDps,
+ minHeightDps, a.minWidthDps, a.minHeightDps),
+ dist(minWidthDps, minHeightDps, b.minWidthDps, b.minHeightDps));
+
+ // Calculate the device profiles as if there is no grid override.
+ Collections.sort(allOptions, comparator);
DisplayOption interpolatedDisplayOption =
invDistWeightedInterpolate(minWidthDps, minHeightDps, allOptions);
+ initGridOption(context, allOptions, interpolatedDisplayOption, displayInfo.metrics);
+
+ // Create IDP with no grid override values.
+ InvariantDeviceProfile originalIDP = new InvariantDeviceProfile(this);
+ originalIDP.landscapeProfile = new DeviceProfile(context, this, null, smallestSize,
+ largestSize, largeSide, smallSide, true /* isLandscape */,
+ false /* isMultiWindowMode */);
+ originalIDP.portraitProfile = new DeviceProfile(context, this, null, smallestSize,
+ largestSize, smallSide, largeSide, false /* isLandscape */,
+ false /* isMultiWindowMode */);
+
+ if (filteredOptions.isEmpty()) {
+ filteredOptions = allOptions;
+
+ landscapeProfile = originalIDP.landscapeProfile;
+ portraitProfile = originalIDP.portraitProfile;
+ } else {
+ Collections.sort(filteredOptions, comparator);
+ interpolatedDisplayOption =
+ invDistWeightedInterpolate(minWidthDps, minHeightDps, filteredOptions);
+
+ initGridOption(context, filteredOptions, interpolatedDisplayOption,
+ displayInfo.metrics);
+ numAllAppsColumns = originalIDP.numAllAppsColumns;
+
+ landscapeProfile = new DeviceProfile(context, this, originalIDP, smallestSize,
+ largestSize, largeSide, smallSide, true /* isLandscape */,
+ false /* isMultiWindowMode */);
+ portraitProfile = new DeviceProfile(context, this, originalIDP, smallestSize,
+ largestSize, smallSide, largeSide, false /* isLandscape */,
+ false /* isMultiWindowMode */);
+ }
- GridOption closestProfile = allOptions.get(0).grid;
- numRows = closestProfile.numRows;
- numColumns = closestProfile.numColumns;
- numHotseatIcons = closestProfile.numHotseatIcons;
- defaultLayoutId = closestProfile.defaultLayoutId;
- demoModeLayoutId = closestProfile.demoModeLayoutId;
- numFolderRows = closestProfile.numFolderRows;
- numFolderColumns = closestProfile.numFolderColumns;
- mExtraAttrs = closestProfile.extraAttrs;
-
+ GridOption closestProfile = filteredOptions.get(0).grid;
if (!closestProfile.name.equals(gridName)) {
Utilities.getPrefs(context).edit()
.putString(KEY_IDP_GRID_NAME, closestProfile.name).apply();
}
- iconSize = interpolatedDisplayOption.iconSize;
- iconShapePath = getIconShapePath(context);
- landscapeIconSize = interpolatedDisplayOption.landscapeIconSize;
- iconBitmapSize = ResourceUtils.pxFromDp(iconSize, dm);
- iconTextSize = interpolatedDisplayOption.iconTextSize;
- fillResIconDpi = getLauncherIconDensity(iconBitmapSize);
-
- // If the partner customization apk contains any grid overrides, apply them
- // Supported overrides: numRows, numColumns, iconSize
- applyPartnerDeviceProfileOverrides(context, dm);
-
- Point realSize = new Point();
- display.getRealSize(realSize);
- // The real size never changes. smallSide and largeSide will remain the
- // same in any orientation.
- int smallSide = Math.min(realSize.x, realSize.y);
- int largeSide = Math.max(realSize.x, realSize.y);
-
- landscapeProfile = new DeviceProfile(context, this, smallestSize, largestSize,
- largeSide, smallSide, true /* isLandscape */, false /* isMultiWindowMode */);
- portraitProfile = new DeviceProfile(context, this, smallestSize, largestSize,
- smallSide, largeSide, false /* isLandscape */, false /* isMultiWindowMode */);
-
// We need to ensure that there is enough extra space in the wallpaper
// for the intended parallax effects
if (context.getResources().getConfiguration().smallestScreenWidthDp >= 720) {
@@ -246,6 +279,33 @@ public class InvariantDeviceProfile {
return closestProfile.name;
}
+ private void initGridOption(Context context, ArrayList<DisplayOption> options,
+ DisplayOption displayOption, DisplayMetrics metrics) {
+ GridOption closestProfile = options.get(0).grid;
+ numRows = closestProfile.numRows;
+ numColumns = closestProfile.numColumns;
+ numHotseatIcons = closestProfile.numHotseatIcons;
+ defaultLayoutId = closestProfile.defaultLayoutId;
+ demoModeLayoutId = closestProfile.demoModeLayoutId;
+ numFolderRows = closestProfile.numFolderRows;
+ numFolderColumns = closestProfile.numFolderColumns;
+ numAllAppsColumns = numColumns;
+
+ mExtraAttrs = closestProfile.extraAttrs;
+
+ iconSize = displayOption.iconSize;
+ iconShapePath = getIconShapePath(context);
+ landscapeIconSize = displayOption.landscapeIconSize;
+ iconBitmapSize = ResourceUtils.pxFromDp(iconSize, metrics);
+ iconTextSize = displayOption.iconTextSize;
+ fillResIconDpi = getLauncherIconDensity(iconBitmapSize);
+
+ // If the partner customization apk contains any grid overrides, apply them
+ // Supported overrides: numRows, numColumns, iconSize
+ applyPartnerDeviceProfileOverrides(context, metrics);
+ }
+
+
@Nullable
public TypedValue getAttrValue(int attr) {
return mExtraAttrs == null ? null : mExtraAttrs.get(attr);
@@ -280,7 +340,7 @@ public class InvariantDeviceProfile {
public void setCurrentGrid(Context context, String gridName) {
Context appContext = context.getApplicationContext();
Utilities.getPrefs(appContext).edit().putString(KEY_IDP_GRID_NAME, gridName).apply();
- new MainThreadExecutor().execute(() -> onConfigChanged(appContext));
+ MAIN_EXECUTOR.execute(() -> onConfigChanged(appContext));
}
private void onConfigChanged(Context context) {
@@ -288,9 +348,10 @@ public class InvariantDeviceProfile {
InvariantDeviceProfile oldProfile = new InvariantDeviceProfile(this);
// Re-init grid
- // TODO(b/131867841): We pass in null here so that we can calculate the closest profile
- // without the bias of the grid name.
- initGrid(context, null);
+ String gridName = Utilities.getPrefs(context).getBoolean(GRID_OPTIONS_PREFERENCE_KEY, false)
+ ? Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null)
+ : null;
+ initGrid(context, gridName);
int changeFlags = 0;
if (numRows != oldProfile.numRows ||
@@ -322,7 +383,13 @@ public class InvariantDeviceProfile {
}
}
- static ArrayList<DisplayOption> getPredefinedDeviceProfiles(Context context, String gridName) {
+ /**
+ * @param gridName The current grid name.
+ * @param filteredOptionsOut List filled with all the filtered options based on gridName.
+ * @param allOptionsOut List filled with all the options that can be the default option.
+ */
+ static void getPredefinedDeviceProfiles(Context context, String gridName,
+ ArrayList<DisplayOption> filteredOptionsOut, ArrayList<DisplayOption> allOptionsOut) {
ArrayList<DisplayOption> profiles = new ArrayList<>();
try (XmlResourceParser parser = context.getResources().getXml(R.xml.device_profiles)) {
final int depth = parser.getDepth();
@@ -349,26 +416,19 @@ public class InvariantDeviceProfile {
throw new RuntimeException(e);
}
- ArrayList<DisplayOption> filteredProfiles = new ArrayList<>();
if (!TextUtils.isEmpty(gridName)) {
for (DisplayOption option : profiles) {
if (gridName.equals(option.grid.name)) {
- filteredProfiles.add(option);
+ filteredOptionsOut.add(option);
}
}
}
- if (filteredProfiles.isEmpty()) {
- // No grid found, use the default options
- for (DisplayOption option : profiles) {
- if (option.canBeDefault) {
- filteredProfiles.add(option);
- }
+
+ for (DisplayOption option : profiles) {
+ if (option.canBeDefault) {
+ allOptionsOut.add(option);
}
}
- if (filteredProfiles.isEmpty()) {
- throw new RuntimeException("No display option with canBeDefault=true");
- }
- return filteredProfiles;
}
private int getLauncherIconDensity(int requiredSize) {
@@ -514,6 +574,7 @@ public class InvariantDeviceProfile {
R.styleable.GridDisplayOption_numFolderRows, numRows);
numFolderColumns = a.getInt(
R.styleable.GridDisplayOption_numFolderColumns, numColumns);
+
a.recycle();
extraAttrs = Themes.createValueMap(context, attrs,
@@ -530,8 +591,8 @@ public class InvariantDeviceProfile {
private final boolean canBeDefault;
private float iconSize;
- private float landscapeIconSize;
private float iconTextSize;
+ private float landscapeIconSize;
DisplayOption(GridOption grid, Context context, AttributeSet attrs) {
this.grid = grid;
@@ -549,6 +610,7 @@ public class InvariantDeviceProfile {
landscapeIconSize = a.getFloat(R.styleable.ProfileDisplayOption_landscapeIconSize,
iconSize);
iconTextSize = a.getFloat(R.styleable.ProfileDisplayOption_iconTextSize, 0);
+
a.recycle();
}