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

Commit b0f89ffc authored by Jeremy Sim's avatar Jeremy Sim Committed by Android (Google) Code Review
Browse files

Merge "Add haptics to magnetic divider" into main

parents 02ef064e 647e5702
Loading
Loading
Loading
Loading
+22 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import androidx.annotation.Nullable;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.protolog.ProtoLog;
import com.android.mechanics.spec.BreakpointKey;
import com.android.mechanics.spec.InputDirection;
import com.android.mechanics.view.DistanceGestureContext;
import com.android.mechanics.view.ViewMotionValue;
@@ -64,6 +65,8 @@ import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.shared.animation.Interpolators;
import com.android.wm.shell.shared.desktopmode.DesktopState;

import com.google.android.msdl.data.model.MSDLToken;

/**
 * Divider for multi window splits.
 */
@@ -96,6 +99,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
    // Calculation classes for "magnetic snap" user-controlled movement
    private DistanceGestureContext mDistanceGestureContext;
    private ViewMotionValue mViewMotionValue;
    private BreakpointKey mCurrentHapticBreakpoint;

    /**
     * This is not the visible bounds you see on screen, but the actual behind-the-scenes window
@@ -377,6 +381,18 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
                                "dividerView::pos" /* label */);
                        mViewMotionValue.addUpdateCallback(viewMotionValue -> {
                            placeDivider((int) viewMotionValue.getOutput());
                            // Each MotionValue "segment" has two "breakpoints", one on each end.
                            // We can uniquely identify each segment by just one of its breakpoints,
                            // so we arbitrarily listen for changes to the "min-side" breakpoint
                            // to determine when the user has moved the onto a new segment (i.e.
                            // moved the divider from the "free-drag" segment to the "snapped"
                            // segment, or vice versa). We play a haptic when this happens.
                            if (!viewMotionValue.getSegmentKey().getMinBreakpoint()
                                    .equals(mCurrentHapticBreakpoint)) {
                                playHapticClick();
                            }
                            mCurrentHapticBreakpoint =
                                    viewMotionValue.getSegmentKey().getMinBreakpoint();
                        });
                    }
                }
@@ -420,6 +436,11 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
        return true;
    }

    /** Plays a short haptic to indicate attaching or detaching from a divider snap point. */
    private void playHapticClick() {
        mSplitLayout.getHapticPlayer().playToken(MSDLToken.SWIPE_THRESHOLD_INDICATOR, null);
    }

    /** Updates the position of the divider. */
    private void placeDivider(int position) {
        mSplitLayout.updateDividerBounds(position, true /* shouldUseParallaxEffect */);
@@ -446,6 +467,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener {
        }
        mDistanceGestureContext = null;
        mViewMotionValue = null;
        mCurrentHapticBreakpoint = null;
    }

    private void setTouching() {
+12 −1
Original line number Diff line number Diff line
@@ -89,6 +89,8 @@ import com.android.wm.shell.shared.split.SplitScreenConstants.SplitPosition;
import com.android.wm.shell.splitscreen.SplitStatusBarHider;
import com.android.wm.shell.splitscreen.StageTaskListener;

import com.google.android.msdl.domain.MSDLPlayer;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -149,6 +151,9 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
    /** Singleton source of truth for the current state of split screen on this device. */
    private final SplitState mSplitState;

    /** A haptics controller that plays haptic effects. */
    private final MSDLPlayer mMSDLPlayer;

    private int mDividerWindowWidth;
    private int mDividerInsets;
    private int mDividerSize;
@@ -215,7 +220,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
            DisplayController displayController, DisplayImeController displayImeController,
            ShellTaskOrganizer taskOrganizer, int parallaxType, SplitState splitState,
            @ShellMainThread Handler handler, SplitStatusBarHider statusBarHider,
            DesktopState desktopState) {
            DesktopState desktopState, MSDLPlayer msdlPlayer) {
        mHandler = handler;
        mStatusBarHider = statusBarHider;
        mContext = context.createConfigurationContext(configuration);
@@ -234,6 +239,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
        mSurfaceEffectPolicy = new ResizingEffectPolicy(parallaxType, this);
        mSplitState = splitState;
        mDesktopState = desktopState;
        mMSDLPlayer = msdlPlayer;

        final Resources res = mContext.getResources();
        mDimNonImeSide = res.getBoolean(R.bool.config_dimNonImeAttachedSide);
@@ -388,6 +394,11 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange
        return mDividerPosition;
    }

    /** Returns the haptic player used in this class. */
    public MSDLPlayer getHapticPlayer() {
        return mMSDLPlayer;
    }

    /**
     * Finds the {@link SnapPosition} nearest to the current divider position.
     */
