From fd2a63b467de5e61c29a9d9f36c3bb9509f74e25 Mon Sep 17 00:00:00 2001 From: Bill Lin Date: Thu, 23 Jul 2020 20:49:47 +0800 Subject: [PATCH 1/2] Decouple Injection from subcomponents of PipManager (5/N) 1) PipManager manages all instances and ensure they are singleton 2) BoundsHandler manages singleton PipSnapAlgorithm 3) Remove unnecessary cached context 4) All context dispatch from PipManager 5) Let PipManager manage DisplayController callback 6) Decouple PipSurfaceTransactionHelper from dagger 7) Decouple PipAnimationController from dagger 8) PipTaskOrganizer own singleton PipAnimationController Bug: 161118569 Test: make SystemUI Test: make ArcSystemUI Test: launch aosp_tv_arm-userdebug & make Test: atest WindowManagerShellTests Test: atest SystemUITests Test: manual test Pip demo AP Change-Id: I9a055b8cae86824c0766a30b8b880891e1552abb --- .../systemui/pip/PipAnimationController.java | 3 - .../systemui/pip/PipBoundsHandler.java | 65 ++++++++++--------- .../systemui/pip/PipSnapAlgorithm.java | 6 -- .../pip/PipSurfaceTransactionHelper.java | 3 - .../systemui/pip/PipTaskOrganizer.java | 6 +- .../systemui/pip/phone/PipManager.java | 64 ++++++++++-------- .../systemui/pip/phone/PipTouchHandler.java | 52 +++++++-------- .../android/systemui/pip/tv/PipManager.java | 19 ++++-- .../systemui/pip/PipBoundsHandlerTest.java | 7 +- .../pip/phone/PipTouchHandlerTest.java | 10 +-- 10 files changed, 117 insertions(+), 118 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java b/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java index 4931388fe3628..fd8ca8044acf3 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipAnimationController.java @@ -31,8 +31,6 @@ import com.android.systemui.Interpolators; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import javax.inject.Inject; - /** * Controller class of PiP animations (both from and to PiP mode). */ @@ -88,7 +86,6 @@ public class PipAnimationController { return handler; }); - @Inject PipAnimationController(PipSurfaceTransactionHelper helper) { mSurfaceTransactionHelper = helper; } diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java index d6aa61b0c7671..b464e8adea593 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipBoundsHandler.java @@ -40,13 +40,10 @@ import android.view.Gravity; import android.window.WindowContainerTransaction; import com.android.systemui.dagger.SysUISingleton; -import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.DisplayLayout; import java.io.PrintWriter; -import javax.inject.Inject; - /** * Handles bounds calculation for PIP on Phone and other form factors, it keeps tracking variant * state changes originated from Window Manager and is the source of truth for PiP window bounds. @@ -57,10 +54,8 @@ public class PipBoundsHandler { private static final String TAG = PipBoundsHandler.class.getSimpleName(); private static final float INVALID_SNAP_FRACTION = -1f; - private final Context mContext; private final PipSnapAlgorithm mSnapAlgorithm; private final DisplayInfo mDisplayInfo = new DisplayInfo(); - private final DisplayController mDisplayController; private DisplayLayout mDisplayLayout; private ComponentName mLastPipComponentName; @@ -82,25 +77,10 @@ public class PipBoundsHandler { private boolean mIsShelfShowing; private int mShelfHeight; - private final DisplayController.OnDisplaysChangedListener mDisplaysChangedListener = - new DisplayController.OnDisplaysChangedListener() { - @Override - public void onDisplayAdded(int displayId) { - if (displayId == mContext.getDisplayId()) { - mDisplayLayout.set(mDisplayController.getDisplayLayout(displayId)); - } - } - }; - - @Inject - public PipBoundsHandler(Context context, PipSnapAlgorithm pipSnapAlgorithm, - DisplayController displayController) { - mContext = context; - mSnapAlgorithm = pipSnapAlgorithm; + public PipBoundsHandler(Context context) { + mSnapAlgorithm = new PipSnapAlgorithm(context); mDisplayLayout = new DisplayLayout(); - mDisplayController = displayController; - mDisplayController.addDisplayWindowListener(mDisplaysChangedListener); - reloadResources(); + reloadResources(context); // Initialize the aspect ratio to the default aspect ratio. Don't do this in reload // resources as it would clobber mAspectRatio when entering PiP from fullscreen which // triggers a configuration change and the resources to be reloaded. @@ -110,8 +90,8 @@ public class PipBoundsHandler { /** * TODO: move the resources to SysUI package. */ - private void reloadResources() { - final Resources res = mContext.getResources(); + private void reloadResources(Context context) { + final Resources res = context.getResources(); mDefaultAspectRatio = res.getFloat( com.android.internal.R.dimen.config_pictureInPictureDefaultAspectRatio); mDefaultStackGravity = res.getInteger( @@ -133,6 +113,19 @@ public class PipBoundsHandler { com.android.internal.R.dimen.config_pictureInPictureMaxAspectRatio); } + /** + * Sets or update latest {@link DisplayLayout} when new display added or rotation callbacks + * from {@link DisplayController.OnDisplaysChangedListener} + * @param newDisplayLayout latest {@link DisplayLayout} + */ + public void setDisplayLayout(DisplayLayout newDisplayLayout) { + mDisplayLayout.set(newDisplayLayout); + } + + /** + * Update the Min edge size for {@link PipSnapAlgorithm} to calculate corresponding bounds + * @param minEdgeSize + */ public void setMinEdgeSize(int minEdgeSize) { mCurrentMinSize = minEdgeSize; } @@ -217,6 +210,14 @@ public class PipBoundsHandler { return mReentrySnapFraction != INVALID_SNAP_FRACTION; } + /** + * The {@link PipSnapAlgorithm} is couple on display bounds + * @return {@link PipSnapAlgorithm}. + */ + public PipSnapAlgorithm getSnapAlgorithm() { + return mSnapAlgorithm; + } + public Rect getDisplayBounds() { return new Rect(0, 0, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight); } @@ -237,8 +238,8 @@ public class PipBoundsHandler { /** * Responds to IPinnedStackListener on configuration change. */ - public void onConfigurationChanged() { - reloadResources(); + public void onConfigurationChanged(Context context) { + reloadResources(context); } /** @@ -300,10 +301,10 @@ public class PipBoundsHandler { * aren't in PIP because the rotation layout is used to calculate the proper insets for the * next enter animation into PIP. */ - public void onDisplayRotationChangedNotInPip(int toRotation) { + public void onDisplayRotationChangedNotInPip(Context context, int toRotation) { // Update the display layout, note that we have to do this on every rotation even if we // aren't in PIP since we need to update the display layout to get the right resources - mDisplayLayout.rotateTo(mContext.getResources(), toRotation); + mDisplayLayout.rotateTo(context.getResources(), toRotation); // Populate the new {@link #mDisplayInfo}. // The {@link DisplayInfo} queried from DisplayManager would be the one before rotation, @@ -319,7 +320,8 @@ public class PipBoundsHandler { * * @return {@code true} if internal {@link DisplayInfo} is rotated, {@code false} otherwise. */ - public boolean onDisplayRotationChanged(Rect outBounds, Rect oldBounds, Rect outInsetBounds, + public boolean onDisplayRotationChanged(Context context, Rect outBounds, Rect oldBounds, + Rect outInsetBounds, int displayId, int fromRotation, int toRotation, WindowContainerTransaction t) { // Bail early if the event is not sent to current {@link #mDisplayInfo} if ((displayId != mDisplayInfo.displayId) || (fromRotation == toRotation)) { @@ -342,7 +344,7 @@ public class PipBoundsHandler { final float snapFraction = getSnapFraction(postChangeStackBounds); // Update the display layout - mDisplayLayout.rotateTo(mContext.getResources(), toRotation); + mDisplayLayout.rotateTo(context.getResources(), toRotation); // Populate the new {@link #mDisplayInfo}. // The {@link DisplayInfo} queried from DisplayManager would be the one before rotation, @@ -546,5 +548,6 @@ public class PipBoundsHandler { pw.println(innerPrefix + "mImeHeight=" + mImeHeight); pw.println(innerPrefix + "mIsShelfShowing=" + mIsShelfShowing); pw.println(innerPrefix + "mShelfHeight=" + mShelfHeight); + pw.println(innerPrefix + "mSnapAlgorithm" + mSnapAlgorithm); } } diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipSnapAlgorithm.java b/packages/SystemUI/src/com/android/systemui/pip/PipSnapAlgorithm.java index a9b32d917d852..5d23e4207c33d 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipSnapAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipSnapAlgorithm.java @@ -22,24 +22,18 @@ import android.graphics.PointF; import android.graphics.Rect; import android.util.Size; -import javax.inject.Inject; - /** * Calculates the snap targets and the snap position for the PIP given a position and a velocity. * All bounds are relative to the display top/left. */ public class PipSnapAlgorithm { - private final Context mContext; - private final float mDefaultSizePercent; private final float mMinAspectRatioForMinSize; private final float mMaxAspectRatioForMinSize; - @Inject public PipSnapAlgorithm(Context context) { Resources res = context.getResources(); - mContext = context; mDefaultSizePercent = res.getFloat( com.android.internal.R.dimen.config_pictureInPictureDefaultSizePercent); mMaxAspectRatioForMinSize = res.getFloat( diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipSurfaceTransactionHelper.java b/packages/SystemUI/src/com/android/systemui/pip/PipSurfaceTransactionHelper.java index e88451ca00b5a..3e98169c5b2b5 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipSurfaceTransactionHelper.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipSurfaceTransactionHelper.java @@ -27,8 +27,6 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.wm.shell.R; -import javax.inject.Inject; - /** * Abstracts the common operations on {@link SurfaceControl.Transaction} for PiP transition. */ @@ -46,7 +44,6 @@ public class PipSurfaceTransactionHelper implements ConfigurationController.Conf private final RectF mTmpDestinationRectF = new RectF(); private final Rect mTmpDestinationRect = new Rect(); - @Inject public PipSurfaceTransactionHelper(Context context, ConfigurationController configController) { final Resources res = context.getResources(); mContext = context; diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java index 0e60c83b8392e..cfc544709725a 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipTaskOrganizer.java @@ -70,8 +70,6 @@ import java.util.Map; import java.util.Objects; import java.util.function.Consumer; -import javax.inject.Inject; - /** * Manages PiP tasks such as resize and offset. * @@ -205,12 +203,10 @@ public class PipTaskOrganizer extends TaskOrganizer implements */ private boolean mShouldDeferEnteringPip; - @Inject public PipTaskOrganizer(Context context, @NonNull PipBoundsHandler boundsHandler, @NonNull PipSurfaceTransactionHelper surfaceTransactionHelper, @Nullable Divider divider, @NonNull DisplayController displayController, - @NonNull PipAnimationController pipAnimationController, @NonNull PipUiEventLogger pipUiEventLogger) { mMainHandler = new Handler(Looper.getMainLooper()); mUpdateHandler = new Handler(PipUpdateThread.get().getLooper(), mUpdateCallbacks); @@ -218,7 +214,7 @@ public class PipTaskOrganizer extends TaskOrganizer implements mEnterExitAnimationDuration = context.getResources() .getInteger(R.integer.config_pipResizeAnimationDuration); mSurfaceTransactionHelper = surfaceTransactionHelper; - mPipAnimationController = pipAnimationController; + mPipAnimationController = new PipAnimationController(mSurfaceTransactionHelper); mPipUiEventLoggerLogger = pipUiEventLogger; mSurfaceControlTransactionFactory = SurfaceControl.Transaction::new; mSplitDivider = divider; diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java index facb3966f78c2..ac076415cd1a7 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java @@ -46,7 +46,7 @@ import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.model.SysUiState; import com.android.systemui.pip.BasePipManager; import com.android.systemui.pip.PipBoundsHandler; -import com.android.systemui.pip.PipSnapAlgorithm; +import com.android.systemui.pip.PipSurfaceTransactionHelper; import com.android.systemui.pip.PipTaskOrganizer; import com.android.systemui.pip.PipUiEventLogger; import com.android.systemui.pip.phone.dagger.PipMenuActivityClass; @@ -56,6 +56,7 @@ import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.PinnedStackListenerForwarder.PinnedStackListener; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.WindowManagerWrapper; +import com.android.systemui.stackdivider.Divider; import com.android.systemui.statusbar.policy.ConfigurationController; import com.android.systemui.util.DeviceConfigProxy; import com.android.systemui.util.FloatingContentCoordinator; @@ -82,15 +83,17 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio private final Rect mTmpNormalBounds = new Rect(); protected final Rect mReentryBounds = new Rect(); - private PipBoundsHandler mPipBoundsHandler; + private DisplayController mDisplayController; private InputConsumerController mInputConsumerController; + private PipAppOpsListener mAppOpsListener; private PipMediaController mMediaController; private PipTouchHandler mTouchHandler; private PipTaskOrganizer mPipTaskOrganizer; - private PipAppOpsListener mAppOpsListener; + private PipSurfaceTransactionHelper mPipSurfaceTransactionHelper; private IPinnedStackAnimationListener mPinnedStackAnimationRecentsListener; private boolean mIsInFixedRotation; + protected PipBoundsHandler mPipBoundsHandler; protected PipMenuActivityController mMenuController; /** @@ -101,15 +104,16 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio if (!mPipTaskOrganizer.isInPip() || mPipTaskOrganizer.isDeferringEnterPipAnimation()) { // Skip if we aren't in PIP or haven't actually entered PIP yet. We still need to update // the display layout in the bounds handler in this case. - mPipBoundsHandler.onDisplayRotationChangedNotInPip(toRotation); + mPipBoundsHandler.onDisplayRotationChangedNotInPip(mContext, toRotation); return; } // If there is an animation running (ie. from a shelf offset), then ensure that we calculate // the bounds for the next orientation using the destination bounds of the animation // TODO: Techincally this should account for movement animation bounds as well Rect currentBounds = mPipTaskOrganizer.getCurrentOrAnimatingBounds(); - final boolean changed = mPipBoundsHandler.onDisplayRotationChanged(mTmpNormalBounds, - currentBounds, mTmpInsetBounds, displayId, fromRotation, toRotation, t); + final boolean changed = mPipBoundsHandler.onDisplayRotationChanged(mContext, + mTmpNormalBounds, currentBounds, mTmpInsetBounds, displayId, fromRotation, + toRotation, t); if (changed) { // If the pip was in the offset zone earlier, adjust the new bounds to the bottom of the // movement bounds @@ -135,16 +139,22 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio private DisplayController.OnDisplaysChangedListener mFixedRotationListener = new DisplayController.OnDisplaysChangedListener() { - @Override - public void onFixedRotationStarted(int displayId, int newRotation) { - mIsInFixedRotation = true; - } + @Override + public void onFixedRotationStarted(int displayId, int newRotation) { + mIsInFixedRotation = true; + } - @Override - public void onFixedRotationFinished(int displayId) { - mIsInFixedRotation = false; - } - }; + @Override + public void onFixedRotationFinished(int displayId) { + mIsInFixedRotation = false; + } + + @Override + public void onDisplayAdded(int displayId) { + mPipBoundsHandler.setDisplayLayout( + mDisplayController.getDisplayLayout(displayId)); + } + }; /** * Handler for system task stack changes. @@ -228,7 +238,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio @Override public void onConfigurationChanged() { - mHandler.post(() -> mPipBoundsHandler.onConfigurationChanged()); + mHandler.post(() -> mPipBoundsHandler.onConfigurationChanged(mContext)); } @Override @@ -256,14 +266,12 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio @Inject public PipManager(Context context, BroadcastDispatcher broadcastDispatcher, @PipMenuActivityClass Class pipMenuActivityClass, - DisplayController displayController, - FloatingContentCoordinator floatingContentCoordinator, - DeviceConfigProxy deviceConfig, - PipBoundsHandler pipBoundsHandler, - PipSnapAlgorithm pipSnapAlgorithm, - PipTaskOrganizer pipTaskOrganizer, - SysUiState sysUiState, ConfigurationController configController, + DeviceConfigProxy deviceConfig, + DisplayController displayController, + Divider divider, + FloatingContentCoordinator floatingContentCoordinator, + SysUiState sysUiState, PipUiEventLogger pipUiEventLogger) { mContext = context; mActivityManager = ActivityManager.getService(); @@ -276,8 +284,11 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio } ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener); - mPipBoundsHandler = pipBoundsHandler; - mPipTaskOrganizer = pipTaskOrganizer; + mDisplayController = displayController; + mPipBoundsHandler = new PipBoundsHandler(mContext); + mPipSurfaceTransactionHelper = new PipSurfaceTransactionHelper(context, configController); + mPipTaskOrganizer = new PipTaskOrganizer(mContext, mPipBoundsHandler, + mPipSurfaceTransactionHelper, divider, mDisplayController, pipUiEventLogger); mPipTaskOrganizer.registerPipTransitionCallback(this); mInputConsumerController = InputConsumerController.getPipInputConsumer(); mMediaController = new PipMediaController(context, mActivityManager, broadcastDispatcher); @@ -285,8 +296,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio mMediaController, mInputConsumerController); mTouchHandler = new PipTouchHandler(context, mActivityManager, mMenuController, mInputConsumerController, mPipBoundsHandler, mPipTaskOrganizer, - floatingContentCoordinator, deviceConfig, pipSnapAlgorithm, sysUiState, - pipUiEventLogger); + floatingContentCoordinator, deviceConfig, sysUiState, pipUiEventLogger); mAppOpsListener = new PipAppOpsListener(context, mActivityManager, mTouchHandler.getMotionHelper()); displayController.addDisplayChangingController(mRotationController); diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java index ecd315b336f26..1b84c1417c515 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java @@ -58,7 +58,6 @@ import com.android.systemui.R; import com.android.systemui.model.SysUiState; import com.android.systemui.pip.PipAnimationController; import com.android.systemui.pip.PipBoundsHandler; -import com.android.systemui.pip.PipSnapAlgorithm; import com.android.systemui.pip.PipTaskOrganizer; import com.android.systemui.pip.PipUiEventLogger; import com.android.systemui.shared.system.InputConsumerController; @@ -99,7 +98,6 @@ public class PipTouchHandler { private IPinnedStackController mPinnedStackController; private final PipMenuActivityController mMenuController; - private final PipSnapAlgorithm mSnapAlgorithm; private final AccessibilityManager mAccessibilityManager; private boolean mShowPipMenuOnAnimationEnd = false; @@ -216,20 +214,19 @@ public class PipTouchHandler { PipTaskOrganizer pipTaskOrganizer, FloatingContentCoordinator floatingContentCoordinator, DeviceConfigProxy deviceConfig, - PipSnapAlgorithm pipSnapAlgorithm, SysUiState sysUiState, PipUiEventLogger pipUiEventLogger) { // Initialize the Pip input consumer mContext = context; mActivityManager = activityManager; mAccessibilityManager = context.getSystemService(AccessibilityManager.class); + mPipBoundsHandler = pipBoundsHandler; mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); mMenuController = menuController; mMenuController.addListener(new PipMenuListener()); - mSnapAlgorithm = pipSnapAlgorithm; mGesture = new DefaultPipTouchGesture(); mMotionHelper = new PipMotionHelper(mContext, pipTaskOrganizer, mMenuController, - mSnapAlgorithm, floatingContentCoordinator); + mPipBoundsHandler.getSnapAlgorithm(), floatingContentCoordinator); mPipResizeGestureHandler = new PipResizeGestureHandler(context, pipBoundsHandler, mMotionHelper, deviceConfig, pipTaskOrganizer, this::getMovementBounds, @@ -248,11 +245,10 @@ public class PipTouchHandler { inputConsumerController.setInputListener(this::handleTouchEvent); inputConsumerController.setRegistrationListener(this::onRegistrationChanged); - mPipBoundsHandler = pipBoundsHandler; mFloatingContentCoordinator = floatingContentCoordinator; mConnection = new PipAccessibilityInteractionConnection(mContext, mMotionHelper, - pipTaskOrganizer, pipSnapAlgorithm, this::onAccessibilityShowMenu, - this::updateMovementBounds, mHandler); + pipTaskOrganizer, mPipBoundsHandler.getSnapAlgorithm(), + this::onAccessibilityShowMenu, this::updateMovementBounds, mHandler); mPipUiEventLogger = pipUiEventLogger; @@ -419,7 +415,8 @@ public class PipTouchHandler { public void adjustBoundsForRotation(Rect outBounds, Rect curBounds, Rect insetBounds) { final Rect toMovementBounds = new Rect(); - mSnapAlgorithm.getMovementBounds(outBounds, insetBounds, toMovementBounds, 0); + mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(outBounds, insetBounds, + toMovementBounds, 0); final int prevBottom = mMovementBounds.bottom - mMovementBoundsExtraOffsets; if ((prevBottom - mBottomOffsetBufferPx) <= curBounds.top) { outBounds.offsetTo(outBounds.left, toMovementBounds.bottom); @@ -450,26 +447,26 @@ public class PipTouchHandler { // Re-calculate the expanded bounds mNormalBounds.set(normalBounds); Rect normalMovementBounds = new Rect(); - mSnapAlgorithm.getMovementBounds(mNormalBounds, insetBounds, normalMovementBounds, - bottomOffset); + mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(mNormalBounds, insetBounds, + normalMovementBounds, bottomOffset); if (mMovementBounds.isEmpty()) { // mMovementBounds is not initialized yet and a clean movement bounds without // bottom offset shall be used later in this function. - mSnapAlgorithm.getMovementBounds(curBounds, insetBounds, mMovementBounds, - 0 /* bottomOffset */); + mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(curBounds, insetBounds, + mMovementBounds, 0 /* bottomOffset */); } // Calculate the expanded size float aspectRatio = (float) normalBounds.width() / normalBounds.height(); Point displaySize = new Point(); mContext.getDisplay().getRealSize(displaySize); - Size expandedSize = mSnapAlgorithm.getSizeForAspectRatio(aspectRatio, + Size expandedSize = mPipBoundsHandler.getSnapAlgorithm().getSizeForAspectRatio(aspectRatio, mExpandedShortestEdgeSize, displaySize.x, displaySize.y); mExpandedBounds.set(0, 0, expandedSize.getWidth(), expandedSize.getHeight()); Rect expandedMovementBounds = new Rect(); - mSnapAlgorithm.getMovementBounds(mExpandedBounds, insetBounds, expandedMovementBounds, - bottomOffset); + mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(mExpandedBounds, insetBounds, + expandedMovementBounds, bottomOffset); mPipResizeGestureHandler.updateMinSize(mNormalBounds.width(), mNormalBounds.height()); mPipResizeGestureHandler.updateMaxSize(mExpandedBounds.width(), mExpandedBounds.height()); @@ -489,7 +486,7 @@ public class PipTouchHandler { } else { final boolean isExpanded = mMenuState == MENU_STATE_FULL && willResizeMenu(); final Rect toMovementBounds = new Rect(); - mSnapAlgorithm.getMovementBounds(curBounds, insetBounds, + mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(curBounds, insetBounds, toMovementBounds, mIsImeShowing ? mImeHeight : 0); final int prevBottom = mMovementBounds.bottom - mMovementBoundsExtraOffsets; // This is to handle landscape fullscreen IMEs, don't apply the extra offset in this @@ -500,8 +497,8 @@ public class PipTouchHandler { if (isExpanded) { curBounds.set(mExpandedBounds); - mSnapAlgorithm.applySnapFraction(curBounds, toMovementBounds, - mSavedSnapFraction); + mPipBoundsHandler.getSnapAlgorithm().applySnapFraction(curBounds, + toMovementBounds, mSavedSnapFraction); } if (prevBottom < toBottom) { @@ -608,7 +605,7 @@ public class PipTouchHandler { .spring(DynamicAnimation.TRANSLATION_Y, mTargetViewContainer.getHeight(), mTargetSpringConfig) - .withEndActions(() -> mTargetViewContainer.setVisibility(View.GONE)) + .withEndActions(() -> mTargetViewContainer.setVisibility(View.GONE)) .start(); ((TransitionDrawable) mTargetViewContainer.getBackground()).reverseTransition( @@ -844,8 +841,8 @@ public class PipTouchHandler { if (mDeferResizeToNormalBoundsUntilRotation == -1) { Rect restoreBounds = new Rect(getUserResizeBounds()); Rect restoredMovementBounds = new Rect(); - mSnapAlgorithm.getMovementBounds(restoreBounds, mInsetBounds, - restoredMovementBounds, mIsImeShowing ? mImeHeight : 0); + mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(restoreBounds, + mInsetBounds, restoredMovementBounds, mIsImeShowing ? mImeHeight : 0); mMotionHelper.animateToUnexpandedState(restoreBounds, mSavedSnapFraction, restoredMovementBounds, mMovementBounds, false /* immediate */); mSavedSnapFraction = -1f; @@ -1025,25 +1022,25 @@ public class PipTouchHandler { mMenuController.hideMenu(); } } - }; + } /** * Updates the current movement bounds based on whether the menu is currently visible and * resized. */ private void updateMovementBounds() { - mSnapAlgorithm.getMovementBounds(mMotionHelper.getBounds(), mInsetBounds, - mMovementBounds, mIsImeShowing ? mImeHeight : 0); + mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(mMotionHelper.getBounds(), + mInsetBounds, mMovementBounds, mIsImeShowing ? mImeHeight : 0); mMotionHelper.setCurrentMovementBounds(mMovementBounds); boolean isMenuExpanded = mMenuState == MENU_STATE_FULL; mPipBoundsHandler.setMinEdgeSize( - isMenuExpanded && willResizeMenu() ? mExpandedShortestEdgeSize : 0); + isMenuExpanded && willResizeMenu() ? mExpandedShortestEdgeSize : 0); } private Rect getMovementBounds(Rect curBounds) { Rect movementBounds = new Rect(); - mSnapAlgorithm.getMovementBounds(curBounds, mInsetBounds, + mPipBoundsHandler.getSnapAlgorithm().getMovementBounds(curBounds, mInsetBounds, movementBounds, mIsImeShowing ? mImeHeight : 0); return movementBounds; } @@ -1075,6 +1072,7 @@ public class PipTouchHandler { pw.println(innerPrefix + "mSavedSnapFraction=" + mSavedSnapFraction); pw.println(innerPrefix + "mEnableDragToEdgeDismiss=" + mEnableDismissDragToEdge); pw.println(innerPrefix + "mMovementBoundsExtraOffsets=" + mMovementBoundsExtraOffsets); + mPipBoundsHandler.dump(pw, innerPrefix); mTouchState.dump(pw, innerPrefix); mMotionHelper.dump(pw, innerPrefix); if (mPipResizeGestureHandler != null) { diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java index 74dc003bd8b61..3aef0dacad728 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java @@ -20,6 +20,7 @@ import static android.app.ActivityTaskManager.INVALID_STACK_ID; import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED; import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; +import android.annotation.NonNull; import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManager.StackInfo; import android.app.ActivityTaskManager; @@ -54,11 +55,14 @@ import com.android.systemui.pip.BasePipManager; import com.android.systemui.pip.PipBoundsHandler; import com.android.systemui.pip.PipSurfaceTransactionHelper; import com.android.systemui.pip.PipTaskOrganizer; +import com.android.systemui.pip.PipUiEventLogger; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.PinnedStackListenerForwarder.PinnedStackListener; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.WindowManagerWrapper; import com.android.systemui.stackdivider.Divider; +import com.android.systemui.statusbar.policy.ConfigurationController; +import com.android.wm.shell.common.DisplayController; import java.util.ArrayList; import java.util.List; @@ -111,6 +115,7 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio private Context mContext; private PipBoundsHandler mPipBoundsHandler; private PipTaskOrganizer mPipTaskOrganizer; + private PipSurfaceTransactionHelper mPipSurfaceTransactionHelper; private IActivityTaskManager mActivityTaskManager; private MediaSessionManager mMediaSessionManager; private int mState = STATE_NO_PIP; @@ -229,17 +234,17 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio @Inject public PipManager(Context context, BroadcastDispatcher broadcastDispatcher, - PipBoundsHandler pipBoundsHandler, - PipTaskOrganizer pipTaskOrganizer, - PipSurfaceTransactionHelper surfaceTransactionHelper, - Divider divider) { + ConfigurationController configController, + DisplayController displayController, + Divider divider, + @NonNull PipUiEventLogger pipUiEventLogger) { if (mInitialized) { return; } mInitialized = true; mContext = context; - mPipBoundsHandler = pipBoundsHandler; + mPipBoundsHandler = new PipBoundsHandler(mContext); // Ensure that we have the display info in case we get calls to update the bounds before the // listener calls back final DisplayInfo displayInfo = new DisplayInfo(); @@ -248,7 +253,9 @@ public class PipManager implements BasePipManager, PipTaskOrganizer.PipTransitio mResizeAnimationDuration = context.getResources() .getInteger(R.integer.config_pipResizeAnimationDuration); - mPipTaskOrganizer = pipTaskOrganizer; + mPipSurfaceTransactionHelper = new PipSurfaceTransactionHelper(context, configController); + mPipTaskOrganizer = new PipTaskOrganizer(mContext, mPipBoundsHandler, + mPipSurfaceTransactionHelper, divider, displayController, pipUiEventLogger); mPipTaskOrganizer.registerPipTransitionCallback(this); mActivityTaskManager = ActivityTaskManager.getService(); ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener); diff --git a/packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java index e9d2b73182e05..cdb177096f117 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/pip/PipBoundsHandlerTest.java @@ -19,7 +19,6 @@ package com.android.systemui.pip; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.mock; import android.content.ComponentName; import android.graphics.Rect; @@ -33,7 +32,6 @@ import android.view.Gravity; import androidx.test.filters.SmallTest; import com.android.systemui.SysuiTestCase; -import com.android.wm.shell.common.DisplayController; import org.junit.Before; import org.junit.Test; @@ -65,8 +63,7 @@ public class PipBoundsHandlerTest extends SysuiTestCase { @Before public void setUp() throws Exception { initializeMockResources(); - mPipBoundsHandler = new PipBoundsHandler(mContext, new PipSnapAlgorithm(mContext), - mock(DisplayController.class)); + mPipBoundsHandler = new PipBoundsHandler(mContext); mTestComponentName1 = new ComponentName(mContext, "component1"); mTestComponentName2 = new ComponentName(mContext, "component2"); @@ -113,7 +110,7 @@ public class PipBoundsHandlerTest extends SysuiTestCase { res.addOverride(com.android.internal.R.dimen.config_pictureInPictureDefaultAspectRatio, newDefaultAspectRatio); - mPipBoundsHandler.onConfigurationChanged(); + mPipBoundsHandler.onConfigurationChanged(mContext); assertEquals("Default aspect ratio should be reloaded", mPipBoundsHandler.getDefaultAspectRatio(), newDefaultAspectRatio, diff --git a/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java index 9f67722041aa7..c8d4aca905194 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/pip/phone/PipTouchHandlerTest.java @@ -71,9 +71,6 @@ public class PipTouchHandlerTest extends SysuiTestCase { @Mock private InputConsumerController mInputConsumerController; - @Mock - private PipBoundsHandler mPipBoundsHandler; - @Mock private PipTaskOrganizer mPipTaskOrganizer; @@ -89,6 +86,7 @@ public class PipTouchHandlerTest extends SysuiTestCase { @Mock private PipUiEventLogger mPipUiEventLogger; + private PipBoundsHandler mPipBoundsHandler; private PipSnapAlgorithm mPipSnapAlgorithm; private PipMotionHelper mMotionHelper; private PipResizeGestureHandler mPipResizeGestureHandler; @@ -104,11 +102,13 @@ public class PipTouchHandlerTest extends SysuiTestCase { @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); + mPipBoundsHandler = new PipBoundsHandler(mContext); + mPipSnapAlgorithm = mPipBoundsHandler.getSnapAlgorithm(); mPipSnapAlgorithm = new PipSnapAlgorithm(mContext); mPipTouchHandler = new PipTouchHandler(mContext, mActivityManager, mPipMenuActivityController, mInputConsumerController, mPipBoundsHandler, - mPipTaskOrganizer, mFloatingContentCoordinator, mDeviceConfigProxy, - mPipSnapAlgorithm, mSysUiState, mPipUiEventLogger); + mPipTaskOrganizer, mFloatingContentCoordinator, mDeviceConfigProxy, mSysUiState, + mPipUiEventLogger); mMotionHelper = Mockito.spy(mPipTouchHandler.getMotionHelper()); mPipResizeGestureHandler = Mockito.spy(mPipTouchHandler.getPipResizeGestureHandler()); mPipTouchHandler.setPipMotionHelper(mMotionHelper); From 21a0fca709baf84c7e4883dcca09acc3b7b37bf5 Mon Sep 17 00:00:00 2001 From: Bill Lin Date: Fri, 14 Aug 2020 13:48:53 +0800 Subject: [PATCH 2/2] Decouple Injection of PipManager (6/N) Let WindowManagerShellModule provides DeviceConfigProxy, FloatingContentCoordinator, and PipUiEventLogger instead of Inject throught PipManager constructor Bug: 161118569 Test: make SystemUI Test: make ArcSystemUI Test: launch aosp_tv_arm-userdebug & make Test: atest WindowManagerShellTests Test: atest SystemUITests Test: manual test Pip demo AP Change-Id: Ib6c9dd8792bca931ce96898bae47767558225f74 --- .../systemui/pip/PipUiEventLogger.java | 4 ---- .../systemui/util/DeviceConfigProxy.java | 4 +--- .../util/FloatingContentCoordinator.kt | 7 +++--- .../systemui/wmshell/WMShellBaseModule.java | 22 +++++++++++++++++++ 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/pip/PipUiEventLogger.java b/packages/SystemUI/src/com/android/systemui/pip/PipUiEventLogger.java index 7ce2028b5f1b0..8bcaa8ab5404d 100644 --- a/packages/SystemUI/src/com/android/systemui/pip/PipUiEventLogger.java +++ b/packages/SystemUI/src/com/android/systemui/pip/PipUiEventLogger.java @@ -22,9 +22,6 @@ import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; import com.android.systemui.dagger.SysUISingleton; -import javax.inject.Inject; - - /** * Helper class that ends PiP log to UiEvent, see also go/uievent */ @@ -35,7 +32,6 @@ public class PipUiEventLogger { private TaskInfo mTaskInfo; - @Inject public PipUiEventLogger(UiEventLogger uiEventLogger) { mUiEventLogger = uiEventLogger; } diff --git a/packages/SystemUI/src/com/android/systemui/util/DeviceConfigProxy.java b/packages/SystemUI/src/com/android/systemui/util/DeviceConfigProxy.java index 3a2172ae0fae3..66f8f74c7caba 100644 --- a/packages/SystemUI/src/com/android/systemui/util/DeviceConfigProxy.java +++ b/packages/SystemUI/src/com/android/systemui/util/DeviceConfigProxy.java @@ -25,13 +25,11 @@ import android.provider.Settings; import java.util.concurrent.Executor; -import javax.inject.Inject; - /** * Wrapper around DeviceConfig useful for testing. */ public class DeviceConfigProxy { - @Inject + public DeviceConfigProxy() { } diff --git a/packages/SystemUI/src/com/android/systemui/util/FloatingContentCoordinator.kt b/packages/SystemUI/src/com/android/systemui/util/FloatingContentCoordinator.kt index f22f59bee42fe..bcfb2afeeda1f 100644 --- a/packages/SystemUI/src/com/android/systemui/util/FloatingContentCoordinator.kt +++ b/packages/SystemUI/src/com/android/systemui/util/FloatingContentCoordinator.kt @@ -4,8 +4,7 @@ import android.graphics.Rect import android.util.Log import com.android.systemui.dagger.SysUISingleton import com.android.systemui.util.FloatingContentCoordinator.FloatingContent -import java.util.* -import javax.inject.Inject +import java.util.HashMap /** Tag for debug logging. */ private const val TAG = "FloatingCoordinator" @@ -20,9 +19,9 @@ private const val TAG = "FloatingCoordinator" * other content out of the way. [onContentRemoved] should be called when the content is removed or * no longer visible. */ -@SysUISingleton -class FloatingContentCoordinator @Inject constructor() { +@SysUISingleton +class FloatingContentCoordinator constructor() { /** * Represents a piece of floating content, such as PIP or the Bubbles stack. Provides methods * that allow the [FloatingContentCoordinator] to determine the current location of the content, diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java index ac47660f3221d..34398cc79bd29 100644 --- a/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java +++ b/packages/SystemUI/src/com/android/systemui/wmshell/WMShellBaseModule.java @@ -20,8 +20,12 @@ import android.content.Context; import android.os.Handler; import android.view.IWindowManager; +import com.android.internal.logging.UiEventLogger; import com.android.systemui.dagger.SysUISingleton; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.pip.PipUiEventLogger; +import com.android.systemui.util.DeviceConfigProxy; +import com.android.systemui.util.FloatingContentCoordinator; import com.android.wm.shell.common.DisplayController; import com.android.wm.shell.common.SystemWindows; import com.android.wm.shell.common.TransactionPool; @@ -49,10 +53,28 @@ public class WMShellBaseModule { return new DisplayController(context, handler, wmService); } + @SysUISingleton + @Provides + static DeviceConfigProxy provideDeviceConfigProxy() { + return new DeviceConfigProxy(); + } + @SysUISingleton + @Provides + static FloatingContentCoordinator provideFloatingContentCoordinator() { + return new FloatingContentCoordinator(); + } + + @SysUISingleton + @Provides + static PipUiEventLogger providePipUiEventLogger(UiEventLogger uiEventLogger) { + return new PipUiEventLogger(uiEventLogger); + } + @SysUISingleton @Provides static SystemWindows provideSystemWindows(DisplayController displayController, IWindowManager wmService) { return new SystemWindows(displayController, wmService); } + }