Merge "Don't show the Tasbar Pinning edu for 3 button nav users" into main
diff --git a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
index b7e1092..2d4894c 100644
--- a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java
@@ -49,7 +49,7 @@
"persist.wm.debug.desktop_stashing", false);
private final Launcher mLauncher;
- private boolean mFreeformTasksVisible;
+ private int mVisibleFreeformTasksCount;
private boolean mInOverviewState;
private boolean mBackgroundStateEnabled;
private boolean mGestureInProgress;
@@ -68,13 +68,13 @@
public void registerSystemUiListener() {
mDesktopTaskListener = new IDesktopTaskListener.Stub() {
@Override
- public void onVisibilityChanged(int displayId, boolean visible) {
+ public void onTasksVisibilityChanged(int displayId, int visibleTasksCount) {
MAIN_EXECUTOR.execute(() -> {
if (displayId == mLauncher.getDisplayId()) {
if (DEBUG) {
- Log.d(TAG, "desktop visibility changed value=" + visible);
+ Log.d(TAG, "desktop visible tasks count changed=" + visibleTasksCount);
}
- setFreeformTasksVisible(visible);
+ setVisibleFreeformTasksCount(visibleTasksCount);
}
});
}
@@ -112,39 +112,53 @@
* Whether freeform windows are visible in desktop mode.
*/
public boolean areFreeformTasksVisible() {
+ boolean freeformTasksVisible = mVisibleFreeformTasksCount > 0;
if (DEBUG) {
- Log.d(TAG, "areFreeformTasksVisible: freeformVisible=" + mFreeformTasksVisible
+ Log.d(TAG, "areFreeformTasksVisible: freeformVisible=" + freeformTasksVisible
+ " overview=" + mInOverviewState);
}
- return mFreeformTasksVisible && !mInOverviewState;
+ return freeformTasksVisible && !mInOverviewState;
}
/**
- * Sets whether freeform windows are visible and updates launcher visibility based on that.
+ * Number of visible freeform windows in desktop mode.
*/
- public void setFreeformTasksVisible(boolean freeformTasksVisible) {
+ public int getVisibleFreeformTasksCount() {
+ return mVisibleFreeformTasksCount;
+ }
+
+ /**
+ * Sets the number of freeform windows that are visible and updates launcher visibility based on
+ * it.
+ */
+ public void setVisibleFreeformTasksCount(int visibleTasksCount) {
if (DEBUG) {
- Log.d(TAG, "setFreeformTasksVisible: visible=" + freeformTasksVisible
- + " currentValue=" + mFreeformTasksVisible);
+ Log.d(TAG, "setVisibleFreeformTasksCount: visibleTasksCount=" + visibleTasksCount
+ + " currentValue=" + mVisibleFreeformTasksCount);
}
if (!isDesktopModeSupported()) {
return;
}
- if (freeformTasksVisible != mFreeformTasksVisible) {
- mFreeformTasksVisible = freeformTasksVisible;
- if (mFreeformTasksVisible) {
- setLauncherViewsVisibility(View.INVISIBLE);
- if (!mInOverviewState) {
- // When freeform is visible & we're not in overview, we want launcher to appear
- // paused, this ensures that taskbar displays.
- markLauncherPaused();
+ if (visibleTasksCount != mVisibleFreeformTasksCount) {
+ final boolean wasVisible = mVisibleFreeformTasksCount > 0;
+ final boolean isVisible = visibleTasksCount > 0;
+ mVisibleFreeformTasksCount = visibleTasksCount;
+
+ if (wasVisible != isVisible) {
+ if (mVisibleFreeformTasksCount > 0) {
+ setLauncherViewsVisibility(View.INVISIBLE);
+ if (!mInOverviewState) {
+ // When freeform is visible & we're not in overview, we want launcher to
+ // appear paused, this ensures that taskbar displays.
+ markLauncherPaused();
+ }
+ } else {
+ setLauncherViewsVisibility(View.VISIBLE);
+ // If freeform isn't visible ensure that launcher appears resumed to behave
+ // normally.
+ markLauncherResumed();
}
- } else {
- setLauncherViewsVisibility(View.VISIBLE);
- // If freeform isn't visible ensure that launcher appears resumed to behave
- // normally.
- markLauncherResumed();
}
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
index 3fb7247..5819bb3 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java
@@ -46,6 +46,8 @@
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Path;
+import android.graphics.Point;
+import android.graphics.Rect;
import android.graphics.drawable.AdaptiveIconDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
@@ -66,6 +68,7 @@
import com.android.launcher3.icons.BubbleIconFactory;
import com.android.launcher3.shortcuts.ShortcutRequest;
import com.android.launcher3.taskbar.TaskbarControllers;
+import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.Executors.SimpleThreadFactory;
import com.android.quickstep.SystemUiProxy;
import com.android.wm.shell.bubbles.IBubblesListener;
@@ -408,8 +411,7 @@
info.getFlags() | Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION);
mSelectedBubble.getView().updateDotVisibility(true /* animate */);
}
- mSystemUiProxy.showBubble(getSelectedBubbleKey(),
- getBubbleBarOffsetX(), getBubbleBarOffsetY());
+ mSystemUiProxy.showBubble(getSelectedBubbleKey(), getExpandedBubbleBarDisplayBounds());
} else {
Log.w(TAG, "Trying to show the selected bubble but it's null");
}
@@ -577,12 +579,27 @@
return mIconFactory.createBadgedIconBitmap(drawable).icon;
}
- private int getBubbleBarOffsetY() {
+ /**
+ * Get bounds of the bubble bar as if it would be expanded.
+ * Calculates the bounds instead of retrieving current view location as the view may be
+ * animating.
+ */
+ private Rect getExpandedBubbleBarDisplayBounds() {
+ Point displaySize = DisplayController.INSTANCE.get(mContext).getInfo().currentSize;
+ Rect currentBarBounds = mBarView.getBubbleBarBounds();
+ Rect location = new Rect();
+ // currentBarBounds is only useful for distance from left or right edge.
+ // It contains the current bounds, calculate the expanded bounds.
+ if (mBarView.isOnLeft()) {
+ location.left = currentBarBounds.left;
+ location.right = (int) (currentBarBounds.left + mBarView.expandedWidth());
+ } else {
+ location.left = (int) (currentBarBounds.right - mBarView.expandedWidth());
+ location.right = currentBarBounds.right;
+ }
final int translation = (int) abs(mBubbleStashController.getBubbleBarTranslationY());
- return translation + mBarView.getHeight();
- }
-
- private int getBubbleBarOffsetX() {
- return mBarView.getWidth() + mBarView.getHorizontalMargin();
+ location.top = displaySize.y - mBarView.getHeight() - translation;
+ location.bottom = displaySize.y - translation;
+ return location;
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
index fbc7da1..8f693a6 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
@@ -205,7 +205,10 @@
mRelativePivotX = onLeft ? 0f : 1f;
}
- private boolean isOnLeft() {
+ /**
+ * @return <code>true</code> when bar is pinned to the left edge of the screen
+ */
+ public boolean isOnLeft() {
return getLayoutDirection() == LAYOUT_DIRECTION_RTL;
}
@@ -509,7 +512,12 @@
return mIsBarExpanded;
}
- private float expandedWidth() {
+ /**
+ * Get width of the bubble bar as if it would be expanded.
+ *
+ * @return width of the bubble bar in its expanded state, regardless of current width
+ */
+ public float expandedWidth() {
final int childCount = getChildCount();
final int horizontalPadding = getPaddingStart() + getPaddingEnd();
return childCount * (mIconSize + mIconSpacing) + horizontalPadding;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java b/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
index c1a85fa..369ff14 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/DeveloperOptionsUI.java
@@ -21,14 +21,14 @@
import static android.view.View.VISIBLE;
import static com.android.launcher3.LauncherPrefs.ALL_APPS_OVERVIEW_THRESHOLD;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_DELAY;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_TIMEOUT_MS;
import static com.android.launcher3.LauncherPrefs.PRIVATE_SPACE_APPS;
+import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_DELAY;
+import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_END_SCALE_PERCENT;
+import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_ITERATIONS;
+import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_SCALE_EXPONENT;
+import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_START_SCALE_PERCENT;
+import static com.android.launcher3.config.FeatureFlags.LPNH_SLOP_PERCENTAGE;
+import static com.android.launcher3.config.FeatureFlags.LPNH_TIMEOUT_MS;
import static com.android.launcher3.settings.SettingsActivity.EXTRA_FRAGMENT_HIGHLIGHT_KEY;
import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.PLUGIN_CHANGED;
import static com.android.launcher3.uioverrides.plugins.PluginManagerWrapper.pluginEnabledKey;
@@ -50,6 +50,7 @@
import android.text.Editable;
import android.text.TextWatcher;
import android.util.ArrayMap;
+import android.util.Log;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
@@ -88,11 +89,14 @@
private static final String ACTION_PLUGIN_SETTINGS =
"com.android.systemui.action.PLUGIN_SETTINGS";
+ private static final String TAG = "DeveloperOptionsUI";
private static final String PLUGIN_PERMISSION = "com.android.systemui.permission.PLUGIN";
private final PreferenceFragmentCompat mFragment;
private final PreferenceScreen mPreferenceScreen;
+ private final FlagTogglerPrefUi mFlagTogglerPrefUi;
+
private PreferenceCategory mPluginsCategory;
public DeveloperOptionsUI(PreferenceFragmentCompat fragment, PreferenceCategory flags) {
@@ -107,8 +111,9 @@
parent.addView(topBar, parent.indexOfChild(listView));
initSearch(topBar.findViewById(R.id.filter_box));
- new FlagTogglerPrefUi(mFragment.requireActivity(), topBar.findViewById(R.id.flag_apply_btn))
- .applyTo(flags);
+ mFlagTogglerPrefUi = new FlagTogglerPrefUi(mFragment.requireActivity(),
+ topBar.findViewById(R.id.flag_apply_btn));
+ mFlagTogglerPrefUi.applyTo(flags);
loadPluginPrefs();
maybeAddSandboxCategory();
@@ -350,23 +355,27 @@
private void addCustomLpnhCategory() {
PreferenceCategory category = newCategory("Long Press Nav Handle Config");
if (FeatureFlags.CUSTOM_LPNH_THRESHOLDS.get()) {
- category.addPreference(createSeekBarPreference("Slop multiplier (applied to edge slop, "
+ category.addPreference(createSeekBarPreference(
+ "Slop multiplier (applied to edge slop, "
+ "which is generally already 50% higher than touch slop)",
- 25, 200, 100, LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE));
- category.addPreference(createSeekBarPreference("Trigger milliseconds",
- 100, 500, 1, LONG_PRESS_NAV_HANDLE_TIMEOUT_MS));
+ 25, 200, 100, LPNH_SLOP_PERCENTAGE));
+ category.addPreference(createSeekBarPreference("LPNH timeout",
+ 100, 500, 1, LPNH_TIMEOUT_MS));
}
if (FeatureFlags.ENABLE_SEARCH_HAPTIC_HINT.get()) {
- category.addPreference(createSeekBarPreference("Haptic hint start scale",
- 0, 100, 100, LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT));
+ category.addPreference(
+ createSeekBarPreference("Haptic hint start scale",
+ 0, 100, 100, LPNH_HAPTIC_HINT_START_SCALE_PERCENT));
category.addPreference(createSeekBarPreference("Haptic hint end scale",
- 0, 100, 100, LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT));
- category.addPreference(createSeekBarPreference("Haptic hint scale exponent",
- 1, 5, 1, LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT));
- category.addPreference(createSeekBarPreference("Haptic hint iterations (12 ms each)",
- 0, 200, 1, LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS));
+ 0, 100, 100, LPNH_HAPTIC_HINT_END_SCALE_PERCENT));
+ category.addPreference(
+ createSeekBarPreference("Haptic hint scale exponent",
+ 1, 5, 1, LPNH_HAPTIC_HINT_SCALE_EXPONENT));
+ category.addPreference(
+ createSeekBarPreference("Haptic hint iterations (12 ms each)",
+ 0, 200, 1, LPNH_HAPTIC_HINT_ITERATIONS));
category.addPreference(createSeekBarPreference("Haptic hint delay (ms)",
- 0, 400, 1, LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_DELAY));
+ 0, 400, 1, LPNH_HAPTIC_HINT_DELAY));
}
}
@@ -376,6 +385,29 @@
"Number of Apps to put in private region", 0, 100, 1, PRIVATE_SPACE_APPS));
}
+ private SeekBarPreference createSeekBarPreference(String title, int min,
+ int max, int scale, FeatureFlags.IntFlag flag) {
+ if (!(flag instanceof IntDebugFlag)) {
+ Log.e(TAG, "Cannot create seekbar preference with IntFlag. Use a launcher preference "
+ + "flag or pref-backed IntDebugFlag instead");
+ return null;
+ }
+ IntDebugFlag debugflag = (IntDebugFlag) flag;
+ if (debugflag.launcherPrefFlag == null) {
+ Log.e(TAG, "Cannot create seekbar preference with IntDebugFlag. Use a launcher "
+ + "preference flag or pref-backed IntDebugFlag instead");
+ return null;
+ }
+ SeekBarPreference seekBarPref = createSeekBarPreference(title, min, max, scale,
+ debugflag.launcherPrefFlag);
+ int value = flag.get();
+ seekBarPref.setValue(value);
+ // For some reason the initial value is not triggering the summary update, so call manually.
+ seekBarPref.setSummary(String.valueOf(scale == 1 ? value
+ : value / (float) scale));
+ return seekBarPref;
+ }
+
/**
* Create a preference with text and a seek bar. Should be added to a PreferenceCategory.
*
@@ -401,6 +433,7 @@
LauncherPrefs.get(getContext()).put(launcherPref, newValue);
preference.setSummary(String.valueOf(scale == 1 ? newValue
: (int) newValue / (float) scale));
+ mFlagTogglerPrefUi.updateMenu();
return true;
});
int value = LauncherPrefs.get(getContext()).get(launcherPref);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java
index ec0566a..4326c67 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagTogglerPrefUi.java
@@ -34,6 +34,7 @@
import androidx.preference.PreferenceViewHolder;
import androidx.preference.SwitchPreference;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter;
@@ -144,7 +145,7 @@
switchPreference.setSummary(Html.fromHtml(summary + flag.description));
}
- private void updateMenu() {
+ public void updateMenu() {
mFlagsApplyButton.setVisibility(anyChanged() ? View.VISIBLE : View.INVISIBLE);
}
@@ -161,12 +162,22 @@
return mDataStore.getBoolean(flag.key, defaultValue);
}
+ private int getIntFlagStateFromSharedPrefs(IntDebugFlag flag) {
+ LauncherPrefs prefs = LauncherPrefs.get(mContext);
+ return flag.launcherPrefFlag == null ? flag.get() : prefs.get(flag.launcherPrefFlag);
+ }
+
private boolean anyChanged() {
for (DebugFlag flag : FlagsFactory.getDebugFlags()) {
if (getFlagStateFromSharedPrefs(flag) != flag.get()) {
return true;
}
}
+ for (IntDebugFlag flag : FlagsFactory.getIntDebugFlags()) {
+ if (getIntFlagStateFromSharedPrefs(flag) != flag.get()) {
+ return true;
+ }
+ }
return false;
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java
index 48d313e..686ed64 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/FlagsFactory.java
@@ -23,6 +23,8 @@
import static com.android.launcher3.config.FeatureFlags.FlagState.ENABLED;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static java.util.Collections.unmodifiableList;
+
import android.content.Context;
import android.content.SharedPreferences;
import android.provider.DeviceConfig;
@@ -30,7 +32,10 @@
import android.util.Log;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import com.android.launcher3.ConstantItem;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.config.FeatureFlags.BooleanFlag;
import com.android.launcher3.config.FeatureFlags.FlagState;
import com.android.launcher3.config.FeatureFlags.IntFlag;
@@ -57,7 +62,7 @@
public static final String NAMESPACE_LAUNCHER = "launcher";
private static final List<DebugFlag> sDebugFlags = new ArrayList<>();
- private static final List<IntFlag> sIntFlags = new ArrayList<>();
+ private static final List<IntDebugFlag> sIntDebugFlags = new ArrayList<>();
private static SharedPreferences sSharedPreferences;
static final BooleanFlag TEAMFOOD_FLAG = getReleaseFlag(
@@ -132,11 +137,32 @@
*/
public static IntFlag getIntFlag(
int bugId, String key, int defaultValueInCode, String description) {
+ return getIntFlag(bugId, key, defaultValueInCode, description, null);
+ }
+
+ /**
+ * Creates a new integer flag.
+ *
+ * @param launcherPrefFlag Set launcherPrefFlag to non-null if you want
+ * to modify the int flag in Launcher Developer Options and IntDebugFlag
+ * will be backed up by LauncherPrefs. Modified int value will be saved
+ * in LauncherPrefs.
+ */
+ public static IntFlag getIntFlag(
+ int bugId, String key, int defaultValueInCode, String description,
+ @Nullable ConstantItem<Integer> launcherPrefFlag) {
INSTANCE.mKeySet.add(key);
int defaultValue = DeviceConfig.getInt(NAMESPACE_LAUNCHER, key, defaultValueInCode);
if (IS_DEBUG_DEVICE) {
- IntDeviceFlag flag = new IntDeviceFlag(key, defaultValue, defaultValueInCode);
- sIntFlags.add(flag);
+ int currentValue;
+ if (launcherPrefFlag == null) {
+ currentValue = defaultValue;
+ } else {
+ currentValue = LauncherPrefs.get(currentApplication()).get(launcherPrefFlag);
+ }
+ IntDebugFlag flag = new IntDebugFlag(key, currentValue, defaultValueInCode,
+ launcherPrefFlag);
+ sIntDebugFlags.add(flag);
return flag;
} else {
return new IntFlag(defaultValue);
@@ -152,6 +178,15 @@
}
}
+ static List<IntDebugFlag> getIntDebugFlags() {
+ if (!IS_DEBUG_DEVICE) {
+ return unmodifiableList(Collections.emptyList());
+ }
+ synchronized (sIntDebugFlags) {
+ return unmodifiableList(sIntDebugFlags);
+ }
+ }
+
/** Returns the SharedPreferences instance backing Debug FeatureFlags. */
@NonNull
static SharedPreferences getSharedPreferences() {
@@ -180,8 +215,8 @@
}
}
pw.println(" IntFlags:");
- synchronized (sIntFlags) {
- for (IntFlag flag : sIntFlags) {
+ synchronized (sIntDebugFlags) {
+ for (IntFlag flag : sIntDebugFlags) {
pw.println(" " + flag);
}
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/flags/IntDeviceFlag.java b/quickstep/src/com/android/launcher3/uioverrides/flags/IntDebugFlag.java
similarity index 73%
rename from quickstep/src/com/android/launcher3/uioverrides/flags/IntDeviceFlag.java
rename to quickstep/src/com/android/launcher3/uioverrides/flags/IntDebugFlag.java
index 4f3b0ae..1350aa8 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/flags/IntDeviceFlag.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/flags/IntDebugFlag.java
@@ -15,16 +15,23 @@
*/
package com.android.launcher3.uioverrides.flags;
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.ConstantItem;
import com.android.launcher3.config.FeatureFlags.IntFlag;
-public class IntDeviceFlag extends IntFlag {
+public class IntDebugFlag extends IntFlag {
public final String key;
private final int mDefaultValueInCode;
+ @Nullable
+ public final ConstantItem<Integer> launcherPrefFlag;
- public IntDeviceFlag(String key, int currentValue, int defaultValueInCode) {
+ public IntDebugFlag(String key, int currentValue, int defaultValueInCode,
+ @Nullable ConstantItem<Integer> launcherPrefFlag) {
super(currentValue);
this.key = key;
mDefaultValueInCode = defaultValueInCode;
+ this.launcherPrefFlag = launcherPrefFlag;
}
@Override
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index 179612b..d617828 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -19,7 +19,6 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.view.Display.DEFAULT_DISPLAY;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE;
import static com.android.launcher3.util.DisplayController.CHANGE_ALL;
import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE;
import static com.android.launcher3.util.DisplayController.CHANGE_ROTATION;
@@ -66,7 +65,6 @@
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
-import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
@@ -608,7 +606,7 @@
if (FeatureFlags.CUSTOM_LPNH_THRESHOLDS.get()) {
float customSlopMultiplier =
- LauncherPrefs.get(mContext).get(LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE) / 100f;
+ FeatureFlags.LPNH_SLOP_PERCENTAGE.get() / 100f;
return customSlopMultiplier * slopMultiplier * touchSlop;
} else {
return slopMultiplier * touchSlop;
diff --git a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
index 2e70703..6a9caf7 100644
--- a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
+++ b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java
@@ -29,6 +29,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.launcher3.statehandlers.DesktopVisibilityController;
import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.util.TaskViewSimulator;
@@ -68,13 +69,16 @@
*/
public RemoteTargetGluer(Context context, BaseActivityInterface sizingStrategy) {
if (isDesktopModeSupported()) {
- // TODO(279931899): binder call, only for prototyping. Creating the gluer should be
- // postponed so we can create it when we have the remote animation targets ready.
- int desktopTasks = SystemUiProxy.INSTANCE.get(context).getVisibleDesktopTaskCount(
- context.getDisplayId());
- if (desktopTasks > 0) {
- init(context, sizingStrategy, desktopTasks, true /* forDesktop */);
- return;
+ DesktopVisibilityController desktopVisibilityController =
+ LauncherActivityInterface.INSTANCE.getDesktopVisibilityController();
+ if (desktopVisibilityController != null) {
+ int visibleTasksCount = desktopVisibilityController.getVisibleFreeformTasksCount();
+ if (visibleTasksCount > 0) {
+ // Allocate +1 to account for a new task added to the desktop mode
+ int numHandles = visibleTasksCount + 1;
+ init(context, sizingStrategy, numHandles, true /* forDesktop */);
+ return;
+ }
}
}
@@ -135,18 +139,7 @@
* the left/top task, index 1 right/bottom.
*/
public RemoteTargetHandle[] assignTargetsForSplitScreen(RemoteAnimationTargets targets) {
- // Resize the mRemoteTargetHandles array since we started assuming split screen, but
- // targets.apps is the ultimate source of truth here
- long appCount = Arrays.stream(targets.apps)
- .filter(app -> app.mode == targets.targetMode)
- .count();
- Log.d(TAG, "appCount: " + appCount + " handleLength: " + mRemoteTargetHandles.length);
- if (appCount < mRemoteTargetHandles.length) {
- Log.d(TAG, "resizing handles");
- RemoteTargetHandle[] newHandles = new RemoteTargetHandle[(int) appCount];
- System.arraycopy(mRemoteTargetHandles, 0/*src*/, newHandles, 0/*dst*/, (int) appCount);
- mRemoteTargetHandles = newHandles;
- }
+ resizeRemoteTargetHandles(targets);
// If we are in a true split screen case (2 apps running on screen), either:
// a) mSplitBounds was already set (from the clicked GroupedTaskView)
@@ -228,6 +221,8 @@
* transform params per app in {@code targets.apps} list.
*/
public RemoteTargetHandle[] assignTargetsForDesktop(RemoteAnimationTargets targets) {
+ resizeRemoteTargetHandles(targets);
+
for (int i = 0; i < mRemoteTargetHandles.length; i++) {
RemoteAnimationTarget primaryTaskTarget = targets.apps[i];
mRemoteTargetHandles[i].mTransformParams.setTargetSet(
@@ -237,6 +232,23 @@
return mRemoteTargetHandles;
}
+ /**
+ * Resize the `mRemoteTargetHandles` array since we assumed initial size, but
+ * `targets.apps` is the ultimate source of truth here
+ */
+ private void resizeRemoteTargetHandles(RemoteAnimationTargets targets) {
+ long appCount = Arrays.stream(targets.apps)
+ .filter(app -> app.mode == targets.targetMode)
+ .count();
+ Log.d(TAG, "appCount: " + appCount + " handleLength: " + mRemoteTargetHandles.length);
+ if (appCount < mRemoteTargetHandles.length) {
+ Log.d(TAG, "resizing handles");
+ RemoteTargetHandle[] newHandles = new RemoteTargetHandle[(int) appCount];
+ System.arraycopy(mRemoteTargetHandles, 0/*src*/, newHandles, 0/*dst*/, (int) appCount);
+ mRemoteTargetHandles = newHandles;
+ }
+ }
+
private Rect getStartBounds(RemoteAnimationTarget target) {
return target.startBounds == null ? target.screenSpaceBounds : target.startBounds;
}
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 56a4024..52f9d8d 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -731,15 +731,12 @@
/**
* Tells SysUI to show the bubble with the provided key.
* @param key the key of the bubble to show.
- * @param bubbleBarOffsetX the offset of the bubble bar from the edge of the screen on the X
- * axis.
- * @param bubbleBarOffsetY the offset of the bubble bar from the edge of the screen on the Y
- * axis.
+ * @param bubbleBarBounds bounds of the bubble bar in display coordinates
*/
- public void showBubble(String key, int bubbleBarOffsetX, int bubbleBarOffsetY) {
+ public void showBubble(String key, Rect bubbleBarBounds) {
if (mBubbles != null) {
try {
- mBubbles.showBubble(key, bubbleBarOffsetX, bubbleBarOffsetY);
+ mBubbles.showBubble(key, bubbleBarBounds);
} catch (RemoteException e) {
Log.w(TAG, "Failed call showBubble");
}
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
index 4c0b550..cf8750f 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java
@@ -15,7 +15,6 @@
*/
package com.android.quickstep.inputconsumers;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_TIMEOUT_MS;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_DEEP_PRESS_NAVBAR;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_DEEP_PRESS_STASHED_TASKBAR;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_LONG_PRESS_NAVBAR;
@@ -26,7 +25,6 @@
import android.view.MotionEvent;
import android.view.ViewConfiguration;
-import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.util.DisplayController;
@@ -63,7 +61,7 @@
mScreenWidth = DisplayController.INSTANCE.get(context).getInfo().currentSize.x;
mDeepPressEnabled = FeatureFlags.ENABLE_LPNH_DEEP_PRESS.get();
if (FeatureFlags.CUSTOM_LPNH_THRESHOLDS.get()) {
- mLongPressTimeout = LauncherPrefs.get(context).get(LONG_PRESS_NAV_HANDLE_TIMEOUT_MS);
+ mLongPressTimeout = FeatureFlags.LPNH_TIMEOUT_MS.get();
} else {
mLongPressTimeout = ViewConfiguration.getLongPressTimeout();
}
diff --git a/res/layout/widgets_two_pane_sheet_paged_view.xml b/res/layout/widgets_two_pane_sheet_paged_view.xml
index 442957a..4a7749b 100644
--- a/res/layout/widgets_two_pane_sheet_paged_view.xml
+++ b/res/layout/widgets_two_pane_sheet_paged_view.xml
@@ -66,7 +66,7 @@
<include layout="@layout/widgets_search_bar" />
</FrameLayout>
- <LinearLayout
+ <FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/suggestions_header"
@@ -74,7 +74,7 @@
android:orientation="horizontal"
android:background="?attr/widgetPickerPrimarySurfaceColor"
launcher:layout_sticky="true">
- </LinearLayout>
+ </FrameLayout>
<com.android.launcher3.workprofile.PersonalWorkSlidingTabStrip
android:id="@+id/tabs"
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index ba65bea..baa1ee3 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -19,7 +19,6 @@
import static android.text.Layout.Alignment.ALIGN_NORMAL;
import static com.android.launcher3.Flags.enableCursorHoverStates;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_ICON_LABEL_AUTO_SCALING;
import static com.android.launcher3.graphics.PreloadIconDrawable.newPendingIcon;
import static com.android.launcher3.icons.BitmapInfo.FLAG_NO_BADGE;
import static com.android.launcher3.icons.BitmapInfo.FLAG_SKIP_USER_BADGE;
@@ -556,9 +555,6 @@
}
private void checkForEllipsis() {
- if (!ENABLE_ICON_LABEL_AUTO_SCALING.get()) {
- return;
- }
float width = getWidth() - getCompoundPaddingLeft() - getCompoundPaddingRight();
if (width <= 0) {
return;
@@ -830,7 +826,6 @@
float currentWordWidth, runningWidth = 0;
CharSequence currentWord;
StringBuilder newString = new StringBuilder();
- // TODO: Remove when ENABLE_ICON_LABEL_AUTO_SCALING feature flag is being cleaned up.
paint.setLetterSpacing(MIN_LETTER_SPACING);
int stringPtr = 0;
for (int i = 0; i < breakPoints.size()+1; i++) {
diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java
index 1b4edf8..941a793 100644
--- a/src/com/android/launcher3/CellLayout.java
+++ b/src/com/android/launcher3/CellLayout.java
@@ -16,7 +16,6 @@
package com.android.launcher3;
-import static com.android.launcher3.LauncherState.EDIT_MODE;
import static com.android.launcher3.dragndrop.DraggableView.DRAGGABLE_ICON;
import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR;
import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_REORDER_PREVIEW_OFFSET;
@@ -214,6 +213,7 @@
// Related to accessible drag and drop
DragAndDropAccessibilityDelegate mTouchHelper;
+ CellLayoutContainer mCellLayoutContainer;
public static final FloatProperty<CellLayout> SPRING_LOADED_PROGRESS =
new FloatProperty<CellLayout>("spring_loaded_progress") {
@@ -228,8 +228,9 @@
}
};
- public CellLayout(Context context) {
- this(context, null);
+ public CellLayout(Context context, CellLayoutContainer container) {
+ this(context, (AttributeSet) null);
+ this.mCellLayoutContainer = container;
}
public CellLayout(Context context, AttributeSet attrs) {
@@ -316,6 +317,14 @@
addView(mShortcutsAndWidgets);
}
+ public CellLayoutContainer getCellLayoutContainer() {
+ return mCellLayoutContainer;
+ }
+
+ public void setCellLayoutContainer(CellLayoutContainer cellLayoutContainer) {
+ mCellLayoutContainer = cellLayoutContainer;
+ }
+
/**
* Sets or clears a delegate used for accessible drag and drop
*/
@@ -573,9 +582,7 @@
}
protected void updateBgAlpha() {
- if (!getWorkspace().mLauncher.isInState(EDIT_MODE)) {
- mBackground.setAlpha((int) (mSpringLoadedProgress * 255));
- }
+ mBackground.setAlpha((int) (mSpringLoadedProgress * 255));
}
/**
@@ -1187,7 +1194,7 @@
// Apply local extracted color if the DragView is an AppWidgetHostViewDrawable.
View view = dragObject.dragView.getContentView();
if (view instanceof LauncherAppWidgetHostView) {
- int screenId = getWorkspace().getIdForScreen(this);
+ int screenId = mCellLayoutContainer.getCellLayoutId(this);
cellToRect(targetCell[0], targetCell[1], spanX, spanY, mTempRect);
((LauncherAppWidgetHostView) view).handleDrag(mTempRect, this, screenId);
@@ -1200,25 +1207,19 @@
return getContext().getString(R.string.move_to_hotseat_position,
Math.max(cellX, cellY) + 1);
} else {
- Workspace<?> workspace = getWorkspace();
int row = cellY + 1;
- int col = workspace.mIsRtl ? mCountX - cellX : cellX + 1;
- int panelCount = workspace.getPanelCount();
- int screenId = workspace.getIdForScreen(this);
- int pageIndex = workspace.getPageIndexForScreenId(screenId);
+ int col = Utilities.isRtl(getResources()) ? mCountX - cellX : cellX + 1;
+ int panelCount = mCellLayoutContainer.getPanelCount();
+ int pageIndex = mCellLayoutContainer.getCellLayoutIndex(this);
if (panelCount > 1) {
// Increment the column if the target is on the right side of a two panel home
col += (pageIndex % panelCount) * mCountX;
}
return getContext().getString(R.string.move_to_empty_cell_description, row, col,
- workspace.getPageDescription(pageIndex));
+ mCellLayoutContainer.getPageDescription(pageIndex));
}
}
- private Workspace<?> getWorkspace() {
- return Launcher.cast(mActivity).getWorkspace();
- }
-
public void clearDragOutlines() {
final int oldIndex = mDragOutlineCurrent;
mDragOutlineAnims[oldIndex].animateOut();
@@ -1452,7 +1453,7 @@
private void commitTempPlacement(View dragView) {
mTmpOccupied.copyTo(mOccupied);
- int screenId = getWorkspace().getIdForScreen(this);
+ int screenId = mCellLayoutContainer.getCellLayoutId(this);
int container = Favorites.CONTAINER_DESKTOP;
if (mContainerType == HOTSEAT) {
diff --git a/src/com/android/launcher3/CellLayoutContainer.java b/src/com/android/launcher3/CellLayoutContainer.java
new file mode 100644
index 0000000..9ee0f70
--- /dev/null
+++ b/src/com/android/launcher3/CellLayoutContainer.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 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;
+
+/**
+ * This interface should be implemented for any container/view that has a CellLayout as a children.
+ */
+public interface CellLayoutContainer {
+
+ /**
+ * Get the CellLayoutId for the given cellLayout.
+ */
+ int getCellLayoutId(CellLayout cellLayout);
+
+ /**
+ * Get the index of the given CellLayout out of all the other CellLayouts.
+ */
+ int getCellLayoutIndex(CellLayout cellLayout);
+
+ /**
+ * The total number of CellLayouts in the container.
+ */
+ int getPanelCount();
+
+ /**
+ * Used for accessibility, it returns the string that the assistant is going to say when
+ * referring to the given CellLayout.
+ */
+ String getPageDescription(int pageIndex);
+}
diff --git a/src/com/android/launcher3/Hotseat.java b/src/com/android/launcher3/Hotseat.java
index 3b12b86..37737d8 100644
--- a/src/com/android/launcher3/Hotseat.java
+++ b/src/com/android/launcher3/Hotseat.java
@@ -207,6 +207,7 @@
public void setWorkspace(Workspace<?> w) {
mWorkspace = w;
+ setCellLayoutContainer(w);
}
@Override
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 44a1bf0..496cb4e 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -99,7 +99,6 @@
import static com.android.launcher3.util.SettingsCache.TOUCHPAD_NATURAL_SCROLLING;
import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.annotation.TargetApi;
@@ -132,6 +131,7 @@
import android.util.AttributeSet;
import android.util.FloatProperty;
import android.util.Log;
+import android.util.Pair;
import android.util.SparseArray;
import android.view.KeyEvent;
import android.view.KeyboardShortcutGroup;
@@ -264,7 +264,6 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
@@ -522,7 +521,7 @@
mAppWidgetHolder.startListening();
mAppWidgetHolder.addProviderChangeListener(() -> refreshAndBindWidgetsForPackageUser(null));
mItemInflater = new ItemInflater<>(this, mAppWidgetHolder, getItemOnClickListener(),
- mFocusHandler, new CellLayout(mWorkspace.getContext()));
+ mFocusHandler, new CellLayout(mWorkspace.getContext(), mWorkspace));
mPopupDataProvider = new PopupDataProvider(this::updateNotificationDots);
@@ -2125,30 +2124,23 @@
*/
@Override
public void bindItems(final List<ItemInfo> items, final boolean forceAnimateIcons) {
- bindItems(items, forceAnimateIcons, /* focusFirstItemForAccessibility= */ false);
+ bindItems(items.stream().map(i -> Pair.create(
+ i, getItemInflater().inflateItem(i, getModelWriter()))).toList(),
+ forceAnimateIcons ? new AnimatorSet() : null);
}
-
/**
- * Bind the items start-end from the list.
+ * Bind all the items in the map, ignoring any null views
*
- * Implementation of the method from LauncherModel.Callbacks.
- *
- * @param focusFirstItemForAccessibility true iff the first item to be added to the workspace
- * should be focused for accessibility.
+ * @param boundAnim if non-null, uses it to create and play the bounce animation for added views
*/
- public void bindItems(
- final List<ItemInfo> items,
- final boolean forceAnimateIcons,
- final boolean focusFirstItemForAccessibility) {
+ public void bindItems(List<Pair<ItemInfo, View>> shortcuts, @Nullable AnimatorSet boundAnim) {
// Get the list of added items and intersect them with the set of items here
- final Collection<Animator> bounceAnims = new ArrayList<>();
Workspace<?> workspace = mWorkspace;
int newItemsScreenId = -1;
- int end = items.size();
- View newView = null;
- for (int i = 0; i < end; i++) {
- final ItemInfo item = items.get(i);
+ int index = 0;
+ for (Pair<ItemInfo, View> e : shortcuts) {
+ final ItemInfo item = e.first;
// Remove colliding items.
CellPos presenterPos = getCellPosMapper().mapModelToPresenter(item);
@@ -2167,42 +2159,26 @@
}
}
- final View view = mItemInflater.inflateItem(item, getModelWriter());
+ final View view = e.second;
if (view == null) {
continue;
}
workspace.addInScreenFromBind(view, item);
- if (forceAnimateIcons) {
+ if (boundAnim != null) {
// Animate all the applications up now
view.setAlpha(0f);
view.setScaleX(0f);
view.setScaleY(0f);
- bounceAnims.add(createNewAppBounceAnimation(view, i));
+ boundAnim.play(createNewAppBounceAnimation(view, index++));
newItemsScreenId = presenterPos.screenId;
}
-
- if (newView == null) {
- newView = view;
- }
}
- View viewToFocus = newView;
// Animate to the correct page
- if (forceAnimateIcons && newItemsScreenId > -1) {
- AnimatorSet anim = new AnimatorSet();
- anim.playTogether(bounceAnims);
- if (focusFirstItemForAccessibility && viewToFocus != null) {
- anim.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- viewToFocus.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
- }
- });
- }
-
+ if (boundAnim != null && newItemsScreenId > -1) {
int currentScreenId = mWorkspace.getScreenIdForPageIndex(mWorkspace.getNextPage());
final int newScreenIndex = mWorkspace.getPageIndexForScreenId(newItemsScreenId);
- final Runnable startBounceAnimRunnable = anim::start;
+ final Runnable startBounceAnimRunnable = boundAnim::start;
if (canAnimatePageChange() && newItemsScreenId != currentScreenId) {
// We post the animation slightly delayed to prevent slowdowns
@@ -2215,8 +2191,6 @@
} else {
mWorkspace.postDelayed(startBounceAnimRunnable, NEW_APPS_ANIMATION_DELAY);
}
- } else if (focusFirstItemForAccessibility && viewToFocus != null) {
- viewToFocus.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
}
workspace.requestLayout();
}
diff --git a/src/com/android/launcher3/LauncherPrefs.kt b/src/com/android/launcher3/LauncherPrefs.kt
index 067d150..3b62ae1 100644
--- a/src/com/android/launcher3/LauncherPrefs.kt
+++ b/src/com/android/launcher3/LauncherPrefs.kt
@@ -20,17 +20,11 @@
import android.content.SharedPreferences
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import android.util.Log
+import android.view.ViewConfiguration
import androidx.annotation.VisibleForTesting
import com.android.launcher3.BuildConfig.WIDGET_ON_FIRST_SCREEN
import com.android.launcher3.LauncherFiles.DEVICE_PREFERENCES_KEY
import com.android.launcher3.LauncherFiles.SHARED_PREFERENCES_KEY
-import com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_DELAY
-import com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_END_SCALE_PERCENT
-import com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_ITERATIONS
-import com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_SCALE_EXPONENT
-import com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_START_SCALE_PERCENT
-import com.android.launcher3.config.FeatureFlags.LPNH_SLOP_PERCENTAGE
-import com.android.launcher3.config.FeatureFlags.LPNH_TIMEOUT_MS
import com.android.launcher3.model.DeviceGridState
import com.android.launcher3.pm.InstallSessionHelper
import com.android.launcher3.provider.RestoreDbTask
@@ -313,53 +307,45 @@
)
@JvmField
val LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE =
- nonRestorableItem(
- "pref_long_press_nav_handle_slop_percentage",
- LPNH_SLOP_PERCENTAGE.get(),
- EncryptionType.MOVE_TO_DEVICE_PROTECTED
- )
+ nonRestorableItem("LPNH_SLOP_PERCENTAGE", 100, EncryptionType.MOVE_TO_DEVICE_PROTECTED)
@JvmField
val LONG_PRESS_NAV_HANDLE_TIMEOUT_MS =
nonRestorableItem(
- "pref_long_press_nav_handle_timeout_ms",
- LPNH_TIMEOUT_MS.get(),
+ "LPNH_TIMEOUT_MS",
+ ViewConfiguration.getLongPressTimeout(),
EncryptionType.MOVE_TO_DEVICE_PROTECTED
)
@JvmField
val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT =
nonRestorableItem(
- "pref_long_press_nav_handle_haptic_hint_start_scale_percent",
- LPNH_HAPTIC_HINT_START_SCALE_PERCENT.get(),
+ "LPNH_HAPTIC_HINT_START_SCALE_PERCENT",
+ 0,
EncryptionType.MOVE_TO_DEVICE_PROTECTED
)
@JvmField
val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT =
nonRestorableItem(
- "pref_long_press_nav_handle_haptic_hint_end_scale_percent",
- LPNH_HAPTIC_HINT_END_SCALE_PERCENT.get(),
+ "LPNH_HAPTIC_HINT_END_SCALE_PERCENT",
+ 100,
EncryptionType.MOVE_TO_DEVICE_PROTECTED
)
@JvmField
val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT =
nonRestorableItem(
- "pref_long_press_nav_handle_haptic_hint_scale_exponent",
- LPNH_HAPTIC_HINT_SCALE_EXPONENT.get(),
+ "LPNH_HAPTIC_HINT_SCALE_EXPONENT",
+ 1,
EncryptionType.MOVE_TO_DEVICE_PROTECTED
)
@JvmField
val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS =
nonRestorableItem(
- "pref_long_press_nav_handle_haptic_hint_iterations",
- LPNH_HAPTIC_HINT_ITERATIONS.get(),
+ "LPNH_HAPTIC_HINT_ITERATIONS",
+ 50,
EncryptionType.MOVE_TO_DEVICE_PROTECTED
)
@JvmField
val LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_DELAY =
- nonRestorableItem(
- "pref_long_press_nav_handle_haptic_hint_delay",
- LPNH_HAPTIC_HINT_DELAY.get(),
- EncryptionType.MOVE_TO_DEVICE_PROTECTED
- )
+ nonRestorableItem("LPNH_HAPTIC_HINT_DELAY", 0, EncryptionType.MOVE_TO_DEVICE_PROTECTED)
@JvmField
val PRIVATE_SPACE_APPS =
nonRestorableItem("pref_private_space_apps", 0, EncryptionType.MOVE_TO_DEVICE_PROTECTED)
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 2eff8aa..984a9ae 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -143,7 +143,7 @@
* @param <T> Class that extends View and PageIndicator
*/
public class Workspace<T extends View & PageIndicator> extends PagedView<T>
- implements DropTarget, DragSource, View.OnTouchListener,
+ implements DropTarget, DragSource, View.OnTouchListener, CellLayoutContainer,
DragController.DragListener, Insettable, StateHandler<LauncherState>,
WorkspaceLayoutManager, LauncherBindableItemsContainer, LauncherOverlayCallbacks {
@@ -511,11 +511,6 @@
return !FOLDABLE_SINGLE_PAGE.get() && mLauncher.mDeviceProfile.isTwoPanels;
}
- @Override
- public int getPanelCount() {
- return isTwoPanelEnabled() ? 2 : super.getPanelCount();
- }
-
public void deferRemoveExtraEmptyScreen() {
mDeferRemoveExtraEmptyScreen = true;
}
@@ -683,6 +678,7 @@
newScreen = (CellLayout) LayoutInflater.from(getContext()).inflate(
R.layout.workspace_screen, this, false /* attachToRoot */);
}
+ newScreen.setCellLayoutContainer(this);
mWorkspaceScreens.put(screenId, newScreen);
mScreenOrder.add(insertIndex, screenId);
@@ -949,7 +945,8 @@
return mWorkspaceScreens.get(screenId);
}
- public int getIdForScreen(CellLayout layout) {
+ @Override
+ public int getCellLayoutId(CellLayout layout) {
int index = mWorkspaceScreens.indexOfValue(layout);
if (index != -1) {
return mWorkspaceScreens.keyAt(index);
@@ -961,6 +958,16 @@
return indexOfChild(mWorkspaceScreens.get(screenId));
}
+ @Override
+ public int getCellLayoutIndex(CellLayout cellLayout) {
+ return indexOfChild(mWorkspaceScreens.get(getCellLayoutId(cellLayout)));
+ }
+
+ @Override
+ public int getPanelCount() {
+ return isTwoPanelEnabled() ? 2 : super.getPanelCount();
+ }
+
public IntSet getCurrentPageScreenIds() {
return IntSet.wrap(getScreenIdForPageIndex(getCurrentPage()));
}
@@ -1001,7 +1008,7 @@
if (!isTwoPanelEnabled()) {
return null;
}
- int screenId = getIdForScreen(cellLayout);
+ int screenId = getCellLayoutId(cellLayout);
if (screenId == -1) {
return null;
}
@@ -1826,7 +1833,7 @@
}
}
- int screenId = getIdForScreen(dropTargetLayout);
+ int screenId = getCellLayoutId(dropTargetLayout);
if (Workspace.EXTRA_EMPTY_SCREEN_IDS.contains(screenId)) {
commitExtraEmptyScreens();
}
@@ -1909,7 +1916,7 @@
if (v == null || hasntMoved || !mCreateUserFolderOnDrop) return false;
mCreateUserFolderOnDrop = false;
- final int screenId = getIdForScreen(target);
+ final int screenId = getCellLayoutId(target);
boolean aboveShortcut = (v.getTag() instanceof WorkspaceItemInfo);
boolean willBecomeShortcut = (newView.getTag() instanceof WorkspaceItemInfo);
@@ -2010,7 +2017,7 @@
LauncherSettings.Favorites.CONTAINER_HOTSEAT :
LauncherSettings.Favorites.CONTAINER_DESKTOP;
int screenId = (mTargetCell[0] < 0) ?
- mDragInfo.screenId : getIdForScreen(dropTargetLayout);
+ mDragInfo.screenId : getCellLayoutId(dropTargetLayout);
int spanX = mDragInfo != null ? mDragInfo.spanX : 1;
int spanY = mDragInfo != null ? mDragInfo.spanY : 1;
// First we find the cell nearest to point at which the item is
@@ -2766,7 +2773,7 @@
final int container = mLauncher.isHotseatLayout(cellLayout)
? LauncherSettings.Favorites.CONTAINER_HOTSEAT
: LauncherSettings.Favorites.CONTAINER_DESKTOP;
- final int screenId = getIdForScreen(cellLayout);
+ final int screenId = getCellLayoutId(cellLayout);
if (!mLauncher.isHotseatLayout(cellLayout)
&& screenId != getScreenIdForPageIndex(mCurrentPage)
&& !mLauncher.isInState(SPRING_LOADED)
@@ -3480,14 +3487,15 @@
@Override
protected String getCurrentPageDescription() {
- int page = (mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage;
- return getPageDescription(page);
+ int pageIndex = (mNextPage != INVALID_PAGE) ? mNextPage : mCurrentPage;
+ return getPageDescription(pageIndex);
}
/**
* @param page page index.
* @return Description of the page at the given page index.
*/
+ @Override
public String getPageDescription(int page) {
int nScreens = getChildCount();
int extraScreenId = mScreenOrder.indexOf(EXTRA_EMPTY_SCREEN_ID);
diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
index 0844275..e65e614 100644
--- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
+++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java
@@ -5,18 +5,22 @@
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
import static com.android.launcher3.LauncherState.NORMAL;
+import static com.android.launcher3.anim.AnimatorListeners.forEndCallback;
import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE;
import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_NOT_PINNABLE;
+import android.animation.AnimatorSet;
import android.appwidget.AppWidgetProviderInfo;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.util.Log;
+import android.util.Pair;
import android.view.KeyEvent;
import android.view.View;
+import android.view.accessibility.AccessibilityEvent;
import com.android.launcher3.BubbleTextView;
import com.android.launcher3.ButtonDropTarget;
@@ -396,10 +400,7 @@
LauncherSettings.Favorites.CONTAINER_DESKTOP,
screenId, coordinates[0], coordinates[1]);
- mContext.bindItems(
- Collections.singletonList(info),
- /* forceAnimateIcons= */ true,
- /* focusFirstItemForAccessibility= */ accessibility);
+ bindItem(item, accessibility);
announceConfirmation(R.string.item_added_to_workspace);
} else if (item instanceof PendingAddItemInfo) {
PendingAddItemInfo info = (PendingAddItemInfo) item;
@@ -412,7 +413,7 @@
mContext.getModelWriter().addItemToDatabase(info,
LauncherSettings.Favorites.CONTAINER_DESKTOP,
screenId, coordinates[0], coordinates[1]);
- mContext.bindItems(Collections.singletonList(info), true, accessibility);
+ bindItem(info, accessibility);
} else if (item instanceof FolderInfo fi) {
mContext.getModelWriter().addItemToDatabase(fi,
LauncherSettings.Favorites.CONTAINER_DESKTOP, screenId, coordinates[0],
@@ -420,11 +421,26 @@
fi.contents.forEach(member -> {
mContext.getModelWriter().addItemToDatabase(member, fi.id, -1, -1, -1);
});
- mContext.bindItems(Collections.singletonList(fi), true, accessibility);
+ bindItem(fi, accessibility);
}
}));
return true;
}
+
+ private void bindItem(ItemInfo item, boolean focusForAccessibility) {
+ View view = mContext.getItemInflater().inflateItem(item, mContext.getModelWriter());
+ if (view == null) {
+ return;
+ }
+ AnimatorSet anim = null;
+ if (focusForAccessibility) {
+ anim = new AnimatorSet();
+ anim.addListener(forEndCallback(
+ () -> view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED)));
+ }
+ mContext.bindItems(Collections.singletonList(Pair.create(item, view)), anim);
+ }
+
/**
* Functionality to move the item {@link ItemInfo} to the workspace
* @param item item to be moved
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 1994bd1..40c368b 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -17,11 +17,17 @@
package com.android.launcher3.config;
import static com.android.launcher3.BuildConfig.WIDGET_ON_FIRST_SCREEN;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_DELAY;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE;
+import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_TIMEOUT_MS;
import static com.android.launcher3.config.FeatureFlags.FlagState.DISABLED;
import static com.android.launcher3.config.FeatureFlags.FlagState.ENABLED;
import static com.android.launcher3.config.FeatureFlags.FlagState.TEAMFOOD;
import static com.android.launcher3.uioverrides.flags.FlagsFactory.getDebugFlag;
-import static com.android.launcher3.uioverrides.flags.FlagsFactory.getIntFlag;
import static com.android.launcher3.uioverrides.flags.FlagsFactory.getReleaseFlag;
import static com.android.wm.shell.Flags.enableTaskbarNavbarUnification;
@@ -31,6 +37,7 @@
import com.android.launcher3.BuildConfig;
import com.android.launcher3.Flags;
+import com.android.launcher3.uioverrides.flags.FlagsFactory;
import java.util.function.Predicate;
import java.util.function.ToIntFunction;
@@ -93,6 +100,12 @@
"ENABLE_DISMISS_PREDICTION_UNDO", DISABLED,
"Show an 'Undo' snackbar when users dismiss a predicted hotseat item");
+ public static final BooleanFlag MOVE_STARTUP_DATA_TO_DEVICE_PROTECTED_STORAGE = getDebugFlag(
+ 251502424, "ENABLE_BOOT_AWARE_STARTUP_DATA", DISABLED,
+ "Marks LauncherPref data as (and allows it to) available while the device is"
+ + " locked. Enabling this causes a 1-time movement of certain SharedPreferences"
+ + " data. Improves startup latency.");
+
public static final BooleanFlag CONTINUOUS_VIEW_TREE_CAPTURE = getDebugFlag(270395171,
"CONTINUOUS_VIEW_TREE_CAPTURE", ENABLED, "Capture View tree every frame");
@@ -129,12 +142,14 @@
"Shrinks navbar when long pressing if ANIMATE_LPNH is enabled");
public static final IntFlag LPNH_SLOP_PERCENTAGE =
- getIntFlag(301680992, "LPNH_SLOP_PERCENTAGE", 100,
- "Controls touch slop percentage for lpnh");
+ FlagsFactory.getIntFlag(301680992, "LPNH_SLOP_PERCENTAGE", 100,
+ "Controls touch slop percentage for lpnh",
+ LONG_PRESS_NAV_HANDLE_SLOP_PERCENTAGE);
public static final IntFlag LPNH_TIMEOUT_MS =
- getIntFlag(301680992, "LPNH_TIMEOUT_MS", ViewConfiguration.getLongPressTimeout(),
- "Controls lpnh timeout in milliseconds");
+ FlagsFactory.getIntFlag(301680992, "LPNH_TIMEOUT_MS",
+ ViewConfiguration.getLongPressTimeout(),
+ "Controls lpnh timeout in milliseconds", LONG_PRESS_NAV_HANDLE_TIMEOUT_MS);
public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = getReleaseFlag(
270394468, "ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", ENABLED,
@@ -280,28 +295,35 @@
"Enables haptic hint at end of long pressing on the bottom bar nav handle.");
public static final IntFlag LPNH_HAPTIC_HINT_START_SCALE_PERCENT =
- getIntFlag(309972570, "LPNH_HAPTIC_HINT_START_SCALE_PERCENT", 0,
- "Haptic hint start scale.");
+ FlagsFactory.getIntFlag(309972570,
+ "LPNH_HAPTIC_HINT_START_SCALE_PERCENT", 0,
+ "Haptic hint start scale.",
+ LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT);
public static final IntFlag LPNH_HAPTIC_HINT_END_SCALE_PERCENT =
- getIntFlag(309972570, "LPNH_HAPTIC_HINT_END_SCALE_PERCENT", 100,
- "Haptic hint end scale.");
+ FlagsFactory.getIntFlag(309972570,
+ "LPNH_HAPTIC_HINT_END_SCALE_PERCENT", 100,
+ "Haptic hint end scale.", LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT);
public static final IntFlag LPNH_HAPTIC_HINT_SCALE_EXPONENT =
- getIntFlag(309972570, "LPNH_HAPTIC_HINT_SCALE_EXPONENT", 1,
- "Haptic hint scale exponent.");
+ FlagsFactory.getIntFlag(309972570,
+ "LPNH_HAPTIC_HINT_SCALE_EXPONENT", 1,
+ "Haptic hint scale exponent.",
+ LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT);
public static final IntFlag LPNH_HAPTIC_HINT_ITERATIONS =
- getIntFlag(309972570, "LPNH_HAPTIC_HINT_ITERATIONS", 50,
- "Haptic hint number of iterations.");
+ FlagsFactory.getIntFlag(309972570, "LPNH_HAPTIC_HINT_ITERATIONS",
+ 50,
+ "Haptic hint number of iterations.",
+ LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS);
public static final BooleanFlag ENABLE_LPNH_DEEP_PRESS =
getReleaseFlag(310952290, "ENABLE_LPNH_DEEP_PRESS", ENABLED,
"Long press of nav handle is instantly triggered if deep press is detected.");
public static final IntFlag LPNH_HAPTIC_HINT_DELAY =
- getIntFlag(309972570, "LPNH_HAPTIC_HINT_DELAY", 0,
- "Delay before haptic hint starts.");
+ FlagsFactory.getIntFlag(309972570, "LPNH_HAPTIC_HINT_DELAY", 0,
+ "Delay before haptic hint starts.", LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_DELAY);
// TODO(Block 17): Clean up flags
// Aconfig migration complete for ENABLE_TASKBAR_PINNING.
@@ -314,12 +336,6 @@
return ENABLE_TASKBAR_PINNING.get() || Flags.enableTaskbarPinning();
}
- public static final BooleanFlag MOVE_STARTUP_DATA_TO_DEVICE_PROTECTED_STORAGE = getDebugFlag(
- 251502424, "ENABLE_BOOT_AWARE_STARTUP_DATA", DISABLED,
- "Marks LauncherPref data as (and allows it to) available while the device is"
- + " locked. Enabling this causes a 1-time movement of certain SharedPreferences"
- + " data. Improves startup latency.");
-
// Aconfig migration complete for ENABLE_APP_PAIRS.
public static final BooleanFlag ENABLE_APP_PAIRS = getDebugFlag(274189428,
"ENABLE_APP_PAIRS", DISABLED,
@@ -413,10 +429,6 @@
"ENABLE_ENFORCED_ROUNDED_CORNERS", ENABLED,
"Enforce rounded corners on all App Widgets");
- public static final BooleanFlag ENABLE_ICON_LABEL_AUTO_SCALING = getDebugFlag(270393294,
- "ENABLE_ICON_LABEL_AUTO_SCALING", ENABLED,
- "Enables scaling/spacing for icon labels to make more characters visible");
-
public static final BooleanFlag USE_LOCAL_ICON_OVERRIDES = getDebugFlag(270394973,
"USE_LOCAL_ICON_OVERRIDES", ENABLED,
"Use inbuilt monochrome icons if app doesn't provide one");
diff --git a/src/com/android/launcher3/model/WorkspaceItemProcessor.kt b/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
index f98cab6..44c41c1 100644
--- a/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
+++ b/src/com/android/launcher3/model/WorkspaceItemProcessor.kt
@@ -26,7 +26,6 @@
import android.text.TextUtils
import android.util.Log
import android.util.LongSparseArray
-import androidx.annotation.VisibleForTesting
import com.android.launcher3.Flags
import com.android.launcher3.InvariantDeviceProfile
import com.android.launcher3.LauncherAppState
@@ -89,7 +88,10 @@
try {
if (c.user == null) {
// User has been deleted, remove the item.
- c.markDeleted("User has been deleted", RestoreError.PROFILE_DELETED)
+ c.markDeleted(
+ "User has been deleted for item id=${c.id}",
+ RestoreError.PROFILE_DELETED
+ )
return
}
when (c.itemType) {
@@ -127,29 +129,24 @@
* data model to be bound to the launcher’s data model.
*/
@SuppressLint("NewApi")
- @VisibleForTesting
- fun processAppOrDeepShortcut() {
+ private fun processAppOrDeepShortcut() {
var allowMissingTarget = false
var intent = c.parseIntent()
if (intent == null) {
- c.markDeleted("Invalid or null intent", RestoreError.MISSING_INFO)
+ c.markDeleted("Null intent for item id=${c.id}", RestoreError.MISSING_INFO)
return
}
var disabledState =
if (userManagerState.isUserQuiet(c.serialNumber))
WorkspaceItemInfo.FLAG_DISABLED_QUIET_USER
else 0
- var cn = intent.component
- val targetPkg = if (cn == null) intent.getPackage() else cn.packageName
- if (TextUtils.isEmpty(targetPkg)) {
- c.markDeleted("Shortcuts can't have null package", RestoreError.MISSING_INFO)
+ val cn = intent.component
+ val targetPkg = cn?.packageName ?: intent.getPackage()
+ if (targetPkg.isNullOrEmpty()) {
+ c.markDeleted("No target package for item id=${c.id}", RestoreError.MISSING_INFO)
return
}
-
- // If there is no target package, it's an implicit intent
- // (legacy shortcut) which is always valid
- var validTarget =
- (TextUtils.isEmpty(targetPkg) || launcherApps.isPackageEnabled(targetPkg, c.user))
+ var validTarget = launcherApps.isPackageEnabled(targetPkg, c.user)
// If it's a deep shortcut, we'll use pinned shortcuts to restore it
if (cn != null && validTarget && (c.itemType != Favorites.ITEM_TYPE_DEEP_SHORTCUT)) {
@@ -359,8 +356,7 @@
* processing for folder content items is done in LoaderTask after all the items in the
* workspace have been loaded. The loaded FolderInfos are stored in the BgDataModel.
*/
- @VisibleForTesting
- fun processFolderOrAppPair() {
+ private fun processFolderOrAppPair() {
val folderInfo =
bgDataModel.findOrMakeFolder(c.id).apply {
c.applyCommonProperties(this)
@@ -394,8 +390,7 @@
* depending on the type of widget. Custom widgets are treated differently than non-custom
* widgets, installing / restoring widgets are treated differently, etc.
*/
- @VisibleForTesting
- fun processWidget() {
+ private fun processWidget() {
val component = ComponentName.unflattenFromString(c.appWidgetProvider)!!
val appWidgetInfo = LauncherAppWidgetInfo(c.appWidgetId, component)
c.applyCommonProperties(appWidgetInfo)
@@ -496,6 +491,7 @@
companion object {
private const val TAG = "WorkspaceItemProcessor"
+
private fun logWidgetInfo(
idp: InvariantDeviceProfile,
widgetProviderInfo: LauncherAppWidgetProviderInfo
diff --git a/src/com/android/launcher3/util/VibratorWrapper.java b/src/com/android/launcher3/util/VibratorWrapper.java
index fef1c72..e1695e9 100644
--- a/src/com/android/launcher3/util/VibratorWrapper.java
+++ b/src/com/android/launcher3/util/VibratorWrapper.java
@@ -19,11 +19,11 @@
import static android.os.VibrationEffect.createPredefined;
import static android.provider.Settings.System.HAPTIC_FEEDBACK_ENABLED;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_DELAY;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT;
-import static com.android.launcher3.LauncherPrefs.LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT;
+import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_DELAY;
+import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_END_SCALE_PERCENT;
+import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_ITERATIONS;
+import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_SCALE_EXPONENT;
+import static com.android.launcher3.config.FeatureFlags.LPNH_HAPTIC_HINT_START_SCALE_PERCENT;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
@@ -39,7 +39,6 @@
import androidx.annotation.Nullable;
-import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
@@ -257,17 +256,11 @@
public void vibrateForSearchHint() {
if (FeatureFlags.ENABLE_SEARCH_HAPTIC_HINT.get() && Utilities.ATLEAST_S
&& mVibrator.areAllPrimitivesSupported(PRIMITIVE_LOW_TICK)) {
- LauncherPrefs launcherPrefs = LauncherPrefs.get(mContext);
- float startScale = launcherPrefs.get(
- LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_START_SCALE_PERCENT) / 100f;
- float endScale = launcherPrefs.get(
- LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_END_SCALE_PERCENT) / 100f;
- int scaleExponent = launcherPrefs.get(
- LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_SCALE_EXPONENT);
- int iterations = launcherPrefs.get(
- LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_ITERATIONS);
- int delayMs = launcherPrefs.get(
- LONG_PRESS_NAV_HANDLE_HAPTIC_HINT_DELAY);
+ float startScale = LPNH_HAPTIC_HINT_START_SCALE_PERCENT.get() / 100f;
+ float endScale = LPNH_HAPTIC_HINT_END_SCALE_PERCENT.get() / 100f;
+ int scaleExponent = LPNH_HAPTIC_HINT_SCALE_EXPONENT.get();
+ int iterations = LPNH_HAPTIC_HINT_ITERATIONS.get();
+ int delayMs = LPNH_HAPTIC_HINT_DELAY.get();
VibrationEffect.Composition composition = VibrationEffect.startComposition();
for (int i = 0; i < iterations; i++) {
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/flags/FlagsFactory.java b/src_ui_overrides/com/android/launcher3/uioverrides/flags/FlagsFactory.java
index eb0494e..b193d37 100644
--- a/src_ui_overrides/com/android/launcher3/uioverrides/flags/FlagsFactory.java
+++ b/src_ui_overrides/com/android/launcher3/uioverrides/flags/FlagsFactory.java
@@ -18,6 +18,9 @@
import static com.android.launcher3.config.FeatureFlags.FlagState.ENABLED;
+import androidx.annotation.Nullable;
+
+import com.android.launcher3.ConstantItem;
import com.android.launcher3.config.FeatureFlags.BooleanFlag;
import com.android.launcher3.config.FeatureFlags.FlagState;
import com.android.launcher3.config.FeatureFlags.IntFlag;
@@ -55,6 +58,15 @@
}
/**
+ * Creates a new debug integer flag and it is saved in LauncherPrefs.
+ */
+ public static IntFlag getIntFlag(
+ int bugId, String key, int defaultValueInCode, String description,
+ @Nullable ConstantItem<Integer> launcherPrefFlag) {
+ return new IntFlag(defaultValueInCode);
+ }
+
+ /**
* Dumps the current flags state to the print writer
*/
public static void dump(PrintWriter pw) { }
diff --git a/tests/multivalentTests/src/com/android/launcher3/celllayout/CellLayoutTestUtils.java b/tests/multivalentTests/src/com/android/launcher3/celllayout/CellLayoutTestUtils.java
index d8ae74b..9fb1989 100644
--- a/tests/multivalentTests/src/com/android/launcher3/celllayout/CellLayoutTestUtils.java
+++ b/tests/multivalentTests/src/com/android/launcher3/celllayout/CellLayoutTestUtils.java
@@ -41,7 +41,7 @@
CellPosMapper.CellPos pos = launcher.getCellPosMapper().mapPresenterToModel(
params.getCellX(), params.getCellY(),
- launcher.getWorkspace().getIdForScreen(cellLayout), CONTAINER_DESKTOP);
+ launcher.getWorkspace().getCellLayoutId(cellLayout), CONTAINER_DESKTOP);
int screenId = pos.screenId;
for (int j = boards.size(); j <= screenId; j++) {
boards.add(new CellLayoutBoard(cellLayout.getCountX(), cellLayout.getCountY()));
diff --git a/tests/multivalentTests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/multivalentTests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
index 79d8c60..f0d2e20 100644
--- a/tests/multivalentTests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
+++ b/tests/multivalentTests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java
@@ -370,7 +370,8 @@
Assert.assertTrue("Setup wizard is still visible", wizardDismissed);
}
- private static void verifyKeyguardInvisible() {
+ /** Asserts that keyguard is not visible */
+ public static void verifyKeyguardInvisible() {
final boolean keyguardAlreadyVisible = sSeenKeyguard;
sSeenKeyguard = sSeenKeyguard
diff --git a/tests/multivalentTests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java b/tests/multivalentTests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
index d94e4a5..3a54915 100644
--- a/tests/multivalentTests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
+++ b/tests/multivalentTests/src/com/android/launcher3/ui/PortraitLandscapeRunner.java
@@ -44,6 +44,7 @@
@Override
public void evaluate() throws Throwable {
try {
+ AbstractLauncherUiTest.verifyKeyguardInvisible();
mTest.mDevice.pressHome();
mTest.waitForLauncherCondition("Launcher activity wasn't created",
launcher -> launcher != null);
diff --git a/tests/src/com/android/launcher3/celllayout/UnitTestCellLayoutBuilderRule.kt b/tests/src/com/android/launcher3/celllayout/UnitTestCellLayoutBuilderRule.kt
index 0f0dd65..b63966d 100644
--- a/tests/src/com/android/launcher3/celllayout/UnitTestCellLayoutBuilderRule.kt
+++ b/tests/src/com/android/launcher3/celllayout/UnitTestCellLayoutBuilderRule.kt
@@ -21,6 +21,7 @@
import android.view.View
import androidx.test.core.app.ApplicationProvider
import com.android.launcher3.CellLayout
+import com.android.launcher3.CellLayoutContainer
import com.android.launcher3.DeviceProfile
import com.android.launcher3.InvariantDeviceProfile
import com.android.launcher3.MultipageCellLayout
@@ -40,6 +41,17 @@
private val applicationContext =
ActivityContextWrapper(ApplicationProvider.getApplicationContext())
+ private val container =
+ object : CellLayoutContainer {
+ override fun getCellLayoutId(cellLayout: CellLayout): Int = 0
+
+ override fun getCellLayoutIndex(cellLayout: CellLayout): Int = 0
+
+ override fun getPanelCount(): Int = 1
+
+ override fun getPageDescription(pageIndex: Int): String = ""
+ }
+
override fun starting(description: Description?) {
val dp = getDeviceProfile()
prevNumColumns = dp.inv.numColumns
@@ -60,7 +72,7 @@
dp.cellLayoutBorderSpacePx = Point(0, 0)
val cl =
if (isMulti) MultipageCellLayout(getWrappedContext(applicationContext, dp))
- else CellLayout(getWrappedContext(applicationContext, dp))
+ else CellLayout(getWrappedContext(applicationContext, dp), container)
// I put a very large number for width and height so that all the items can fit, it doesn't
// need to be exact, just bigger than the sum of cell border
cl.measure(
diff --git a/tests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt b/tests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt
new file mode 100644
index 0000000..e94dc02
--- /dev/null
+++ b/tests/src/com/android/launcher3/model/WorkspaceItemProcessorTest.kt
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2024 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 android.appwidget.AppWidgetProviderInfo
+import android.content.ComponentName
+import android.content.Intent
+import android.content.pm.LauncherApps
+import android.content.pm.PackageInstaller
+import android.content.pm.ShortcutInfo
+import android.os.UserHandle
+import android.util.LongSparseArray
+import com.android.launcher3.LauncherAppState
+import com.android.launcher3.LauncherSettings.Favorites
+import com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION
+import com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RestoreError.Companion.MISSING_INFO
+import com.android.launcher3.backuprestore.LauncherRestoreEventLogger.RestoreError.Companion.PROFILE_DELETED
+import com.android.launcher3.model.data.IconRequestInfo
+import com.android.launcher3.model.data.WorkspaceItemInfo
+import com.android.launcher3.shortcuts.ShortcutKey
+import com.android.launcher3.util.ComponentKey
+import com.android.launcher3.util.PackageManagerHelper
+import com.android.launcher3.util.PackageUserKey
+import com.android.launcher3.widget.WidgetInflater
+import com.google.common.truth.Truth.assertWithMessage
+import org.junit.Before
+import org.junit.Test
+import org.mockito.Mockito.RETURNS_DEEP_STUBS
+import org.mockito.Mockito.mock
+import org.mockito.kotlin.doAnswer
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.times
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+class WorkspaceItemProcessorTest {
+ private var itemProcessor = createTestWorkspaceItemProcessor()
+
+ @Before
+ fun setup() {
+ itemProcessor = createTestWorkspaceItemProcessor()
+ }
+
+ @Test
+ fun `When user is null then mark item deleted`() {
+ // Given
+ val mockCursor = mock<LoaderCursor>().apply { id = 1 }
+ val itemProcessor = createTestWorkspaceItemProcessor(cursor = mockCursor)
+ // When
+ itemProcessor.processItem()
+ // Then
+ verify(mockCursor).markDeleted("User has been deleted for item id=1", PROFILE_DELETED)
+ }
+
+ @Test
+ fun `When app has null intent then mark deleted`() {
+ // Given
+ val mockCursor =
+ mock<LoaderCursor>().apply {
+ user = UserHandle(0)
+ id = 1
+ itemType = ITEM_TYPE_APPLICATION
+ }
+ val itemProcessor = createTestWorkspaceItemProcessor(cursor = mockCursor)
+ // When
+ itemProcessor.processItem()
+ // Then
+ verify(mockCursor).markDeleted("Null intent for item id=1", MISSING_INFO)
+ }
+
+ @Test
+ fun `When app has null target package then mark deleted`() {
+ // Given
+ val mockCursor =
+ mock<LoaderCursor>().apply {
+ user = UserHandle(0)
+ itemType = ITEM_TYPE_APPLICATION
+ id = 1
+ whenever(parseIntent()).thenReturn(Intent())
+ }
+ val itemProcessor = createTestWorkspaceItemProcessor(cursor = mockCursor)
+ // When
+ itemProcessor.processItem()
+ // Then
+ verify(mockCursor).markDeleted("No target package for item id=1", MISSING_INFO)
+ }
+
+ @Test
+ fun `When app has empty String target package then mark deleted`() {
+ // Given
+ val mockIntent =
+ mock<Intent>().apply {
+ whenever(component).thenReturn(null)
+ whenever(`package`).thenReturn("")
+ }
+ val mockCursor =
+ mock<LoaderCursor>().apply {
+ user = UserHandle(0)
+ itemType = ITEM_TYPE_APPLICATION
+ id = 1
+ whenever(parseIntent()).thenReturn(mockIntent)
+ }
+ val itemProcessor = createTestWorkspaceItemProcessor(cursor = mockCursor)
+ // When
+ itemProcessor.processItem()
+ // Then
+ verify(mockCursor).markDeleted("No target package for item id=1", MISSING_INFO)
+ }
+
+ @Test
+ fun `When valid app then mark restored`() {
+ // Given
+ val userHandle = UserHandle(0)
+ val componentName = ComponentName("package", "class")
+ val mockIntent =
+ mock<Intent>().apply {
+ whenever(component).thenReturn(componentName)
+ whenever(`package`).thenReturn("")
+ }
+ val mockLauncherApps =
+ mock<LauncherApps>().apply {
+ whenever(isPackageEnabled("package", userHandle)).thenReturn(true)
+ whenever(isActivityEnabled(componentName, userHandle)).thenReturn(true)
+ }
+ val mockCursor =
+ mock<LoaderCursor>().apply {
+ user = userHandle
+ itemType = ITEM_TYPE_APPLICATION
+ id = 1
+ restoreFlag = 1
+ whenever(parseIntent()).thenReturn(mockIntent)
+ whenever(markRestored()).doAnswer { restoreFlag = 0 }
+ }
+ val itemProcessor =
+ createTestWorkspaceItemProcessor(cursor = mockCursor, launcherApps = mockLauncherApps)
+ // When
+ itemProcessor.processItem()
+ // Then
+ assertWithMessage("item restoreFlag should be set to 0")
+ .that(mockCursor.restoreFlag)
+ .isEqualTo(0)
+ // currently gets marked restored twice, although markRestore() has check for restoreFlag
+ verify(mockCursor, times(2)).markRestored()
+ }
+
+ @Test
+ fun `When fallback Activity found for app then mark restored`() {
+ // Given
+ val userHandle = UserHandle(0)
+ val componentName = ComponentName("package", "class")
+ val mockIntent =
+ mock<Intent>().apply {
+ whenever(component).thenReturn(componentName)
+ whenever(`package`).thenReturn("")
+ whenever(toUri(0)).thenReturn("")
+ }
+ val mockLauncherApps =
+ mock<LauncherApps>().apply {
+ whenever(isPackageEnabled("package", userHandle)).thenReturn(true)
+ whenever(isActivityEnabled(componentName, userHandle)).thenReturn(false)
+ }
+ val mockPmHelper =
+ mock<PackageManagerHelper>().apply {
+ whenever(getAppLaunchIntent(componentName.packageName, userHandle))
+ .thenReturn(mockIntent)
+ }
+ val mockCursor =
+ mock(LoaderCursor::class.java, RETURNS_DEEP_STUBS).apply {
+ user = userHandle
+ itemType = ITEM_TYPE_APPLICATION
+ id = 1
+ restoreFlag = 1
+ whenever(parseIntent()).thenReturn(mockIntent)
+ whenever(markRestored()).doAnswer { restoreFlag = 0 }
+ whenever(updater().put(Favorites.INTENT, mockIntent.toUri(0)).commit())
+ .thenReturn(1)
+ }
+ val itemProcessor =
+ createTestWorkspaceItemProcessor(
+ cursor = mockCursor,
+ launcherApps = mockLauncherApps,
+ pmHelper = mockPmHelper
+ )
+ // When
+ itemProcessor.processItem()
+ // Then
+ assertWithMessage("item restoreFlag should be set to 0")
+ .that(mockCursor.restoreFlag)
+ .isEqualTo(0)
+ verify(mockCursor.updater().put(Favorites.INTENT, mockIntent.toUri(0))).commit()
+ }
+
+ @Test
+ fun `When app with disabled activity and no fallback found then mark deleted`() {
+ // Given
+ val userHandle = UserHandle(0)
+ val componentName = ComponentName("package", "class")
+ val mockIntent =
+ mock<Intent>().apply {
+ whenever(component).thenReturn(componentName)
+ whenever(`package`).thenReturn("")
+ }
+ val mockLauncherApps =
+ mock<LauncherApps>().apply {
+ whenever(isPackageEnabled("package", userHandle)).thenReturn(true)
+ whenever(isActivityEnabled(componentName, userHandle)).thenReturn(false)
+ }
+ val mockPmHelper =
+ mock<PackageManagerHelper>().apply {
+ whenever(getAppLaunchIntent(componentName.packageName, userHandle)).thenReturn(null)
+ }
+ val mockCursor =
+ mock<LoaderCursor>().apply {
+ user = userHandle
+ itemType = ITEM_TYPE_APPLICATION
+ id = 1
+ restoreFlag = 1
+ whenever(parseIntent()).thenReturn(mockIntent)
+ }
+ val itemProcessor =
+ createTestWorkspaceItemProcessor(
+ cursor = mockCursor,
+ launcherApps = mockLauncherApps,
+ pmHelper = mockPmHelper
+ )
+ // When
+ itemProcessor.processItem()
+ // Then
+ assertWithMessage("item restoreFlag should be unchanged")
+ .that(mockCursor.restoreFlag)
+ .isEqualTo(1)
+ verify(mockCursor).markDeleted("Intent null, unable to find a launch target", MISSING_INFO)
+ }
+
+ /**
+ * Helper to create WorkspaceItemProcessor with defaults. WorkspaceItemProcessor has a lot of
+ * dependencies, so this method can be used to inject concrete arguments while keeping the rest
+ * as mocks/defaults.
+ */
+ private fun createTestWorkspaceItemProcessor(
+ cursor: LoaderCursor = mock(),
+ memoryLogger: LoaderMemoryLogger? = null,
+ userManagerState: UserManagerState = mock(),
+ launcherApps: LauncherApps = mock(),
+ shortcutKeyToPinnedShortcuts: Map<ShortcutKey, ShortcutInfo> = mapOf(),
+ app: LauncherAppState = mock(),
+ bgDataModel: BgDataModel = mock(),
+ widgetProvidersMap: MutableMap<ComponentKey, AppWidgetProviderInfo?> = mutableMapOf(),
+ widgetInflater: WidgetInflater = mock(),
+ pmHelper: PackageManagerHelper = mock(),
+ iconRequestInfos: MutableList<IconRequestInfo<WorkspaceItemInfo>> = mutableListOf(),
+ isSdCardReady: Boolean = false,
+ pendingPackages: MutableSet<PackageUserKey> = mutableSetOf(),
+ unlockedUsers: LongSparseArray<Boolean> = LongSparseArray(),
+ installingPkgs: HashMap<PackageUserKey, PackageInstaller.SessionInfo> = hashMapOf(),
+ allDeepShortcuts: MutableList<ShortcutInfo> = mutableListOf()
+ ) =
+ WorkspaceItemProcessor(
+ c = cursor,
+ memoryLogger = memoryLogger,
+ userManagerState = userManagerState,
+ launcherApps = launcherApps,
+ app = app,
+ bgDataModel = bgDataModel,
+ widgetProvidersMap = widgetProvidersMap,
+ widgetInflater = widgetInflater,
+ pmHelper = pmHelper,
+ unlockedUsers = unlockedUsers,
+ iconRequestInfos = iconRequestInfos,
+ pendingPackages = pendingPackages,
+ isSdCardReady = isSdCardReady,
+ shortcutKeyToPinnedShortcuts = shortcutKeyToPinnedShortcuts,
+ installingPkgs = installingPkgs,
+ allDeepShortcuts = allDeepShortcuts
+ )
+}
diff --git a/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java
index db38c68..ec226af 100644
--- a/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java
@@ -15,6 +15,9 @@
*/
package com.android.launcher3.ui.widget;
+import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
+import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
+
import static org.junit.Assert.assertNotNull;
import android.platform.test.annotations.PlatinumTest;
@@ -30,10 +33,11 @@
import com.android.launcher3.ui.TestViewHelpers;
import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord;
import com.android.launcher3.util.rule.ShellCommandRule;
+import com.android.launcher3.util.rule.TestStabilityRule.Stability;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
+import org.junit.Assume;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -89,10 +93,13 @@
* A custom shortcut is a 1x1 widget that launches a specific intent when user tap on it.
* Custom shortcuts are replaced by deep shortcuts after api 25.
*/
- @Ignore
+ @Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT)
@Test
@PortraitLandscape
public void testDragCustomShortcut() throws Throwable {
+ // TODO(b/322820039): Enable test for tablets - the picker UI has changed and test needs to
+ // be updated to look for appropriate UI elements.
+ Assume.assumeFalse(mLauncher.isTablet());
new FavoriteItemsTransaction(mTargetContext).commitAndLoadHome(mLauncher);
mLauncher.getWorkspace().openAllWidgets()
diff --git a/tests/src/com/android/launcher3/ui/workspace/TaplTwoPanelWorkspaceTest.java b/tests/src/com/android/launcher3/ui/workspace/TaplTwoPanelWorkspaceTest.java
index 3693163..43fc8ff 100644
--- a/tests/src/com/android/launcher3/ui/workspace/TaplTwoPanelWorkspaceTest.java
+++ b/tests/src/com/android/launcher3/ui/workspace/TaplTwoPanelWorkspaceTest.java
@@ -349,7 +349,7 @@
assertEquals("Existing page count does NOT match.", pageIds.length, pageCount);
for (int i = 0; i < pageCount; i++) {
CellLayout page = (CellLayout) launcher.getWorkspace().getPageAt(i);
- int pageId = launcher.getWorkspace().getIdForScreen(page);
+ int pageId = launcher.getWorkspace().getCellLayoutId(page);
assertEquals("The page's id at index " + i + " does NOT match.", pageId,
pageIds[i]);
}