+5 −2
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@ import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.Transitions;

import com.google.android.msdl.domain.MSDLPlayer;

import dagger.Module;
import dagger.Provides;

@@ -99,12 +101,13 @@ public class TvWMShellModule {
            SystemWindows systemWindows,
            RootDisplayAreaOrganizer rootDisplayAreaOrganizer,
            DesktopState desktopState,
            IActivityTaskManager activityTaskManager) {
            IActivityTaskManager activityTaskManager,
            MSDLPlayer msdlPlayer) {
        return new TvSplitScreenController(context, shellInit, shellCommandHandler, shellController,
                shellTaskOrganizer, syncQueue, rootTDAOrganizer, displayController,
                displayImeController, displayInsetsController, transitions, transactionPool,
                iconProvider, recentTasks, launchAdjacentController, multiInstanceHelper,
                splitState, mainExecutor, mainHandler, systemWindows, rootDisplayAreaOrganizer,
                desktopState, activityTaskManager);
                desktopState, activityTaskManager, msdlPlayer);
    }
}
+15 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import static com.android.wm.shell.compatui.CompatUIStatusManager.COMPAT_UI_EDUC
import static com.android.wm.shell.onehanded.OneHandedController.SUPPORT_ONE_HANDED_MODE;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityTaskManager;
import android.content.Context;
import android.content.pm.PackageManager;
@@ -29,6 +30,7 @@ import android.hardware.display.DisplayManager;
import android.os.Handler;
import android.os.SystemProperties;
import android.os.UserManager;
import android.os.Vibrator;
import android.provider.Settings;
import android.view.IWindowManager;
import android.view.accessibility.AccessibilityManager;
@@ -147,12 +149,15 @@ import com.android.wm.shell.windowdecor.WindowDecorViewModel;
import com.android.wm.shell.windowdecor.viewholder.AppHandleNotifier;
import com.android.wm.shell.windowdecor.viewholder.AppHandles;

import com.google.android.msdl.domain.MSDLPlayer;

import dagger.BindsOptionalOf;
import dagger.Lazy;
import dagger.Module;
import dagger.Provides;

import java.util.Optional;
import java.util.concurrent.Executors;

/**
 * Provides basic dependencies from {@link com.android.wm.shell}, these dependencies are only
@@ -244,6 +249,16 @@ public abstract class WMShellBaseModule {
                context, shellInit, postureController, displayController, mainExecutor);
    }

    @WMSingleton
    @Provides
    static MSDLPlayer provideMSDLPlayer(@Nullable Vibrator vibrator) {
        return MSDLPlayer.Companion.createPlayer(
                vibrator,
                Executors.newSingleThreadExecutor(),
                null /* useHapticFeedbackForToken */
        );
    }

    @WMSingleton
    @Provides
    static ShellTaskOrganizer provideShellTaskOrganizer(
+6 −2
Original line number Diff line number Diff line
@@ -192,6 +192,8 @@ import com.android.wm.shell.windowdecor.education.DesktopWindowingEducationToolt
import com.android.wm.shell.windowdecor.tiling.DesktopTilingDecorViewModel;
import com.android.wm.shell.windowdecor.viewholder.AppHandleNotifier;

import com.google.android.msdl.domain.MSDLPlayer;

import dagger.Binds;
import dagger.Lazy;
import dagger.Module;
@@ -613,7 +615,8 @@ public abstract class WMShellModule {
            @ShellMainThread Handler mainHandler,
            RootDisplayAreaOrganizer rootDisplayAreaOrganizer,
            DesktopState desktopState,
            IActivityTaskManager activityTaskManager) {
            IActivityTaskManager activityTaskManager,
            MSDLPlayer msdlPlayer) {
        return new SplitScreenController(
                context,
                shellInit,
@@ -640,7 +643,8 @@ public abstract class WMShellModule {
                mainHandler,
                rootDisplayAreaOrganizer,
                desktopState,
                activityTaskManager);
                activityTaskManager,
                msdlPlayer);
    }

    //
Loading