Loading libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/DragToBubbleControllerTest.kt +1 −20 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import android.app.PendingIntent import android.content.Context import android.content.IIntentSender import android.content.pm.ShortcutInfo import android.graphics.Insets import android.graphics.Rect import android.os.UserHandle import android.platform.test.annotations.EnableFlags Loading @@ -32,9 +31,7 @@ import androidx.test.filters.SmallTest import androidx.test.platform.app.InstrumentationRegistry import com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_ANYTHING import com.android.wm.shell.bubbles.BubbleController import com.android.wm.shell.bubbles.BubblePositioner import com.android.wm.shell.shared.bubbles.BubbleBarLocation import com.android.wm.shell.shared.bubbles.DeviceConfig import com.android.wm.shell.shared.bubbles.DragZoneFactory import com.android.wm.shell.shared.bubbles.DropTargetView import com.google.common.truth.Truth.assertThat Loading @@ -56,7 +53,6 @@ class DragToBubbleControllerTest { @get:Rule val animatorTestRule = AnimatorTestRule() private val context = getApplicationContext<Context>() private val bubblePositioner: BubblePositioner = mock() private val bubbleController: BubbleController = mock() private lateinit var dragToBubbleController: DragToBubbleController Loading @@ -76,8 +72,7 @@ class DragToBubbleControllerTest { @Before fun setUp() { bubblePositioner.stub { on { currentConfig } doReturn createDeviceConfig() } dragToBubbleController = DragToBubbleController(context, bubblePositioner, bubbleController) dragToBubbleController = DragToBubbleController(context, bubbleController) dropTargetContainer = dragToBubbleController.getDropTargetContainer() } Loading Loading @@ -223,18 +218,4 @@ class DragToBubbleControllerTest { on { getBubbleBarLocation() } doReturn bubbleBarLocation } } private fun createDeviceConfig( isLargeScreen: Boolean = true, isSmallTablet: Boolean = false, isLandscape: Boolean = true, isRtl: Boolean = false, windowBounds: Rect = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), insets: Insets = Insets.NONE, ) = DeviceConfig(isLargeScreen, isSmallTablet, isLandscape, isRtl, windowBounds, insets) companion object { const val SCREEN_WIDTH = 2000 const val SCREEN_HEIGHT = 1000 } } libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java +108 −86 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.wm.shell.bubbles.bar; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BUBBLES; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BUBBLES_NOISY; import static com.android.wm.shell.shared.animation.Interpolators.ALPHA_IN; import static com.android.wm.shell.shared.animation.Interpolators.ALPHA_OUT; Loading Loading @@ -89,6 +88,7 @@ public class BubbleBarLayerView extends FrameLayout private final BubbleEducationViewController mEducationViewController; private final View mScrimView; private final BubbleExpandedViewPinController mBubbleExpandedViewPinController; private final LocationChangeListener mLocationChangeListener = new LocationChangeListener(); @Nullable private DropTargetManager mDropTargetManager = null; @Nullable Loading Loading @@ -141,14 +141,22 @@ public class BubbleBarLayerView extends FrameLayout mBubbleExpandedViewPinController = new BubbleExpandedViewPinController( context, this, mPositioner); LocationChangeListener locationChangeListener = new LocationChangeListener(); mBubbleExpandedViewPinController.setListener(locationChangeListener); mBubbleExpandedViewPinController.setListener(mLocationChangeListener); if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) { mDropTargetManager = new DropTargetManager(context, this, setupDropTargetManager(); setupDragZoneFactory(); setOnClickListener(view -> hideModalOrCollapse()); } private void setupDropTargetManager() { if (!BubbleAnythingFlagHelper.enableBubbleToFullscreen()) { return; } mDropTargetManager = new DropTargetManager(getContext(), this, new DropTargetManager.DragZoneChangedListener() { private DragZone mLastBubbleLocationDragZone = null; private BubbleBarLocation mInitialLocation = null; @Override public void onDragEnded(@Nullable DragZone zone) { if (mExpandedBubble == null || !(mExpandedBubble instanceof Bubble)) { Loading @@ -161,18 +169,18 @@ public class BubbleBarLayerView extends FrameLayout if (!isBubbleLeft && !isBubbleRight) { // If we didn't finish the "change" animation make sure to animate // it back to the right spot locationChangeListener.onChange(mInitialLocation); mLocationChangeListener.onChange(mInitialLocation); } if (zone instanceof DragZone.FullScreen) { ((Bubble) mExpandedBubble).getTaskView().moveToFullscreen(); // Make sure location change listener is updated with the initial // location -- even if we "switched sides" during the drag, since // we've ended up in fullscreen, the location shouldn't change. locationChangeListener.onRelease(mInitialLocation); mLocationChangeListener.onRelease(mInitialLocation); } else if (isBubbleLeft) { locationChangeListener.onRelease(BubbleBarLocation.LEFT); mLocationChangeListener.onRelease(BubbleBarLocation.LEFT); } else if (isBubbleRight) { locationChangeListener.onRelease(BubbleBarLocation.RIGHT); mLocationChangeListener.onRelease(BubbleBarLocation.RIGHT); } } Loading @@ -181,7 +189,7 @@ public class BubbleBarLayerView extends FrameLayout mInitialLocation = dragZone instanceof DragZone.Bubble.Left ? BubbleBarLocation.LEFT : BubbleBarLocation.RIGHT; locationChangeListener.onStart(mInitialLocation); mLocationChangeListener.onStart(mInitialLocation); } @Override Loading @@ -192,28 +200,38 @@ public class BubbleBarLayerView extends FrameLayout if ((isBubbleLeft || isBubbleRight) && to != mLastBubbleLocationDragZone) { mLastBubbleLocationDragZone = to; locationChangeListener.onChange(isBubbleLeft mLocationChangeListener.onChange(isBubbleLeft ? BubbleBarLocation.LEFT : BubbleBarLocation.RIGHT); } } }); // TODO - currently only fullscreen is supported, should enable for split & desktop mDragZoneFactory = new DragZoneFactory(context, mPositioner.getCurrentConfig(), } private void setupDragZoneFactory() { if (!BubbleAnythingFlagHelper.enableBubbleToFullscreen()) { return; } DragZoneFactory.SplitScreenModeChecker splitScreenModeChecker = new DragZoneFactory.SplitScreenModeChecker() { @NonNull @Override public SplitScreenMode getSplitScreenMode() { return SplitScreenMode.UNSUPPORTED; } }, }; DragZoneFactory.DesktopWindowModeChecker desktopWindowModeChecker = new DragZoneFactory.DesktopWindowModeChecker() { @Override public boolean isSupported() { return false; } }, }; DragZoneFactory.BubbleBarPropertiesProvider bubbleBarPropertiesProvider = new DragZoneFactory.BubbleBarPropertiesProvider() { // this is only used in launcher @Override Loading @@ -230,9 +248,10 @@ public class BubbleBarLayerView extends FrameLayout public int getHeight() { return 0; } }); } setOnClickListener(view -> hideModalOrCollapse()); }; mDragZoneFactory = new DragZoneFactory(getContext(), mPositioner.getCurrentConfig(), splitScreenModeChecker, desktopWindowModeChecker, bubbleBarPropertiesProvider); } /** Hides the expanded view drop target. */ Loading Loading @@ -427,7 +446,8 @@ public class BubbleBarLayerView extends FrameLayout * * @param previousBubble If non-null, this is a bubble that is already showing before the new * bubble is expanded. * @param animFinish If non-null, the callback triggered after the expand animation completes * @param animFinish If non-null, the callback triggered after the expand animation * completes */ @Override public void animateExpand(BubbleViewProvider previousBubble, Loading Loading @@ -568,6 +588,7 @@ public class BubbleBarLayerView extends FrameLayout /** * Show bubble bar user education relative to the reference position. * * @param position the reference position in Screen coordinates. */ public void showUserEducation(Point position) { Loading Loading @@ -691,6 +712,7 @@ public class BubbleBarLayerView extends FrameLayout mInsets = newInsets; updateExpandedView(); } setupDragZoneFactory(); } private class LocationChangeListener implements Loading libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/DragToBubbleController.kt +11 −4 Original line number Diff line number Diff line Loading @@ -21,14 +21,15 @@ import android.content.Context import android.content.pm.ShortcutInfo import android.os.UserHandle import android.view.ViewGroup import android.view.WindowManager import android.widget.FrameLayout import androidx.annotation.VisibleForTesting import com.android.wm.shell.bubbles.BubbleController import com.android.wm.shell.bubbles.BubblePositioner import com.android.wm.shell.draganddrop.DragAndDropController.DragAndDropListener import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper import com.android.wm.shell.shared.bubbles.BubbleBarLocation import com.android.wm.shell.shared.bubbles.ContextUtils.isRtl import com.android.wm.shell.shared.bubbles.DeviceConfig import com.android.wm.shell.shared.bubbles.DragToBubblesZoneChangeListener import com.android.wm.shell.shared.bubbles.DragZone import com.android.wm.shell.shared.bubbles.DragZoneFactory Loading @@ -40,7 +41,6 @@ import com.android.wm.shell.shared.bubbles.DropTargetManager /** Handles scenarios when launcher icon is being dragged to the bubble bar drop zones. */ class DragToBubbleController( val context: Context, val bubblePositioner: BubblePositioner, val bubbleController: BubbleController, ) : DragAndDropListener { Loading @@ -62,7 +62,8 @@ class DragToBubbleController( ) @VisibleForTesting val dragZoneFactory = createDragZoneFactory() var dragZoneFactory = createDragZoneFactory() private set @VisibleForTesting var isDropHandled = false private var lastDragZone: DragZone? = null Loading @@ -70,6 +71,10 @@ class DragToBubbleController( /** Returns the container view in which drop targets are added. */ fun getDropTargetContainer(): ViewGroup = containerView override fun onConfigurationChanged() { dragZoneFactory = createDragZoneFactory() } /** Called when the drag is tarted. */ override fun onDragStarted() { if (!BubbleAnythingFlagHelper.enableCreateAnyBubble()) { Loading Loading @@ -119,9 +124,11 @@ class DragToBubbleController( } private fun createDragZoneFactory(): DragZoneFactory { val deviceConfig = DeviceConfig.create(context, context.getSystemService(WindowManager::class.java)) return DragZoneFactory( context, bubblePositioner.currentConfig, deviceConfig, { SplitScreenMode.UNSUPPORTED }, { false }, object : BubbleBarPropertiesProvider {}, Loading libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +2 −2 Original line number Diff line number Diff line Loading @@ -1931,8 +1931,8 @@ public abstract class WMShellModule { @WMSingleton @Provides static DragToBubbleController getDragToBubbleController(Context context, BubblePositioner bubblePositioner, BubbleController bubbleController) { return new DragToBubbleController(context, bubblePositioner, bubbleController); BubbleController bubbleController) { return new DragToBubbleController(context, bubbleController); } // Loading libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java +6 −0 Original line number Diff line number Diff line Loading @@ -136,6 +136,9 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll @NonNull Consumer<Boolean> onFinishCallback) { return false; } /** Called when the configuration changed. */ default void onConfigurationChanged() {} } public DragAndDropController(Context context, Loading Loading @@ -520,6 +523,9 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll for (int i = 0; i < mDisplayDropTargets.size(); i++) { mDisplayDropTargets.get(i).dragLayout.onConfigChanged(newConfig); } for (DragAndDropListener listener : mListeners) { listener.onConfigurationChanged(); } }); } Loading Loading
libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/DragToBubbleControllerTest.kt +1 −20 Original line number Diff line number Diff line Loading @@ -20,7 +20,6 @@ import android.app.PendingIntent import android.content.Context import android.content.IIntentSender import android.content.pm.ShortcutInfo import android.graphics.Insets import android.graphics.Rect import android.os.UserHandle import android.platform.test.annotations.EnableFlags Loading @@ -32,9 +31,7 @@ import androidx.test.filters.SmallTest import androidx.test.platform.app.InstrumentationRegistry import com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_ANYTHING import com.android.wm.shell.bubbles.BubbleController import com.android.wm.shell.bubbles.BubblePositioner import com.android.wm.shell.shared.bubbles.BubbleBarLocation import com.android.wm.shell.shared.bubbles.DeviceConfig import com.android.wm.shell.shared.bubbles.DragZoneFactory import com.android.wm.shell.shared.bubbles.DropTargetView import com.google.common.truth.Truth.assertThat Loading @@ -56,7 +53,6 @@ class DragToBubbleControllerTest { @get:Rule val animatorTestRule = AnimatorTestRule() private val context = getApplicationContext<Context>() private val bubblePositioner: BubblePositioner = mock() private val bubbleController: BubbleController = mock() private lateinit var dragToBubbleController: DragToBubbleController Loading @@ -76,8 +72,7 @@ class DragToBubbleControllerTest { @Before fun setUp() { bubblePositioner.stub { on { currentConfig } doReturn createDeviceConfig() } dragToBubbleController = DragToBubbleController(context, bubblePositioner, bubbleController) dragToBubbleController = DragToBubbleController(context, bubbleController) dropTargetContainer = dragToBubbleController.getDropTargetContainer() } Loading Loading @@ -223,18 +218,4 @@ class DragToBubbleControllerTest { on { getBubbleBarLocation() } doReturn bubbleBarLocation } } private fun createDeviceConfig( isLargeScreen: Boolean = true, isSmallTablet: Boolean = false, isLandscape: Boolean = true, isRtl: Boolean = false, windowBounds: Rect = Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT), insets: Insets = Insets.NONE, ) = DeviceConfig(isLargeScreen, isSmallTablet, isLandscape, isRtl, windowBounds, insets) companion object { const val SCREEN_WIDTH = 2000 const val SCREEN_HEIGHT = 1000 } }
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java +108 −86 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.wm.shell.bubbles.bar; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BUBBLES; import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BUBBLES_NOISY; import static com.android.wm.shell.shared.animation.Interpolators.ALPHA_IN; import static com.android.wm.shell.shared.animation.Interpolators.ALPHA_OUT; Loading Loading @@ -89,6 +88,7 @@ public class BubbleBarLayerView extends FrameLayout private final BubbleEducationViewController mEducationViewController; private final View mScrimView; private final BubbleExpandedViewPinController mBubbleExpandedViewPinController; private final LocationChangeListener mLocationChangeListener = new LocationChangeListener(); @Nullable private DropTargetManager mDropTargetManager = null; @Nullable Loading Loading @@ -141,14 +141,22 @@ public class BubbleBarLayerView extends FrameLayout mBubbleExpandedViewPinController = new BubbleExpandedViewPinController( context, this, mPositioner); LocationChangeListener locationChangeListener = new LocationChangeListener(); mBubbleExpandedViewPinController.setListener(locationChangeListener); mBubbleExpandedViewPinController.setListener(mLocationChangeListener); if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) { mDropTargetManager = new DropTargetManager(context, this, setupDropTargetManager(); setupDragZoneFactory(); setOnClickListener(view -> hideModalOrCollapse()); } private void setupDropTargetManager() { if (!BubbleAnythingFlagHelper.enableBubbleToFullscreen()) { return; } mDropTargetManager = new DropTargetManager(getContext(), this, new DropTargetManager.DragZoneChangedListener() { private DragZone mLastBubbleLocationDragZone = null; private BubbleBarLocation mInitialLocation = null; @Override public void onDragEnded(@Nullable DragZone zone) { if (mExpandedBubble == null || !(mExpandedBubble instanceof Bubble)) { Loading @@ -161,18 +169,18 @@ public class BubbleBarLayerView extends FrameLayout if (!isBubbleLeft && !isBubbleRight) { // If we didn't finish the "change" animation make sure to animate // it back to the right spot locationChangeListener.onChange(mInitialLocation); mLocationChangeListener.onChange(mInitialLocation); } if (zone instanceof DragZone.FullScreen) { ((Bubble) mExpandedBubble).getTaskView().moveToFullscreen(); // Make sure location change listener is updated with the initial // location -- even if we "switched sides" during the drag, since // we've ended up in fullscreen, the location shouldn't change. locationChangeListener.onRelease(mInitialLocation); mLocationChangeListener.onRelease(mInitialLocation); } else if (isBubbleLeft) { locationChangeListener.onRelease(BubbleBarLocation.LEFT); mLocationChangeListener.onRelease(BubbleBarLocation.LEFT); } else if (isBubbleRight) { locationChangeListener.onRelease(BubbleBarLocation.RIGHT); mLocationChangeListener.onRelease(BubbleBarLocation.RIGHT); } } Loading @@ -181,7 +189,7 @@ public class BubbleBarLayerView extends FrameLayout mInitialLocation = dragZone instanceof DragZone.Bubble.Left ? BubbleBarLocation.LEFT : BubbleBarLocation.RIGHT; locationChangeListener.onStart(mInitialLocation); mLocationChangeListener.onStart(mInitialLocation); } @Override Loading @@ -192,28 +200,38 @@ public class BubbleBarLayerView extends FrameLayout if ((isBubbleLeft || isBubbleRight) && to != mLastBubbleLocationDragZone) { mLastBubbleLocationDragZone = to; locationChangeListener.onChange(isBubbleLeft mLocationChangeListener.onChange(isBubbleLeft ? BubbleBarLocation.LEFT : BubbleBarLocation.RIGHT); } } }); // TODO - currently only fullscreen is supported, should enable for split & desktop mDragZoneFactory = new DragZoneFactory(context, mPositioner.getCurrentConfig(), } private void setupDragZoneFactory() { if (!BubbleAnythingFlagHelper.enableBubbleToFullscreen()) { return; } DragZoneFactory.SplitScreenModeChecker splitScreenModeChecker = new DragZoneFactory.SplitScreenModeChecker() { @NonNull @Override public SplitScreenMode getSplitScreenMode() { return SplitScreenMode.UNSUPPORTED; } }, }; DragZoneFactory.DesktopWindowModeChecker desktopWindowModeChecker = new DragZoneFactory.DesktopWindowModeChecker() { @Override public boolean isSupported() { return false; } }, }; DragZoneFactory.BubbleBarPropertiesProvider bubbleBarPropertiesProvider = new DragZoneFactory.BubbleBarPropertiesProvider() { // this is only used in launcher @Override Loading @@ -230,9 +248,10 @@ public class BubbleBarLayerView extends FrameLayout public int getHeight() { return 0; } }); } setOnClickListener(view -> hideModalOrCollapse()); }; mDragZoneFactory = new DragZoneFactory(getContext(), mPositioner.getCurrentConfig(), splitScreenModeChecker, desktopWindowModeChecker, bubbleBarPropertiesProvider); } /** Hides the expanded view drop target. */ Loading Loading @@ -427,7 +446,8 @@ public class BubbleBarLayerView extends FrameLayout * * @param previousBubble If non-null, this is a bubble that is already showing before the new * bubble is expanded. * @param animFinish If non-null, the callback triggered after the expand animation completes * @param animFinish If non-null, the callback triggered after the expand animation * completes */ @Override public void animateExpand(BubbleViewProvider previousBubble, Loading Loading @@ -568,6 +588,7 @@ public class BubbleBarLayerView extends FrameLayout /** * Show bubble bar user education relative to the reference position. * * @param position the reference position in Screen coordinates. */ public void showUserEducation(Point position) { Loading Loading @@ -691,6 +712,7 @@ public class BubbleBarLayerView extends FrameLayout mInsets = newInsets; updateExpandedView(); } setupDragZoneFactory(); } private class LocationChangeListener implements Loading
libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/DragToBubbleController.kt +11 −4 Original line number Diff line number Diff line Loading @@ -21,14 +21,15 @@ import android.content.Context import android.content.pm.ShortcutInfo import android.os.UserHandle import android.view.ViewGroup import android.view.WindowManager import android.widget.FrameLayout import androidx.annotation.VisibleForTesting import com.android.wm.shell.bubbles.BubbleController import com.android.wm.shell.bubbles.BubblePositioner import com.android.wm.shell.draganddrop.DragAndDropController.DragAndDropListener import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper import com.android.wm.shell.shared.bubbles.BubbleBarLocation import com.android.wm.shell.shared.bubbles.ContextUtils.isRtl import com.android.wm.shell.shared.bubbles.DeviceConfig import com.android.wm.shell.shared.bubbles.DragToBubblesZoneChangeListener import com.android.wm.shell.shared.bubbles.DragZone import com.android.wm.shell.shared.bubbles.DragZoneFactory Loading @@ -40,7 +41,6 @@ import com.android.wm.shell.shared.bubbles.DropTargetManager /** Handles scenarios when launcher icon is being dragged to the bubble bar drop zones. */ class DragToBubbleController( val context: Context, val bubblePositioner: BubblePositioner, val bubbleController: BubbleController, ) : DragAndDropListener { Loading @@ -62,7 +62,8 @@ class DragToBubbleController( ) @VisibleForTesting val dragZoneFactory = createDragZoneFactory() var dragZoneFactory = createDragZoneFactory() private set @VisibleForTesting var isDropHandled = false private var lastDragZone: DragZone? = null Loading @@ -70,6 +71,10 @@ class DragToBubbleController( /** Returns the container view in which drop targets are added. */ fun getDropTargetContainer(): ViewGroup = containerView override fun onConfigurationChanged() { dragZoneFactory = createDragZoneFactory() } /** Called when the drag is tarted. */ override fun onDragStarted() { if (!BubbleAnythingFlagHelper.enableCreateAnyBubble()) { Loading Loading @@ -119,9 +124,11 @@ class DragToBubbleController( } private fun createDragZoneFactory(): DragZoneFactory { val deviceConfig = DeviceConfig.create(context, context.getSystemService(WindowManager::class.java)) return DragZoneFactory( context, bubblePositioner.currentConfig, deviceConfig, { SplitScreenMode.UNSUPPORTED }, { false }, object : BubbleBarPropertiesProvider {}, Loading
libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java +2 −2 Original line number Diff line number Diff line Loading @@ -1931,8 +1931,8 @@ public abstract class WMShellModule { @WMSingleton @Provides static DragToBubbleController getDragToBubbleController(Context context, BubblePositioner bubblePositioner, BubbleController bubbleController) { return new DragToBubbleController(context, bubblePositioner, bubbleController); BubbleController bubbleController) { return new DragToBubbleController(context, bubbleController); } // Loading
libs/WindowManager/Shell/src/com/android/wm/shell/draganddrop/DragAndDropController.java +6 −0 Original line number Diff line number Diff line Loading @@ -136,6 +136,9 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll @NonNull Consumer<Boolean> onFinishCallback) { return false; } /** Called when the configuration changed. */ default void onConfigurationChanged() {} } public DragAndDropController(Context context, Loading Loading @@ -520,6 +523,9 @@ public class DragAndDropController implements RemoteCallable<DragAndDropControll for (int i = 0; i < mDisplayDropTargets.size(); i++) { mDisplayDropTargets.get(i).dragLayout.onConfigChanged(newConfig); } for (DragAndDropListener listener : mListeners) { listener.onConfigurationChanged(); } }); } Loading