Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java +22 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. */ Loading Loading @@ -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 Loading Loading @@ -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(); }); } } Loading Loading @@ -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 */); Loading @@ -446,6 +467,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { } mDistanceGestureContext = null; mViewMotionValue = null; mCurrentHapticBreakpoint = null; } private void setTouching() { Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +12 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading @@ -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); Loading Loading @@ -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. */ Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java +5 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java +15 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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( Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +6 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading @@ -640,7 +643,8 @@ public abstract class WMShellModule { mainHandler, rootDisplayAreaOrganizer, desktopState, activityTaskManager); activityTaskManager, msdlPlayer); } // Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/split/DividerView.java +22 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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. */ Loading Loading @@ -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 Loading Loading @@ -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(); }); } } Loading Loading @@ -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 */); Loading @@ -446,6 +467,7 @@ public class DividerView extends FrameLayout implements View.OnTouchListener { } mDistanceGestureContext = null; mViewMotionValue = null; mCurrentHapticBreakpoint = null; } private void setTouching() { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +12 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading @@ -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); Loading Loading @@ -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. */ Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/TvWMShellModule.java +5 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } }
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java +15 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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( Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +6 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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, Loading @@ -640,7 +643,8 @@ public abstract class WMShellModule { mainHandler, rootDisplayAreaOrganizer, desktopState, activityTaskManager); activityTaskManager, msdlPlayer); } // Loading