Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 82379187 authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Adding support for multiple overlay callbacks

Bug: 193244407
Test: Presubmit
Change-Id: Ic345972056752238e7e46226533fd8f33d664213
parent ef24d595
Loading
Loading
Loading
Loading
+2 −11
Original line number Diff line number Diff line
@@ -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);
+13 −24
Original line number Diff line number Diff line
@@ -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<LauncherState>
        implements LauncherExterns, Callbacks, InvariantDeviceProfile.OnIDPChangeListener,
        PluginListener<LauncherOverlayPlugin>, LauncherOverlayCallbacks {
        PluginListener<LauncherOverlayPlugin> {
    public static final String TAG = "Launcher";

    public static final ActivityTracker<Launcher> ACTIVITY_TRACKER = new ActivityTracker<>();
@@ -696,17 +696,9 @@ public class Launcher extends StatefulActivity<LauncherState>
     */
    @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<LauncherState>
        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<LauncherState>
    /**
     * 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
+36 −119
Original line number Diff line number Diff line
@@ -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<T extends View & PageIndicator> extends PagedView<T>
        implements DropTarget, DragSource, View.OnTouchListener,
        DragController.DragListener, Insettable, StateHandler<LauncherState>,
        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<T extends View & PageIndicator> extends PagedView<T>

    // 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<LauncherOverlayCallbacks> 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<T extends View & PageIndicator> extends PagedView<T>
    }

    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<T extends View & PageIndicator> extends PagedView<T>
    @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;

            // 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) {
            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();
                mLauncher.onOverlayVisibilityChanged(true);
            }
        } else if (Float.compare(mOverlayProgress, 0f) == 0) {
            if (mOverlayShown) {
                mOverlayShown = false;

            // Let the Launcher activity know that the overlay is no longer visible.
            mLauncher.onOverlayVisibilityChanged(mOverlayShown);

            tryRunOverlayCallback();
                mLauncher.onOverlayVisibilityChanged(false);
            }

        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;
        }
        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);
        int count = mOverlayCallbacks.size();
        for (int i = 0; i < count; i++) {
            mOverlayCallbacks.get(i).onOverlayScrollChanged(mOverlayProgress);
        }
    }

    /**
     * @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<T extends View & PageIndicator> extends PagedView<T>
    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
+20 −1
Original line number Diff line number Diff line
@@ -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<Launcher> {
public class DragLayer extends BaseDragLayer<Launcher> 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<Launcher> {
    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<Launcher> {
        setChildrenDrawingOrderEnabled(true);

        mFocusIndicatorHelper = new ViewGroupFocusHelper(this);
        mIsRtl = Utilities.isRtl(getResources());
    }

    /**
@@ -109,6 +115,7 @@ public class DragLayer extends BaseDragLayer<Launcher> {
        mDragController = dragController;
        recreateControllers();
        mWorkspaceDragScrim = new Scrim(this);
        workspace.addOverlayCallback(this);
    }

    @Override
@@ -476,4 +483,16 @@ public class DragLayer extends BaseDragLayer<Launcher> {
            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);
    }
}
+0 −6
Original line number Diff line number Diff line
@@ -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);

}
Loading