diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index b228fdb1cf..9813c8a987 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -219,6 +219,8 @@ public class QuickstepLauncher extends Launcher { mEnableWidgetDepth = ENABLE_WIDGET_PICKER_DEPTH.get() && SystemProperties.getBoolean("ro.launcher.depth.widget", true); + getWorkspace().addOverlayCallback(progress -> + onTaskbarInAppDisplayProgressUpdate(progress, MINUS_ONE_PAGE_PROGRESS_INDEX)); } @Override @@ -594,17 +596,6 @@ public class QuickstepLauncher extends Launcher { recentsView.finishRecentsAnimation(true /* toRecents */, null); } - /** - * {@code LauncherOverlayCallbacks} scroll amount. - * Indicates transition progress to -1 screen. - * @param progress From 0 to 1. - */ - @Override - public void onScrollChanged(float progress) { - super.onScrollChanged(progress); - onTaskbarInAppDisplayProgressUpdate(progress, MINUS_ONE_PAGE_PROGRESS_INDEX); - } - @Override public void onAllAppsTransition(float progress) { super.onAllAppsTransition(progress); diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 9426ae9a92..c73e07794f 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -53,6 +53,8 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_EXIT; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ONRESUME; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ONSTOP; +import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPELEFT; +import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPERIGHT; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGET_RECONFIGURED; import static com.android.launcher3.model.ItemInstallQueue.FLAG_ACTIVITY_PAUSED; import static com.android.launcher3.model.ItemInstallQueue.FLAG_DRAG_AND_DROP; @@ -183,7 +185,6 @@ import com.android.launcher3.states.RotationHelper; import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.shared.TestProtocol; import com.android.launcher3.touch.AllAppsSwipeController; -import com.android.launcher3.touch.ItemClickHandler; import com.android.launcher3.uioverrides.plugins.PluginManagerWrapper; import com.android.launcher3.util.ActivityResultInfo; import com.android.launcher3.util.ActivityTracker; @@ -222,7 +223,6 @@ import com.android.systemui.plugins.PluginListener; import com.android.systemui.plugins.shared.LauncherExterns; import com.android.systemui.plugins.shared.LauncherOverlayManager; import com.android.systemui.plugins.shared.LauncherOverlayManager.LauncherOverlay; -import com.android.systemui.plugins.shared.LauncherOverlayManager.LauncherOverlayCallbacks; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -242,7 +242,7 @@ import java.util.stream.Stream; */ public class Launcher extends StatefulActivity implements LauncherExterns, Callbacks, InvariantDeviceProfile.OnIDPChangeListener, - PluginListener, LauncherOverlayCallbacks { + PluginListener { public static final String TAG = "Launcher"; public static final ActivityTracker ACTIVITY_TRACKER = new ActivityTracker<>(); @@ -696,17 +696,9 @@ public class Launcher extends StatefulActivity */ @Override public void setLauncherOverlay(LauncherOverlay overlay) { - if (overlay != null) { - overlay.setOverlayCallbacks(this); - } mWorkspace.setLauncherOverlay(overlay); } - @Override - public void runOnOverlayHidden(Runnable runnable) { - getWorkspace().runOnOverlayHidden(runnable); - } - public boolean setLauncherCallbacks(LauncherCallbacks callbacks) { mLauncherCallbacks = callbacks; return true; @@ -1213,18 +1205,6 @@ public class Launcher extends StatefulActivity mAppWidgetHolder.setActivityResumed(false); } - /** - * {@code LauncherOverlayCallbacks} scroll amount. - * Indicates transition progress to -1 screen. - * @param progress From 0 to 1. - */ - @Override - public void onScrollChanged(float progress) { - if (mWorkspace != null) { - mWorkspace.onOverlayScrollChanged(progress); - } - } - /** * Restores the previous state, if it exists. * @@ -2895,7 +2875,16 @@ public class Launcher extends StatefulActivity /** * Informs us that the overlay (-1 screen, typically), has either become visible or invisible. */ - public void onOverlayVisibilityChanged(boolean visible) {} + public void onOverlayVisibilityChanged(boolean visible) { + getStatsLogManager().logger() + .withSrcState(LAUNCHER_STATE_HOME) + .withDstState(LAUNCHER_STATE_HOME) + .withContainerInfo(LauncherAtom.ContainerInfo.newBuilder() + .setWorkspace(WorkspaceContainer.newBuilder() + .setPageIndex(visible ? 0 : -1)) + .build()) + .log(visible ? LAUNCHER_SWIPELEFT : LAUNCHER_SWIPERIGHT); + } /** * Informs us that the page transition has ended, so that we can react to the newly selected diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index b6eb58973d..8f07a0df53 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -26,7 +26,6 @@ import static com.android.launcher3.LauncherState.HINT_STATE; import static com.android.launcher3.LauncherState.NORMAL; import static com.android.launcher3.LauncherState.SPRING_LOADED; import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback; -import static com.android.launcher3.dragndrop.DragLayer.ALPHA_INDEX_OVERLAY; import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPELEFT; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SWIPERIGHT; @@ -58,7 +57,6 @@ import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; -import android.view.ViewTreeObserver; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.FrameLayout; import android.widget.Toast; @@ -119,6 +117,7 @@ import com.android.launcher3.widget.WidgetManagerHelper; import com.android.launcher3.widget.dragndrop.AppWidgetHostViewDragListener; import com.android.launcher3.widget.util.WidgetSizes; import com.android.systemui.plugins.shared.LauncherOverlayManager.LauncherOverlay; +import com.android.systemui.plugins.shared.LauncherOverlayManager.LauncherOverlayCallbacks; import java.util.ArrayList; import java.util.Iterator; @@ -136,7 +135,7 @@ import java.util.stream.Collectors; public class Workspace extends PagedView implements DropTarget, DragSource, View.OnTouchListener, DragController.DragListener, Insettable, StateHandler, - WorkspaceLayoutManager, LauncherBindableItemsContainer { + WorkspaceLayoutManager, LauncherBindableItemsContainer, LauncherOverlayCallbacks { /** The value that {@link #mTransitionProgress} must be greater than for * {@link #transitionStateShouldAllowDrop()} to return true. */ @@ -254,14 +253,12 @@ public class Workspace extends PagedView // State related to Launcher Overlay private OverlayEdgeEffect mOverlayEdgeEffect; - boolean mOverlayShown = false; - private Runnable mOnOverlayHiddenCallback; + private boolean mOverlayShown = false; + private float mOverlayProgress; // 1 -> overlay completely visible, 0 -> home visible + private final List mOverlayCallbacks = new ArrayList<>(); private boolean mForceDrawAdjacentPages = false; - // Total over scrollX in the overlay direction. - private float mOverlayTranslation; - // Handles workspace state transitions private final WorkspaceStateTransitionAnimation mStateTransitionAnimation; @@ -1151,9 +1148,15 @@ public class Workspace extends PagedView } public void setLauncherOverlay(LauncherOverlay overlay) { - mOverlayEdgeEffect = overlay == null ? null : new OverlayEdgeEffect(getContext(), overlay); - EdgeEffectCompat newEffect = overlay == null - ? new EdgeEffectCompat(getContext()) : mOverlayEdgeEffect; + final EdgeEffectCompat newEffect; + if (overlay == null) { + newEffect = new EdgeEffectCompat(getContext()); + mOverlayEdgeEffect = null; + } else { + newEffect = mOverlayEdgeEffect = new OverlayEdgeEffect(getContext(), overlay); + overlay.setOverlayCallbacks(this); + } + if (mIsRtl) { mEdgeGlowRight = newEffect; } else { @@ -1203,132 +1206,46 @@ public class Workspace extends PagedView @Override protected boolean shouldFlingForVelocity(int velocityX) { // When the overlay is moving, the fling or settle transition is controlled by the overlay. - return Float.compare(Math.abs(mOverlayTranslation), 0) == 0 && - super.shouldFlingForVelocity(velocityX); + return Float.compare(Math.abs(mOverlayProgress), 0) == 0 + && super.shouldFlingForVelocity(velocityX); } /** * The overlay scroll is being controlled locally, just update our overlay effect */ + @Override public void onOverlayScrollChanged(float scroll) { - if (Float.compare(scroll, 1f) == 0) { + mOverlayProgress = Utilities.boundToRange(scroll, 0, 1); + if (Float.compare(mOverlayProgress, 1f) == 0) { if (!mOverlayShown) { - mLauncher.getStatsLogManager().logger() - .withSrcState(LAUNCHER_STATE_HOME) - .withDstState(LAUNCHER_STATE_HOME) - .withContainerInfo(LauncherAtom.ContainerInfo.newBuilder() - .setWorkspace( - LauncherAtom.WorkspaceContainer.newBuilder() - .setPageIndex(0)) - .build()) - .log(LAUNCHER_SWIPELEFT); + mOverlayShown = true; + mLauncher.onOverlayVisibilityChanged(true); } - mOverlayShown = true; - - // Let the Launcher activity know that the overlay is now visible. - mLauncher.onOverlayVisibilityChanged(mOverlayShown); - - // Not announcing the overlay page for accessibility since it announces itself. - } else if (Float.compare(scroll, 0f) == 0) { + } else if (Float.compare(mOverlayProgress, 0f) == 0) { if (mOverlayShown) { - // TODO: this is logged unnecessarily on home gesture. - mLauncher.getStatsLogManager().logger() - .withSrcState(LAUNCHER_STATE_HOME) - .withDstState(LAUNCHER_STATE_HOME) - .withContainerInfo(LauncherAtom.ContainerInfo.newBuilder() - .setWorkspace( - LauncherAtom.WorkspaceContainer.newBuilder() - .setPageIndex(-1)) - .build()) - .log(LAUNCHER_SWIPERIGHT); - } else if (Float.compare(mOverlayTranslation, 0f) != 0) { - // When arriving to 0 overscroll from non-zero overscroll, announce page for - // accessibility since default announcements were disabled while in overscroll - // state. - // Not doing this if mOverlayShown because in that case the accessibility service - // will announce the launcher window description upon regaining focus after - // switching from the overlay screen. - announcePageForAccessibility(); + mOverlayShown = false; + mLauncher.onOverlayVisibilityChanged(false); } - mOverlayShown = false; - - // Let the Launcher activity know that the overlay is no longer visible. - mLauncher.onOverlayVisibilityChanged(mOverlayShown); - - tryRunOverlayCallback(); } - - float offset = 0f; - - scroll = Math.max(scroll - offset, 0); - scroll = Math.min(1, scroll / (1 - offset)); - - float alpha = 1 - Interpolators.DEACCEL_3.getInterpolation(scroll); - float transX = mLauncher.getDragLayer().getMeasuredWidth() * scroll; - - if (mIsRtl) { - transX = -transX; + int count = mOverlayCallbacks.size(); + for (int i = 0; i < count; i++) { + mOverlayCallbacks.get(i).onOverlayScrollChanged(mOverlayProgress); } - mOverlayTranslation = transX; - - // TODO(adamcohen): figure out a final effect here. We may need to recommend - // different effects based on device performance. On at least one relatively high-end - // device I've tried, translating the launcher causes things to get quite laggy. - mLauncher.getDragLayer().setTranslationX(transX); - mLauncher.getDragLayer().getAlphaProperty(ALPHA_INDEX_OVERLAY).setValue(alpha); } /** - * @return false if the callback is still pending + * Adds a callback for receiving overlay progress */ - private boolean tryRunOverlayCallback() { - if (mOnOverlayHiddenCallback == null) { - // Return true as no callback is pending. This is used by OnWindowFocusChangeListener - // to remove itself if multiple focus handles were added. - return true; - } - if (mOverlayShown || !hasWindowFocus()) { - return false; - } - - mOnOverlayHiddenCallback.run(); - mOnOverlayHiddenCallback = null; - return true; + public void addOverlayCallback(LauncherOverlayCallbacks callback) { + mOverlayCallbacks.add(callback); + callback.onOverlayScrollChanged(mOverlayProgress); } /** - * Runs the given callback when the minus one overlay is hidden. Specifically, it is run - * when launcher's window has focus and the overlay is no longer being shown. If a callback - * is already present, the new callback will chain off it so both are run. - * - * @return Whether the callback was deferred. + * Removes a previously added overlay progress callback */ - public boolean runOnOverlayHidden(Runnable callback) { - if (mOnOverlayHiddenCallback == null) { - mOnOverlayHiddenCallback = callback; - } else { - // Chain the new callback onto the previous callback(s). - Runnable oldCallback = mOnOverlayHiddenCallback; - mOnOverlayHiddenCallback = () -> { - oldCallback.run(); - callback.run(); - }; - } - if (!tryRunOverlayCallback()) { - ViewTreeObserver observer = getViewTreeObserver(); - if (observer != null && observer.isAlive()) { - observer.addOnWindowFocusChangeListener( - new ViewTreeObserver.OnWindowFocusChangeListener() { - @Override - public void onWindowFocusChanged(boolean hasFocus) { - if (tryRunOverlayCallback() && observer.isAlive()) { - observer.removeOnWindowFocusChangeListener(this); - } - }}); - } - return true; - } - return false; + public void removeOverlayCallback(LauncherOverlayCallbacks callback) { + mOverlayCallbacks.remove(callback); } @Override @@ -3470,7 +3387,7 @@ public class Workspace extends PagedView protected boolean canAnnouncePageDescription() { // Disable announcements while overscrolling potentially to overlay screen because if we end // up on the overlay screen, it will take care of announcing itself. - return Float.compare(mOverlayTranslation, 0f) == 0; + return Float.compare(mOverlayProgress, 0f) == 0; } @Override diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java index 4bea0adebc..1ee7fc1fa3 100644 --- a/src/com/android/launcher3/dragndrop/DragLayer.java +++ b/src/com/android/launcher3/dragndrop/DragLayer.java @@ -47,7 +47,9 @@ import com.android.launcher3.DropTargetBar; import com.android.launcher3.Launcher; import com.android.launcher3.R; import com.android.launcher3.ShortcutAndWidgetContainer; +import com.android.launcher3.Utilities; import com.android.launcher3.Workspace; +import com.android.launcher3.anim.Interpolators; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.SpringProperty; import com.android.launcher3.celllayout.CellLayoutLayoutParams; @@ -56,13 +58,14 @@ import com.android.launcher3.graphics.Scrim; import com.android.launcher3.keyboard.ViewGroupFocusHelper; import com.android.launcher3.util.TouchController; import com.android.launcher3.views.BaseDragLayer; +import com.android.systemui.plugins.shared.LauncherOverlayManager.LauncherOverlayCallbacks; import java.util.ArrayList; /** * A ViewGroup that coordinates dragging across its descendants */ -public class DragLayer extends BaseDragLayer { +public class DragLayer extends BaseDragLayer implements LauncherOverlayCallbacks { public static final int ALPHA_INDEX_OVERLAY = 0; private static final int ALPHA_CHANNEL_COUNT = 1; @@ -70,6 +73,8 @@ public class DragLayer extends BaseDragLayer { public static final int ANIMATION_END_DISAPPEAR = 0; public static final int ANIMATION_END_REMAIN_VISIBLE = 2; + private final boolean mIsRtl; + private DragController mDragController; // Variables relating to animation of views after drop @@ -100,6 +105,7 @@ public class DragLayer extends BaseDragLayer { setChildrenDrawingOrderEnabled(true); mFocusIndicatorHelper = new ViewGroupFocusHelper(this); + mIsRtl = Utilities.isRtl(getResources()); } /** @@ -109,6 +115,7 @@ public class DragLayer extends BaseDragLayer { mDragController = dragController; recreateControllers(); mWorkspaceDragScrim = new Scrim(this); + workspace.addOverlayCallback(this); } @Override @@ -476,4 +483,16 @@ public class DragLayer extends BaseDragLayer { controller.onOneHandedModeStateChanged(activated); } } + + @Override + public void onOverlayScrollChanged(float progress) { + float alpha = 1 - Interpolators.DEACCEL_3.getInterpolation(progress); + float transX = getMeasuredWidth() * progress; + + if (mIsRtl) { + transX = -transX; + } + setTranslationX(transX); + getAlphaProperty(ALPHA_INDEX_OVERLAY).setValue(alpha); + } } diff --git a/src_plugins/com/android/systemui/plugins/shared/LauncherExterns.java b/src_plugins/com/android/systemui/plugins/shared/LauncherExterns.java index 13e4999623..173b4540e6 100644 --- a/src_plugins/com/android/systemui/plugins/shared/LauncherExterns.java +++ b/src_plugins/com/android/systemui/plugins/shared/LauncherExterns.java @@ -40,10 +40,4 @@ public interface LauncherExterns { * Sets the overlay on the target activity */ void setLauncherOverlay(LauncherOverlay overlay); - - /** - * Executes the command, next time the overlay is hidden - */ - void runOnOverlayHidden(Runnable runnable); - } diff --git a/src_plugins/com/android/systemui/plugins/shared/LauncherOverlayManager.java b/src_plugins/com/android/systemui/plugins/shared/LauncherOverlayManager.java index ac02ba4528..582ab230c3 100644 --- a/src_plugins/com/android/systemui/plugins/shared/LauncherOverlayManager.java +++ b/src_plugins/com/android/systemui/plugins/shared/LauncherOverlayManager.java @@ -93,6 +93,6 @@ public interface LauncherOverlayManager extends Application.ActivityLifecycleCal interface LauncherOverlayCallbacks { - void onScrollChanged(float progress); + void onOverlayScrollChanged(float progress); } }