Merge "Enabling Least square velocity tracker algorithm" into ub-launcher3-master
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
index da58817..5b01185 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduController.java
@@ -26,6 +26,7 @@
import androidx.core.app.NotificationCompat;
+import com.android.launcher3.ArrowTipView;
import com.android.launcher3.CellLayout;
import com.android.launcher3.FolderInfo;
import com.android.launcher3.Hotseat;
@@ -42,6 +43,7 @@
import com.android.launcher3.util.GridOccupancy;
import com.android.launcher3.util.IntArray;
import com.android.launcher3.util.Themes;
+import com.android.launcher3.views.Snackbar;
import java.util.ArrayDeque;
import java.util.ArrayList;
@@ -56,7 +58,11 @@
private static final String NOTIFICATION_CHANNEL_ID = "launcher_onboarding";
private static final int ONBOARDING_NOTIFICATION_ID = 7641;
+ private static final String SETTINGS_ACTION =
+ "android.settings.ACTION_CONTENT_SUGGESTIONS_SETTINGS";
+
private final Launcher mLauncher;
+ private final Hotseat mHotseat;
private final NotificationManager mNotificationManager;
private final Notification mNotification;
private List<WorkspaceItemInfo> mPredictedApps;
@@ -68,6 +74,7 @@
HotseatEduController(Launcher launcher, Runnable runnable) {
mLauncher = launcher;
+ mHotseat = launcher.getHotseat();
mOnOnboardingComplete = runnable;
mNotificationManager = mLauncher.getSystemService(NotificationManager.class);
createNotificationChannel();
@@ -98,7 +105,7 @@
//separate folders and items that can get in folders
for (int i = 0; i < mLauncher.getDeviceProfile().inv.numHotseatIcons; i++) {
- View view = mLauncher.getHotseat().getChildAt(i, 0);
+ View view = mHotseat.getChildAt(i, 0);
if (view == null) continue;
ItemInfo info = (ItemInfo) view.getTag();
if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_FOLDER) {
@@ -178,7 +185,6 @@
*/
private int migrateHotseatWhole() {
Workspace workspace = mLauncher.getWorkspace();
- Hotseat hotseatVG = mLauncher.getHotseat();
int pageId = -1;
int toRow = 0;
@@ -196,7 +202,7 @@
.getInt(LauncherSettings.Settings.EXTRA_VALUE);
}
for (int i = 0; i < mLauncher.getDeviceProfile().inv.numHotseatIcons; i++) {
- View child = hotseatVG.getChildAt(i, 0);
+ View child = mHotseat.getChildAt(i, 0);
if (child == null || child.getTag() == null) continue;
ItemInfo tag = (ItemInfo) child.getTag();
mLauncher.getModelWriter().moveItemInDatabase(tag,
@@ -211,8 +217,8 @@
mNotificationManager.cancel(ONBOARDING_NOTIFICATION_ID);
}
- void finishOnboarding() {
- mLauncher.getHotseat().removeAllViewsInLayout();
+ void moveHotseatItems() {
+ mHotseat.removeAllViewsInLayout();
if (!mNewItems.isEmpty()) {
int lastPage = mNewItems.get(mNewItems.size() - 1).screenId;
ArrayList<ItemInfo> animated = new ArrayList<>();
@@ -227,17 +233,34 @@
}
mLauncher.bindAppsAdded(mNewScreens, nonAnimated, animated);
}
+ }
+
+ void finishOnboarding() {
mOnOnboardingComplete.run();
destroy();
mLauncher.getSharedPrefs().edit().putBoolean(KEY_HOTSEAT_EDU_SEEN, true).apply();
}
+ void showDimissTip() {
+ if (mHotseat.getShortcutsAndWidgets().getChildCount()
+ < mLauncher.getDeviceProfile().inv.numHotseatIcons) {
+ Snackbar.show(mLauncher, R.string.hotseat_tip_gaps_filled, R.string.hotseat_turn_off,
+ null, () -> mLauncher.startActivity(new Intent(SETTINGS_ACTION)));
+ } else {
+ new ArrowTipView(mLauncher).show(
+ mLauncher.getString(R.string.hotseat_tip_no_empty_slots), mHotseat.getTop());
+ }
+ }
+
void setPredictedApps(List<WorkspaceItemInfo> predictedApps) {
mPredictedApps = predictedApps;
if (!mPredictedApps.isEmpty()
&& mLauncher.getOrientation() == Configuration.ORIENTATION_PORTRAIT) {
mNotificationManager.notify(ONBOARDING_NOTIFICATION_ID, mNotification);
}
+ else {
+ removeNotification();
+ }
}
private void createNotificationChannel() {
@@ -275,6 +298,17 @@
}
}
+ void showEdu() {
+ // hotseat is already empty and does not require migration. show edu tip
+ if (mHotseat.getShortcutsAndWidgets().getChildCount() == 0) {
+ new ArrowTipView(mLauncher).show(mLauncher.getString(R.string.hotseat_auto_enrolled),
+ mHotseat.getTop());
+ finishOnboarding();
+ } else {
+ showDialog();
+ }
+ }
+
void showDialog() {
if (mPredictedApps == null || mPredictedApps.isEmpty()) {
return;
@@ -291,7 +325,7 @@
ActivityTracker.SchedulerCallback<QuickstepLauncher> {
@Override
public boolean init(QuickstepLauncher activity, boolean alreadyOnHome) {
- activity.getHotseatPredictionController().showEduDialog();
+ activity.getHotseatPredictionController().showEdu();
return true;
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
index bcce168..8944088 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatEduDialog.java
@@ -16,7 +16,8 @@
package com.android.launcher3.hybridhotseat;
import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.HYBRID_HOTSEAT_CANCELED;
+import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType
+ .HYBRID_HOTSEAT_CANCELED;
import android.animation.PropertyValuesHolder;
import android.content.Context;
@@ -27,9 +28,7 @@
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
-import android.widget.Toast;
-import com.android.launcher3.ArrowTipView;
import com.android.launcher3.CellLayout;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Insettable;
@@ -109,18 +108,16 @@
private void onAccept(View v) {
mHotseatEduController.migrate();
handleClose(true);
+
+ mHotseatEduController.moveHotseatItems();
mHotseatEduController.finishOnboarding();
//TODO: pass actual page index here.
// Temporarily we're passing 1 for folder migration and 2 for page migration
logUserAction(true, FeatureFlags.HOTSEAT_MIGRATE_TO_FOLDER.get() ? 1 : 2);
- int toastStringRes = !FeatureFlags.HOTSEAT_MIGRATE_TO_FOLDER.get()
- ? R.string.hotseat_items_migrated : R.string.hotseat_items_migrated_alt;
- Toast.makeText(mLauncher, toastStringRes, Toast.LENGTH_LONG).show();
}
private void onDismiss(View v) {
- int top = mLauncher.getHotseat().getTop();
- new ArrowTipView(mLauncher).show(mLauncher.getString(R.string.hotseat_no_migration), top);
+ mHotseatEduController.showDimissTip();
mHotseatEduController.finishOnboarding();
logUserAction(false, -1);
handleClose(true);
@@ -166,6 +163,7 @@
target.rank = MIGRATION_EXPERIMENT_IDENTIFIER;
// encoding migration type on pageIndex
target.pageIndex = pageIndex;
+ target.cardinality = HotseatPredictionController.MAX_ITEMS_FOR_MIGRATION;
LauncherLogProto.LauncherEvent event = newLauncherEvent(action, target);
UserEventDispatcher.newInstance(getContext()).dispatchUserEvent(event, null);
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
index d82e9f0..d3bb4f9 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java
@@ -16,6 +16,9 @@
package com.android.launcher3.hybridhotseat;
import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY;
+import static com.android.launcher3.logging.LoggerUtils.newAction;
+import static com.android.launcher3.logging.LoggerUtils.newContainerTarget;
+import static com.android.launcher3.logging.LoggerUtils.newLauncherEvent;
import android.animation.Animator;
import android.animation.AnimatorSet;
@@ -28,6 +31,7 @@
import android.app.prediction.AppTargetId;
import android.content.ComponentName;
import android.os.Bundle;
+import android.provider.DeviceConfig;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
@@ -48,6 +52,7 @@
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.LauncherState;
import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
import com.android.launcher3.WorkspaceItemInfo;
import com.android.launcher3.allapps.AllAppsStore;
@@ -58,9 +63,11 @@
import com.android.launcher3.dragndrop.DragOptions;
import com.android.launcher3.icons.IconCache;
import com.android.launcher3.logging.FileLog;
+import com.android.launcher3.logging.UserEventDispatcher;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.shortcuts.ShortcutKey;
import com.android.launcher3.touch.ItemLongClickListener;
+import com.android.launcher3.uioverrides.DeviceFlag;
import com.android.launcher3.uioverrides.PredictedAppIcon;
import com.android.launcher3.uioverrides.QuickstepLauncher;
import com.android.launcher3.userevent.nano.LauncherLogProto;
@@ -84,6 +91,9 @@
private static final String TAG = "PredictiveHotseat";
private static final boolean DEBUG = false;
+ public static final int MAX_ITEMS_FOR_MIGRATION = DeviceConfig.getInt(
+ DeviceFlag.NAMESPACE_LAUNCHER, "max_homepage_items_for_migration", 5);
+
//TODO: replace this with AppTargetEvent.ACTION_UNPIN (b/144119543)
private static final int APPTARGET_ACTION_UNPIN = 4;
@@ -112,8 +122,8 @@
private HotseatEduController mHotseatEduController;
- private List<PredictedAppIcon.PredictedIconOutlineDrawing> mOutlineDrawings = new ArrayList<>();
+ private List<PredictedAppIcon.PredictedIconOutlineDrawing> mOutlineDrawings = new ArrayList<>();
private final View.OnLongClickListener mPredictionLongClickListener = v -> {
if (!ItemLongClickListener.canStartDrag(mLauncher)) return false;
@@ -146,12 +156,12 @@
}
/**
- * Transitions to NORMAL workspace mode and shows edu dialog
+ * Transitions to NORMAL workspace mode and shows edu
*/
- public void showEduDialog() {
+ public void showEdu() {
if (mHotseatEduController == null) return;
mLauncher.getStateManager().goToState(LauncherState.NORMAL, true,
- () -> mHotseatEduController.showDialog());
+ () -> mHotseatEduController.showEdu());
}
@Override
@@ -277,7 +287,7 @@
mAppPredictor.registerPredictionUpdates(mLauncher.getMainExecutor(),
this::setPredictedApps);
setPauseUIUpdate(false);
-
+ performBetaCheck();
if (!isReady()) {
mHotseatEduController = new HotseatEduController(mLauncher, this::createPredictor);
}
@@ -325,7 +335,7 @@
mComponentKeyMappers.add(new ComponentKeyMapper(key, mDynamicItemCache));
}
predictionLog.append("]");
- if (false) FileLog.d(TAG, predictionLog.toString());
+ if (Utilities.IS_DEBUG_DEVICE) FileLog.d(TAG, predictionLog.toString());
updateDependencies();
if (isReady()) {
fillGapsWithPrediction();
@@ -589,6 +599,39 @@
}
}
+ private void performBetaCheck() {
+ if (isReady()) return;
+ int hotseatItemsCount = mHotseat.getShortcutsAndWidgets().getChildCount();
+
+ // -1 to exclude smart space
+ int workspaceItemCount = mLauncher.getWorkspace().getScreenWithId(
+ Workspace.FIRST_SCREEN_ID).getShortcutsAndWidgets().getChildCount() - 1;
+
+ // opt user into the feature without onboarding tip or migration if they don't have any
+ // open spots in their hotseat and have more than maxItems in their hotseat + workspace
+
+ if (hotseatItemsCount == mHotSeatItemsCount && workspaceItemCount + hotseatItemsCount
+ > MAX_ITEMS_FOR_MIGRATION) {
+ mLauncher.getSharedPrefs().edit().putBoolean(HotseatEduController.KEY_HOTSEAT_EDU_SEEN,
+ true).apply();
+
+ LauncherLogProto.Action action = newAction(LauncherLogProto.Action.Type.TOUCH);
+ LauncherLogProto.Target target = newContainerTarget(LauncherLogProto.ContainerType.TIP);
+ action.touch = LauncherLogProto.Action.Touch.TAP;
+ target.tipType = LauncherLogProto.TipType.HYBRID_HOTSEAT;
+ target.controlType = LauncherLogProto.ControlType.HYBRID_HOTSEAT_CANCELED;
+
+ // temporarily encode details in log target (go/hotseat_migration)
+ target.rank = 2;
+ target.cardinality = MAX_ITEMS_FOR_MIGRATION;
+ target.pageIndex = (workspaceItemCount * 1000) + hotseatItemsCount;
+ LauncherLogProto.LauncherEvent event = newLauncherEvent(action, target);
+ UserEventDispatcher.newInstance(mLauncher).dispatchUserEvent(event, null);
+
+
+ }
+ }
+
/**
* Fill in predicted_rank field based on app prediction.
* Only applicable when {@link ItemInfo#itemType} is PREDICTED_HOTSEAT
diff --git a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index d1a487a..a6eea0c 100644
--- a/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/recents_ui_overrides/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -183,8 +183,8 @@
onStateOrResumeChanged();
}
- if ((changeBits & ACTIVITY_STATE_STARTED) != 0 && mHotseatPredictionController != null
- && (getActivityFlags() & ACTIVITY_STATE_USER_ACTIVE) == 0) {
+ if (mHotseatPredictionController != null && ((changeBits & ACTIVITY_STATE_STARTED) != 0
+ || (changeBits & getActivityFlags() & ACTIVITY_STATE_DEFERRED_RESUMED) != 0)) {
mHotseatPredictionController.setPauseUIUpdate(false);
}
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
index ce7fa0d..9dce984 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/AppToOverviewAnimationProvider.java
@@ -19,7 +19,7 @@
import static com.android.launcher3.LauncherState.OVERVIEW;
import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN;
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
-import static com.android.launcher3.uioverrides.DepthController.DEPTH;
+import static com.android.launcher3.statehandlers.DepthController.DEPTH;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
@@ -34,7 +34,7 @@
import com.android.launcher3.AbstractFloatingView;
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.anim.AnimationSuccessListener;
-import com.android.launcher3.uioverrides.DepthController;
+import com.android.launcher3.statehandlers.DepthController;
import com.android.quickstep.util.AppWindowAnimationHelper;
import com.android.quickstep.util.AppWindowAnimationHelper.TransformParams;
import com.android.quickstep.util.RemoteAnimationProvider;
@@ -105,12 +105,6 @@
mRecentsView.setRunningTaskIconScaledDown(true);
}
- DepthController depthController = mActivityInterface.getDepthController();
- if (depthController != null) {
- // Update the surface to be the lowest closing app surface
- depthController.setSurfaceToLauncher(mRecentsView);
- }
-
AnimatorSet anim = new AnimatorSet();
anim.addListener(new AnimationSuccessListener() {
@Override
@@ -123,11 +117,17 @@
});
if (mActivity == null) {
Log.e(TAG, "Animation created, before activity");
- anim.play(ValueAnimator.ofInt(0, 1).setDuration(RECENTS_LAUNCH_DURATION))
- .with(createDepthAnimator(depthController));
return anim;
}
+ DepthController depthController = mActivityInterface.getDepthController();
+ if (depthController != null) {
+ anim.play(ObjectAnimator.ofFloat(depthController, DEPTH,
+ BACKGROUND_APP.getDepth(mActivity),
+ OVERVIEW.getDepth(mActivity))
+ .setDuration(RECENTS_LAUNCH_DURATION));
+ }
+
RemoteAnimationTargets targets = new RemoteAnimationTargets(appTargets,
wallpaperTargets, MODE_CLOSING);
@@ -135,8 +135,6 @@
RemoteAnimationTargetCompat runningTaskTarget = targets.findTask(mTargetTaskId);
if (runningTaskTarget == null) {
Log.e(TAG, "No closing app");
- anim.play(ValueAnimator.ofInt(0, 1).setDuration(RECENTS_LAUNCH_DURATION))
- .with(createDepthAnimator(depthController));
return anim;
}
@@ -183,8 +181,6 @@
transaction.apply();
});
}
- anim.play(valueAnimator)
- .with(createDepthAnimator(depthController));
return anim;
}
@@ -196,15 +192,4 @@
long getRecentsLaunchDuration() {
return RECENTS_LAUNCH_DURATION;
}
-
- private Animator createDepthAnimator(DepthController depthController) {
- if (depthController == null) {
- // Dummy animation
- return ValueAnimator.ofInt(0);
- }
- return ObjectAnimator.ofFloat(depthController, DEPTH,
- BACKGROUND_APP.getDepth(mActivity),
- OVERVIEW.getDepth(mActivity))
- .setDuration(RECENTS_LAUNCH_DURATION);
- }
}
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
index 55e6ba2..455ae76 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherActivityInterface.java
@@ -55,9 +55,9 @@
import com.android.launcher3.allapps.DiscoveryBounce;
import com.android.launcher3.anim.AnimatorPlaybackController;
import com.android.launcher3.appprediction.PredictionUiStateManager;
+import com.android.launcher3.statehandlers.DepthController;
+import com.android.launcher3.statehandlers.DepthController.ClampedDepthProperty;
import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.uioverrides.DepthController;
-import com.android.launcher3.uioverrides.DepthController.ClampedDepthProperty;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.views.FloatingIconView;
import com.android.quickstep.SysUINavigationMode.Mode;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java
index cafdb62..5bac844 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/LauncherSwipeHandler.java
@@ -294,7 +294,6 @@
}
setupRecentsViewUi();
- mActivityInterface.getDepthController().setSurfaceToLauncher(mRecentsView);
if (mDeviceState.getNavMode() == TWO_BUTTONS) {
// If the device is in two button mode, swiping up will show overview with predictions
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
index 7ec083e..6a3e1fe 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TaskViewUtils.java
@@ -19,7 +19,7 @@
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
-import static com.android.launcher3.uioverrides.DepthController.DEPTH;
+import static com.android.launcher3.statehandlers.DepthController.DEPTH;
import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING;
import android.animation.Animator;
@@ -35,7 +35,7 @@
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Utilities;
-import com.android.launcher3.uioverrides.DepthController;
+import com.android.launcher3.statehandlers.DepthController;
import com.android.quickstep.util.AppWindowAnimationHelper;
import com.android.quickstep.util.MultiValueUpdateListener;
import com.android.quickstep.views.RecentsView;
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
index eb5c7f9..496a3d8 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/TouchInteractionService.java
@@ -22,6 +22,7 @@
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+import static com.android.quickstep.GestureState.DEFAULT_STATE;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_INPUT_MONITOR;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TRACING_ENABLED;
@@ -124,6 +125,7 @@
private static final String NOTIFY_ACTION_BACK = "com.android.quickstep.action.BACK_GESTURE";
private static final String HAS_ENABLED_QUICKSTEP_ONCE = "launcher.has_enabled_quickstep_once";
private static final int MAX_BACK_NOTIFICATION_COUNT = 3;
+
private int mBackGestureNotificationCounter = -1;
@Nullable
private OverscrollPlugin mOverscrollPlugin;
@@ -263,7 +265,7 @@
private InputConsumer mConsumer = InputConsumer.NO_OP;
private Choreographer mMainChoreographer;
private InputConsumer mResetGestureInputConsumer;
- private GestureState mGestureState = new GestureState();
+ private GestureState mGestureState = DEFAULT_STATE;
private InputMonitorCompat mInputMonitorCompat;
private InputEventReceiver mInputEventReceiver;
@@ -435,16 +437,14 @@
Object traceToken = TraceHelper.INSTANCE.beginFlagsOverride(
TraceHelper.FLAG_ALLOW_BINDER_TRACKING);
- mDeviceState.setOrientationTransformIfNeeded(event);
final int action = event.getAction();
if (action == ACTION_DOWN) {
- GestureState newGestureState = new GestureState(mOverviewComponentObserver,
- ActiveGestureLog.INSTANCE.generateAndSetLogId());
- newGestureState.updateRunningTask(TraceHelper.whitelistIpcs("getRunningTask.0",
- () -> mAM.getRunningTask(0)));
+ mDeviceState.setOrientationTransformIfNeeded(event);
+ GestureState newGestureState;
if (mDeviceState.isInSwipeUpTouchRegion(event)) {
+ newGestureState = createGestureState();
mConsumer.onConsumerAboutToBeSwitched();
mConsumer = newConsumer(mGestureState, newGestureState, event);
@@ -453,6 +453,7 @@
} else if (mDeviceState.isUserUnlocked()
&& mDeviceState.isFullyGesturalNavMode()
&& mDeviceState.canTriggerAssistantAction(event)) {
+ newGestureState = createGestureState();
// Do not change mConsumer as if there is an ongoing QuickSwitch gesture, we should
// not interrupt it. QuickSwitch assumes that interruption can only happen if the
// next gesture is also quick switch.
@@ -462,11 +463,18 @@
InputConsumer.NO_OP, mInputMonitorCompat,
mOverviewComponentObserver.assistantGestureIsConstrained());
} else {
+ newGestureState = DEFAULT_STATE;
mUncheckedConsumer = InputConsumer.NO_OP;
}
// Save the current gesture state
mGestureState = newGestureState;
+ } else {
+ // Other events
+ if (mUncheckedConsumer != InputConsumer.NO_OP) {
+ // Only transform the event if we are handling it in a proper consumer
+ mDeviceState.setOrientationTransformIfNeeded(event);
+ }
}
ActiveGestureLog.INSTANCE.addLog("onMotionEvent", event.getActionMasked());
@@ -481,6 +489,14 @@
TraceHelper.INSTANCE.endFlagsOverride(traceToken);
}
+ private GestureState createGestureState() {
+ GestureState gestureState = new GestureState(mOverviewComponentObserver,
+ ActiveGestureLog.INSTANCE.generateAndSetLogId());
+ gestureState.updateRunningTask(TraceHelper.whitelistIpcs("getRunningTask.0",
+ () -> mAM.getRunningTask(0)));
+ return gestureState;
+ }
+
private InputConsumer newConsumer(GestureState previousGestureState,
GestureState newGestureState, MotionEvent event) {
boolean canStartSystemGesture = mDeviceState.canStartSystemGesture();
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
index a027fea..24703bd 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/LauncherRecentsView.java
@@ -37,9 +37,9 @@
import android.view.View;
import android.widget.FrameLayout;
+import com.android.launcher3.BaseQuickstepLauncher;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.Hotseat;
-import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
import com.android.launcher3.LauncherStateManager.StateListener;
import com.android.launcher3.R;
@@ -47,8 +47,8 @@
import com.android.launcher3.appprediction.PredictionUiStateManager;
import com.android.launcher3.appprediction.PredictionUiStateManager.Client;
import com.android.launcher3.config.FeatureFlags;
+import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.states.RotationHelper;
-import com.android.launcher3.uioverrides.DepthController;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.util.TraceHelper;
import com.android.launcher3.views.ScrimView;
@@ -63,7 +63,8 @@
* {@link RecentsView} used in Launcher activity
*/
@TargetApi(Build.VERSION_CODES.O)
-public class LauncherRecentsView extends RecentsView<Launcher> implements StateListener {
+public class LauncherRecentsView extends RecentsView<BaseQuickstepLauncher>
+ implements StateListener {
private static final Rect sTempRect = new Rect();
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
index 68c51a0..57a9940 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/RecentsView.java
@@ -30,7 +30,7 @@
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.config.FeatureFlags.ENABLE_OVERVIEW_ACTIONS;
import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE;
-import static com.android.launcher3.uioverrides.DepthController.DEPTH;
+import static com.android.launcher3.statehandlers.DepthController.DEPTH;
import static com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController.SUCCESS_TRANSITION_PROGRESS;
import static com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch.TAP;
import static com.android.launcher3.userevent.nano.LauncherLogProto.ControlType.CLEAR_ALL_BUTTON;
@@ -96,9 +96,9 @@
import com.android.launcher3.compat.AccessibilityManagerCompat;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.graphics.RotationMode;
+import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.states.RotationHelper;
import com.android.launcher3.touch.PagedOrientationHandler.CurveProperties;
-import com.android.launcher3.uioverrides.DepthController;
import com.android.launcher3.userevent.nano.LauncherLogProto;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Direction;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action.Touch;
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index b55b042..ab34f47 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -78,16 +78,21 @@
<string name="hotseat_edu_message_migrate">Easily access your most-used apps right on the Home screen. Suggestions will change based on your routines. Apps on the bottom row will move up to your Home screen. </string>
<string name="hotseat_edu_message_migrate_alt">Easily access your most-used apps, right on the Home screen. Suggestions will change based on your routines. Apps on the bottom row will move to a new folder.</string>
- <!-- Toast message user sees after opting into fully predicted hybrid hotseat -->
- <string name="hotseat_items_migrated">Your hotseat items have been moved up to your homescreen</string>
- <string name="hotseat_items_migrated_alt">Your hotseat items have been moved to a folder</string>
- <!-- Toast message user sees after opting into fully predicted hybrid hotseat -->
- <string name="hotseat_no_migration">Drag apps off the bottom row to see app suggestions</string>
<!-- Button text to opt in for fully predicted hotseat -->
<string name="hotseat_edu_accept">Get app suggestions</string>
<!-- Button text to dismiss opt in for fully predicted hotseat -->
<string name="hotseat_edu_dismiss">No thanks</string>
+ <!-- action shown to turn off predictions after onboarding -->
+ <string name="hotseat_turn_off">Settings</string>
+
+ <!-- tip shown if user has no items in hotseat to migrate -->
+ <string name="hotseat_auto_enrolled">Most-used apps appear here, and change based on routines</string>
+ <!-- tip shown if user declines migration and has no open spots for prediction -->
+ <string name="hotseat_tip_no_empty_slots">Drag apps off the bottom row to get app suggestions</string>
+ <!-- tip shown if user declines migration and has some open spots for prediction -->
+ <string name="hotseat_tip_gaps_filled">App suggestions added to empty space</string>
+
<!-- Title shown during interactive part of Back gesture tutorial for right edge. [CHAR LIMIT=30] -->
<string name="back_gesture_tutorial_playground_title_swipe_inward_right_edge" translatable="false">Try the back gesture</string>
diff --git a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
index ec66f11..83c67bb 100644
--- a/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/BaseQuickstepLauncher.java
@@ -43,8 +43,9 @@
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.proxy.ProxyActivityStarter;
import com.android.launcher3.proxy.StartActivityParams;
+import com.android.launcher3.statehandlers.BackButtonAlphaHandler;
+import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.uioverrides.BackButtonAlphaHandler;
import com.android.launcher3.uioverrides.RecentsViewStateController;
import com.android.launcher3.util.UiThreadHelper;
import com.android.quickstep.RecentsModel;
@@ -67,6 +68,7 @@
public abstract class BaseQuickstepLauncher extends Launcher
implements NavigationModeChangeListener {
+ private DepthController mDepthController = new DepthController(this);
protected SystemActions mSystemActions;
/**
@@ -249,6 +251,10 @@
new BackButtonAlphaHandler(this)};
}
+ public DepthController getDepthController() {
+ return mDepthController;
+ }
+
@Override
protected ScaleAndTranslation getOverviewScaleAndTranslationForNormalState() {
if (SysUINavigationMode.getMode(this) == Mode.NO_BUTTON) {
@@ -294,6 +300,10 @@
onLauncherStateOrFocusChanged();
}
+ if ((changeBits & ACTIVITY_STATE_STARTED) != 0) {
+ mDepthController.setActivityStarted(isStarted());
+ }
+
super.onActivityFlagsChanged(changeBits);
}
diff --git a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
index c93a4ba..a30e102 100644
--- a/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
+++ b/quickstep/src/com/android/launcher3/QuickstepAppTransitionManagerImpl.java
@@ -33,7 +33,7 @@
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION;
import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_TRANSITIONS;
-import static com.android.launcher3.uioverrides.DepthController.DEPTH;
+import static com.android.launcher3.statehandlers.DepthController.DEPTH;
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
import static com.android.quickstep.TaskUtils.taskIsATargetWithMode;
import static com.android.systemui.shared.system.QuickStepContract.getWindowCornerRadius;
@@ -72,7 +72,7 @@
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.shortcuts.DeepShortcutView;
-import com.android.launcher3.uioverrides.DepthController;
+import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.util.DynamicResource;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.launcher3.util.MultiValueAlpha.AlphaProperty;
@@ -622,7 +622,7 @@
backgroundRadiusAnim.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- depthController.setSurfaceToLauncher(mLauncher.getDragLayer());
+ depthController.setSurfaceToApp(null);
}
});
}
diff --git a/quickstep/src/com/android/launcher3/uioverrides/BackButtonAlphaHandler.java b/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
similarity index 95%
rename from quickstep/src/com/android/launcher3/uioverrides/BackButtonAlphaHandler.java
rename to quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
index e82a504..983702a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/BackButtonAlphaHandler.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/BackButtonAlphaHandler.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.launcher3.uioverrides;
+package com.android.launcher3.statehandlers;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.quickstep.AnimatedFloat.VALUE;
@@ -29,6 +29,9 @@
import com.android.quickstep.SysUINavigationMode;
import com.android.quickstep.SystemUiProxy;
+/**
+ * State handler for animating back button alpha
+ */
public class BackButtonAlphaHandler implements LauncherStateManager.StateHandler {
private final BaseQuickstepLauncher mLauncher;
diff --git a/quickstep/src/com/android/launcher3/uioverrides/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
similarity index 84%
rename from quickstep/src/com/android/launcher3/uioverrides/DepthController.java
rename to quickstep/src/com/android/launcher3/statehandlers/DepthController.java
index 8995a7e..24ba89a 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/DepthController.java
+++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java
@@ -14,13 +14,14 @@
* limitations under the License.
*/
-package com.android.launcher3.uioverrides;
+package com.android.launcher3.statehandlers;
import static com.android.launcher3.anim.Interpolators.LINEAR;
import android.os.IBinder;
import android.util.FloatProperty;
import android.view.View;
+import android.view.ViewTreeObserver;
import com.android.launcher3.Launcher;
import com.android.launcher3.LauncherState;
@@ -77,6 +78,16 @@
}
}
+ private final ViewTreeObserver.OnDrawListener mOnDrawListener =
+ new ViewTreeObserver.OnDrawListener() {
+ @Override
+ public void onDraw() {
+ View view = mLauncher.getDragLayer();
+ setSurface(new SurfaceControlCompat(view));
+ view.post(() -> view.getViewTreeObserver().removeOnDrawListener(this));
+ }
+ };
+
private final Launcher mLauncher;
/**
* Blur radius when completely zoomed out, in pixels.
@@ -103,21 +114,28 @@
}
/**
+ * Sets if the underlying activity is started or not
+ */
+ public void setActivityStarted(boolean isStarted) {
+ if (isStarted) {
+ mLauncher.getDragLayer().getViewTreeObserver().addOnDrawListener(mOnDrawListener);
+ } else {
+ mLauncher.getDragLayer().getViewTreeObserver().removeOnDrawListener(mOnDrawListener);
+ setSurface(null);
+ }
+ }
+
+ /**
* Sets the specified app target surface to apply the blur to.
*/
public void setSurfaceToApp(RemoteAnimationTargetCompat target) {
if (target != null) {
setSurface(target.leash);
+ } else {
+ setActivityStarted(mLauncher.isStarted());
}
}
- /**
- * Sets the surface to apply the blur to as the launcher surface.
- */
- public void setSurfaceToLauncher(View v) {
- setSurface(v != null ? new SurfaceControlCompat(v) : null);
- }
-
private void setSurface(SurfaceControlCompat surface) {
if (mSurface != surface) {
mSurface = surface;
diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
index 2a569f5..94ef15a 100644
--- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java
@@ -32,8 +32,8 @@
import com.android.launcher3.BaseDraggingActivity;
import com.android.launcher3.DeviceProfile;
import com.android.launcher3.anim.AnimatorPlaybackController;
+import com.android.launcher3.statehandlers.DepthController;
import com.android.launcher3.touch.PagedOrientationHandler;
-import com.android.launcher3.uioverrides.DepthController;
import com.android.quickstep.util.ActivityInitListener;
import com.android.quickstep.util.ShelfPeekAnim;
import com.android.systemui.shared.recents.model.ThumbnailData;
diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java
index 501c6f0..f7e40ca 100644
--- a/quickstep/src/com/android/quickstep/GestureState.java
+++ b/quickstep/src/com/android/quickstep/GestureState.java
@@ -64,6 +64,8 @@
private static final String TAG = "GestureState";
private static final ArrayList<String> STATE_NAMES = new ArrayList<>();
+ public static final GestureState DEFAULT_STATE = new GestureState();
+
private static int FLAG_COUNT = 0;
private static int getFlagForIndex(String name) {
if (DEBUG_STATES) {
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
index 1299a53..491c611 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java
@@ -22,6 +22,7 @@
import static com.android.quickstep.SysUINavigationMode.Mode.TWO_BUTTONS;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BUBBLES_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NAV_BAR_HIDDEN;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
@@ -356,6 +357,7 @@
return (mSystemUiStateFlags & SYSUI_STATE_NAV_BAR_HIDDEN) == 0
&& (mSystemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) == 0
&& (mSystemUiStateFlags & SYSUI_STATE_QUICK_SETTINGS_EXPANDED) == 0
+ && (mSystemUiStateFlags & SYSUI_STATE_BUBBLES_EXPANDED) == 0
&& ((mSystemUiStateFlags & SYSUI_STATE_HOME_DISABLED) == 0
|| (mSystemUiStateFlags & SYSUI_STATE_OVERVIEW_DISABLED) == 0);
}
diff --git a/res/layout/work_apps_paused.xml b/res/layout/work_apps_paused.xml
index cf1e835..f64b2d9 100644
--- a/res/layout/work_apps_paused.xml
+++ b/res/layout/work_apps_paused.xml
@@ -20,7 +20,7 @@
android:gravity="center">
<TextView
- style="@style/TextHeadline"
+ style="@style/PrimaryMediumText"
android:textColor="?attr/workProfileOverlayTextColor"
android:id="@+id/work_apps_paused_title"
android:layout_width="wrap_content"
diff --git a/src/com/android/launcher3/BaseRecyclerView.java b/src/com/android/launcher3/BaseRecyclerView.java
index 38e1201..9e8441a 100644
--- a/src/com/android/launcher3/BaseRecyclerView.java
+++ b/src/com/android/launcher3/BaseRecyclerView.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.util.AttributeSet;
+import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
@@ -25,6 +26,7 @@
import androidx.recyclerview.widget.RecyclerView;
import com.android.launcher3.compat.AccessibilityManagerCompat;
+import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.views.RecyclerViewFastScroller;
@@ -177,6 +179,10 @@
public void onScrollStateChanged(int state) {
super.onScrollStateChanged(state);
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "onScrollStateChanged: " + state);
+ }
+
if (state == SCROLL_STATE_IDLE) {
AccessibilityManagerCompat.sendScrollFinishedEventToTest(getContext());
}
diff --git a/src/com/android/launcher3/FolderInfo.java b/src/com/android/launcher3/FolderInfo.java
index 336e423..b75a5e7 100644
--- a/src/com/android/launcher3/FolderInfo.java
+++ b/src/com/android/launcher3/FolderInfo.java
@@ -79,7 +79,7 @@
* Add an app or shortcut for a specified rank.
*/
public void add(WorkspaceItemInfo item, int rank, boolean animate) {
- rank = Utilities.boundToRange(rank, 0, contents.size() + 1);
+ rank = Utilities.boundToRange(rank, 0, contents.size());
contents.add(rank, item);
for (int i = 0; i < mListeners.size(); i++) {
mListeners.get(i).onAdd(item, rank);
diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java
index a83a694..573aa07 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -77,7 +77,6 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.OvershootInterpolator;
import android.widget.Toast;
@@ -115,6 +114,7 @@
import com.android.launcher3.model.ModelWriter;
import com.android.launcher3.notification.NotificationListener;
import com.android.launcher3.pm.PinRequestHelper;
+import com.android.launcher3.pm.UserCache;
import com.android.launcher3.popup.PopupContainerWithArrow;
import com.android.launcher3.popup.PopupDataProvider;
import com.android.launcher3.popup.SystemShortcut;
@@ -124,7 +124,6 @@
import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.touch.AllAppsSwipeController;
import com.android.launcher3.touch.ItemClickHandler;
-import com.android.launcher3.uioverrides.DepthController;
import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
@@ -139,6 +138,7 @@
import com.android.launcher3.util.PackageManagerHelper;
import com.android.launcher3.util.PackageUserKey;
import com.android.launcher3.util.PendingRequestArgs;
+import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.util.ShortcutUtil;
import com.android.launcher3.util.SystemUiController;
import com.android.launcher3.util.Themes;
@@ -326,20 +326,10 @@
private boolean mDeferOverlayCallbacks;
private final Runnable mDeferredOverlayCallbacks = this::checkIfOverlayStillDeferred;
- private DepthController mDepthController =
- new DepthController(this);
-
- private final ViewTreeObserver.OnDrawListener mOnDrawListener =
- new ViewTreeObserver.OnDrawListener() {
- @Override
- public void onDraw() {
- getDepthController().setSurfaceToLauncher(mDragLayer);
- mDragLayer.post(() -> mDragLayer.getViewTreeObserver().removeOnDrawListener(
- this));
- }
- };
-
private long mLastTouchUpTime = -1;
+ private boolean mTouchInProgress;
+
+ private SafeCloseable mUserChangedCallbackCloseable;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -459,6 +449,9 @@
});
TraceHelper.INSTANCE.endSection(traceToken);
+
+ mUserChangedCallbackCloseable = UserCache.INSTANCE.get(this).addUserChangeListener(
+ () -> getStateManager().goToState(NORMAL));
}
protected LauncherOverlayManager getDefaultOverlay() {
@@ -760,8 +753,8 @@
data.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1) : -1;
if (resultCode == RESULT_CANCELED) {
completeTwoStageWidgetDrop(RESULT_CANCELED, appWidgetId, requestArgs);
- mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,
- ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);
+ mWorkspace.removeExtraEmptyScreenDelayed(
+ ON_ACTIVITY_RESULT_ANIMATION_DELAY, false, exitSpringLoaded);
} else if (resultCode == RESULT_OK) {
addAppWidgetImpl(
appWidgetId, requestArgs, null,
@@ -791,15 +784,9 @@
"returned from the widget configuration activity.");
result = RESULT_CANCELED;
completeTwoStageWidgetDrop(result, appWidgetId, requestArgs);
- final Runnable onComplete = new Runnable() {
- @Override
- public void run() {
- getStateManager().goToState(NORMAL);
- }
- };
-
- mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,
- ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);
+ mWorkspace.removeExtraEmptyScreenDelayed(
+ ON_ACTIVITY_RESULT_ANIMATION_DELAY, false,
+ () -> getStateManager().goToState(NORMAL));
} else {
if (requestArgs.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
// When the screen id represents an actual screen (as opposed to a rank)
@@ -818,8 +805,8 @@
dropLayout.setDropPending(false);
}
};
- mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete,
- ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);
+ mWorkspace.removeExtraEmptyScreenDelayed(
+ ON_ACTIVITY_RESULT_ANIMATION_DELAY, false, onComplete);
}
return;
}
@@ -838,12 +825,12 @@
// Handle custom shortcuts created using ACTION_CREATE_SHORTCUT.
if (resultCode == RESULT_OK && requestArgs.container != ItemInfo.NO_ID) {
completeAdd(requestCode, data, -1, requestArgs);
- mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,
- ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);
+ mWorkspace.removeExtraEmptyScreenDelayed(
+ ON_ACTIVITY_RESULT_ANIMATION_DELAY, false, exitSpringLoaded);
} else if (resultCode == RESULT_CANCELED) {
- mWorkspace.removeExtraEmptyScreenDelayed(true, exitSpringLoaded,
- ON_ACTIVITY_RESULT_ANIMATION_DELAY, false);
+ mWorkspace.removeExtraEmptyScreenDelayed(
+ ON_ACTIVITY_RESULT_ANIMATION_DELAY, false, exitSpringLoaded);
}
}
@@ -942,8 +929,6 @@
final int origDragLayerChildCount = mDragLayer.getChildCount();
super.onStop();
- mDragLayer.getViewTreeObserver().removeOnDrawListener(mOnDrawListener);
-
if (mDeferOverlayCallbacks) {
checkIfOverlayStillDeferred();
} else {
@@ -956,7 +941,6 @@
NotificationListener.removeNotificationsChangedListener();
getStateManager().moveToRestState();
- getDepthController().setSurfaceToLauncher(null);
// Workaround for b/78520668, explicitly trim memory once UI is hidden
onTrimMemory(TRIM_MEMORY_UI_HIDDEN);
@@ -984,7 +968,6 @@
if (!mDeferOverlayCallbacks) {
mOverlayManager.onActivityStarted(this);
}
- mDragLayer.getViewTreeObserver().addOnDrawListener(mOnDrawListener);
mAppWidgetHost.setListenIfResumed(true);
TraceHelper.INSTANCE.endSection(traceToken);
@@ -1207,7 +1190,6 @@
mScrimView = findViewById(R.id.scrim_view);
// Setup the drag controller (drop targets have to be added in reverse order in priority)
- mDragController.setMoveTarget(mWorkspace);
mDropTargetBar.setup(mDragController);
mAllAppsController.setupViews(mAppsView);
@@ -1507,11 +1489,7 @@
target.pageIndex = mWorkspace.getCurrentPage();
ued.logActionCommand(Action.Command.HOME_INTENT, target,
newContainerTarget(ContainerType.WORKSPACE));
-
- final View v = getWindow().peekDecorView();
- if (v != null && v.getWindowToken() != null) {
- UiThreadHelper.hideKeyboardAsync(this, v.getWindowToken());
- }
+ hideKeyboard();
if (mLauncherCallbacks != null) {
mLauncherCallbacks.onHomeIntent(internalStateHandled);
@@ -1522,6 +1500,16 @@
TraceHelper.INSTANCE.endSection(traceToken);
}
+ /**
+ * Hides the keyboard if visible
+ */
+ public void hideKeyboard() {
+ final View v = getWindow().peekDecorView();
+ if (v != null && v.getWindowToken() != null) {
+ UiThreadHelper.hideKeyboardAsync(this, v.getWindowToken());
+ }
+ }
+
@Override
public void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
@@ -1589,6 +1577,7 @@
mOverlayManager.onActivityDestroyed(this);
mAppTransitionManager.unregisterRemoteAnimations();
+ mUserChangedCallbackCloseable.close();
}
public LauncherAccessibilityDelegate getAccessibilityDelegate() {
@@ -1682,7 +1671,7 @@
};
completeAddAppWidget(appWidgetId, info, boundWidget,
addFlowHandler.getProviderInfo(this));
- mWorkspace.removeExtraEmptyScreenDelayed(true, onComplete, delay, false);
+ mWorkspace.removeExtraEmptyScreenDelayed(delay, false, onComplete);
}
}
@@ -1840,13 +1829,28 @@
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
- if (ev.getAction() == MotionEvent.ACTION_UP) {
- mLastTouchUpTime = System.currentTimeMillis();
+ switch (ev.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ mTouchInProgress = true;
+ break;
+ case MotionEvent.ACTION_UP:
+ mLastTouchUpTime = System.currentTimeMillis();
+ // Follow through
+ case MotionEvent.ACTION_CANCEL:
+ mTouchInProgress = false;
+ break;
}
TestLogging.recordMotionEvent(TestProtocol.SEQUENCE_MAIN, "Touch event", ev);
return super.dispatchTouchEvent(ev);
}
+ /**
+ * Returns true if a touch interaction is in progress
+ */
+ public boolean isTouchInProgress() {
+ return mTouchInProgress;
+ }
+
@Override
public void onBackPressed() {
if (finishAutoCancelActionMode()) {
@@ -2112,7 +2116,7 @@
}
// Remove the extra empty screen
- mWorkspace.removeExtraEmptyScreen(false, false);
+ mWorkspace.removeExtraEmptyScreen(false);
}
/**
@@ -2716,8 +2720,7 @@
}
protected StateHandler[] createStateHandlers() {
- return new StateHandler[] { getAllAppsController(), getWorkspace(),
- getDepthController() };
+ return new StateHandler[] { getAllAppsController(), getWorkspace() };
}
public TouchController[] createTouchControllers() {
@@ -2754,10 +2757,6 @@
return Stream.of(APP_INFO, WIDGETS, INSTALL);
}
- public DepthController getDepthController() {
- return mDepthController;
- }
-
public static Launcher getLauncher(Context context) {
return fromContext(context);
}
diff --git a/src/com/android/launcher3/LauncherStateManager.java b/src/com/android/launcher3/LauncherStateManager.java
index 24d0c41..e071777 100644
--- a/src/com/android/launcher3/LauncherStateManager.java
+++ b/src/com/android/launcher3/LauncherStateManager.java
@@ -324,6 +324,7 @@
public AnimatorPlaybackController createAnimationToNewWorkspace(LauncherState state,
StateAnimationConfig config) {
+ config.userControlled = true;
mConfig.reset();
config.copyTo(mConfig);
mConfig.playbackController = createAnimationToNewWorkspaceInternal(state)
diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java
index c42e480..ee9c099 100644
--- a/src/com/android/launcher3/Workspace.java
+++ b/src/com/android/launcher3/Workspace.java
@@ -29,7 +29,6 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.LayoutTransition;
-import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.annotation.SuppressLint;
@@ -43,7 +42,6 @@
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Handler;
-import android.os.IBinder;
import android.os.Message;
import android.os.Parcelable;
import android.os.UserHandle;
@@ -125,9 +123,6 @@
private static final boolean ENFORCE_DRAG_EVENT_ORDER = false;
- private static final int SNAP_OFF_EMPTY_SCREEN_DURATION = 400;
- private static final int FADE_EMPTY_SCREEN_DURATION = 150;
-
private static final int ADJACENT_SCREEN_DROP_DURATION = 300;
private static final int DEFAULT_PAGE = 0;
@@ -140,7 +135,6 @@
@Thunk final IntSparseArrayMap<CellLayout> mWorkspaceScreens = new IntSparseArrayMap<>();
@Thunk final IntArray mScreenOrder = new IntArray();
- @Thunk Runnable mRemoveEmptyScreenRunnable;
@Thunk boolean mDeferRemoveExtraEmptyScreen = false;
/**
@@ -428,7 +422,7 @@
}
if (!mDeferRemoveExtraEmptyScreen) {
- removeExtraEmptyScreen(true, mDragSourceInternal != null);
+ removeExtraEmptyScreen(mDragSourceInternal != null);
}
updateChildrenLayersEnabled();
@@ -453,8 +447,16 @@
private void setupLayoutTransition() {
// We want to show layout transitions when pages are deleted, to close the gap.
mLayoutTransition = new LayoutTransition();
+
mLayoutTransition.enableTransitionType(LayoutTransition.DISAPPEARING);
mLayoutTransition.enableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
+ // Change the interpolators such that the fade animation plays before the move animation.
+ // This prevents empty adjacent pages to overlay during animation
+ mLayoutTransition.setInterpolator(LayoutTransition.DISAPPEARING,
+ Interpolators.clampToProgress(Interpolators.ACCEL_DEACCEL, 0, 0.5f));
+ mLayoutTransition.setInterpolator(LayoutTransition.CHANGE_DISAPPEARING,
+ Interpolators.clampToProgress(Interpolators.ACCEL_DEACCEL, 0.5f, 1));
+
mLayoutTransition.disableTransitionType(LayoutTransition.APPEARING);
mLayoutTransition.disableTransitionType(LayoutTransition.CHANGE_APPEARING);
setLayoutTransition(mLayoutTransition);
@@ -571,9 +573,6 @@
boolean lastChildOnScreen = false;
boolean childOnFinalScreen = false;
- // Cancel any pending removal of empty screen
- mRemoveEmptyScreenRunnable = null;
-
if (mDragSourceInternal != null) {
if (mDragSourceInternal.getChildCount() == 1) {
lastChildOnScreen = true;
@@ -624,43 +623,34 @@
}
}
- public void removeExtraEmptyScreen(final boolean animate, boolean stripEmptyScreens) {
- removeExtraEmptyScreenDelayed(animate, null, 0, stripEmptyScreens);
+ public void removeExtraEmptyScreen(boolean stripEmptyScreens) {
+ removeExtraEmptyScreenDelayed(0, stripEmptyScreens, null);
}
- public void removeExtraEmptyScreenDelayed(final boolean animate, final Runnable onComplete,
- final int delay, final boolean stripEmptyScreens) {
+ public void removeExtraEmptyScreenDelayed(
+ int delay, boolean stripEmptyScreens, Runnable onComplete) {
if (mLauncher.isWorkspaceLoading()) {
// Don't strip empty screens if the workspace is still loading
return;
}
if (delay > 0) {
- postDelayed(new Runnable() {
- @Override
- public void run() {
- removeExtraEmptyScreenDelayed(animate, onComplete, 0, stripEmptyScreens);
- }
- }, delay);
+ postDelayed(
+ () -> removeExtraEmptyScreenDelayed(0, stripEmptyScreens, onComplete), delay);
return;
}
convertFinalScreenToEmptyScreenIfNecessary();
if (hasExtraEmptyScreen()) {
- int emptyIndex = mScreenOrder.indexOf(EXTRA_EMPTY_SCREEN_ID);
- if (getNextPage() == emptyIndex) {
- snapToPage(getNextPage() - 1, SNAP_OFF_EMPTY_SCREEN_DURATION);
- fadeAndRemoveEmptyScreen(SNAP_OFF_EMPTY_SCREEN_DURATION, FADE_EMPTY_SCREEN_DURATION,
- onComplete, stripEmptyScreens);
- } else {
- snapToPage(getNextPage(), 0);
- fadeAndRemoveEmptyScreen(0, FADE_EMPTY_SCREEN_DURATION,
- onComplete, stripEmptyScreens);
- }
- return;
- } else if (stripEmptyScreens) {
- // If we're not going to strip the empty screens after removing
- // the extra empty screen, do it right away.
+ removeView(mWorkspaceScreens.get(EXTRA_EMPTY_SCREEN_ID));
+ mWorkspaceScreens.remove(EXTRA_EMPTY_SCREEN_ID);
+ mScreenOrder.removeValue(EXTRA_EMPTY_SCREEN_ID);
+
+ // Update the page indicator to reflect the removed page.
+ showPageIndicatorAtCurrentScroll();
+ }
+
+ if (stripEmptyScreens) {
stripEmptyScreens();
}
@@ -669,44 +659,6 @@
}
}
- private void fadeAndRemoveEmptyScreen(int delay, int duration, final Runnable onComplete,
- final boolean stripEmptyScreens) {
- // XXX: Do we need to update LM workspace screens below?
- final CellLayout cl = mWorkspaceScreens.get(EXTRA_EMPTY_SCREEN_ID);
-
- mRemoveEmptyScreenRunnable = new Runnable() {
- @Override
- public void run() {
- if (hasExtraEmptyScreen()) {
- mWorkspaceScreens.remove(EXTRA_EMPTY_SCREEN_ID);
- mScreenOrder.removeValue(EXTRA_EMPTY_SCREEN_ID);
- removeView(cl);
- if (stripEmptyScreens) {
- stripEmptyScreens();
- }
- // Update the page indicator to reflect the removed page.
- showPageIndicatorAtCurrentScroll();
- }
- }
- };
-
- ObjectAnimator oa = ObjectAnimator.ofFloat(cl, ALPHA, 0f);
- oa.setDuration(duration);
- oa.setStartDelay(delay);
- oa.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- if (mRemoveEmptyScreenRunnable != null) {
- mRemoveEmptyScreenRunnable.run();
- }
- if (onComplete != null) {
- onComplete.run();
- }
- }
- });
- oa.start();
- }
-
public boolean hasExtraEmptyScreen() {
return mWorkspaceScreens.containsKey(EXTRA_EMPTY_SCREEN_ID) && getChildCount() > 1;
}
@@ -793,8 +745,6 @@
}
}
- boolean isInAccessibleDrag = mLauncher.getAccessibilityDelegate().isInAccessibleDrag();
-
// We enforce at least one page to add new items to. In the case that we remove the last
// such screen, we convert the last screen to the empty screen
int minScreens = 1;
@@ -813,7 +763,6 @@
removeView(cl);
} else {
// if this is the last screen, convert it to the empty screen
- mRemoveEmptyScreenRunnable = null;
mWorkspaceScreens.put(EXTRA_EMPTY_SCREEN_ID, cl);
mScreenOrder.add(EXTRA_EMPTY_SCREEN_ID);
}
@@ -1224,10 +1173,8 @@
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- IBinder windowToken = getWindowToken();
- mWallpaperOffset.setWindowToken(windowToken);
+ mWallpaperOffset.setWindowToken(getWindowToken());
computeScroll();
- mDragController.setWindowToken(windowToken);
}
protected void onDetachedFromWindow() {
diff --git a/src/com/android/launcher3/allapps/AllAppsContainerView.java b/src/com/android/launcher3/allapps/AllAppsContainerView.java
index dd0212a..8d1a102 100644
--- a/src/com/android/launcher3/allapps/AllAppsContainerView.java
+++ b/src/com/android/launcher3/allapps/AllAppsContainerView.java
@@ -406,6 +406,11 @@
setupWorkToggle();
mAH[AdapterHolder.MAIN].setup(mViewPager.getChildAt(0), mPersonalMatcher);
mAH[AdapterHolder.WORK].setup(mViewPager.getChildAt(1), mWorkMatcher);
+ mViewPager.getPageIndicator().setActiveMarker(AdapterHolder.MAIN);
+ findViewById(R.id.tab_personal)
+ .setOnClickListener((View view) -> mViewPager.snapToPage(AdapterHolder.MAIN));
+ findViewById(R.id.tab_work)
+ .setOnClickListener((View view) -> mViewPager.snapToPage(AdapterHolder.WORK));
onTabChanged(mViewPager.getNextPage());
} else {
mAH[AdapterHolder.MAIN].setup(findViewById(R.id.apps_list_view), null);
@@ -456,16 +461,10 @@
public void onTabChanged(int pos) {
mHeader.setMainActive(pos == 0);
- reset(true /* animate */);
- mViewPager.getPageIndicator().updateTabTextColor(pos);
if (mAH[pos].recyclerView != null) {
mAH[pos].recyclerView.bindFastScrollbar();
-
- findViewById(R.id.tab_personal)
- .setOnClickListener((View view) -> mViewPager.snapToPage(AdapterHolder.MAIN));
- findViewById(R.id.tab_work)
- .setOnClickListener((View view) -> mViewPager.snapToPage(AdapterHolder.WORK));
}
+ reset(true /* animate */);
if (mWorkModeSwitch != null) {
mWorkModeSwitch.setWorkTabVisible(pos == AdapterHolder.WORK);
}
diff --git a/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java b/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java
index 3e40392..2515c24 100644
--- a/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java
+++ b/src/com/android/launcher3/allapps/PersonalWorkSlidingTabStrip.java
@@ -135,6 +135,7 @@
@Override
public void setActiveMarker(int activePage) {
updateTabTextColor(activePage);
+ updateIndicatorPosition(activePage);
if (mContainerView != null && mLastActivePage != activePage) {
mContainerView.onTabChanged(activePage);
}
diff --git a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
index 1d32d1d..737c97b 100644
--- a/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
+++ b/src/com/android/launcher3/compat/AccessibilityManagerCompat.java
@@ -75,6 +75,9 @@
}
public static void sendScrollFinishedEventToTest(Context context) {
+ if (TestProtocol.sDebugTracing) {
+ Log.d(TestProtocol.NO_SCROLL_END_WIDGETS, "sendScrollFinishedEventToTest");
+ }
final AccessibilityManager accessibilityManager = getAccessibilityManagerForTest(context);
if (accessibilityManager == null) return;
diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java
index 92f5112..1cc8a98 100644
--- a/src/com/android/launcher3/config/FeatureFlags.java
+++ b/src/com/android/launcher3/config/FeatureFlags.java
@@ -163,7 +163,7 @@
"Always use hardware optimization for folder animations.");
public static final BooleanFlag ENABLE_FIXED_ROTATION_TRANSFORM = getDebugFlag(
- FLAG_ENABLE_FIXED_ROTATION_TRANSFORM, true,
+ FLAG_ENABLE_FIXED_ROTATION_TRANSFORM, false,
"Launch/close apps without rotation animation. Fix Launcher to portrait");
public static void initialize(Context context) {
diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java
index d0d9aaf..db61f59 100644
--- a/src/com/android/launcher3/dragndrop/DragController.java
+++ b/src/com/android/launcher3/dragndrop/DragController.java
@@ -20,6 +20,7 @@
import static com.android.launcher3.LauncherAnimUtils.SPRING_LOADED_EXIT_DELAY;
import static com.android.launcher3.LauncherState.NORMAL;
import static com.android.launcher3.Utilities.ATLEAST_Q;
+import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.animation.ValueAnimator;
import android.content.ComponentName;
@@ -27,7 +28,6 @@
import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
-import android.os.IBinder;
import android.view.DragEvent;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
@@ -44,7 +44,6 @@
import com.android.launcher3.accessibility.DragViewStateAnnouncer;
import com.android.launcher3.util.ItemInfoMatcher;
import com.android.launcher3.util.TouchController;
-import com.android.launcher3.util.UiThreadHelper;
import java.util.ArrayList;
@@ -64,7 +63,7 @@
private final FlingToDeleteHelper mFlingToDeleteHelper;
// temporaries to avoid gc thrash
- private Rect mRectTemp = new Rect();
+ private final Rect mRectTemp = new Rect();
private final int[] mCoordinatesTemp = new int[2];
/**
@@ -86,21 +85,14 @@
private DropTarget.DragObject mDragObject;
/** Who can receive drop events */
- private ArrayList<DropTarget> mDropTargets = new ArrayList<>();
- private ArrayList<DragListener> mListeners = new ArrayList<>();
-
- /** The window token used as the parent for the DragView. */
- private IBinder mWindowToken;
-
- private View mMoveTarget;
+ private final ArrayList<DropTarget> mDropTargets = new ArrayList<>();
+ private final ArrayList<DragListener> mListeners = new ArrayList<>();
private DropTarget mLastDropTarget;
private int mLastTouchClassification;
private int mDistanceSinceScroll = 0;
- private Rect mDragLayerRect = new Rect();
-
private boolean mIsInPreDrag;
/**
@@ -153,8 +145,7 @@
android.os.Debug.startMethodTracing("Launcher");
}
- // Hide soft keyboard, if visible
- UiThreadHelper.hideKeyboardAsync(mLauncher, mWindowToken);
+ mLauncher.hideKeyboard();
AbstractFloatingView.closeOpenViews(mLauncher, false, TYPE_DISCOVERY_BOUNCE);
mOptions = options;
@@ -217,6 +208,11 @@
handleMoveEvent(mLastTouch.x, mLastTouch.y);
mLauncher.getUserEventDispatcher().resetActionDurationMillis();
+
+ if (!mLauncher.isTouchInProgress() && options.simulatedDndStartPoint == null) {
+ // If it is an internal drag and the touch is already complete, cancel immediately
+ MAIN_EXECUTOR.submit(this::cancelDrag);
+ }
return dragView;
}
@@ -362,9 +358,9 @@
* Clamps the position to the drag layer bounds.
*/
private Point getClampedDragLayerPos(float x, float y) {
- mLauncher.getDragLayer().getLocalVisibleRect(mDragLayerRect);
- mTmpPoint.x = (int) Math.max(mDragLayerRect.left, Math.min(x, mDragLayerRect.right - 1));
- mTmpPoint.y = (int) Math.max(mDragLayerRect.top, Math.min(y, mDragLayerRect.bottom - 1));
+ mLauncher.getDragLayer().getLocalVisibleRect(mRectTemp);
+ mTmpPoint.x = (int) Math.max(mRectTemp.left, Math.min(x, mRectTemp.right - 1));
+ mTmpPoint.y = (int) Math.max(mRectTemp.top, Math.min(y, mRectTemp.bottom - 1));
return mTmpPoint;
}
@@ -439,17 +435,6 @@
return mDragDriver != null && mDragDriver.onDragEvent(event);
}
- /**
- * Sets the view that should handle move events.
- */
- public void setMoveTarget(View view) {
- mMoveTarget = view;
- }
-
- public boolean dispatchUnhandledMove(View focused, int direction) {
- return mMoveTarget != null && mMoveTarget.dispatchUnhandledMove(focused, direction);
- }
-
private void handleMoveEvent(int x, int y) {
mDragObject.dragView.move(x, y);
@@ -593,10 +578,6 @@
return mLauncher.getWorkspace();
}
- public void setWindowToken(IBinder token) {
- mWindowToken = token;
- }
-
/**
* Sets the drag listener which will be notified when a drag starts or ends.
*/
diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java
index e18ca54..9ece3d3 100644
--- a/src/com/android/launcher3/dragndrop/DragLayer.java
+++ b/src/com/android/launcher3/dragndrop/DragLayer.java
@@ -21,6 +21,7 @@
import static android.view.View.MeasureSpec.getMode;
import static android.view.View.MeasureSpec.getSize;
+import static com.android.launcher3.anim.Interpolators.DEACCEL_1_5;
import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent;
import android.animation.Animator;
@@ -49,7 +50,6 @@
import com.android.launcher3.R;
import com.android.launcher3.ShortcutAndWidgetContainer;
import com.android.launcher3.Workspace;
-import com.android.launcher3.anim.Interpolators;
import com.android.launcher3.folder.Folder;
import com.android.launcher3.graphics.OverviewScrim;
import com.android.launcher3.graphics.RotationMode;
@@ -74,11 +74,11 @@
public static final int ANIMATION_END_DISAPPEAR = 0;
public static final int ANIMATION_END_REMAIN_VISIBLE = 2;
- @Thunk DragController mDragController;
+ private DragController mDragController;
// Variables relating to animation of views after drop
private ValueAnimator mDropAnim = null;
- private final TimeInterpolator mCubicEaseOutInterpolator = Interpolators.DEACCEL_1_5;
+
@Thunk DragView mDropView = null;
@Thunk int mAnchorViewInitialScrollX = 0;
@Thunk View mAnchorView = null;
@@ -88,13 +88,14 @@
private int mTopViewIndex;
private int mChildCountOnLastUpdate = -1;
- private Rect mTmpRect = new Rect();
-
// Related to adjacent page hints
private final ViewGroupFocusHelper mFocusIndicatorHelper;
private final WorkspaceAndHotseatScrim mWorkspaceScrim;
private final OverviewScrim mOverviewScrim;
+ // View that should handle move events
+ private View mMoveTarget;
+
/**
* Used to create a new DragLayer from XML.
*
@@ -116,6 +117,7 @@
public void setup(DragController dragController, Workspace workspace) {
mDragController = dragController;
mWorkspaceScrim.setWorkspace(workspace);
+ mMoveTarget = workspace;
recreateControllers();
}
@@ -223,7 +225,7 @@
@Override
public boolean dispatchUnhandledMove(View focused, int direction) {
return super.dispatchUnhandledMove(focused, direction)
- || mDragController.dispatchUnhandledMove(focused, direction);
+ || mMoveTarget.dispatchUnhandledMove(focused, direction);
}
@Override
@@ -260,9 +262,10 @@
parentChildren.measureChild(child);
parentChildren.layoutChild(child);
- getViewRectRelativeToSelf(dragView, mTmpRect);
- final int fromX = mTmpRect.left;
- final int fromY = mTmpRect.top;
+ Rect dragViewBounds = new Rect();
+ getViewRectRelativeToSelf(dragView, dragViewBounds);
+ final int fromX = dragViewBounds.left;
+ final int fromY = dragViewBounds.top;
float coord[] = new float[2];
float childScale = child.getScaleX();
@@ -283,15 +286,15 @@
if (child instanceof DraggableView) {
DraggableView d = (DraggableView) child;
- d.getVisualDragBounds(mTmpRect);
+ d.getVisualDragBounds(dragViewBounds);
// This accounts for the offset of the DragView created by scaling it about its
// center as it animates into place.
float scaleShiftX = dragView.getMeasuredWidth() * (1 - scale) / 2;
float scaleShiftY = dragView.getMeasuredHeight() * (1 - scale) / 2;
- toX += scale * (mTmpRect.left - dragView.getBlurSizeOutline() / 2) - scaleShiftX;
- toY += scale * (mTmpRect.top - dragView.getBlurSizeOutline() / 2) - scaleShiftY;
+ toX += scale * (dragViewBounds.left - dragView.getBlurSizeOutline() / 2) - scaleShiftX;
+ toY += scale * (dragViewBounds.top - dragView.getBlurSizeOutline() / 2) - scaleShiftY;
}
child.setVisibility(INVISIBLE);
@@ -348,7 +351,7 @@
if (duration < 0) {
duration = res.getInteger(R.integer.config_dropAnimMaxDuration);
if (dist < maxDist) {
- duration *= mCubicEaseOutInterpolator.getInterpolation(dist / maxDist);
+ duration *= DEACCEL_1_5.getInterpolation(dist / maxDist);
}
duration = Math.max(duration, res.getInteger(R.integer.config_dropAnimMinDuration));
}
@@ -356,7 +359,7 @@
// Fall back to cubic ease out interpolator for the animation if none is specified
TimeInterpolator interpolator = null;
if (alphaInterpolator == null || motionInterpolator == null) {
- interpolator = mCubicEaseOutInterpolator;
+ interpolator = DEACCEL_1_5;
}
// Animate the view
diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java
index 14fa1f4..365e76f 100644
--- a/src/com/android/launcher3/folder/Folder.java
+++ b/src/com/android/launcher3/folder/Folder.java
@@ -81,6 +81,7 @@
import com.android.launcher3.PagedView;
import com.android.launcher3.R;
import com.android.launcher3.ShortcutAndWidgetContainer;
+import com.android.launcher3.Utilities;
import com.android.launcher3.Workspace;
import com.android.launcher3.Workspace.ItemOperator;
import com.android.launcher3.WorkspaceItemInfo;
@@ -962,6 +963,7 @@
View icon = (mCurrentDragView != null && mCurrentDragView.getTag() == info)
? mCurrentDragView : mContent.createNewView(info);
ArrayList<View> views = getIconsInReadingOrder();
+ info.rank = Utilities.boundToRange(info.rank, 0, views.size());
views.add(info.rank, icon);
mContent.arrangeChildren(views);
mItemsInvalidated = true;
diff --git a/src/com/android/launcher3/logging/LoggerUtils.java b/src/com/android/launcher3/logging/LoggerUtils.java
index a9d10d7..1b70fde 100644
--- a/src/com/android/launcher3/logging/LoggerUtils.java
+++ b/src/com/android/launcher3/logging/LoggerUtils.java
@@ -15,8 +15,6 @@
*/
package com.android.launcher3.logging;
-import static com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType.NAVBAR;
-
import android.util.ArrayMap;
import android.util.SparseArray;
import android.view.View;
@@ -27,12 +25,9 @@
import com.android.launcher3.LauncherSettings;
import com.android.launcher3.userevent.nano.LauncherLogExtensions.TargetExtension;
import com.android.launcher3.userevent.nano.LauncherLogProto.Action;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ContainerType;
-import com.android.launcher3.userevent.nano.LauncherLogProto.ControlType;
import com.android.launcher3.userevent.nano.LauncherLogProto.ItemType;
import com.android.launcher3.userevent.nano.LauncherLogProto.LauncherEvent;
import com.android.launcher3.userevent.nano.LauncherLogProto.Target;
-import com.android.launcher3.userevent.nano.LauncherLogProto.TipType;
import com.android.launcher3.util.InstantAppResolver;
import java.lang.reflect.Field;
@@ -70,93 +65,6 @@
return result != null ? result : UNKNOWN;
}
- public static String getActionStr(Action action) {
- String str = "";
- switch (action.type) {
- case Action.Type.TOUCH:
- str += getFieldName(action.touch, Action.Touch.class);
- if (action.touch == Action.Touch.SWIPE || action.touch == Action.Touch.FLING) {
- str += " direction=" + getFieldName(action.dir, Action.Direction.class);
- }
- break;
- case Action.Type.COMMAND:
- str += getFieldName(action.command, Action.Command.class);
- break;
- default: return getFieldName(action.type, Action.Type.class);
- }
- if (action.touch == Action.Touch.SWIPE || action.touch == Action.Touch.FLING ||
- (action.command == Action.Command.BACK && action.dir != Action.Direction.NONE)) {
- str += " direction=" + getFieldName(action.dir, Action.Direction.class);
- }
- return str;
- }
-
- public static String getTargetStr(Target t) {
- if (t == null) {
- return "";
- }
- String str = "";
- switch (t.type) {
- case Target.Type.ITEM:
- str = getItemStr(t);
- break;
- case Target.Type.CONTROL:
- str = getFieldName(t.controlType, ControlType.class);
- break;
- case Target.Type.CONTAINER:
- str = getFieldName(t.containerType, ContainerType.class);
- if (t.containerType == ContainerType.WORKSPACE ||
- t.containerType == ContainerType.HOTSEAT ||
- t.containerType == NAVBAR) {
- str += " id=" + t.pageIndex;
- } else if (t.containerType == ContainerType.FOLDER) {
- str += " grid(" + t.gridX + "," + t.gridY + ")";
- }
- break;
- default:
- str += "UNKNOWN TARGET TYPE";
- }
-
- if (t.spanX != 1 || t.spanY != 1) {
- str += " span(" + t.spanX + "," + t.spanY + ")";
- }
-
- if (t.tipType != TipType.DEFAULT_NONE) {
- str += " " + getFieldName(t.tipType, TipType.class);
- }
-
- return str;
- }
-
- private static String getItemStr(Target t) {
- String typeStr = getFieldName(t.itemType, ItemType.class);
- if (t.packageNameHash != 0) {
- typeStr += ", packageHash=" + t.packageNameHash;
- }
- if (t.componentHash != 0) {
- typeStr += ", componentHash=" + t.componentHash;
- }
- if (t.intentHash != 0) {
- typeStr += ", intentHash=" + t.intentHash;
- }
- if (t.itemType == ItemType.FOLDER_ICON) {
- typeStr += ", grid(" + t.gridX + "," + t.gridY + ")";
- } else if ((t.packageNameHash != 0 || t.componentHash != 0 || t.intentHash != 0)
- && t.itemType != ItemType.TASK) {
- typeStr +=
- ", isWorkApp=" + t.isWorkApp + ", predictiveRank=" + t.predictedRank + ", grid("
- + t.gridX + "," + t.gridY + "), span(" + t.spanX + "," + t.spanY
- + "), pageIdx=" + t.pageIndex;
- }
- if (t.searchQueryLength != 0) {
- typeStr += ", searchQueryLength=" + t.searchQueryLength;
- }
- if (t.itemType == ItemType.TASK) {
- typeStr += ", pageIdx=" + t.pageIndex;
- }
- return typeStr;
- }
-
public static Target newItemTarget(int itemType) {
Target t = newTarget(Target.Type.ITEM);
t.itemType = itemType;
diff --git a/src/com/android/launcher3/pm/UserCache.java b/src/com/android/launcher3/pm/UserCache.java
index 678b647..f723256 100644
--- a/src/com/android/launcher3/pm/UserCache.java
+++ b/src/com/android/launcher3/pm/UserCache.java
@@ -95,7 +95,7 @@
private void removeUserChangeListener(Runnable command) {
synchronized (this) {
- mUserChangeListeners.add(command);
+ mUserChangeListeners.remove(command);
if (mUserChangeListeners.isEmpty()) {
// Disable cache and stop listening
mContext.unregisterReceiver(mUserChangeReceiver);
diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java
index fae0fe2..8c8aa9b 100644
--- a/src/com/android/launcher3/states/RotationHelper.java
+++ b/src/com/android/launcher3/states/RotationHelper.java
@@ -134,7 +134,7 @@
*/
private void updateForcedRotation(boolean setValueFromPrefs) {
boolean isForcedRotation = mFeatureFlagsPrefs
- .getBoolean(FLAG_ENABLE_FIXED_ROTATION_TRANSFORM, true)
+ .getBoolean(FLAG_ENABLE_FIXED_ROTATION_TRANSFORM, false)
&& !getAllowRotationDefaultValue();
if (mForcedRotation == isForcedRotation) {
return;
diff --git a/src/com/android/launcher3/states/SpringLoadedState.java b/src/com/android/launcher3/states/SpringLoadedState.java
index 97c67c5..2ba624c 100644
--- a/src/com/android/launcher3/states/SpringLoadedState.java
+++ b/src/com/android/launcher3/states/SpringLoadedState.java
@@ -17,6 +17,7 @@
import static com.android.launcher3.states.RotationHelper.REQUEST_LOCK;
+import android.content.Context;
import android.graphics.Rect;
import com.android.launcher3.DeviceProfile;
@@ -77,6 +78,11 @@
}
@Override
+ public float getDepth(Context context) {
+ return 0.5f;
+ }
+
+ @Override
public ScaleAndTranslation getHotseatScaleAndTranslation(Launcher launcher) {
return new ScaleAndTranslation(1, 0, 0);
}
diff --git a/src/com/android/launcher3/testing/TestProtocol.java b/src/com/android/launcher3/testing/TestProtocol.java
index 97ce65e..dd97b10 100644
--- a/src/com/android/launcher3/testing/TestProtocol.java
+++ b/src/com/android/launcher3/testing/TestProtocol.java
@@ -95,4 +95,5 @@
public static final String NO_BACKGROUND_TO_OVERVIEW_TAG = "b/138251824";
public static final String APP_NOT_DISABLED = "b/139891609";
+ public static final String NO_SCROLL_END_WIDGETS = "b/152354290";
}
diff --git a/src/com/android/launcher3/views/ClipIconView.java b/src/com/android/launcher3/views/ClipIconView.java
new file mode 100644
index 0000000..478141a
--- /dev/null
+++ b/src/com/android/launcher3/views/ClipIconView.java
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.views;
+
+import static com.android.launcher3.Utilities.mapToRange;
+import static com.android.launcher3.anim.Interpolators.LINEAR;
+import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Outline;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.drawable.AdaptiveIconDrawable;
+import android.graphics.drawable.ColorDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewOutlineProvider;
+
+import androidx.annotation.Nullable;
+import androidx.dynamicanimation.animation.FloatPropertyCompat;
+import androidx.dynamicanimation.animation.SpringAnimation;
+import androidx.dynamicanimation.animation.SpringForce;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.InsettableFrameLayout.LayoutParams;
+import com.android.launcher3.Launcher;
+import com.android.launcher3.R;
+import com.android.launcher3.Utilities;
+import com.android.launcher3.dragndrop.FolderAdaptiveIcon;
+import com.android.launcher3.graphics.IconShape;
+
+/**
+ * A view used to draw both layers of an {@link AdaptiveIconDrawable}.
+ * Supports springing just the foreground layer.
+ * Supports clipping the icon to/from its icon shape.
+ */
+@TargetApi(Build.VERSION_CODES.Q)
+public class ClipIconView extends View implements ClipPathView {
+
+ private static final Rect sTmpRect = new Rect();
+
+ // We spring the foreground drawable relative to the icon's movement in the DragLayer.
+ // We then use these two factor values to scale the movement of the fg within this view.
+ private static final int FG_TRANS_X_FACTOR = 60;
+ private static final int FG_TRANS_Y_FACTOR = 75;
+
+ private static final FloatPropertyCompat<ClipIconView> mFgTransYProperty =
+ new FloatPropertyCompat<ClipIconView>("ClipIconViewFgTransY") {
+ @Override
+ public float getValue(ClipIconView view) {
+ return view.mFgTransY;
+ }
+
+ @Override
+ public void setValue(ClipIconView view, float transY) {
+ view.mFgTransY = transY;
+ view.invalidate();
+ }
+ };
+
+ private static final FloatPropertyCompat<ClipIconView> mFgTransXProperty =
+ new FloatPropertyCompat<ClipIconView>("ClipIconViewFgTransX") {
+ @Override
+ public float getValue(ClipIconView view) {
+ return view.mFgTransX;
+ }
+
+ @Override
+ public void setValue(ClipIconView view, float transX) {
+ view.mFgTransX = transX;
+ view.invalidate();
+ }
+ };
+
+ private final Launcher mLauncher;
+ private final int mBlurSizeOutline;
+ private final boolean mIsRtl;
+
+ private @Nullable Drawable mForeground;
+ private @Nullable Drawable mBackground;
+
+ private boolean mIsVerticalBarLayout = false;
+ private boolean mIsAdaptiveIcon = false;
+
+ private ValueAnimator mRevealAnimator;
+
+ private final Rect mStartRevealRect = new Rect();
+ private final Rect mEndRevealRect = new Rect();
+ private Path mClipPath;
+ private float mTaskCornerRadius;
+
+ private final Rect mOutline = new Rect();
+ private final Rect mFinalDrawableBounds = new Rect();
+
+ private final SpringAnimation mFgSpringY;
+ private float mFgTransY;
+ private final SpringAnimation mFgSpringX;
+ private float mFgTransX;
+
+ public ClipIconView(Context context) {
+ this(context, null);
+ }
+
+ public ClipIconView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public ClipIconView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ mLauncher = Launcher.getLauncher(context);
+ mBlurSizeOutline = getResources().getDimensionPixelSize(
+ R.dimen.blur_size_medium_outline);
+ mIsRtl = Utilities.isRtl(getResources());
+
+ mFgSpringX = new SpringAnimation(this, mFgTransXProperty)
+ .setSpring(new SpringForce()
+ .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)
+ .setStiffness(SpringForce.STIFFNESS_LOW));
+ mFgSpringY = new SpringAnimation(this, mFgTransYProperty)
+ .setSpring(new SpringForce()
+ .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)
+ .setStiffness(SpringForce.STIFFNESS_LOW));
+ }
+
+ void update(RectF rect, float progress, float shapeProgressStart, float cornerRadius,
+ boolean isOpening, float scale, float minSize, LayoutParams parentLp) {
+ DeviceProfile dp = mLauncher.getDeviceProfile();
+ float dX = mIsRtl
+ ? rect.left - (dp.widthPx - parentLp.getMarginStart() - parentLp.width)
+ : rect.left - parentLp.getMarginStart();
+ float dY = rect.top - parentLp.topMargin;
+
+ // shapeRevealProgress = 1 when progress = shapeProgressStart + SHAPE_PROGRESS_DURATION
+ float toMax = isOpening ? 1 / SHAPE_PROGRESS_DURATION : 1f;
+ float shapeRevealProgress = Utilities.boundToRange(mapToRange(
+ Math.max(shapeProgressStart, progress), shapeProgressStart, 1f, 0, toMax,
+ LINEAR), 0, 1);
+
+ if (mIsVerticalBarLayout) {
+ mOutline.right = (int) (rect.width() / scale);
+ } else {
+ mOutline.bottom = (int) (rect.height() / scale);
+ }
+
+ mTaskCornerRadius = cornerRadius / scale;
+ if (mIsAdaptiveIcon) {
+ if (!isOpening && progress >= shapeProgressStart) {
+ if (mRevealAnimator == null) {
+ mRevealAnimator = (ValueAnimator) IconShape.getShape().createRevealAnimator(
+ this, mStartRevealRect, mOutline, mTaskCornerRadius, !isOpening);
+ mRevealAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mRevealAnimator = null;
+ }
+ });
+ mRevealAnimator.start();
+ // We pause here so we can set the current fraction ourselves.
+ mRevealAnimator.pause();
+ }
+ mRevealAnimator.setCurrentFraction(shapeRevealProgress);
+ }
+
+ float drawableScale = (mIsVerticalBarLayout ? mOutline.width() : mOutline.height())
+ / minSize;
+ setBackgroundDrawableBounds(drawableScale);
+ if (isOpening) {
+ // Center align foreground
+ int height = mFinalDrawableBounds.height();
+ int width = mFinalDrawableBounds.width();
+ int diffY = mIsVerticalBarLayout ? 0
+ : (int) (((height * drawableScale) - height) / 2);
+ int diffX = mIsVerticalBarLayout ? (int) (((width * drawableScale) - width) / 2)
+ : 0;
+ sTmpRect.set(mFinalDrawableBounds);
+ sTmpRect.offset(diffX, diffY);
+ mForeground.setBounds(sTmpRect);
+ } else {
+ // Spring the foreground relative to the icon's movement within the DragLayer.
+ int diffX = (int) (dX / dp.availableWidthPx * FG_TRANS_X_FACTOR);
+ int diffY = (int) (dY / dp.availableHeightPx * FG_TRANS_Y_FACTOR);
+
+ mFgSpringX.animateToFinalPosition(diffX);
+ mFgSpringY.animateToFinalPosition(diffY);
+ }
+ }
+ invalidate();
+ invalidateOutline();
+ }
+
+ private void setBackgroundDrawableBounds(float scale) {
+ sTmpRect.set(mFinalDrawableBounds);
+ Utilities.scaleRectAboutCenter(sTmpRect, scale);
+ // Since the drawable is at the top of the view, we need to offset to keep it centered.
+ if (mIsVerticalBarLayout) {
+ sTmpRect.offsetTo((int) (mFinalDrawableBounds.left * scale), sTmpRect.top);
+ } else {
+ sTmpRect.offsetTo(sTmpRect.left, (int) (mFinalDrawableBounds.top * scale));
+ }
+ mBackground.setBounds(sTmpRect);
+ }
+
+ protected void endReveal() {
+ if (mRevealAnimator != null) {
+ mRevealAnimator.end();
+ }
+ }
+
+ void setIcon(@Nullable Drawable drawable, int iconOffset, LayoutParams lp, boolean isOpening) {
+ mIsAdaptiveIcon = drawable instanceof AdaptiveIconDrawable;
+ if (mIsAdaptiveIcon) {
+ boolean isFolderIcon = drawable instanceof FolderAdaptiveIcon;
+
+ AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) drawable;
+ Drawable background = adaptiveIcon.getBackground();
+ if (background == null) {
+ background = new ColorDrawable(Color.TRANSPARENT);
+ }
+ mBackground = background;
+ Drawable foreground = adaptiveIcon.getForeground();
+ if (foreground == null) {
+ foreground = new ColorDrawable(Color.TRANSPARENT);
+ }
+ mForeground = foreground;
+
+ final int originalHeight = lp.height;
+ final int originalWidth = lp.width;
+
+ int blurMargin = mBlurSizeOutline / 2;
+ mFinalDrawableBounds.set(0, 0, originalWidth, originalHeight);
+
+ if (!isFolderIcon) {
+ mFinalDrawableBounds.inset(iconOffset - blurMargin, iconOffset - blurMargin);
+ }
+ mForeground.setBounds(mFinalDrawableBounds);
+ mBackground.setBounds(mFinalDrawableBounds);
+
+ mStartRevealRect.set(0, 0, originalWidth, originalHeight);
+
+ if (!isFolderIcon) {
+ Utilities.scaleRectAboutCenter(mStartRevealRect, IconShape.getNormalizationScale());
+ }
+
+ float aspectRatio = mLauncher.getDeviceProfile().aspectRatio;
+ if (mIsVerticalBarLayout) {
+ lp.width = (int) Math.max(lp.width, lp.height * aspectRatio);
+ } else {
+ lp.height = (int) Math.max(lp.height, lp.width * aspectRatio);
+ }
+
+ int left = mIsRtl
+ ? mLauncher.getDeviceProfile().widthPx - lp.getMarginStart() - lp.width
+ : lp.leftMargin;
+ layout(left, lp.topMargin, left + lp.width, lp.topMargin + lp.height);
+
+ float scale = Math.max((float) lp.height / originalHeight,
+ (float) lp.width / originalWidth);
+ float bgDrawableStartScale;
+ if (isOpening) {
+ bgDrawableStartScale = 1f;
+ mOutline.set(0, 0, originalWidth, originalHeight);
+ } else {
+ bgDrawableStartScale = scale;
+ mOutline.set(0, 0, lp.width, lp.height);
+ }
+ setBackgroundDrawableBounds(bgDrawableStartScale);
+ mEndRevealRect.set(0, 0, lp.width, lp.height);
+ setOutlineProvider(new ViewOutlineProvider() {
+ @Override
+ public void getOutline(View view, Outline outline) {
+ outline.setRoundRect(mOutline, mTaskCornerRadius);
+ }
+ });
+ setClipToOutline(true);
+ } else {
+ setBackground(drawable);
+ setClipToOutline(false);
+ }
+
+ invalidate();
+ invalidateOutline();
+ }
+
+ @Override
+ public void setClipPath(Path clipPath) {
+ mClipPath = clipPath;
+ invalidate();
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ int count = canvas.save();
+ if (mClipPath != null) {
+ canvas.clipPath(mClipPath);
+ }
+ super.draw(canvas);
+ if (mBackground != null) {
+ mBackground.draw(canvas);
+ }
+ if (mForeground != null) {
+ int count2 = canvas.save();
+ canvas.translate(mFgTransX, mFgTransY);
+ mForeground.draw(canvas);
+ canvas.restoreToCount(count2);
+ }
+ canvas.restoreToCount(count);
+ }
+
+ void recycle() {
+ setBackground(null);
+ mIsAdaptiveIcon = false;
+ mForeground = null;
+ mBackground = null;
+ mClipPath = null;
+ mFinalDrawableBounds.setEmpty();
+ if (mRevealAnimator != null) {
+ mRevealAnimator.cancel();
+ }
+ mRevealAnimator = null;
+ mTaskCornerRadius = 0;
+ mOutline.setEmpty();
+ mFgTransY = 0;
+ mFgSpringX.cancel();
+ mFgTransX = 0;
+ mFgSpringY.cancel();
+ }
+}
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index d41bb86..3e2560f 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -18,8 +18,6 @@
import static com.android.launcher3.LauncherAnimUtils.DRAWABLE_ALPHA;
import static com.android.launcher3.Utilities.getBadge;
import static com.android.launcher3.Utilities.getFullDrawable;
-import static com.android.launcher3.Utilities.mapToRange;
-import static com.android.launcher3.anim.Interpolators.LINEAR;
import static com.android.launcher3.config.FeatureFlags.ADAPTIVE_ICON_WINDOW_ANIM;
import static com.android.launcher3.states.RotationHelper.REQUEST_LOCK;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
@@ -28,17 +26,12 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
-import android.animation.ValueAnimator;
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Outline;
-import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.AdaptiveIconDrawable;
-import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.CancellationSignal;
@@ -46,19 +39,17 @@
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
-import android.view.ViewOutlineProvider;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.annotation.WorkerThread;
-import androidx.dynamicanimation.animation.FloatPropertyCompat;
-import androidx.dynamicanimation.animation.SpringAnimation;
-import androidx.dynamicanimation.animation.SpringForce;
import com.android.launcher3.BubbleTextView;
-import com.android.launcher3.InsettableFrameLayout.LayoutParams;
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.InsettableFrameLayout;
import com.android.launcher3.ItemInfo;
import com.android.launcher3.Launcher;
import com.android.launcher3.R;
@@ -66,7 +57,6 @@
import com.android.launcher3.dragndrop.DragLayer;
import com.android.launcher3.dragndrop.FolderAdaptiveIcon;
import com.android.launcher3.folder.FolderIcon;
-import com.android.launcher3.graphics.IconShape;
import com.android.launcher3.icons.LauncherIcons;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.shortcuts.DeepShortcutView;
@@ -75,8 +65,8 @@
* A view that is created to look like another view with the purpose of creating fluid animations.
*/
@TargetApi(Build.VERSION_CODES.Q)
-public class FloatingIconView extends View implements
- Animator.AnimatorListener, ClipPathView, OnGlobalLayoutListener {
+public class FloatingIconView extends FrameLayout implements
+ Animator.AnimatorListener, OnGlobalLayoutListener {
private static final String TAG = FloatingIconView.class.getSimpleName();
@@ -85,81 +75,34 @@
public static final float SHAPE_PROGRESS_DURATION = 0.10f;
private static final int FADE_DURATION_MS = 200;
- private static final Rect sTmpRect = new Rect();
private static final RectF sTmpRectF = new RectF();
private static final Object[] sTmpObjArray = new Object[1];
- // We spring the foreground drawable relative to the icon's movement in the DragLayer.
- // We then use these two factor values to scale the movement of the fg within this view.
- private static final int FG_TRANS_X_FACTOR = 60;
- private static final int FG_TRANS_Y_FACTOR = 75;
-
- private static final FloatPropertyCompat<FloatingIconView> mFgTransYProperty
- = new FloatPropertyCompat<FloatingIconView>("FloatingViewFgTransY") {
- @Override
- public float getValue(FloatingIconView view) {
- return view.mFgTransY;
- }
-
- @Override
- public void setValue(FloatingIconView view, float transY) {
- view.mFgTransY = transY;
- view.invalidate();
- }
- };
-
- private static final FloatPropertyCompat<FloatingIconView> mFgTransXProperty
- = new FloatPropertyCompat<FloatingIconView>("FloatingViewFgTransX") {
- @Override
- public float getValue(FloatingIconView view) {
- return view.mFgTransX;
- }
-
- @Override
- public void setValue(FloatingIconView view, float transX) {
- view.mFgTransX = transX;
- view.invalidate();
- }
- };
-
private Runnable mEndRunnable;
private CancellationSignal mLoadIconSignal;
private final Launcher mLauncher;
- private final int mBlurSizeOutline;
private final boolean mIsRtl;
private boolean mIsVerticalBarLayout = false;
- private boolean mIsAdaptiveIcon = false;
private boolean mIsOpening;
private IconLoadResult mIconLoadResult;
+ private ClipIconView mClipIconView;
private @Nullable Drawable mBadge;
- private @Nullable Drawable mForeground;
- private @Nullable Drawable mBackground;
+
private float mRotation;
- private ValueAnimator mRevealAnimator;
- private final Rect mStartRevealRect = new Rect();
- private final Rect mEndRevealRect = new Rect();
- private Path mClipPath;
- private float mTaskCornerRadius;
private View mOriginalIcon;
private RectF mPositionOut;
private Runnable mOnTargetChangeRunnable;
- private final Rect mOutline = new Rect();
private final Rect mFinalDrawableBounds = new Rect();
private AnimatorSet mFadeAnimatorSet;
private ListenerView mListenerView;
- private final SpringAnimation mFgSpringY;
- private float mFgTransY;
- private final SpringAnimation mFgSpringX;
- private float mFgTransX;
-
public FloatingIconView(Context context) {
this(context, null);
}
@@ -171,19 +114,11 @@
public FloatingIconView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mLauncher = Launcher.getLauncher(context);
- mBlurSizeOutline = getResources().getDimensionPixelSize(
- R.dimen.blur_size_medium_outline);
mIsRtl = Utilities.isRtl(getResources());
mListenerView = new ListenerView(context, attrs);
-
- mFgSpringX = new SpringAnimation(this, mFgTransXProperty)
- .setSpring(new SpringForce()
- .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)
- .setStiffness(SpringForce.STIFFNESS_LOW));
- mFgSpringY = new SpringAnimation(this, mFgTransYProperty)
- .setSpring(new SpringForce()
- .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)
- .setStiffness(SpringForce.STIFFNESS_LOW));
+ mClipIconView = new ClipIconView(context, attrs);
+ addView(mClipIconView);
+ setWillNotDraw(false);
}
@Override
@@ -212,10 +147,12 @@
float cornerRadius, boolean isOpening) {
setAlpha(alpha);
- LayoutParams lp = (LayoutParams) getLayoutParams();
+ InsettableFrameLayout.LayoutParams lp =
+ (InsettableFrameLayout.LayoutParams) getLayoutParams();
+
+ DeviceProfile dp = mLauncher.getDeviceProfile();
float dX = mIsRtl
- ? rect.left
- - (mLauncher.getDeviceProfile().widthPx - lp.getMarginStart() - lp.width)
+ ? rect.left - (dp.widthPx - lp.getMarginStart() - lp.width)
: rect.left - lp.getMarginStart();
float dY = rect.top - lp.topMargin;
setTranslationX(dX);
@@ -226,69 +163,15 @@
float scaleY = rect.height() / minSize;
float scale = Math.max(1f, Math.min(scaleX, scaleY));
+ mClipIconView.update(rect, progress, shapeProgressStart, cornerRadius, isOpening, scale,
+ minSize, lp);
+
setPivotX(0);
setPivotY(0);
setScaleX(scale);
setScaleY(scale);
- // shapeRevealProgress = 1 when progress = shapeProgressStart + SHAPE_PROGRESS_DURATION
- float toMax = isOpening ? 1 / SHAPE_PROGRESS_DURATION : 1f;
- float shapeRevealProgress = Utilities.boundToRange(mapToRange(
- Math.max(shapeProgressStart, progress), shapeProgressStart, 1f, 0, toMax,
- LINEAR), 0, 1);
-
- if (mIsVerticalBarLayout) {
- mOutline.right = (int) (rect.width() / scale);
- } else {
- mOutline.bottom = (int) (rect.height() / scale);
- }
-
- mTaskCornerRadius = cornerRadius / scale;
- if (mIsAdaptiveIcon) {
- if (!isOpening && progress >= shapeProgressStart) {
- if (mRevealAnimator == null) {
- mRevealAnimator = (ValueAnimator) IconShape.getShape().createRevealAnimator(
- this, mStartRevealRect, mOutline, mTaskCornerRadius, !isOpening);
- mRevealAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- mRevealAnimator = null;
- }
- });
- mRevealAnimator.start();
- // We pause here so we can set the current fraction ourselves.
- mRevealAnimator.pause();
- }
- mRevealAnimator.setCurrentFraction(shapeRevealProgress);
- }
-
- float drawableScale = (mIsVerticalBarLayout ? mOutline.width() : mOutline.height())
- / minSize;
- setBackgroundDrawableBounds(drawableScale);
- if (isOpening) {
- // Center align foreground
- int height = mFinalDrawableBounds.height();
- int width = mFinalDrawableBounds.width();
- int diffY = mIsVerticalBarLayout ? 0
- : (int) (((height * drawableScale) - height) / 2);
- int diffX = mIsVerticalBarLayout ? (int) (((width * drawableScale) - width) / 2)
- : 0;
- sTmpRect.set(mFinalDrawableBounds);
- sTmpRect.offset(diffX, diffY);
- mForeground.setBounds(sTmpRect);
- } else {
- // Spring the foreground relative to the icon's movement within the DragLayer.
- int diffX = (int) (dX / mLauncher.getDeviceProfile().availableWidthPx
- * FG_TRANS_X_FACTOR);
- int diffY = (int) (dY / mLauncher.getDeviceProfile().availableHeightPx
- * FG_TRANS_Y_FACTOR);
-
- mFgSpringX.animateToFinalPosition(diffX);
- mFgSpringY.animateToFinalPosition(diffY);
- }
- }
invalidate();
- invalidateOutline();
}
@Override
@@ -300,9 +183,7 @@
mEndRunnable.run();
} else {
// End runnable also ends the reveal animator, so we manually handle it here.
- if (mRevealAnimator != null) {
- mRevealAnimator.end();
- }
+ mClipIconView.endReveal();
}
}
@@ -314,23 +195,25 @@
*/
private void matchPositionOf(Launcher launcher, View v, boolean isOpening, RectF positionOut) {
float rotation = getLocationBoundsForView(launcher, v, isOpening, positionOut);
- final LayoutParams lp = new LayoutParams(
+ final InsettableFrameLayout.LayoutParams lp = new InsettableFrameLayout.LayoutParams(
Math.round(positionOut.width()),
Math.round(positionOut.height()));
updatePosition(rotation, positionOut, lp);
setLayoutParams(lp);
+
+ mClipIconView.setLayoutParams(new FrameLayout.LayoutParams(lp.width, lp.height));
}
- private void updatePosition(float rotation, RectF position, LayoutParams lp) {
+ private void updatePosition(float rotation, RectF pos, InsettableFrameLayout.LayoutParams lp) {
mRotation = rotation;
- mPositionOut.set(position);
+ mPositionOut.set(pos);
lp.ignoreInsets = true;
// Position the floating view exactly on top of the original
- lp.topMargin = Math.round(position.top);
+ lp.topMargin = Math.round(pos.top);
if (mIsRtl) {
- lp.setMarginStart(Math.round(mLauncher.getDeviceProfile().widthPx - position.right));
+ lp.setMarginStart(Math.round(mLauncher.getDeviceProfile().widthPx - pos.right));
} else {
- lp.setMarginStart(Math.round(position.left));
+ lp.setMarginStart(Math.round(pos.left));
}
// Set the properties here already to make sure they are available when running the first
// animation frame.
@@ -449,97 +332,42 @@
/**
* Sets the drawables of the {@param originalView} onto this view.
*
- * @param originalView The View that the FloatingIconView will replace.
* @param drawable The drawable of the original view.
* @param badge The badge of the original view.
* @param iconOffset The amount of offset needed to match this view with the original view.
*/
@UiThread
- private void setIcon(View originalView, @Nullable Drawable drawable, @Nullable Drawable badge,
- int iconOffset) {
+ private void setIcon(@Nullable Drawable drawable, @Nullable Drawable badge, int iconOffset) {
+ final InsettableFrameLayout.LayoutParams lp =
+ (InsettableFrameLayout.LayoutParams) getLayoutParams();
mBadge = badge;
-
- mIsAdaptiveIcon = drawable instanceof AdaptiveIconDrawable;
- if (mIsAdaptiveIcon) {
- boolean isFolderIcon = drawable instanceof FolderAdaptiveIcon;
-
- AdaptiveIconDrawable adaptiveIcon = (AdaptiveIconDrawable) drawable;
- Drawable background = adaptiveIcon.getBackground();
- if (background == null) {
- background = new ColorDrawable(Color.TRANSPARENT);
- }
- mBackground = background;
- Drawable foreground = adaptiveIcon.getForeground();
- if (foreground == null) {
- foreground = new ColorDrawable(Color.TRANSPARENT);
- }
- mForeground = foreground;
-
- final LayoutParams lp = (LayoutParams) getLayoutParams();
+ mClipIconView.setIcon(drawable, iconOffset, lp, mIsOpening);
+ if (drawable instanceof AdaptiveIconDrawable) {
final int originalHeight = lp.height;
final int originalWidth = lp.width;
- int blurMargin = mBlurSizeOutline / 2;
mFinalDrawableBounds.set(0, 0, originalWidth, originalHeight);
- if (!isFolderIcon) {
- mFinalDrawableBounds.inset(iconOffset - blurMargin, iconOffset - blurMargin);
- }
- mForeground.setBounds(mFinalDrawableBounds);
- mBackground.setBounds(mFinalDrawableBounds);
-
- mStartRevealRect.set(0, 0, originalWidth, originalHeight);
-
- if (mBadge != null) {
- mBadge.setBounds(mStartRevealRect);
- if (!mIsOpening && !isFolderIcon) {
- DRAWABLE_ALPHA.set(mBadge, 0);
- }
- }
-
- if (!isFolderIcon) {
- Utilities.scaleRectAboutCenter(mStartRevealRect,
- IconShape.getNormalizationScale());
- }
-
float aspectRatio = mLauncher.getDeviceProfile().aspectRatio;
if (mIsVerticalBarLayout) {
lp.width = (int) Math.max(lp.width, lp.height * aspectRatio);
} else {
lp.height = (int) Math.max(lp.height, lp.width * aspectRatio);
}
+ setLayoutParams(lp);
- int left = mIsRtl
- ? mLauncher.getDeviceProfile().widthPx - lp.getMarginStart() - lp.width
- : lp.leftMargin;
- layout(left, lp.topMargin, left + lp.width, lp.topMargin + lp.height);
+ final LayoutParams clipViewLp = (LayoutParams) mClipIconView.getLayoutParams();
+ final int clipViewOgHeight = clipViewLp.height;
+ final int clipViewOgWidth = clipViewLp.width;
+ clipViewLp.width = lp.width;
+ clipViewLp.height = lp.height;
+ mClipIconView.setLayoutParams(clipViewLp);
- float scale = Math.max((float) lp.height / originalHeight,
- (float) lp.width / originalWidth);
- float bgDrawableStartScale;
- if (mIsOpening) {
- bgDrawableStartScale = 1f;
- mOutline.set(0, 0, originalWidth, originalHeight);
- } else {
- bgDrawableStartScale = scale;
- mOutline.set(0, 0, lp.width, lp.height);
+ if (mBadge != null) {
+ mBadge.setBounds(0, 0, clipViewOgWidth, clipViewOgHeight);
}
- setBackgroundDrawableBounds(bgDrawableStartScale);
- mEndRevealRect.set(0, 0, lp.width, lp.height);
- setOutlineProvider(new ViewOutlineProvider() {
- @Override
- public void getOutline(View view, Outline outline) {
- outline.setRoundRect(mOutline, mTaskCornerRadius);
- }
- });
- setClipToOutline(true);
- } else {
- setBackground(drawable);
- setClipToOutline(false);
}
-
invalidate();
- invalidateOutline();
}
/**
@@ -556,7 +384,7 @@
synchronized (mIconLoadResult) {
if (mIconLoadResult.isIconLoaded) {
- setIcon(originalView, mIconLoadResult.drawable, mIconLoadResult.badge,
+ setIcon(mIconLoadResult.drawable, mIconLoadResult.badge,
mIconLoadResult.iconOffset);
hideOriginalView(originalView);
} else {
@@ -565,7 +393,7 @@
return;
}
- setIcon(originalView, mIconLoadResult.drawable, mIconLoadResult.badge,
+ setIcon(mIconLoadResult.drawable, mIconLoadResult.badge,
mIconLoadResult.iconOffset);
setVisibility(VISIBLE);
@@ -585,18 +413,6 @@
}
}
- private void setBackgroundDrawableBounds(float scale) {
- sTmpRect.set(mFinalDrawableBounds);
- Utilities.scaleRectAboutCenter(sTmpRect, scale);
- // Since the drawable is at the top of the view, we need to offset to keep it centered.
- if (mIsVerticalBarLayout) {
- sTmpRect.offsetTo((int) (mFinalDrawableBounds.left * scale), sTmpRect.top);
- } else {
- sTmpRect.offsetTo(sTmpRect.left, (int) (mFinalDrawableBounds.top * scale));
- }
- mBackground.setBounds(sTmpRect);
- }
-
@WorkerThread
@SuppressWarnings("WrongThread")
private static int getOffsetForIconBounds(Launcher l, Drawable drawable, RectF position) {
@@ -626,29 +442,11 @@
}
@Override
- public void setClipPath(Path clipPath) {
- mClipPath = clipPath;
- invalidate();
- }
-
- @Override
- public void draw(Canvas canvas) {
+ protected void dispatchDraw(Canvas canvas) {
int count = canvas.save();
canvas.rotate(mRotation,
mFinalDrawableBounds.exactCenterX(), mFinalDrawableBounds.exactCenterY());
- if (mClipPath != null) {
- canvas.clipPath(mClipPath);
- }
- super.draw(canvas);
- if (mBackground != null) {
- mBackground.draw(canvas);
- }
- if (mForeground != null) {
- int count2 = canvas.save();
- canvas.translate(mFgTransX, mFgTransY);
- mForeground.draw(canvas);
- canvas.restoreToCount(count2);
- }
+ super.dispatchDraw(canvas);
if (mBadge != null) {
mBadge.draw(canvas);
}
@@ -692,7 +490,8 @@
float rotation = getLocationBoundsForView(mLauncher, mOriginalIcon, mIsOpening,
sTmpRectF);
if (rotation != mRotation || !sTmpRectF.equals(mPositionOut)) {
- updatePosition(rotation, sTmpRectF, (LayoutParams) getLayoutParams());
+ updatePosition(rotation, sTmpRectF,
+ (InsettableFrameLayout.LayoutParams) getLayoutParams());
if (mOnTargetChangeRunnable != null) {
mOnTargetChangeRunnable.run();
}
@@ -808,12 +607,6 @@
}
});
- if (mBadge != null) {
- ObjectAnimator badgeFade = ObjectAnimator.ofInt(mBadge, DRAWABLE_ALPHA, 255);
- badgeFade.addUpdateListener(valueAnimator -> invalidate());
- fade.play(badgeFade);
- }
-
if (originalView instanceof IconLabelDotView) {
IconLabelDotView view = (IconLabelDotView) originalView;
fade.addListener(new AnimatorListenerAdapter() {
@@ -855,21 +648,12 @@
setScaleX(1);
setScaleY(1);
setAlpha(1);
- setBackground(null);
if (mLoadIconSignal != null) {
mLoadIconSignal.cancel();
}
mLoadIconSignal = null;
mEndRunnable = null;
- mIsAdaptiveIcon = false;
- mForeground = null;
- mBackground = null;
- mClipPath = null;
mFinalDrawableBounds.setEmpty();
- if (mRevealAnimator != null) {
- mRevealAnimator.cancel();
- }
- mRevealAnimator = null;
if (mFadeAnimatorSet != null) {
mFadeAnimatorSet.cancel();
}
@@ -878,15 +662,10 @@
mListenerView.setListener(null);
mOriginalIcon = null;
mOnTargetChangeRunnable = null;
- mTaskCornerRadius = 0;
- mOutline.setEmpty();
- mFgTransY = 0;
- mFgSpringX.cancel();
- mFgTransX = 0;
- mFgSpringY.cancel();
mBadge = null;
sTmpObjArray[0] = null;
mIconLoadResult = null;
+ mClipIconView.recycle();
}
private static class IconLoadResult {
@@ -897,7 +676,7 @@
Runnable onIconLoaded;
boolean isIconLoaded;
- public IconLoadResult(ItemInfo itemInfo) {
+ IconLoadResult(ItemInfo itemInfo) {
this.itemInfo = itemInfo;
}
}
diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/DepthController.java b/src_ui_overrides/com/android/launcher3/uioverrides/DepthController.java
deleted file mode 100644
index 7ad85e2..0000000
--- a/src_ui_overrides/com/android/launcher3/uioverrides/DepthController.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.uioverrides;
-
-
-import android.util.FloatProperty;
-import android.view.View;
-
-import com.android.launcher3.Launcher;
-import com.android.launcher3.LauncherState;
-import com.android.launcher3.LauncherStateManager;
-import com.android.launcher3.anim.PendingAnimation;
-import com.android.launcher3.states.StateAnimationConfig;
-
-/**
- * Controls blur and wallpaper zoom, for the Launcher surface only.
- */
-public class DepthController implements LauncherStateManager.StateHandler {
-
- public static final FloatProperty<DepthController> DEPTH =
- new FloatProperty<DepthController>("depth") {
- @Override
- public void setValue(DepthController depthController, float depth) {}
-
- @Override
- public Float get(DepthController depthController) {
- return 0f;
- }
- };
-
- public DepthController(Launcher l) {}
-
- public void setSurfaceToLauncher(View v) {}
-
- @Override
- public void setState(LauncherState toState) {}
-
- @Override
- public void setStateWithAnimation(LauncherState toState, StateAnimationConfig config,
- PendingAnimation animation) { }
-}