Merge "Still launch disabled item if we can't handle its click." into tm-qpr-dev
diff --git a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
index c997e52..253147d 100644
--- a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
+++ b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java
@@ -50,8 +50,8 @@
import androidx.annotation.VisibleForTesting;
import com.android.launcher3.BaseActivity;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.views.ArrowTipView;
import com.android.quickstep.util.AssistContentRequester;
import com.android.quickstep.util.RecentsOrientedState;
@@ -124,7 +124,7 @@
AssistContentRequester assistContentRequester) {
super(taskThumbnailView);
mFactoryContentRequester = assistContentRequester;
- mSharedPreferences = Utilities.getPrefs(mApplicationContext);
+ mSharedPreferences = LauncherPrefs.getPrefs(mApplicationContext);
}
/**
@@ -151,7 +151,7 @@
boolean isAllowedByPolicy = mThumbnailView.isRealSnapshot() && !isManagedProfileTask;
getActionsView().setCallbacks(new OverlayUICallbacksGoImpl(isAllowedByPolicy, task));
mTaskPackageName = task.key.getPackageName();
- mSharedPreferences = Utilities.getPrefs(mApplicationContext);
+ mSharedPreferences = LauncherPrefs.getPrefs(mApplicationContext);
checkSettings();
if (!mAssistStructurePermitted || !mAssistScreenshotPermitted
diff --git a/lint-baseline-launcher3.xml b/lint-baseline-launcher3.xml
index 107a346..a9dc0c6 100644
--- a/lint-baseline-launcher3.xml
+++ b/lint-baseline-launcher3.xml
@@ -606,4 +606,20 @@
column="61"/>
</issue>
+ <issue
+ id="NewApi"
+ message="Call requires API level 33 (current min is 26): `android.app.Activity#getOnBackInvokedDispatcher`">
+ <location
+ file="packages/apps/Launcher3/src/com/android/launcher3/BaseActivity.java"
+ line="182"/>
+ </issue>
+
+ <issue
+ id="NewApi"
+ message="Call requires API level 33 (current min is 26): `android.window.OnBackInvokedDispatcher#registerOnBackInvokedCallback`">
+ <location
+ file="packages/apps/Launcher3/src/com/android/launcher3/BaseActivity.java"
+ line="182"/>
+ </issue>
+
</issues>
diff --git a/quickstep/res/layout/all_apps_edu_view.xml b/quickstep/res/layout/all_apps_edu_view.xml
index e7ef6e6..0dd4df1 100644
--- a/quickstep/res/layout/all_apps_edu_view.xml
+++ b/quickstep/res/layout/all_apps_edu_view.xml
@@ -3,4 +3,5 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="@dimen/swipe_edu_width"
- android:layout_height="@dimen/swipe_edu_max_height"/>
+ android:layout_height="@dimen/swipe_edu_max_height"
+ android:accessibilityPaneTitle="@string/taskbar_edu_a11y_title"/>
diff --git a/quickstep/res/layout/taskbar_all_apps.xml b/quickstep/res/layout/taskbar_all_apps.xml
index 34d4b23..a0dce65 100644
--- a/quickstep/res/layout/taskbar_all_apps.xml
+++ b/quickstep/res/layout/taskbar_all_apps.xml
@@ -17,7 +17,8 @@
<com.android.launcher3.taskbar.allapps.TaskbarAllAppsSlideInView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:accessibilityPaneTitle="@string/all_apps_label">
<com.android.launcher3.taskbar.allapps.TaskbarAllAppsContainerView
android:id="@+id/apps_view"
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index cd60879..c0b6657 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -289,6 +289,8 @@
<dimen name="transient_taskbar_key_shadow_distance">10dp</dimen>
<dimen name="transient_taskbar_stashed_size">32dp</dimen>
<dimen name="transient_taskbar_icon_spacing">10dp</dimen>
+ <!-- An additional touch slop to prevent x-axis movement during the swipe up to show taskbar -->
+ <dimen name="transient_taskbar_clamped_offset_bound">16dp</dimen>
<!-- Taskbar swipe up thresholds -->
<dimen name="taskbar_app_window_threshold">150dp</dimen>
<dimen name="taskbar_home_overview_threshold">225dp</dimen>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index 1a801b5..eabe079 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -189,10 +189,10 @@
<string name="allset_hint">Swipe up to go Home</string>
<!-- Hint string at the bottom of "All Set" page for button navigation [CHAR LIMIT=NONE] -->
<string name="allset_button_hint">Tap the home button to go to your home screen</string>
- <!-- Description of "All Set" page on phones [CHAR LIMIT=NONE] -->
- <string name="allset_description">You\u2019re ready to start using your phone</string>
- <!-- Description of "All Set" page on tablets [CHAR LIMIT=NONE] -->
- <string name="allset_description_tablet">You\u2019re ready to start using your tablet</string>
+ <!-- Description of "All Set" page on the user's device [CHAR LIMIT=NONE] -->
+ <string name="allset_description_generic">You\u2019re ready to start using your <xliff:g id="device" example="Pixel 6">%1$s</xliff:g></string>
+ <!-- A default device name to use in the description of the "All Set" page [CHAR LIMIT=NONE] -->
+ <string name="default_device_name">device</string>
<!-- String linking to navigation settings on "All Set" page [CHAR LIMIT=NONE] -->
<string name="allset_navigation_settings"><annotation id="link">System navigation settings</annotation></string>
@@ -224,6 +224,8 @@
<string name="accessibility_rotate_button">Rotate screen</string>
<!-- ******* Taskbar Edu ******* -->
+ <!-- Accessibility title for the taskbar education window. [CHAR_LIMIT=NONE] -->
+ <string name="taskbar_edu_a11y_title">Taskbar education</string>
<!-- Accessibility text spoken when the taskbar education panel appears [CHAR_LIMIT=NONE] -->
<string name="taskbar_edu_opened">Taskbar education appeared</string>
<!-- Accessibility text spoken when the taskbar education panel disappears [CHAR_LIMIT=NONE] -->
@@ -259,6 +261,10 @@
<string name="taskbar_button_notifications">Notifications</string>
<!-- Content description for quick settings button [CHAR_LIMIT=16] -->
<string name="taskbar_button_quick_settings">Quick Settings</string>
+ <!-- Accessibility title for the taskbar window. [CHAR_LIMIT=NONE] -->
+ <string name="taskbar_a11y_title">Taskbar</string>
+ <!-- Accessibility title for the taskbar window on phones. [CHAR_LIMIT=NONE] -->
+ <string name="taskbar_phone_a11y_title">Navigation bar</string>
<!-- Label for moving drop target to the top or left side of the screen, depending on orientation (from the taskbar only). -->
<string name="move_drop_target_top_or_left">Move to top/left</string>
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index dcad873..59dbd4b 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -1678,9 +1678,10 @@
mLauncher.getStateManager().moveToRestState();
}
+ RectF windowTargetBounds =
+ new RectF(getWindowTargetBounds(appTargets, getRotationChange(appTargets)));
Pair<RectFSpringAnim, AnimatorSet> pair = createWallpaperOpenAnimations(
- appTargets, wallpaperTargets, mFromUnlock,
- new RectF(0, 0, mDeviceProfile.widthPx, mDeviceProfile.heightPx),
+ appTargets, wallpaperTargets, mFromUnlock, windowTargetBounds,
QuickStepContract.getWindowCornerRadius(mLauncher));
mLauncher.clearForceInvisibleFlag(INVISIBLE_ALL);
diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index 05b8167..0a2a9b3 100644
--- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -305,7 +305,7 @@
* Sets or updates the predicted items only once the hotseat becomes hidden to the user
*/
private void applyPredictedItems(FixedContainerItems items) {
- mPredictedItems = items.items;
+ mPredictedItems = new ArrayList(items.items);
if (mPredictedItems.isEmpty()) {
HotseatRestoreHelper.restoreBackup(mLauncher);
}
diff --git a/quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java b/quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java
index bc3253f..e504141 100644
--- a/quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java
+++ b/quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java
@@ -30,12 +30,14 @@
import androidx.annotation.NonNull;
import com.android.launcher3.LauncherAppState;
-import com.android.launcher3.Utilities;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
import com.android.launcher3.model.QuickstepModelDelegate.PredictorState;
import com.android.launcher3.model.data.AppInfo;
+import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
+import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
@@ -59,7 +61,7 @@
Context context = app.getContext();
// TODO: remove this
- Utilities.getDevicePrefs(context).edit()
+ LauncherPrefs.getDevicePrefs(context).edit()
.putBoolean(LAST_PREDICTION_ENABLED_STATE, !mTargets.isEmpty()).apply();
Set<UserHandle> usersForChangedShortcuts =
@@ -68,7 +70,7 @@
.map(info -> info.user)
.collect(Collectors.toSet());
- FixedContainerItems fci = new FixedContainerItems(mPredictorState.containerId);
+ List<ItemInfo> items = new ArrayList<>(mTargets.size());
for (AppTarget target : mTargets) {
WorkspaceItemInfo itemInfo;
ShortcutInfo si = target.getShortcutInfo();
@@ -107,10 +109,11 @@
}
}
- itemInfo.container = fci.containerId;
- fci.items.add(itemInfo);
+ itemInfo.container = mPredictorState.containerId;
+ items.add(itemInfo);
}
+ FixedContainerItems fci = new FixedContainerItems(mPredictorState.containerId, items);
dataModel.extraItems.put(fci.containerId, fci);
bindExtraContainerItems(fci);
usersForChangedShortcuts.forEach(
diff --git a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
index de0b14d..118cfc6 100644
--- a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
+++ b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java
@@ -18,12 +18,12 @@
import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.text.format.DateUtils.formatElapsedTime;
+import static com.android.launcher3.LauncherPrefs.getDevicePrefs;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PREDICTION;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_PREDICTION;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT;
-import static com.android.launcher3.Utilities.getDevicePrefs;
import static com.android.launcher3.hybridhotseat.HotseatPredictionModel.convertDataModelToAppTargetBundle;
import static com.android.launcher3.model.PredictionHelper.getAppTargetFromItemInfo;
import static com.android.launcher3.model.PredictionHelper.wrapAppTargetWithItemLocation;
@@ -132,7 +132,8 @@
// Widgets prediction isn't used frequently. And thus, it is not persisted on disk.
mDataModel.extraItems.put(mWidgetsRecommendationState.containerId,
- new FixedContainerItems(mWidgetsRecommendationState.containerId));
+ new FixedContainerItems(mWidgetsRecommendationState.containerId,
+ new ArrayList<>()));
mActive = true;
}
diff --git a/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java b/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java
index 1beabf1..6160378 100644
--- a/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java
+++ b/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java
@@ -25,6 +25,7 @@
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.model.BgDataModel.FixedContainerItems;
import com.android.launcher3.model.QuickstepModelDelegate.PredictorState;
+import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.util.ComponentKey;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.widget.PendingAddWidgetInfo;
@@ -91,10 +92,12 @@
if (servicePredictedItems.isEmpty()) {
servicePredictedItems.addAll(localFilteredWidgets);
}
+
+ List<ItemInfo> items = servicePredictedItems.stream()
+ .map(it -> new PendingAddWidgetInfo(it.widgetInfo, CONTAINER_WIDGETS_PREDICTION))
+ .collect(Collectors.toList());
FixedContainerItems fixedContainerItems =
- new FixedContainerItems(mPredictorState.containerId);
- servicePredictedItems.forEach(w -> fixedContainerItems.items.add(
- new PendingAddWidgetInfo(w.widgetInfo, CONTAINER_WIDGETS_PREDICTION)));
+ new FixedContainerItems(mPredictorState.containerId, items);
dataModel.extraItems.put(mPredictorState.containerId, fixedContainerItems);
bindExtraContainerItems(fixedContainerItems);
diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
index 45d5739..af46df4 100644
--- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
@@ -26,8 +26,8 @@
import android.view.ViewOutlineProvider;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.anim.RevealOutlineAnimation;
import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
import com.android.launcher3.util.DisplayController;
@@ -81,7 +81,7 @@
public StashedHandleViewController(TaskbarActivityContext activity,
StashedHandleView stashedHandleView) {
mActivity = activity;
- mPrefs = Utilities.getPrefs(mActivity);
+ mPrefs = LauncherPrefs.getPrefs(mActivity);
mStashedHandleView = stashedHandleView;
mTaskbarStashedHandleAlpha = new MultiValueAlpha(mStashedHandleView, NUM_ALPHA_CHANNELS);
mTaskbarStashedHandleAlpha.setUpdateVisibility(true);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 3ee9051..13ca58d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -332,6 +332,10 @@
windowLayoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
windowLayoutParams.privateFlags =
WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
+ windowLayoutParams.accessibilityTitle = getString(
+ TaskbarManager.isPhoneMode(mDeviceProfile)
+ ? R.string.taskbar_phone_a11y_title
+ : R.string.taskbar_a11y_title);
return windowLayoutParams;
}
@@ -956,12 +960,13 @@
}
mControllers.taskbarStashController.addUnstashToHotseatAnimation(fullAnimation, duration);
- if (!FeatureFlags.ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT.get()) {
+ View allAppsButton = mControllers.taskbarViewController.getAllAppsButtonView();
+ if (allAppsButton != null && !FeatureFlags.ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT.get()) {
ValueAnimator alphaOverride = ValueAnimator.ofFloat(0, 1);
alphaOverride.setDuration(duration);
alphaOverride.addUpdateListener(a -> {
// Override the alpha updates in the icon alignment animation.
- mControllers.taskbarViewController.getAllAppsButtonView().setAlpha(0);
+ allAppsButton.setAlpha(0);
});
fullAnimation.play(alphaOverride);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
index 3045eca..dfff7ee 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java
@@ -305,6 +305,9 @@
if (mDisallowGlobalDrag) {
AbstractFloatingView.closeAllOpenViewsExcept(mActivity, TYPE_TASKBAR_ALL_APPS);
} else {
+ // stash the transient taskbar
+ mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true);
+
AbstractFloatingView.closeAllOpenViews(mActivity);
}
@@ -413,6 +416,9 @@
if (dragEvent.getResult()) {
maybeOnDragEnd();
} else {
+ // un-stash the transient taskbar in case drag and drop was canceled
+ mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(false);
+
// This will take care of calling maybeOnDragEnd() after the animation
animateGlobalDragViewToOriginalPosition(btv, dragEvent);
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index ea5df87..d790b4b 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -186,6 +186,10 @@
animatorSet.play(stashController.applyStateWithoutStart(duration));
animatorSet.play(applyState(duration, false));
+ if (mTaskBarRecentsAnimationListener != null) {
+ mTaskBarRecentsAnimationListener.endGestureStateOverride(
+ !mLauncher.isInState(LauncherState.OVERVIEW));
+ }
mTaskBarRecentsAnimationListener = new TaskBarRecentsAnimationListener(callbacks);
callbacks.addListener(mTaskBarRecentsAnimationListener);
((RecentsView) mLauncher.getOverviewPanel()).setTaskLaunchListener(() ->
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 06348e2..6274ec0 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -42,6 +42,7 @@
import com.android.internal.jank.InteractionJankMonitor;
import com.android.launcher3.Alarm;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorListeners;
@@ -187,7 +188,7 @@
public TaskbarStashController(TaskbarActivityContext activity) {
mActivity = activity;
- mPrefs = Utilities.getPrefs(mActivity);
+ mPrefs = LauncherPrefs.getPrefs(mActivity);
mSystemUiProxy = SystemUiProxy.INSTANCE.get(activity);
if (isPhoneMode()) {
// DeviceProfile's taskbar vars aren't initialized w/ the flag off
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index fe38bb1..c4eeca7 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -422,6 +422,7 @@
/**
* Returns the all apps button in the taskbar.
*/
+ @Nullable
public View getAllAppsButtonView() {
return mAllAppsButton;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 80a31b4..9936d27 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -240,6 +240,7 @@
return mTaskbarView.getIconViews();
}
+ @Nullable
public View getAllAppsButtonView() {
return mTaskbarView.getAllAppsButtonView();
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java
index 7e3163d..ebaf60a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java
@@ -19,8 +19,8 @@
import android.view.View;
import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.ActivityAllAppsContainerView;
import com.android.launcher3.allapps.search.DefaultSearchAdapterProvider;
import com.android.launcher3.allapps.search.SearchAdapterProvider;
@@ -62,7 +62,7 @@
mOverlayController = controllers.taskbarOverlayController;
mDragController = new TaskbarDragController(this);
mDragController.init(controllers);
- mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this));
+ mOnboardingPrefs = new OnboardingPrefs<>(this, LauncherPrefs.getPrefs(this));
mDragLayer = new TaskbarOverlayDragLayer(this);
TaskbarStashController taskbarStashController = controllers.taskbarStashController;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java
index 5afeca7..faa900b 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java
@@ -18,11 +18,11 @@
import android.content.Context;
import android.content.SharedPreferences;
-import com.android.launcher3.Utilities;
-import com.android.systemui.shared.plugins.PluginEnabler;
-
import androidx.preference.PreferenceDataStore;
+import com.android.launcher3.LauncherPrefs;
+import com.android.systemui.shared.plugins.PluginEnabler;
+
public class PluginEnablerImpl extends PreferenceDataStore implements PluginEnabler {
private static final String PREFIX_PLUGIN_ENABLED = "PLUGIN_ENABLED_";
@@ -30,7 +30,7 @@
final private SharedPreferences mSharedPrefs;
public PluginEnablerImpl(Context context) {
- mSharedPrefs = Utilities.getDevicePrefs(context);
+ mSharedPrefs = LauncherPrefs.getDevicePrefs(context);
}
@Override
diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
index fe0bca6..e3d386c 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java
@@ -28,9 +28,9 @@
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.plugins.PluginListener;
+import com.android.systemui.plugins.PluginManager;
import com.android.systemui.shared.plugins.PluginActionManager;
import com.android.systemui.shared.plugins.PluginInstance;
-import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.shared.plugins.PluginManagerImpl;
import com.android.systemui.shared.plugins.PluginPrefs;
import com.android.systemui.shared.system.UncaughtExceptionPreHandlerManager;
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index b09e531..4b35859 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -95,6 +95,7 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimationSuccessListener;
import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.dragndrop.DragView;
import com.android.launcher3.logging.StatsLogManager;
import com.android.launcher3.logging.StatsLogManager.StatsLogger;
import com.android.launcher3.statemanager.BaseState;
@@ -287,7 +288,7 @@
private AnimatorControllerWithResistance mLauncherTransitionController;
private boolean mHasEndedLauncherTransition;
- private AnimationFactory mAnimationFactory = (t, s) -> { };
+ private AnimationFactory mAnimationFactory = (t) -> { };
private boolean mWasLauncherAlreadyVisible;
@@ -317,6 +318,9 @@
private final int mTaskbarAppWindowThreshold;
private final int mTaskbarCatchUpThreshold;
private boolean mTaskbarAlreadyOpen;
+ private final boolean mIsTransientTaskbar;
+ // Only used when mIsTransientTaskbar is true.
+ private boolean mHasReachedHomeOverviewThreshold;
public AbsSwipeUpHandler(Context context, RecentsAnimationDeviceState deviceState,
TaskAnimationManager taskAnimationManager, GestureState gestureState,
@@ -343,6 +347,7 @@
mTaskbarAppWindowThreshold = res
.getDimensionPixelSize(R.dimen.taskbar_app_window_threshold);
mTaskbarCatchUpThreshold = res.getDimensionPixelSize(R.dimen.taskbar_catch_up_threshold);
+ mIsTransientTaskbar = DisplayController.isTransientTaskbar(mActivity);
mQuickSwitchScaleScrollThreshold = res
.getDimension(R.dimen.quick_switch_scaling_scroll_threshold);
@@ -531,9 +536,7 @@
Runnable initAnimFactory = () -> {
mAnimationFactory = mActivityInterface.prepareRecentsUI(mDeviceState,
mWasLauncherAlreadyVisible, this::onAnimatorPlaybackControllerCreated);
- maybeUpdateRecentsAttachedState(
- false /* animate */,
- new ActiveGestureLog.CompoundString("on Launcher start (animate=false)"));
+ maybeUpdateRecentsAttachedState(false /* animate */);
if (mGestureState.getEndTarget() != null) {
// Update the end target in case the gesture ended before we init.
mAnimationFactory.setEndTarget(mGestureState.getEndTarget());
@@ -638,8 +641,7 @@
}
private void initializeLauncherAnimationController() {
- buildAnimationController(new ActiveGestureLog.CompoundString(
- "initializing launcher animation controller"));
+ buildAnimationController();
Object traceToken = TraceHelper.INSTANCE.beginSection("logToggleRecents",
TraceHelper.FLAG_IGNORE_BINDERS);
@@ -658,11 +660,7 @@
@Override
public void onMotionPauseDetected() {
mHasMotionEverBeenPaused = true;
- maybeUpdateRecentsAttachedState(
- true/* animate */,
- true/* moveFocusedTask */,
- new ActiveGestureLog.CompoundString(
- "motion pause detected (animate=true)"));
+ maybeUpdateRecentsAttachedState(true/* animate */, true/* moveFocusedTask */);
Optional.ofNullable(mActivityInterface.getTaskbarController())
.ifPresent(TaskbarUIController::startTranslationSpring);
performHapticFeedback();
@@ -675,13 +673,12 @@
};
}
- private void maybeUpdateRecentsAttachedState(ActiveGestureLog.CompoundString reason) {
- maybeUpdateRecentsAttachedState(true /* animate */, reason.append(" (animate=true)"));
+ private void maybeUpdateRecentsAttachedState() {
+ maybeUpdateRecentsAttachedState(true /* animate */);
}
- private void maybeUpdateRecentsAttachedState(
- boolean animate, ActiveGestureLog.CompoundString reason) {
- maybeUpdateRecentsAttachedState(animate, false /* moveFocusedTask */, reason);
+ private void maybeUpdateRecentsAttachedState(boolean animate) {
+ maybeUpdateRecentsAttachedState(animate, false /* moveFocusedTask */);
}
/**
@@ -693,8 +690,7 @@
* @param animate whether to animate when attaching RecentsView
* @param moveFocusedTask whether to move focused task to front when attaching
*/
- private void maybeUpdateRecentsAttachedState(
- boolean animate, boolean moveFocusedTask, ActiveGestureLog.CompoundString reason) {
+ private void maybeUpdateRecentsAttachedState(boolean animate, boolean moveFocusedTask) {
if (!mDeviceState.isFullyGesturalNavMode() || mRecentsView == null) {
return;
}
@@ -704,25 +700,14 @@
final boolean recentsAttachedToAppWindow;
if (mGestureState.getEndTarget() != null) {
recentsAttachedToAppWindow = mGestureState.getEndTarget().recentsAttachedToAppWindow;
- reason.append("; gesture state end target != null (attached=")
- .append(Boolean.toString(recentsAttachedToAppWindow))
- .append(")");
} else if (mContinuingLastGesture
&& mRecentsView.getRunningTaskIndex() != mRecentsView.getNextPage()) {
recentsAttachedToAppWindow = true;
- reason.append("; continuing last gesture (attached=true)");
} else if (runningTaskTarget != null && isNotInRecents(runningTaskTarget)) {
// The window is going away so make sure recents is always visible in this case.
recentsAttachedToAppWindow = true;
- reason.append("; make sure recents is always visible (attached=true)");
} else {
recentsAttachedToAppWindow = mHasMotionEverBeenPaused || mIsLikelyToStartNewTask;
- reason.append(mHasMotionEverBeenPaused
- ? "; motion has been paused"
- : "; gesture is likely to start a new task")
- .append(" (attached=")
- .append(Boolean.toString(recentsAttachedToAppWindow))
- .append(")");
}
if (moveFocusedTask && !mAnimationFactory.hasRecentsEverAttachedToAppWindow()
&& recentsAttachedToAppWindow) {
@@ -730,8 +715,7 @@
// TaskView jumping to new position as we move the tasks.
mRecentsView.moveFocusedTaskToFront();
}
- mAnimationFactory.setRecentsAttachedToAppWindow(
- recentsAttachedToAppWindow, animate, reason);
+ mAnimationFactory.setRecentsAttachedToAppWindow(recentsAttachedToAppWindow, animate);
// Reapply window transform throughout the attach animation, as the animation affects how
// much the window is bound by overscroll (vs moving freely).
@@ -750,30 +734,38 @@
}
}
- public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) {
- setIsLikelyToStartNewTask(
- isLikelyToStartNewTask,
- true /* animate */,
- new ActiveGestureLog.CompoundString(
- "setting gesture likely to start (animate=true)"));
+ /**
+ * Sets whether or not we should clamp the scroll offset.
+ * This is used to avoid x-axis movement when swiping up transient taskbar.
+ * @param clampScrollOffset When true, we clamp the scroll to 0 before the clamp threshold is
+ * met.
+ */
+ public void setClampScrollOffset(boolean clampScrollOffset) {
+ if (mRecentsView == null) {
+ mStateCallback.runOnceAtState(STATE_LAUNCHER_PRESENT,
+ () -> mRecentsView.setClampScrollOffset(clampScrollOffset));
+ return;
+ }
+ mRecentsView.setClampScrollOffset(clampScrollOffset);
}
- private void setIsLikelyToStartNewTask(
- boolean isLikelyToStartNewTask,
- boolean animate,
- ActiveGestureLog.CompoundString reason) {
+ public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) {
+ setIsLikelyToStartNewTask(isLikelyToStartNewTask, true /* animate */);
+ }
+
+ private void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask, boolean animate) {
if (mIsLikelyToStartNewTask != isLikelyToStartNewTask) {
mIsLikelyToStartNewTask = isLikelyToStartNewTask;
- maybeUpdateRecentsAttachedState(animate, reason);
+ maybeUpdateRecentsAttachedState(animate);
}
}
- private void buildAnimationController(ActiveGestureLog.CompoundString reason) {
+ private void buildAnimationController() {
if (!canCreateNewOrUpdateExistingLauncherTransitionController()) {
return;
}
initTransitionEndpoints(mActivity.getDeviceProfile());
- mAnimationFactory.createActivityInterface(mTransitionDragLength, reason);
+ mAnimationFactory.createActivityInterface(mTransitionDragLength);
}
/**
@@ -788,7 +780,7 @@
@Override
public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) {
WindowInsets result = view.onApplyWindowInsets(windowInsets);
- buildAnimationController(new ActiveGestureLog.CompoundString("applying window insets"));
+ buildAnimationController();
// Reapply the current shift to ensure it takes new insets into account, e.g. when long
// pressing to stash taskbar without moving the finger.
updateFinalShift();
@@ -819,7 +811,7 @@
@UiThread
@Override
public void updateFinalShift() {
- final boolean passed = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW;
+ final boolean passed = hasReachedHomeOverviewThreshold();
if (passed != mPassedOverviewThreshold) {
mPassedOverviewThreshold = passed;
if (mDeviceState.isTwoButtonNavMode() && !mGestureState.isHandlingAtomicEvent()) {
@@ -962,10 +954,7 @@
});
}
notifyGestureStartedAsync();
- setIsLikelyToStartNewTask(
- isLikelyToStartNewTask,
- false /* animate */,
- new ActiveGestureLog.CompoundString("on gesture started (animate=false)"));
+ setIsLikelyToStartNewTask(isLikelyToStartNewTask, false /* animate */);
mStateCallback.setStateOnUiThread(STATE_GESTURE_STARTED);
mGestureStarted = true;
}
@@ -1046,8 +1035,7 @@
private void onSettledOnEndTarget() {
// Fast-finish the attaching animation if it's still running.
- maybeUpdateRecentsAttachedState(false, new ActiveGestureLog.CompoundString(
- "on settled on end target (animate=false)"));
+ maybeUpdateRecentsAttachedState(false);
final GestureEndTarget endTarget = mGestureState.getEndTarget();
// Wait until the given View (if supplied) draws before resuming the last task.
View postResumeLastTask = mActivityInterface.onSettledOnEndTarget(endTarget);
@@ -1145,16 +1133,16 @@
}
if (!mDeviceState.isFullyGesturalNavMode()) {
- return (!hasReachedOverviewThreshold() && willGoToNewTask) ? NEW_TASK : RECENTS;
+ return (!hasReachedHomeOverviewThreshold() && willGoToNewTask) ? NEW_TASK : RECENTS;
}
return willGoToNewTask ? NEW_TASK : HOME;
}
private GestureEndTarget calculateEndTargetForNonFling(PointF velocity) {
final boolean isScrollingToNewTask = isScrollingToNewTask();
- final boolean reachedOverviewThreshold = hasReachedOverviewThreshold();
+ final boolean reachedHomeOverviewThreshold = hasReachedHomeOverviewThreshold();
if (!mDeviceState.isFullyGesturalNavMode()) {
- return reachedOverviewThreshold && mGestureStarted
+ return reachedHomeOverviewThreshold && mGestureStarted
? RECENTS
: (isScrollingToNewTask ? NEW_TASK : LAST_TASK);
}
@@ -1170,7 +1158,7 @@
return RECENTS;
} else if (isScrollingToNewTask) {
return NEW_TASK;
- } else if (reachedOverviewThreshold) {
+ } else if (reachedHomeOverviewThreshold) {
return HOME;
}
return LAST_TASK;
@@ -1189,8 +1177,22 @@
return runningTaskIndex >= 0 && mRecentsView.getNextPage() != runningTaskIndex;
}
- private boolean hasReachedOverviewThreshold() {
- return getTaskbarProgress() > MIN_PROGRESS_FOR_OVERVIEW;
+ /**
+ * Sets whether the current swipe has reached the threshold where if user lets go they would
+ * go to either the home state or overview state.
+ */
+ public void setHasReachedHomeOverviewThreshold(boolean hasReachedHomeOverviewThreshold) {
+ mHasReachedHomeOverviewThreshold = hasReachedHomeOverviewThreshold;
+ }
+
+ /**
+ * Returns true iff swipe has reached the overview threshold.
+ */
+ public boolean hasReachedHomeOverviewThreshold() {
+ if (mIsTransientTaskbar) {
+ return mHasReachedHomeOverviewThreshold;
+ }
+ return mCurrentShift.value > MIN_PROGRESS_FOR_OVERVIEW;
}
@UiThread
@@ -1357,12 +1359,15 @@
@UiThread
private void animateToProgressInternal(float start, float end, long duration,
Interpolator interpolator, GestureEndTarget target, PointF velocityPxPerMs) {
- maybeUpdateRecentsAttachedState(new ActiveGestureLog.CompoundString(
- "animate to progress internal"));
+ maybeUpdateRecentsAttachedState();
// If we are transitioning to launcher, then listen for the activity to be restarted while
// the transition is in progress
if (mGestureState.getEndTarget().isLauncher) {
+ // This is also called when the launcher is resumed, in order to clear the pending
+ // widgets that have yet to be configured.
+ DragView.removeAllViews(mActivity);
+
TaskStackChangeListeners.getInstance().registerTaskStackListener(
mActivityRestartListener);
@@ -1677,9 +1682,7 @@
mRecentsView.post(mRecentsView::resetTaskVisuals);
}
// Make sure recents is in its final state
- maybeUpdateRecentsAttachedState(
- false, new ActiveGestureLog.CompoundString(
- "setting up window animation (animate=false)"));
+ maybeUpdateRecentsAttachedState(false);
mActivityInterface.onSwipeUpToHomeComplete(mDeviceState);
}
});
@@ -2267,7 +2270,7 @@
* There is also a catch up period so that the window can start moving 1:1 with the swipe.
*/
private float getTaskbarProgress() {
- if (!DisplayController.isTransientTaskbar(mContext)) {
+ if (!mIsTransientTaskbar) {
return mCurrentShift.value;
}
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 2c3ba85..274b686 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -60,7 +60,6 @@
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.views.ScrimView;
-import com.android.quickstep.util.ActiveGestureLog;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.AnimatorControllerWithResistance;
import com.android.quickstep.views.RecentsView;
@@ -399,16 +398,14 @@
public interface AnimationFactory {
- void createActivityInterface(long transitionLength, ActiveGestureLog.CompoundString reason);
+ void createActivityInterface(long transitionLength);
/**
* @param attached Whether to show RecentsView alongside the app window. If false, recents
* will be hidden by some property we can animate, e.g. alpha.
* @param animate Whether to animate recents to/from its new attached state.
- * @param reason Explanation for why this method is being called with the given param values
*/
- default void setRecentsAttachedToAppWindow(
- boolean attached, boolean animate, ActiveGestureLog.CompoundString reason) { }
+ default void setRecentsAttachedToAppWindow(boolean attached, boolean animate) { }
default boolean isRecentsAttachedToAppWindow() {
return false;
@@ -450,8 +447,7 @@
}
@Override
- public void createActivityInterface(
- long transitionLength, ActiveGestureLog.CompoundString reason) {
+ public void createActivityInterface(long transitionLength) {
PendingAnimation pa = new PendingAnimation(transitionLength * 2);
createBackgroundToOverviewAnim(mActivity, pa);
AnimatorPlaybackController controller = pa.createPlaybackController();
@@ -474,29 +470,13 @@
// (because we set the animation as the current state animation), so we reapply the
// attached state here as well to ensure recents is shown/hidden appropriately.
if (DisplayController.getNavigationMode(mActivity) == NavigationMode.NO_BUTTON) {
- setRecentsAttachedToAppWindow(
- mIsAttachedToWindow,
- false,
- reason.append("; reapplying the attached state (attached=")
- .append(Boolean.toString(mIsAttachedToWindow))
- .append(", animate=false)"));
+ setRecentsAttachedToAppWindow(mIsAttachedToWindow, false);
}
}
@Override
- public void setRecentsAttachedToAppWindow(
- boolean attached, boolean animate, ActiveGestureLog.CompoundString reason) {
- // TODO(b/244593270): remove these logs; too verbose
- ActiveGestureLog.INSTANCE.addLog(
- new ActiveGestureLog.CompoundString("setRecentsAttachedToAppWindow: attached=")
- .append(Boolean.toString(attached))
- .append(", animate=")
- .append(Boolean.toString(animate))
- .append(", reason=")
- .append(reason));
+ public void setRecentsAttachedToAppWindow(boolean attached, boolean animate) {
if (mIsAttachedToWindow == attached && animate) {
- ActiveGestureLog.INSTANCE.addLog(new ActiveGestureLog.CompoundString(
- "setRecentsAttachedToAppWindow: exiting early"));
return;
}
mActivity.getStateManager()
@@ -525,11 +505,6 @@
float fromTranslation = ADJACENT_PAGE_HORIZONTAL_OFFSET.get(
mActivity.getOverviewPanel());
float toTranslation = attached ? 0 : 1;
- ActiveGestureLog.INSTANCE.addLog(new ActiveGestureLog.CompoundString(
- "setRecentsAttachedToAppWindow: fromTranslation=")
- .append(Float.toString(fromTranslation))
- .append(", toTranslation=")
- .append(Float.toString(toTranslation)));
Animator translationAnimator = mActivity.getStateManager().createStateElementAnimation(
INDEX_RECENTS_TRANSLATE_X_ANIM, fromTranslation, toTranslation);
diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
index 65614ba..54e4a0d 100644
--- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
+++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java
@@ -138,15 +138,11 @@
return response;
case TestProtocol.REQUEST_ENABLE_TRANSIENT_TASKBAR:
- runOnTISBinder(tisBinder -> {
- enableTransientTaskbar(tisBinder, true);
- });
+ enableTransientTaskbar(true);
return response;
case TestProtocol.REQUEST_DISABLE_TRANSIENT_TASKBAR:
- runOnTISBinder(tisBinder -> {
- enableTransientTaskbar(tisBinder, false);
- });
+ enableTransientTaskbar(false);
return response;
}
@@ -179,24 +175,21 @@
private void enableBlockingTimeout(
TouchInteractionService.TISBinder tisBinder, boolean enable) {
- // Allow null-pointer to catch illegal states.
- tisBinder.getTaskbarManager().getCurrentActivityContext().enableBlockingTimeoutDuringTests(
- enable);
- }
-
- private void enableTransientTaskbar(
- TouchInteractionService.TISBinder tisBinder, boolean enable) {
TaskbarActivityContext context = tisBinder.getTaskbarManager().getCurrentActivityContext();
if (context == null) {
if (TestProtocol.sDebugTracing) {
- Log.d(NPE_TRANSIENT_TASKBAR, "enableTransientTaskbar: enable=" + enable,
+ Log.d(NPE_TRANSIENT_TASKBAR, "enableBlockingTimeout: enable=" + enable,
new Exception());
}
} else {
- DisplayController.INSTANCE.get(context).enableTransientTaskbarForTests(enable);
+ context.enableBlockingTimeoutDuringTests(enable);
}
}
+ private void enableTransientTaskbar(boolean enable) {
+ DisplayController.INSTANCE.get(mContext).enableTransientTaskbarForTests(enable);
+ }
+
/**
* Runs the given command on the UI thread, after ensuring we are connected to
* TouchInteractionService.
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index 450774b..af6a45a 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -31,6 +31,7 @@
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TRACING_ENABLED;
import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_BACK_ANIMATION;
import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_DESKTOP_MODE;
@@ -69,6 +70,7 @@
import com.android.app.viewcapture.ViewCapture;
import com.android.launcher3.BaseDraggingActivity;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
@@ -479,7 +481,7 @@
}
// Reset home bounce seen on quick step enabled for first time
- SharedPreferences sharedPrefs = Utilities.getPrefs(this);
+ SharedPreferences sharedPrefs = LauncherPrefs.getPrefs(this);
if (!sharedPrefs.getBoolean(HAS_ENABLED_QUICKSTEP_ONCE, true)) {
sharedPrefs.edit()
.putBoolean(HAS_ENABLED_QUICKSTEP_ONCE, true)
@@ -533,9 +535,10 @@
}
}
- boolean wasExpanded = (lastSysUIFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) != 0;
- boolean isExpanded =
- (systemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) != 0;
+ int isShadeExpandedFlag =
+ SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED | SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
+ boolean wasExpanded = (lastSysUIFlags & isShadeExpandedFlag) != 0;
+ boolean isExpanded = (systemUiStateFlags & isShadeExpandedFlag) != 0;
if (wasExpanded != isExpanded && isExpanded) {
// End live tile when expanding the notification panel for the first time from
// overview.
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
index 8410149..db7e087 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
@@ -53,6 +53,7 @@
import com.android.quickstep.RecentsAnimationController;
import com.android.quickstep.RecentsAnimationDeviceState;
import com.android.quickstep.RecentsAnimationTargets;
+import com.android.quickstep.RemoteAnimationTargets;
import com.android.quickstep.TaskAnimationManager;
import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties;
import com.android.quickstep.util.TransformParams;
@@ -226,6 +227,10 @@
mStateCallback.setState(STATE_HANDLER_INVALIDATED);
}
});
+ RemoteAnimationTargets targets = mTransformParams.getTargetSet();
+ if (targets != null) {
+ targets.addReleaseCheck(new DeviceLockedReleaseCheck(animator));
+ }
animator.start();
} else {
mStateCallback.setState(STATE_HANDLER_INVALIDATED);
@@ -304,4 +309,27 @@
public boolean allowInterceptByParent() {
return !mThresholdCrossed;
}
+
+ private static final class DeviceLockedReleaseCheck extends
+ RemoteAnimationTargets.ReleaseCheck {
+
+ private DeviceLockedReleaseCheck(Animator animator) {
+ setCanRelease(true);
+
+ animator.addListener(new AnimatorListenerAdapter() {
+
+ @Override
+ public void onAnimationStart(Animator animation) {
+ super.onAnimationStart(animation);
+ setCanRelease(false);
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
+ setCanRelease(true);
+ }
+ });
+ }
+ }
}
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
index b3d3c3d..f842fd0 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java
@@ -36,7 +36,6 @@
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
-import android.content.res.Resources;
import android.graphics.PointF;
import android.os.Build;
import android.util.Log;
@@ -151,10 +150,6 @@
mHandlerFactory = handlerFactory;
mActivityInterface = mGestureState.getActivityInterface();
- Resources res = base.getResources();
- mTaskbarHomeOverviewThreshold = res
- .getDimensionPixelSize(R.dimen.taskbar_home_overview_threshold);
-
mMotionPauseDetector = new MotionPauseDetector(base, false,
mNavBarPosition.isLeftEdge() || mNavBarPosition.isRightEdge()
? MotionEvent.AXIS_X : MotionEvent.AXIS_Y);
@@ -168,6 +163,8 @@
TaskbarUIController controller = mActivityInterface.getTaskbarController();
mTaskbarAlreadyOpen = controller != null && !controller.isTaskbarStashed();
mIsTransientTaskbar = DisplayController.isTransientTaskbar(base);
+ mTaskbarHomeOverviewThreshold = base.getResources()
+ .getDimensionPixelSize(R.dimen.taskbar_home_overview_threshold);
boolean continuingPreviousGesture = mTaskAnimationManager.isRecentsAnimationRunning();
mIsDeferredDownTarget = !continuingPreviousGesture && isDeferredDownTarget;
@@ -340,13 +337,12 @@
}
if (mDeviceState.isFullyGesturalNavMode()) {
- float minDisplacement = mMotionPauseMinDisplacement;
-
- if (mIsTransientTaskbar && !mTaskbarAlreadyOpen) {
- minDisplacement += mTaskbarHomeOverviewThreshold;
+ boolean minSwipeMet = upDist >= mMotionPauseMinDisplacement;
+ if (mIsTransientTaskbar) {
+ minSwipeMet = upDist >= mTaskbarHomeOverviewThreshold;
+ mInteractionHandler.setHasReachedHomeOverviewThreshold(minSwipeMet);
}
-
- mMotionPauseDetector.setDisallowPause(upDist < minDisplacement
+ mMotionPauseDetector.setDisallowPause(!minSwipeMet
|| isLikelyToStartNewTask);
mMotionPauseDetector.addPosition(ev);
mInteractionHandler.setIsLikelyToStartNewTask(isLikelyToStartNewTask);
@@ -382,6 +378,9 @@
mInteractionHandler.onGestureStarted(isLikelyToStartNewTask);
mInteractionHandler.setTaskbarAlreadyOpen(mTaskbarAlreadyOpen);
+ if (mIsTransientTaskbar && !mTaskbarAlreadyOpen && !isLikelyToStartNewTask) {
+ mInteractionHandler.setClampScrollOffset(true);
+ }
}
private void startTouchTrackingForWindowAnimation(long touchTimeMs) {
@@ -477,6 +476,9 @@
@UiThread
private void onInteractionGestureFinished() {
Preconditions.assertUIThread();
+ if (mInteractionHandler != null) {
+ mInteractionHandler.setClampScrollOffset(false);
+ }
removeListener();
mInteractionHandler = null;
cleanupAfterGesture();
diff --git a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
index 897b559..52f1867 100644
--- a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
+++ b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java
@@ -42,6 +42,7 @@
import android.os.Bundle;
import android.os.VibrationEffect;
import android.os.Vibrator;
+import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.View.AccessibilityDelegate;
@@ -79,6 +80,7 @@
"#Intent;action=com.android.settings.SEARCH_RESULT_TRAMPOLINE;S.:settings:fragment_args_key=gesture_system_navigation_input_summary;S.:settings:show_fragment=com.android.settings.gestures.SystemNavigationGestureSettings;end";
private static final String EXTRA_ACCENT_COLOR_DARK_MODE = "suwColorAccentDark";
private static final String EXTRA_ACCENT_COLOR_LIGHT_MODE = "suwColorAccentLight";
+ private static final String EXTRA_DEVICE_NAME = "suwDeviceName";
private static final float HINT_BOTTOM_FACTOR = 1 - .94f;
@@ -110,7 +112,8 @@
int mode = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK;
boolean isDarkTheme = mode == Configuration.UI_MODE_NIGHT_YES;
- int accentColor = getIntent().getIntExtra(
+ Intent intent = getIntent();
+ int accentColor = intent.getIntExtra(
isDarkTheme ? EXTRA_ACCENT_COLOR_DARK_MODE : EXTRA_ACCENT_COLOR_LIGHT_MODE,
isDarkTheme ? Color.WHITE : Color.BLACK);
@@ -121,10 +124,12 @@
mContentView = findViewById(R.id.content_view);
mSwipeUpShift = getResources().getDimension(R.dimen.allset_swipe_up_shift);
- DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(this).getDeviceProfile(this);
TextView subtitle = findViewById(R.id.subtitle);
- subtitle.setText(dp.isTablet
- ? R.string.allset_description_tablet : R.string.allset_description);
+ String suwDeviceName = intent.getStringExtra(EXTRA_DEVICE_NAME);
+ subtitle.setText(getString(
+ R.string.allset_description_generic,
+ !TextUtils.isEmpty(suwDeviceName)
+ ? suwDeviceName : getString(R.string.default_device_name)));
TextView tv = findViewById(R.id.navigation_settings);
tv.setTextColor(accentColor);
@@ -138,6 +143,7 @@
});
TextView hintTextView = findViewById(R.id.hint);
+ DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(this).getDeviceProfile(this);
if (!dp.isGestureMode) {
hintTextView.setText(R.string.allset_button_hint);
}
diff --git a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
index bf7023c..4a70120 100644
--- a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
+++ b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
@@ -28,8 +28,8 @@
import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.logging.StatsLogManager;
import com.android.quickstep.TouchInteractionService.TISBinder;
import com.android.quickstep.interaction.TutorialController.TutorialType;
@@ -63,7 +63,7 @@
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.gesture_tutorial_activity);
- mSharedPrefs = Utilities.getPrefs(this);
+ mSharedPrefs = LauncherPrefs.getPrefs(this);
mStatsLogManager = StatsLogManager.newInstance(getApplicationContext());
Bundle args = savedInstanceState == null ? getIntent().getExtras() : savedInstanceState;
diff --git a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
index 2ccdfa3..5efc45e 100644
--- a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
+++ b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java
@@ -16,8 +16,8 @@
package com.android.quickstep.logging;
-import static com.android.launcher3.Utilities.getDevicePrefs;
-import static com.android.launcher3.Utilities.getPrefs;
+import static com.android.launcher3.LauncherPrefs.getDevicePrefs;
+import static com.android.launcher3.LauncherPrefs.getPrefs;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_SCREEN_SUGGESTIONS_DISABLED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_SCREEN_SUGGESTIONS_ENABLED;
import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_DOT_DISABLED;
diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
index c459f30..db8c7f2 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
+++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java
@@ -45,7 +45,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.Utilities;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.testing.shared.TestProtocol;
import com.android.launcher3.touch.PagedOrientationHandler;
import com.android.launcher3.util.DisplayController;
@@ -139,7 +139,7 @@
public RecentsOrientedState(Context context, BaseActivityInterface sizeStrategy,
IntConsumer rotationChangeListener) {
mContext = context;
- mSharedPrefs = Utilities.getPrefs(context);
+ mSharedPrefs = LauncherPrefs.getPrefs(context);
mOrientationListener = new OrientationEventListener(context) {
@Override
public void onOrientationChanged(int degrees) {
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 80b41a7..5a26f32 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -498,6 +498,9 @@
private boolean mOverviewFullscreenEnabled;
private boolean mOverviewSelectEnabled;
+ private boolean mShouldClampScrollOffset;
+ private int mClampedScrollOffsetBound;
+
private float mAdjacentPageHorizontalOffset = 0;
protected float mTaskViewsSecondaryTranslation = 0;
protected float mTaskViewsPrimarySplitTranslation = 0;
@@ -752,6 +755,8 @@
mSplitPlaceholderInset = getResources().getDimensionPixelSize(
R.dimen.split_placeholder_inset);
mSquaredTouchSlop = squaredTouchSlop(context);
+ mClampedScrollOffsetBound = getResources().getDimensionPixelSize(
+ R.dimen.transient_taskbar_clamped_offset_bound);
mEmptyIcon = context.getDrawable(R.drawable.ic_empty_recents);
mEmptyIcon.setCallback(this);
@@ -5055,9 +5060,35 @@
}
/**
+ * Sets whether or not we should clamp the scroll offset.
+ * This is used to avoid x-axis movement when swiping up transient taskbar.
+ * Should only be set at the beginning and end of the gesture, otherwise a jump may occur.
+ * @param clampScrollOffset When true, we clamp the scroll to 0 before the clamp threshold is
+ * met.
+ */
+ public void setClampScrollOffset(boolean clampScrollOffset) {
+ mShouldClampScrollOffset = clampScrollOffset;
+ }
+
+ /**
* Returns how many pixels the page is offset on the currently laid out dominant axis.
*/
public int getScrollOffset(int pageIndex) {
+ int unboundedOffset = getUnclampedScrollOffset(pageIndex);
+ if (!mShouldClampScrollOffset) {
+ return unboundedOffset;
+ }
+ if (Math.abs(unboundedOffset) < mClampedScrollOffsetBound) {
+ return 0;
+ }
+ return unboundedOffset
+ - Math.round(Math.signum(unboundedOffset) * mClampedScrollOffsetBound);
+ }
+
+ /**
+ * Returns how many pixels the page is offset on the currently laid out dominant axis.
+ */
+ private int getUnclampedScrollOffset(int pageIndex) {
if (pageIndex == -1) {
return 0;
}
diff --git a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
index 6d47281..0c96539 100644
--- a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
+++ b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt
@@ -94,8 +94,13 @@
params.setProgress(/* fullscreenProgress= */ 1.0f, /* parentScale= */ 1.0f,
/* taskViewScale= */ 1.0f, /* previewWidth= */ 0, dp, mPreviewPositionHelper)
+ // Probably unhelpful, but also unclear how to test otherwise ¯\_(ツ)_/¯
+ val fullscreenTaskHeight = (dp.heightPx - dp.taskbarSize) *
+ (1 - (splitBounds.topTaskPercent + splitBounds.dividerHeightPercent))
+ val canvasScreenRatio = canvasHeight / fullscreenTaskHeight
+ val expectedBottomHint = dp.taskbarSize * canvasScreenRatio
assertThat(params.mCurrentDrawnInsets.bottom)
- .isWithin(1f).of((dp.taskbarSize * TASK_SCALE))
+ .isWithin(1f).of(expectedBottomHint)
}
@Test
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 3b92ac4..50b7563 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -368,6 +368,7 @@
<dimen name="transient_taskbar_shadow_blur">0dp</dimen>
<dimen name="transient_taskbar_key_shadow_distance">0dp</dimen>
<dimen name="transient_taskbar_stashed_size">0dp</dimen>
+ <dimen name="transient_taskbar_clamped_offset_bound">0dp</dimen>
<!-- Note that this applies to both sides of all icons, so visible space is double this. -->
<dimen name="transient_taskbar_icon_spacing">0dp</dimen>
<!-- Note that this applies to both sides of all icons, so visible space is double this. -->
diff --git a/res/xml/paddings_handhelds.xml b/res/xml/paddings_handhelds.xml
new file mode 100644
index 0000000..b9549a6
--- /dev/null
+++ b/res/xml/paddings_handhelds.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2022 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.
+ -->
+
+<!-- Putting in the test/xml folder gives an error that maxEmptySpace doesn't exist -->
+<device-paddings xmlns:launcher="http://schemas.android.com/apk/res-auto" >
+
+ <device-padding
+ launcher:maxEmptySpace="9999dp">
+ <workspaceTopPadding
+ launcher:a="0.48"
+ launcher:b="0"/>
+ <workspaceBottomPadding
+ launcher:a="0.52"
+ launcher:b="0"/>
+ <hotseatBottomPadding
+ launcher:a="0"
+ launcher:b="0"/>
+ </device-padding>
+</device-paddings>
\ No newline at end of file
diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java
index 73acd87..28d4a9f 100644
--- a/src/com/android/launcher3/AbstractFloatingView.java
+++ b/src/com/android/launcher3/AbstractFloatingView.java
@@ -102,13 +102,15 @@
| TYPE_OPTIONS_POPUP | TYPE_SNACKBAR | TYPE_LISTENER | TYPE_ALL_APPS_EDU
| TYPE_ICON_SURFACE | TYPE_DRAG_DROP_POPUP | TYPE_PIN_WIDGET_FROM_EXTERNAL_POPUP
| TYPE_WIDGETS_EDUCATION_DIALOG | TYPE_TASKBAR_EDUCATION_DIALOG | TYPE_TASKBAR_ALL_APPS
- | TYPE_OPTIONS_POPUP_DIALOG | TYPE_ADD_TO_HOME_CONFIRMATION;
+ | TYPE_OPTIONS_POPUP_DIALOG | TYPE_ADD_TO_HOME_CONFIRMATION
+ | TYPE_TASKBAR_OVERLAY_PROXY;
// Type of popups which should be kept open during launcher rebind
public static final int TYPE_REBIND_SAFE = TYPE_WIDGETS_FULL_SHEET
| TYPE_WIDGETS_BOTTOM_SHEET | TYPE_ON_BOARD_POPUP | TYPE_DISCOVERY_BOUNCE
| TYPE_ALL_APPS_EDU | TYPE_ICON_SURFACE | TYPE_WIDGETS_EDUCATION_DIALOG
- | TYPE_TASKBAR_EDUCATION_DIALOG | TYPE_TASKBAR_ALL_APPS | TYPE_OPTIONS_POPUP_DIALOG;
+ | TYPE_TASKBAR_EDUCATION_DIALOG | TYPE_TASKBAR_ALL_APPS | TYPE_OPTIONS_POPUP_DIALOG
+ | TYPE_TASKBAR_OVERLAY_PROXY;
public static final int TYPE_ACCESSIBLE = TYPE_ALL & ~TYPE_DISCOVERY_BOUNCE & ~TYPE_LISTENER
& ~TYPE_ALL_APPS_EDU;
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 3cb3461..92530ea 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -498,10 +498,11 @@
extraSpace = updateAvailableDimensions(res);
// Now that we have all of the variables calculated, we can tune certain sizes.
- if (isScalableGrid && inv.devicePaddings != null) {
+ if (isScalableGrid && inv.devicePaddingId != INVALID_RESOURCE_HANDLE) {
// Paddings were created assuming no scaling, so we first unscale the extra space.
int unscaledExtraSpace = (int) (extraSpace / cellScaleToFit);
- DevicePadding padding = inv.devicePaddings.getDevicePadding(unscaledExtraSpace);
+ DevicePaddings devicePaddings = new DevicePaddings(context, inv.devicePaddingId);
+ DevicePadding padding = devicePaddings.getDevicePadding(unscaledExtraSpace);
int paddingWorkspaceTop = padding.getWorkspaceTopPadding(unscaledExtraSpace);
int paddingWorkspaceBottom = padding.getWorkspaceBottomPadding(unscaledExtraSpace);
@@ -1565,10 +1566,11 @@
writer.println(prefix + pxToDpStr("extraSpace", extraSpace));
writer.println(prefix + pxToDpStr("unscaled extraSpace", extraSpace / iconScale));
- if (inv.devicePaddings != null) {
+ if (inv.devicePaddingId != INVALID_RESOURCE_HANDLE) {
int unscaledExtraSpace = (int) (extraSpace / iconScale);
+ DevicePaddings devicePaddings = new DevicePaddings(context, inv.devicePaddingId);
writer.println(prefix + pxToDpStr("maxEmptySpace",
- inv.devicePaddings.getDevicePadding(unscaledExtraSpace).getMaxEmptySpacePx()));
+ devicePaddings.getDevicePadding(unscaledExtraSpace).getMaxEmptySpacePx()));
}
writer.println(prefix + pxToDpStr("workspaceTopPadding", workspaceTopPadding));
writer.println(prefix + pxToDpStr("workspaceBottomPadding", workspaceBottomPadding));
diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java
index 9c5ec38..1f97535 100644
--- a/src/com/android/launcher3/InvariantDeviceProfile.java
+++ b/src/com/android/launcher3/InvariantDeviceProfile.java
@@ -47,9 +47,9 @@
import androidx.annotation.DimenRes;
import androidx.annotation.IntDef;
-import androidx.annotation.Nullable;
import androidx.annotation.StyleRes;
import androidx.annotation.VisibleForTesting;
+import androidx.annotation.XmlRes;
import androidx.core.content.res.ResourcesCompat;
import com.android.launcher3.icons.DotRenderer;
@@ -172,7 +172,8 @@
* Do not query directly. see {@link DeviceProfile#isScalableGrid}.
*/
protected boolean isScalable;
- public int devicePaddingId;
+ @XmlRes
+ public int devicePaddingId = INVALID_RESOURCE_HANDLE;
public String dbFile;
public int defaultLayoutId;
@@ -184,9 +185,6 @@
*/
public List<DeviceProfile> supportedProfiles = Collections.EMPTY_LIST;
- @Nullable
- public DevicePaddings devicePaddings;
-
public Point defaultWallpaperSize;
public Rect defaultWidgetPadding;
@@ -200,7 +198,8 @@
String gridName = getCurrentGridName(context);
String newGridName = initGrid(context, gridName);
if (!newGridName.equals(gridName)) {
- Utilities.getPrefs(context).edit().putString(KEY_IDP_GRID_NAME, newGridName).apply();
+ LauncherPrefs.getPrefs(context).edit().putString(KEY_IDP_GRID_NAME, newGridName)
+ .apply();
}
new DeviceGridState(this).writeToPrefs(context);
@@ -308,7 +307,7 @@
}
public static String getCurrentGridName(Context context) {
- return Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null);
+ return LauncherPrefs.getPrefs(context).getString(KEY_IDP_GRID_NAME, null);
}
private String initGrid(Context context, String gridName) {
@@ -384,10 +383,6 @@
allAppsIconSize = displayOption.allAppsIconSizes;
allAppsIconTextSize = displayOption.allAppsIconTextSizes;
- if (devicePaddingId != 0) {
- devicePaddings = new DevicePaddings(context, devicePaddingId);
- }
-
inlineQsb = closestProfile.inlineQsb;
// If the partner customization apk contains any grid overrides, apply them
@@ -436,7 +431,7 @@
public void setCurrentGrid(Context context, String gridName) {
Context appContext = context.getApplicationContext();
- Utilities.getPrefs(appContext).edit().putString(KEY_IDP_GRID_NAME, gridName).apply();
+ LauncherPrefs.getPrefs(appContext).edit().putString(KEY_IDP_GRID_NAME, gridName).apply();
MAIN_EXECUTOR.execute(() -> onConfigChanged(appContext));
}
@@ -825,7 +820,7 @@
isScalable = a.getBoolean(
R.styleable.GridDisplayOption_isScalable, false);
devicePaddingId = a.getResourceId(
- R.styleable.GridDisplayOption_devicePaddingId, 0);
+ R.styleable.GridDisplayOption_devicePaddingId, INVALID_RESOURCE_HANDLE);
int deviceCategory = a.getInt(R.styleable.GridDisplayOption_deviceCategory,
DEVICE_CATEGORY_ALL);
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index 578efdf..5cce407 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -473,7 +473,7 @@
InvariantDeviceProfile idp = app.getInvariantDeviceProfile();
initDeviceProfile(idp);
idp.addOnChangeListener(this);
- mSharedPrefs = Utilities.getPrefs(this);
+ mSharedPrefs = LauncherPrefs.getPrefs(this);
mIconCache = app.getIconCache();
mAccessibilityDelegate = createAccessibilityDelegate();
@@ -1563,7 +1563,7 @@
@Override
public SharedPreferences getDevicePrefs() {
- return Utilities.getDevicePrefs(this);
+ return LauncherPrefs.getDevicePrefs(this);
}
public int getOrientation() {
diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java
index ea3f723..4965936 100644
--- a/src/com/android/launcher3/LauncherAppState.java
+++ b/src/com/android/launcher3/LauncherAppState.java
@@ -18,7 +18,7 @@
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED;
-import static com.android.launcher3.Utilities.getDevicePrefs;
+import static com.android.launcher3.LauncherPrefs.getDevicePrefs;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI;
@@ -117,7 +117,7 @@
observer, MODEL_EXECUTOR.getHandler());
mOnTerminateCallback.add(iconChangeTracker::close);
MODEL_EXECUTOR.execute(observer::verifyIconChanged);
- SharedPreferences prefs = Utilities.getPrefs(mContext);
+ SharedPreferences prefs = LauncherPrefs.getPrefs(mContext);
prefs.registerOnSharedPreferenceChangeListener(observer);
mOnTerminateCallback.add(
() -> prefs.unregisterOnSharedPreferenceChangeListener(observer));
diff --git a/src/com/android/launcher3/LauncherPrefs.kt b/src/com/android/launcher3/LauncherPrefs.kt
new file mode 100644
index 0000000..23ff10a
--- /dev/null
+++ b/src/com/android/launcher3/LauncherPrefs.kt
@@ -0,0 +1,20 @@
+package com.android.launcher3
+
+import android.content.Context
+import android.content.SharedPreferences
+
+object LauncherPrefs {
+
+ @JvmStatic
+ fun getPrefs(context: Context): SharedPreferences {
+ // Use application context for shared preferences, so that we use a single cached instance
+ return context.applicationContext.getSharedPreferences(
+ LauncherFiles.SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE)
+ }
+
+ @JvmStatic
+ fun getDevicePrefs(context: Context): SharedPreferences {
+ // Use application context for shared preferences, so that we use a single cached instance
+ return context.applicationContext.getSharedPreferences(
+ LauncherFiles.DEVICE_PREFERENCES_KEY, Context.MODE_PRIVATE)
+ }}
\ No newline at end of file
diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java
index 457e126..d002c2b 100644
--- a/src/com/android/launcher3/LauncherProvider.java
+++ b/src/com/android/launcher3/LauncherProvider.java
@@ -374,7 +374,7 @@
case LauncherSettings.Settings.METHOD_WAS_EMPTY_DB_CREATED : {
Bundle result = new Bundle();
result.putBoolean(LauncherSettings.Settings.EXTRA_VALUE,
- Utilities.getPrefs(getContext()).getBoolean(
+ LauncherPrefs.getPrefs(getContext()).getBoolean(
mOpenHelper.getKey(EMPTY_DATABASE_CREATED), false));
return result;
}
@@ -520,7 +520,7 @@
}
private void clearFlagEmptyDbCreated() {
- Utilities.getPrefs(getContext()).edit()
+ LauncherPrefs.getPrefs(getContext()).edit()
.remove(mOpenHelper.getKey(EMPTY_DATABASE_CREATED)).commit();
}
@@ -532,7 +532,7 @@
* 4) The default configuration for the particular device
*/
synchronized private void loadDefaultFavoritesIfNecessary() {
- SharedPreferences sp = Utilities.getPrefs(getContext());
+ SharedPreferences sp = LauncherPrefs.getPrefs(getContext());
if (sp.getBoolean(mOpenHelper.getKey(EMPTY_DATABASE_CREATED), false)) {
Log.d(TAG, "loading default workspace");
@@ -738,7 +738,7 @@
*/
protected void onEmptyDbCreated() {
// Set the flag for empty DB
- Utilities.getPrefs(mContext).edit().putBoolean(getKey(EMPTY_DATABASE_CREATED), true)
+ LauncherPrefs.getPrefs(mContext).edit().putBoolean(getKey(EMPTY_DATABASE_CREATED), true)
.commit();
}
diff --git a/src/com/android/launcher3/SessionCommitReceiver.java b/src/com/android/launcher3/SessionCommitReceiver.java
index bcd4c3f..50ad2be 100644
--- a/src/com/android/launcher3/SessionCommitReceiver.java
+++ b/src/com/android/launcher3/SessionCommitReceiver.java
@@ -98,6 +98,6 @@
}
public static boolean isEnabled(Context context) {
- return Utilities.getPrefs(context).getBoolean(ADD_ICON_PREFERENCE_KEY, true);
+ return LauncherPrefs.getPrefs(context).getBoolean(ADD_ICON_PREFERENCE_KEY, true);
}
}
diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java
index 743e3ae..ce009a1 100644
--- a/src/com/android/launcher3/Utilities.java
+++ b/src/com/android/launcher3/Utilities.java
@@ -27,7 +27,6 @@
import android.app.Person;
import android.app.WallpaperManager;
import android.content.Context;
-import android.content.SharedPreferences;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.ShortcutInfo;
@@ -509,18 +508,6 @@
return spanned;
}
- public static SharedPreferences getPrefs(Context context) {
- // Use application context for shared preferences, so that we use a single cached instance
- return context.getApplicationContext().getSharedPreferences(
- LauncherFiles.SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE);
- }
-
- public static SharedPreferences getDevicePrefs(Context context) {
- // Use application context for shared preferences, so that we use a single cached instance
- return context.getApplicationContext().getSharedPreferences(
- LauncherFiles.DEVICE_PREFERENCES_KEY, Context.MODE_PRIVATE);
- }
-
public static boolean isWallpaperSupported(Context context) {
return context.getSystemService(WallpaperManager.class).isWallpaperSupported();
}
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index 517bbf8..191d063 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -2385,6 +2385,9 @@
ItemInfo item = d.dragInfo;
final View child = (mDragInfo == null) ? null : mDragInfo.cell;
if (!nearestDropOccupied) {
+ mDragTargetLayout.performReorder((int) mDragViewVisualCenter[0],
+ (int) mDragViewVisualCenter[1], minSpanX, minSpanY, item.spanX, item.spanY,
+ child, mTargetCell, new int[2], CellLayout.MODE_SHOW_REORDER_HINT);
mDragTargetLayout.visualizeDropLocation(mTargetCell[0], mTargetCell[1],
item.spanX, item.spanY, d);
} else if ((mDragMode == DRAG_MODE_NONE || mDragMode == DRAG_MODE_REORDER)
diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
index da86d98..8e519c1 100644
--- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java
@@ -54,6 +54,7 @@
import com.android.launcher3.DropTarget.DragObject;
import com.android.launcher3.Insettable;
import com.android.launcher3.InsettableFrameLayout;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.search.SearchAdapterProvider;
@@ -148,7 +149,7 @@
mWorkManager = new WorkProfileManager(
mActivityContext.getSystemService(UserManager.class),
- this, Utilities.getPrefs(mActivityContext));
+ this, LauncherPrefs.getPrefs(mActivityContext));
mAH = Arrays.asList(null, null, null);
mAH.set(AdapterHolder.MAIN, new AdapterHolder(AdapterHolder.MAIN));
mAH.set(AdapterHolder.WORK, new AdapterHolder(AdapterHolder.WORK));
diff --git a/src/com/android/launcher3/allapps/WorkEduCard.java b/src/com/android/launcher3/allapps/WorkEduCard.java
index 968a556..b3245ee 100644
--- a/src/com/android/launcher3/allapps/WorkEduCard.java
+++ b/src/com/android/launcher3/allapps/WorkEduCard.java
@@ -26,8 +26,8 @@
import android.widget.FrameLayout;
import android.widget.TextView;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.model.StringCache;
import com.android.launcher3.views.ActivityContext;
@@ -85,7 +85,7 @@
@Override
public void onClick(View view) {
startAnimation(mDismissAnim);
- Utilities.getPrefs(getContext()).edit().putInt(WorkProfileManager.KEY_WORK_EDU_STEP,
+ LauncherPrefs.getPrefs(getContext()).edit().putInt(WorkProfileManager.KEY_WORK_EDU_STEP,
1).apply();
}
diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java
index 0a938b2..2272cdc 100644
--- a/src/com/android/launcher3/allapps/WorkModeSwitch.java
+++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java
@@ -154,6 +154,7 @@
private void updateVisibility() {
clearAnimation();
+ onApplyWindowInsets(getRootWindowInsets());
if (mWorkEnabled && mOnWorkTab) {
setFlag(FLAG_FADE_ONGOING);
setVisibility(VISIBLE);
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 9607da8..819463d 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -273,6 +273,10 @@
"ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES", false,
"Enable option to replace decorator-based search result backgrounds with drawables");
+ public static final BooleanFlag TWO_PREDICTED_ROWS_ALL_APPS_SEARCH = new DeviceFlag(
+ "TWO_PREDICTED_ROWS_ALL_APPS_SEARCH", false,
+ "Use 2 rows of app predictions in All Apps search zero-state");
+
public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = new DeviceFlag(
"ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", true,
"Enable option to show keyboard when going to all-apps");
diff --git a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
index c28bab5..feadafa 100644
--- a/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
+++ b/src/com/android/launcher3/graphics/GridCustomizationsProvider.java
@@ -1,6 +1,6 @@
package com.android.launcher3.graphics;
-import static com.android.launcher3.Utilities.getPrefs;
+import static com.android.launcher3.LauncherPrefs.getPrefs;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
import static com.android.launcher3.util.Themes.KEY_THEMED_ICONS;
import static com.android.launcher3.util.Themes.isThemedIconEnabled;
diff --git a/src/com/android/launcher3/model/BaseModelUpdateTask.java b/src/com/android/launcher3/model/BaseModelUpdateTask.java
index 5b6f9f6..74a2c5d 100644
--- a/src/com/android/launcher3/model/BaseModelUpdateTask.java
+++ b/src/com/android/launcher3/model/BaseModelUpdateTask.java
@@ -118,8 +118,7 @@
}
public void bindExtraContainerItems(@NonNull final FixedContainerItems item) {
- FixedContainerItems copy = item.clone();
- scheduleCallbackTask(c -> c.bindExtraContainerItems(copy));
+ scheduleCallbackTask(c -> c.bindExtraContainerItems(item));
}
public void bindDeepShortcuts(@NonNull final BgDataModel dataModel) {
diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java
index de23c4b..b0f6e13 100644
--- a/src/com/android/launcher3/model/BgDataModel.java
+++ b/src/com/android/launcher3/model/BgDataModel.java
@@ -433,26 +433,9 @@
public final int containerId;
public final List<ItemInfo> items;
- public FixedContainerItems(int containerId) {
- this(containerId, new ArrayList<>());
- }
-
public FixedContainerItems(int containerId, List<ItemInfo> items) {
this.containerId = containerId;
- this.items = items;
- }
-
- @Override
- public FixedContainerItems clone() {
- return new FixedContainerItems(containerId, new ArrayList<>(items));
- }
-
- public void setItems(List<ItemInfo> newItems) {
- items.clear();
- newItems.forEach(item -> {
- item.container = containerId;
- items.add(item);
- });
+ this.items = Collections.unmodifiableList(items);
}
}
diff --git a/src/com/android/launcher3/model/DeviceGridState.java b/src/com/android/launcher3/model/DeviceGridState.java
index 46f0b0b..85d54c0 100644
--- a/src/com/android/launcher3/model/DeviceGridState.java
+++ b/src/com/android/launcher3/model/DeviceGridState.java
@@ -29,7 +29,7 @@
import android.text.TextUtils;
import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.Utilities;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.logging.StatsLogManager.LauncherEvent;
import java.util.Locale;
@@ -58,7 +58,7 @@
}
public DeviceGridState(Context context) {
- SharedPreferences prefs = Utilities.getPrefs(context);
+ SharedPreferences prefs = LauncherPrefs.getPrefs(context);
mGridSizeString = prefs.getString(KEY_WORKSPACE_SIZE, "");
mNumHotseat = prefs.getInt(KEY_HOTSEAT_COUNT, -1);
mDeviceType = prefs.getInt(KEY_DEVICE_TYPE, TYPE_PHONE);
@@ -90,7 +90,7 @@
* Stores the device state to shared preferences
*/
public void writeToPrefs(Context context) {
- Utilities.getPrefs(context).edit()
+ LauncherPrefs.getPrefs(context).edit()
.putString(KEY_WORKSPACE_SIZE, mGridSizeString)
.putInt(KEY_HOTSEAT_COUNT, mNumHotseat)
.putInt(KEY_DEVICE_TYPE, mDeviceType)
diff --git a/src/com/android/launcher3/pm/InstallSessionHelper.java b/src/com/android/launcher3/pm/InstallSessionHelper.java
index 16bb868..150bca4 100644
--- a/src/com/android/launcher3/pm/InstallSessionHelper.java
+++ b/src/com/android/launcher3/pm/InstallSessionHelper.java
@@ -16,7 +16,7 @@
package com.android.launcher3.pm;
-import static com.android.launcher3.Utilities.getPrefs;
+import static com.android.launcher3.LauncherPrefs.getPrefs;
import android.content.Context;
import android.content.pm.ApplicationInfo;
diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java
index 95ac7b0..a45e835 100644
--- a/src/com/android/launcher3/provider/RestoreDbTask.java
+++ b/src/com/android/launcher3/provider/RestoreDbTask.java
@@ -36,6 +36,7 @@
import com.android.launcher3.AppWidgetsRestoredReceiver;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.LauncherProvider.DatabaseHelper;
import com.android.launcher3.LauncherSettings.Favorites;
import com.android.launcher3.Utilities;
@@ -86,7 +87,7 @@
// Set is pending to false irrespective of the result, so that it doesn't get
// executed again.
- Utilities.getPrefs(context).edit().remove(RESTORED_DEVICE_TYPE).commit();
+ LauncherPrefs.getPrefs(context).edit().remove(RESTORED_DEVICE_TYPE).commit();
idp.reinitializeAfterRestore(context);
}
@@ -239,7 +240,7 @@
}
// If restored from a single display backup, remove gaps between screenIds
- if (Utilities.getPrefs(context).getInt(RESTORED_DEVICE_TYPE, TYPE_PHONE)
+ if (LauncherPrefs.getPrefs(context).getInt(RESTORED_DEVICE_TYPE, TYPE_PHONE)
!= TYPE_MULTI_DISPLAY) {
removeScreenIdGaps(db);
}
@@ -338,7 +339,7 @@
}
public static boolean isPending(Context context) {
- return Utilities.getPrefs(context).contains(RESTORED_DEVICE_TYPE);
+ return LauncherPrefs.getPrefs(context).contains(RESTORED_DEVICE_TYPE);
}
/**
@@ -346,13 +347,13 @@
*/
public static void setPending(Context context) {
FileLog.d(TAG, "Restore data received through full backup ");
- Utilities.getPrefs(context).edit()
+ LauncherPrefs.getPrefs(context).edit()
.putInt(RESTORED_DEVICE_TYPE, new DeviceGridState(context).getDeviceType())
.commit();
}
private void restoreAppWidgetIdsIfExists(Context context) {
- SharedPreferences prefs = Utilities.getPrefs(context);
+ SharedPreferences prefs = LauncherPrefs.getPrefs(context);
if (prefs.contains(APPWIDGET_OLD_IDS) && prefs.contains(APPWIDGET_IDS)) {
LauncherWidgetHolder holder = new LauncherWidgetHolder(context);
AppWidgetsRestoredReceiver.restoreAppWidgetIds(context,
@@ -370,7 +371,7 @@
public static void setRestoredAppWidgetIds(Context context, @NonNull int[] oldIds,
@NonNull int[] newIds) {
- Utilities.getPrefs(context).edit()
+ LauncherPrefs.getPrefs(context).edit()
.putString(APPWIDGET_OLD_IDS, IntArray.wrap(oldIds).toConcatString())
.putString(APPWIDGET_IDS, IntArray.wrap(newIds).toConcatString())
.commit();
diff --git a/src/com/android/launcher3/qsb/QsbContainerView.java b/src/com/android/launcher3/qsb/QsbContainerView.java
index 23ee251..f295204 100644
--- a/src/com/android/launcher3/qsb/QsbContainerView.java
+++ b/src/com/android/launcher3/qsb/QsbContainerView.java
@@ -43,8 +43,8 @@
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.FragmentWithPreview;
import com.android.launcher3.widget.util.WidgetSizes;
@@ -200,7 +200,7 @@
Context context = getContext();
AppWidgetManager widgetManager = AppWidgetManager.getInstance(context);
- int widgetId = Utilities.getPrefs(context).getInt(mKeyWidgetId, -1);
+ int widgetId = LauncherPrefs.getPrefs(context).getInt(mKeyWidgetId, -1);
AppWidgetProviderInfo widgetInfo = widgetManager.getAppWidgetInfo(widgetId);
boolean isWidgetBound = (widgetInfo != null) &&
widgetInfo.provider.equals(mWidgetInfo.provider);
@@ -244,7 +244,7 @@
}
private void saveWidgetId(int widgetId) {
- Utilities.getPrefs(getContext()).edit().putInt(mKeyWidgetId, widgetId).apply();
+ LauncherPrefs.getPrefs(getContext()).edit().putInt(mKeyWidgetId, widgetId).apply();
}
@Override
diff --git a/src/com/android/launcher3/search/StringMatcherUtility.java b/src/com/android/launcher3/search/StringMatcherUtility.java
index acab52b..c66f3a1 100644
--- a/src/com/android/launcher3/search/StringMatcherUtility.java
+++ b/src/com/android/launcher3/search/StringMatcherUtility.java
@@ -24,8 +24,8 @@
public class StringMatcherUtility {
/**
- * Returns {@code true} is {@code query} is a prefix substring of a complete word/phrase in
- * {@code target}.
+ * Returns {@code true} if {@code query} is a prefix of a substring in {@code target}. How to
+ * break target to valid substring is defined in the given {@code matcher}.
*/
public static boolean matches(String query, String target, StringMatcher matcher) {
int queryLength = query.length();
@@ -50,7 +50,7 @@
thisType = nextType;
nextType = i < (targetLength - 1)
? Character.getType(target.codePointAt(i + 1)) : Character.UNASSIGNED;
- if (isBreak(thisType, lastType, nextType)
+ if (matcher.isBreak(thisType, lastType, nextType)
&& matcher.matches(query, target.substring(i, i + queryLength))) {
return true;
}
@@ -59,52 +59,6 @@
}
/**
- * Returns true if the current point should be a break point. Following cases
- * are considered as break points:
- * 1) Any non space character after a space character
- * 2) Any digit after a non-digit character
- * 3) Any capital character after a digit or small character
- * 4) Any capital character before a small character
- */
- private static boolean isBreak(int thisType, int prevType, int nextType) {
- switch (prevType) {
- case Character.UNASSIGNED:
- case Character.SPACE_SEPARATOR:
- case Character.LINE_SEPARATOR:
- case Character.PARAGRAPH_SEPARATOR:
- return true;
- }
- switch (thisType) {
- case Character.UPPERCASE_LETTER:
- if (nextType == Character.UPPERCASE_LETTER) {
- return true;
- }
- // Follow through
- case Character.TITLECASE_LETTER:
- // Break point if previous was not a upper case
- return prevType != Character.UPPERCASE_LETTER;
- case Character.LOWERCASE_LETTER:
- // Break point if previous was not a letter.
- return prevType > Character.OTHER_LETTER || prevType <= Character.UNASSIGNED;
- case Character.DECIMAL_DIGIT_NUMBER:
- case Character.LETTER_NUMBER:
- case Character.OTHER_NUMBER:
- // Break point if previous was not a number
- return !(prevType == Character.DECIMAL_DIGIT_NUMBER
- || prevType == Character.LETTER_NUMBER
- || prevType == Character.OTHER_NUMBER);
- case Character.MATH_SYMBOL:
- case Character.CURRENCY_SYMBOL:
- case Character.OTHER_PUNCTUATION:
- case Character.DASH_PUNCTUATION:
- // Always a break point for a symbol
- return true;
- default:
- return false;
- }
- }
-
- /**
* Performs locale sensitive string comparison using {@link Collator}.
*/
public static class StringMatcher {
@@ -142,6 +96,75 @@
public static StringMatcher getInstance() {
return new StringMatcher();
}
+
+ /**
+ * Returns true if the current point should be a break point.
+ *
+ * Following cases are considered as break points:
+ * 1) Any non space character after a space character
+ * 2) Any digit after a non-digit character
+ * 3) Any capital character after a digit or small character
+ * 4) Any capital character before a small character
+ *
+ * E.g., "YouTube" matches the input "you" and "tube", but not "out".
+ */
+ protected boolean isBreak(int thisType, int prevType, int nextType) {
+ switch (prevType) {
+ case Character.UNASSIGNED:
+ case Character.SPACE_SEPARATOR:
+ case Character.LINE_SEPARATOR:
+ case Character.PARAGRAPH_SEPARATOR:
+ return true;
+ }
+ switch (thisType) {
+ case Character.UPPERCASE_LETTER:
+ if (nextType == Character.UPPERCASE_LETTER) {
+ return true;
+ }
+ // Follow through
+ case Character.TITLECASE_LETTER:
+ // Break point if previous was not a upper case
+ return prevType != Character.UPPERCASE_LETTER;
+ case Character.LOWERCASE_LETTER:
+ // Break point if previous was not a letter.
+ return prevType > Character.OTHER_LETTER || prevType <= Character.UNASSIGNED;
+ case Character.DECIMAL_DIGIT_NUMBER:
+ case Character.LETTER_NUMBER:
+ case Character.OTHER_NUMBER:
+ // Break point if previous was not a number
+ return !(prevType == Character.DECIMAL_DIGIT_NUMBER
+ || prevType == Character.LETTER_NUMBER
+ || prevType == Character.OTHER_NUMBER);
+ case Character.MATH_SYMBOL:
+ case Character.CURRENCY_SYMBOL:
+ case Character.OTHER_PUNCTUATION:
+ case Character.DASH_PUNCTUATION:
+ // Always a break point for a symbol
+ return true;
+ default:
+ return false;
+ }
+ }
+ }
+
+ /**
+ * Subclass of {@code StringMatcher} using simple space break for prefix matching.
+ * E.g., "YouTube" matches the input "you". "Play Store" matches the input "play".
+ */
+ public static class StringMatcherSpace extends StringMatcher {
+
+ public static StringMatcherSpace getInstance() {
+ return new StringMatcherSpace();
+ }
+
+ /**
+ * The first character or any character after a space is considered as a break point.
+ * Returns true if the current point should be a break point.
+ */
+ @Override
+ protected boolean isBreak(int thisType, int prevType, int nextType) {
+ return prevType == Character.UNASSIGNED || prevType == Character.SPACE_SEPARATOR;
+ }
}
/**
diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
index 7b32d8b..dbab700 100644
--- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
+++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java
@@ -35,9 +35,9 @@
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherAppState;
import com.android.launcher3.LauncherModel;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.allapps.ActivityAllAppsContainerView;
import com.android.launcher3.dragndrop.DragController;
import com.android.launcher3.dragndrop.DragOptions;
@@ -87,7 +87,7 @@
super.onCreate(savedInstanceState);
mModel = LauncherAppState.getInstance(this).getModel();
mDragController = new SecondaryDragController(this);
- mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this));
+ mOnboardingPrefs = new OnboardingPrefs<>(this, LauncherPrefs.getPrefs(this));
mSecondaryDisplayPredictions = SecondaryDisplayPredictions.newInstance(this);
if (getWindow().getDecorView().isAttachedToWindow()) {
initUi();
diff --git a/src/com/android/launcher3/settings/DeveloperOptionsFragment.java b/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
index 6057586..c81214e 100644
--- a/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
+++ b/src/com/android/launcher3/settings/DeveloperOptionsFragment.java
@@ -59,8 +59,8 @@
import androidx.preference.PreferenceViewHolder;
import androidx.preference.SwitchPreference;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
-import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.config.FlagTogglerPrefUi;
import com.android.launcher3.secondarydisplay.SecondaryDisplayLauncher;
@@ -392,7 +392,8 @@
onboardingPref.setTitle(title);
onboardingPref.setSummary("Tap to reset");
onboardingPref.setOnPreferenceClickListener(preference -> {
- SharedPreferences.Editor sharedPrefsEdit = Utilities.getPrefs(getContext()).edit();
+ SharedPreferences.Editor sharedPrefsEdit = LauncherPrefs.getPrefs(getContext())
+ .edit();
for (String key : keys) {
sharedPrefsEdit.remove(key);
}
diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java
index 70956a3..4cb4348 100644
--- a/src/com/android/launcher3/settings/SettingsActivity.java
+++ b/src/com/android/launcher3/settings/SettingsActivity.java
@@ -46,6 +46,7 @@
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.InvariantDeviceProfile;
import com.android.launcher3.LauncherFiles;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
@@ -113,7 +114,8 @@
// Display the fragment as the main content.
fm.beginTransaction().replace(R.id.content_frame, f).commit();
}
- Utilities.getPrefs(getApplicationContext()).registerOnSharedPreferenceChangeListener(this);
+ LauncherPrefs.getPrefs(getApplicationContext())
+ .registerOnSharedPreferenceChangeListener(this);
}
/**
diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java
index b94ea07..642bdcd 100644
--- a/src/com/android/launcher3/states/RotationHelper.java
+++ b/src/com/android/launcher3/states/RotationHelper.java
@@ -36,7 +36,7 @@
import com.android.launcher3.BaseActivity;
import com.android.launcher3.DeviceProfile;
-import com.android.launcher3.Utilities;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.util.DisplayController;
/**
@@ -104,7 +104,7 @@
mIgnoreAutoRotateSettings = ignoreAutoRotateSettings;
if (!mIgnoreAutoRotateSettings) {
if (mSharedPrefs == null) {
- mSharedPrefs = Utilities.getPrefs(mActivity);
+ mSharedPrefs = LauncherPrefs.getPrefs(mActivity);
mSharedPrefs.registerOnSharedPreferenceChangeListener(this);
}
mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY,
diff --git a/src/com/android/launcher3/util/Themes.java b/src/com/android/launcher3/util/Themes.java
index 1728f4d..585bea9 100644
--- a/src/com/android/launcher3/util/Themes.java
+++ b/src/com/android/launcher3/util/Themes.java
@@ -30,6 +30,7 @@
import android.util.SparseArray;
import android.util.TypedValue;
+import com.android.launcher3.LauncherPrefs;
import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.icons.GraphicsUtils;
@@ -73,7 +74,7 @@
* Returns true if workspace icon theming is enabled
*/
public static boolean isThemedIconEnabled(Context context) {
- return Utilities.getPrefs(context).getBoolean(KEY_THEMED_ICONS, false);
+ return LauncherPrefs.getPrefs(context).getBoolean(KEY_THEMED_ICONS, false);
}
public static String getDefaultBodyFont(Context context) {
diff --git a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
index fe30fdc..4e166ce 100644
--- a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
+++ b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt
@@ -16,7 +16,6 @@
package com.android.launcher3
import android.content.Context
-import android.graphics.Point
import android.graphics.PointF
import android.graphics.Rect
import android.util.SparseArray
@@ -26,7 +25,6 @@
import com.android.launcher3.util.WindowBounds
import org.junit.Before
import org.mockito.ArgumentMatchers.any
-import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mockito.mock
import java.io.PrintWriter
import java.io.StringWriter
@@ -42,9 +40,6 @@
protected var transposeLayoutWithOrientation: Boolean = false
protected var useTwoPanels: Boolean = false
protected var isGestureMode: Boolean = true
- protected var devicePaddingsMock: DevicePaddings = mock(DevicePaddings::class.java)
- protected var staticdevicePaddingsMock: DevicePaddings.DevicePadding =
- mock(DevicePaddings.DevicePadding::class.java)
@Before
fun setUp() {
@@ -83,11 +78,6 @@
whenever(info.isTablet(any())).thenReturn(false)
whenever(info.getDensityDpi()).thenReturn(420)
whenever(info.smallestSizeDp(any())).thenReturn(411f)
- whenever(devicePaddingsMock.getDevicePadding(anyInt())).thenReturn(staticdevicePaddingsMock)
- whenever(staticdevicePaddingsMock.getWorkspaceTopPadding(anyInt())).thenReturn(95)
- whenever(staticdevicePaddingsMock.getWorkspaceBottomPadding(anyInt())).thenReturn(116)
- whenever(staticdevicePaddingsMock.maxEmptySpacePx)
- .thenReturn(if (isVerticalBar) if (isGestureMode) 131 else 184 else 315)
this.isGestureMode = isGestureMode
transposeLayoutWithOrientation = true
@@ -152,7 +142,7 @@
inlineQsb = BooleanArray(4) { false }
- devicePaddings = devicePaddingsMock
+ devicePaddingId = R.xml.paddings_handhelds
}
}
@@ -169,13 +159,6 @@
whenever(info.isTablet(any())).thenReturn(true)
whenever(info.getDensityDpi()).thenReturn(320)
whenever(info.smallestSizeDp(any())).thenReturn(800f)
- whenever(devicePaddingsMock.getDevicePadding(anyInt())).thenReturn(staticdevicePaddingsMock)
- whenever(staticdevicePaddingsMock.getWorkspaceTopPadding(anyInt()))
- .thenReturn(if (isLandscape) 32 else 159)
- whenever(staticdevicePaddingsMock.getWorkspaceBottomPadding(anyInt()))
- .thenReturn(if (isLandscape) 72 else 203)
- whenever(staticdevicePaddingsMock.maxEmptySpacePx).thenReturn(if (isLandscape) 200 else 19998)
-
this.isGestureMode = isGestureMode
useTwoPanels = false
@@ -246,7 +229,7 @@
false
)
- devicePaddings = devicePaddingsMock
+ devicePaddingId = R.xml.paddings_handhelds
}
}
@@ -263,15 +246,6 @@
whenever(info.isTablet(any())).thenReturn(true)
whenever(info.getDensityDpi()).thenReturn(420)
whenever(info.smallestSizeDp(any())).thenReturn(700f)
- whenever(devicePaddingsMock.getDevicePadding(anyInt())).thenReturn(staticdevicePaddingsMock)
-
- val topPadding = if (isLandscape) 18 else 89
- val bottomPadding = if (isLandscape) 39 else 146
- val maxEmptySpace = if (isLandscape) 131 else 236
- whenever(staticdevicePaddingsMock.getWorkspaceTopPadding(anyInt())).thenReturn(topPadding)
- whenever(staticdevicePaddingsMock.getWorkspaceBottomPadding(anyInt()))
- .thenReturn(bottomPadding)
- whenever(staticdevicePaddingsMock.maxEmptySpacePx).thenReturn(maxEmptySpace)
this.isGestureMode = isGestureMode
useTwoPanels = true
@@ -342,7 +316,7 @@
false
)
- devicePaddings = devicePaddingsMock
+ devicePaddingId = R.xml.paddings_handhelds
}
}
diff --git a/tests/src/com/android/launcher3/search/StringMatcherUtilityTest.java b/tests/src/com/android/launcher3/search/StringMatcherUtilityTest.java
index 413f404..3b53255 100644
--- a/tests/src/com/android/launcher3/search/StringMatcherUtilityTest.java
+++ b/tests/src/com/android/launcher3/search/StringMatcherUtilityTest.java
@@ -24,6 +24,7 @@
import androidx.test.runner.AndroidJUnit4;
import com.android.launcher3.search.StringMatcherUtility.StringMatcher;
+import com.android.launcher3.search.StringMatcherUtility.StringMatcherSpace;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -34,11 +35,12 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
public class StringMatcherUtilityTest {
- private static final StringMatcher MATCHER =
- StringMatcher.getInstance();
+ private static final StringMatcher MATCHER = StringMatcher.getInstance();
+ private static final StringMatcherSpace MATCHER_SPACE = StringMatcherSpace.getInstance();
@Test
public void testMatches() {
+ assertTrue(matches("white", "white cow", MATCHER));
assertTrue(matches("white ", "white cow", MATCHER));
assertTrue(matches("white c", "white cow", MATCHER));
assertTrue(matches("cow", "white cow", MATCHER));
@@ -93,4 +95,47 @@
assertFalse(matches("ㄷ", "로드라이브", MATCHER));
assertFalse(matches("åç", "abc", MATCHER));
}
+
+ @Test
+ public void testMatchesWithSpaceBreakOnly() {
+ assertTrue(matches("white", "white cow", MATCHER_SPACE));
+ assertTrue(matches("white ", "white cow", MATCHER_SPACE));
+ assertTrue(matches("white c", "white cow", MATCHER_SPACE));
+ assertTrue(matches("cow", "white cow", MATCHER_SPACE));
+ assertTrue(matches("cow", "whitecow cow", MATCHER_SPACE));
+
+ assertFalse(matches("cow", "whiteCow", MATCHER_SPACE));
+ assertFalse(matches("cow", "whiteCOW", MATCHER_SPACE));
+ assertFalse(matches("cow", "whitecowCOW", MATCHER_SPACE));
+ assertFalse(matches("cow", "white2cow", MATCHER_SPACE));
+ assertFalse(matches("cow", "whitecow", MATCHER_SPACE));
+ assertFalse(matches("cow", "whitEcow", MATCHER_SPACE));
+ assertFalse(matches("cow", "whitecowCow", MATCHER_SPACE));
+ assertFalse(matches("cow", "whitecowcow", MATCHER_SPACE));
+ assertFalse(matches("cow", "whit ecowcow", MATCHER_SPACE));
+
+ assertFalse(matches("dog", "cats&dogs", MATCHER_SPACE));
+ assertFalse(matches("dog", "cats&Dogs", MATCHER_SPACE));
+ assertFalse(matches("&", "cats&Dogs", MATCHER_SPACE));
+
+ assertFalse(matches("43", "2+43", MATCHER_SPACE));
+ assertFalse(matches("3", "2+43", MATCHER_SPACE));
+
+ assertTrue(matches("q", "Q", MATCHER_SPACE));
+ assertTrue(matches("q", " Q", MATCHER_SPACE));
+
+ // match lower case words
+ assertTrue(matches("e", "elephant", MATCHER_SPACE));
+ assertTrue(matches("eL", "Elephant", MATCHER_SPACE));
+
+ assertTrue(matches("电", "电子邮件", MATCHER_SPACE));
+ assertTrue(matches("电子", "电子邮件", MATCHER_SPACE));
+ assertTrue(matches("子", "电子邮件", MATCHER_SPACE));
+ assertTrue(matches("邮件", "电子邮件", MATCHER_SPACE));
+
+ assertFalse(matches("ba", "Bot", MATCHER_SPACE));
+ assertFalse(matches("ba", "bot", MATCHER_SPACE));
+ assertFalse(matches("phant", "elephant", MATCHER_SPACE));
+ assertFalse(matches("elephants", "elephant", MATCHER_SPACE));
+ }
}