diff options
13 files changed, 609 insertions, 22 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java index 4de96e342b2f..50cfb6a905c9 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamOverlayContainerViewController.java @@ -37,8 +37,10 @@ import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dreams.complication.ComplicationHostViewController; import com.android.systemui.dreams.dagger.DreamOverlayComponent; import com.android.systemui.dreams.dagger.DreamOverlayModule; +import com.android.systemui.dreams.touch.scrim.BouncerlessScrimController; import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor; import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback; +import com.android.systemui.shade.ShadeExpansionChangeEvent; import com.android.systemui.statusbar.BlurUtils; import com.android.systemui.util.ViewController; import com.android.systemui.util.concurrency.DelayableExecutor; @@ -82,6 +84,22 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve private long mJitterStartTimeMillis; private boolean mBouncerAnimating; + private boolean mWakingUpFromSwipe; + + private final BouncerlessScrimController mBouncerlessScrimController; + + private final BouncerlessScrimController.Callback mBouncerlessExpansionCallback = + new BouncerlessScrimController.Callback() { + @Override + public void onExpansion(ShadeExpansionChangeEvent event) { + updateTransitionState(event.getFraction()); + } + + @Override + public void onWakeup() { + mWakingUpFromSwipe = true; + } + }; private final PrimaryBouncerExpansionCallback mBouncerExpansionCallback = @@ -156,7 +174,8 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve @Named(DreamOverlayModule.MILLIS_UNTIL_FULL_JITTER) long millisUntilFullJitter, PrimaryBouncerCallbackInteractor primaryBouncerCallbackInteractor, DreamOverlayAnimationsController animationsController, - DreamOverlayStateController stateController) { + DreamOverlayStateController stateController, + BouncerlessScrimController bouncerlessScrimController) { super(containerView); mDreamOverlayContentView = contentView; mStatusBarViewController = statusBarViewController; @@ -164,6 +183,9 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve mDreamOverlayAnimationsController = animationsController; mStateController = stateController; + mBouncerlessScrimController = bouncerlessScrimController; + mBouncerlessScrimController.addCallback(mBouncerlessExpansionCallback); + mComplicationHostViewController = complicationHostViewController; mDreamOverlayMaxTranslationY = resources.getDimensionPixelSize( R.dimen.dream_overlay_y_offset); @@ -190,6 +212,7 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve @Override protected void onViewAttached() { + mWakingUpFromSwipe = false; mJitterStartTimeMillis = System.currentTimeMillis(); mHandler.postDelayed(this::updateBurnInOffsets, mBurnInProtectionUpdateInterval); mPrimaryBouncerCallbackInteractor.addBouncerExpansionCallback(mBouncerExpansionCallback); @@ -278,6 +301,13 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve */ public void wakeUp(@NonNull Runnable onAnimationEnd, @NonNull DelayableExecutor callbackExecutor) { + // When swiping causes wakeup, do not run any animations as the dream should exit as soon + // as possible. + if (mWakingUpFromSwipe) { + onAnimationEnd.run(); + return; + } + mDreamOverlayAnimationsController.wakeUp(onAnimationEnd, callbackExecutor); } } diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java index e7b29bb84b3d..0ab8c8e42b03 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java @@ -28,6 +28,7 @@ import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dreams.DreamOverlayNotificationCountProvider; import com.android.systemui.dreams.DreamOverlayService; import com.android.systemui.dreams.complication.dagger.RegisteredComplicationsModule; +import com.android.systemui.dreams.touch.scrim.dagger.ScrimModule; import java.util.Optional; @@ -42,6 +43,7 @@ import dagger.Provides; @Module(includes = { RegisteredComplicationsModule.class, LowLightDreamModule.class, + ScrimModule.class }, subcomponents = { DreamOverlayComponent.class, diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java index 44207f4aecf5..73c2289ad6bd 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandler.java @@ -36,11 +36,12 @@ import androidx.annotation.VisibleForTesting; import com.android.internal.logging.UiEvent; import com.android.internal.logging.UiEventLogger; +import com.android.systemui.dreams.touch.scrim.ScrimController; +import com.android.systemui.dreams.touch.scrim.ScrimManager; import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants; import com.android.systemui.shade.ShadeExpansionChangeEvent; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.phone.CentralSurfaces; -import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.wm.shell.animation.FlingAnimationUtils; import java.util.Optional; @@ -78,7 +79,8 @@ public class BouncerSwipeTouchHandler implements DreamTouchHandler { private final NotificationShadeWindowController mNotificationShadeWindowController; private final float mBouncerZoneScreenPercentage; - private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; + private final ScrimManager mScrimManager; + private ScrimController mCurrentScrimController; private float mCurrentExpansion; private final Optional<CentralSurfaces> mCentralSurfaces; @@ -90,6 +92,7 @@ public class BouncerSwipeTouchHandler implements DreamTouchHandler { private final DisplayMetrics mDisplayMetrics; private Boolean mCapture; + private Boolean mExpanded; private boolean mBouncerInitiallyShowing; @@ -101,6 +104,17 @@ public class BouncerSwipeTouchHandler implements DreamTouchHandler { private final UiEventLogger mUiEventLogger; + private final ScrimManager.Callback mScrimManagerCallback = new ScrimManager.Callback() { + @Override + public void onScrimControllerChanged(ScrimController controller) { + if (mCurrentScrimController != null) { + mCurrentScrimController.reset(); + } + + mCurrentScrimController = controller; + } + }; + private final GestureDetector.OnGestureListener mOnGestureListener = new GestureDetector.SimpleOnGestureListener() { @Override @@ -115,8 +129,10 @@ public class BouncerSwipeTouchHandler implements DreamTouchHandler { .orElse(false); if (mCapture) { + // reset expanding + mExpanded = false; // Since the user is dragging the bouncer up, set scrimmed to false. - mStatusBarKeyguardViewManager.showPrimaryBouncer(false); + mCurrentScrimController.show(); } } @@ -157,10 +173,10 @@ public class BouncerSwipeTouchHandler implements DreamTouchHandler { ShadeExpansionChangeEvent event = new ShadeExpansionChangeEvent( /* fraction= */ mCurrentExpansion, - /* expanded= */ false, + /* expanded= */ mExpanded, /* tracking= */ true, /* dragDownPxAmount= */ dragDownAmount); - mStatusBarKeyguardViewManager.onPanelExpansionChanged(event); + mCurrentScrimController.expand(event); } @@ -187,7 +203,7 @@ public class BouncerSwipeTouchHandler implements DreamTouchHandler { @Inject public BouncerSwipeTouchHandler( DisplayMetrics displayMetrics, - StatusBarKeyguardViewManager statusBarKeyguardViewManager, + ScrimManager scrimManager, Optional<CentralSurfaces> centralSurfaces, NotificationShadeWindowController notificationShadeWindowController, ValueAnimatorCreator valueAnimatorCreator, @@ -200,7 +216,7 @@ public class BouncerSwipeTouchHandler implements DreamTouchHandler { UiEventLogger uiEventLogger) { mDisplayMetrics = displayMetrics; mCentralSurfaces = centralSurfaces; - mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; + mScrimManager = scrimManager; mNotificationShadeWindowController = notificationShadeWindowController; mBouncerZoneScreenPercentage = swipeRegionPercentage; mFlingAnimationUtils = flingAnimationUtils; @@ -234,9 +250,12 @@ public class BouncerSwipeTouchHandler implements DreamTouchHandler { mTouchSession = session; mVelocityTracker.clear(); mNotificationShadeWindowController.setForcePluginOpen(true, this); + mScrimManager.addCallback(mScrimManagerCallback); + mCurrentScrimController = mScrimManager.getCurrentController(); session.registerCallback(() -> { mVelocityTracker.recycle(); + mScrimManager.removeCallback(mScrimManagerCallback); mCapture = null; mNotificationShadeWindowController.setForcePluginOpen(false, this); }); @@ -273,9 +292,10 @@ public class BouncerSwipeTouchHandler implements DreamTouchHandler { final float velocityVector = (float) Math.hypot(horizontalVelocity, verticalVelocity); - final float expansion = flingRevealsOverlay(verticalVelocity, velocityVector) - ? KeyguardBouncerConstants.EXPANSION_HIDDEN - : KeyguardBouncerConstants.EXPANSION_VISIBLE; + mExpanded = !flingRevealsOverlay(verticalVelocity, velocityVector); + final float expansion = mExpanded + ? KeyguardBouncerConstants.EXPANSION_VISIBLE + : KeyguardBouncerConstants.EXPANSION_HIDDEN; // Log the swiping up to show Bouncer event. if (!mBouncerInitiallyShowing @@ -286,7 +306,7 @@ public class BouncerSwipeTouchHandler implements DreamTouchHandler { flingToExpansion(verticalVelocity, expansion); if (expansion == KeyguardBouncerConstants.EXPANSION_HIDDEN) { - mStatusBarKeyguardViewManager.reset(false); + mCurrentScrimController.reset(); } break; default: diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/scrim/BouncerScrimController.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/scrim/BouncerScrimController.java new file mode 100644 index 000000000000..f5bbba780b27 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/scrim/BouncerScrimController.java @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.dreams.touch.scrim; + +import com.android.systemui.shade.ShadeExpansionChangeEvent; +import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; + +import javax.inject.Inject; + +/** + * Implementation for handling swipe movements on the overlay when the keyguard is present. + */ +public class BouncerScrimController implements ScrimController { + private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; + + @Inject + BouncerScrimController(StatusBarKeyguardViewManager statusBarKeyguardViewManager) { + mStatusBarKeyguardViewManager = statusBarKeyguardViewManager; + } + + @Override + public void show() { + mStatusBarKeyguardViewManager.showBouncer(false); + } + + @Override + public void expand(ShadeExpansionChangeEvent event) { + mStatusBarKeyguardViewManager.onPanelExpansionChanged(event); + } + + @Override + public void reset() { + mStatusBarKeyguardViewManager.reset(false); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimController.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimController.java new file mode 100644 index 000000000000..01e4d04dcc2c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimController.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.dreams.touch.scrim; + +import android.os.PowerManager; +import android.os.SystemClock; + +import com.android.systemui.dagger.SysUISingleton; +import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.shade.ShadeExpansionChangeEvent; +import com.android.systemui.unfold.util.CallbackController; + +import java.util.HashSet; +import java.util.concurrent.Executor; + +import javax.inject.Inject; + +/** + * {@link BouncerlessScrimController} handles scrim progression when no keyguard is set. When + * fully expanded, the controller dismisses the dream. + */ +@SysUISingleton +public class BouncerlessScrimController implements ScrimController, + CallbackController<BouncerlessScrimController.Callback> { + private static final String TAG = "BLScrimController"; + + /** + * {@link Callback} allows {@link BouncerlessScrimController} clients to be informed of + * expansion progression and wakeup + */ + public interface Callback { + /** + * Invoked when there is a change to the scrim expansion. + */ + void onExpansion(ShadeExpansionChangeEvent event); + + /** + * Invoked after {@link BouncerlessScrimController} has started waking up the device. + */ + void onWakeup(); + } + + private final Executor mExecutor; + private final PowerManager mPowerManager; + + @Override + public void addCallback(Callback listener) { + mExecutor.execute(() -> mCallbacks.add(listener)); + } + + @Override + public void removeCallback(Callback listener) { + mExecutor.execute(() -> mCallbacks.remove(listener)); + } + + private final HashSet<Callback> mCallbacks; + + + @Inject + public BouncerlessScrimController(@Main Executor executor, + PowerManager powerManager) { + mExecutor = executor; + mPowerManager = powerManager; + mCallbacks = new HashSet<>(); + } + + @Override + public void expand(ShadeExpansionChangeEvent event) { + if (event.getExpanded()) { + mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_GESTURE, + "com.android.systemui:SwipeUp"); + mExecutor.execute(() -> mCallbacks.forEach(callback -> callback.onWakeup())); + } else { + mExecutor.execute(() -> mCallbacks.forEach(callback -> callback.onExpansion(event))); + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/scrim/ScrimController.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/scrim/ScrimController.java new file mode 100644 index 000000000000..61629ef79637 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/scrim/ScrimController.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.dreams.touch.scrim; + +import com.android.systemui.shade.ShadeExpansionChangeEvent; + +/** + * {@link ScrimController} provides an interface for the different consumers of scrolling/expansion + * events over the dream. + */ +public interface ScrimController { + /** + * Called at the start of expansion before any expansion amount updates. + */ + default void show() { + } + + /** + * Called for every expansion update. + * @param event {@link ShadeExpansionChangeEvent} detailing the change. + */ + default void expand(ShadeExpansionChangeEvent event) { + } + + /** + * Called at the end of the movement. + */ + default void reset() { + } +} diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/scrim/ScrimManager.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/scrim/ScrimManager.java new file mode 100644 index 000000000000..0d0dff6c8fb0 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/scrim/ScrimManager.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.dreams.touch.scrim; + +import static com.android.systemui.dreams.touch.scrim.dagger.ScrimModule.BOUNCERLESS_SCRIM_CONTROLLER; +import static com.android.systemui.dreams.touch.scrim.dagger.ScrimModule.BOUNCER_SCRIM_CONTROLLER; + +import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.statusbar.policy.KeyguardStateController; + +import java.util.HashSet; +import java.util.concurrent.Executor; + +import javax.inject.Inject; +import javax.inject.Named; + +/** + * {@link ScrimManager} helps manage multiple {@link ScrimController} instances, specifying the + * appropriate one to use at the current moment and managing the handoff between controllers. + */ +public class ScrimManager { + private final ScrimController mBouncerScrimController; + private final ScrimController mBouncerlessScrimController; + private final KeyguardStateController mKeyguardStateController; + private final Executor mExecutor; + + private ScrimController mCurrentController; + private final HashSet<Callback> mCallbacks; + + /** + * Interface implemented for receiving updates to the active {@link ScrimController}. + */ + public interface Callback { + /** + * Invoked when the controller changes. + * @param controller The currently active {@link ScrimController}. + */ + void onScrimControllerChanged(ScrimController controller); + } + + private final KeyguardStateController.Callback mKeyguardStateCallback = + new KeyguardStateController.Callback() { + @Override + public void onKeyguardShowingChanged() { + mExecutor.execute(() -> updateController()); + } + }; + + @Inject + ScrimManager(@Main Executor executor, + @Named(BOUNCER_SCRIM_CONTROLLER) ScrimController bouncerScrimController, + @Named(BOUNCERLESS_SCRIM_CONTROLLER)ScrimController bouncerlessScrimController, + KeyguardStateController keyguardStateController) { + mExecutor = executor; + mCallbacks = new HashSet<>(); + mBouncerlessScrimController = bouncerlessScrimController; + mBouncerScrimController = bouncerScrimController; + mKeyguardStateController = keyguardStateController; + + mKeyguardStateController.addCallback(mKeyguardStateCallback); + updateController(); + } + + private void updateController() { + final ScrimController existingController = mCurrentController; + mCurrentController = mKeyguardStateController.canDismissLockScreen() + ? mBouncerlessScrimController + : mBouncerScrimController; + + if (existingController == mCurrentController) { + return; + } + + mCallbacks.forEach(callback -> callback.onScrimControllerChanged(mCurrentController)); + } + + /** + * Adds a {@link Callback} to receive future changes to the active {@link ScrimController}. + */ + public void addCallback(Callback callback) { + mExecutor.execute(() -> mCallbacks.add(callback)); + } + + /** + * Removes the {@link Callback} from receiving further updates. + */ + public void removeCallback(Callback callback) { + mExecutor.execute(() -> mCallbacks.remove(callback)); + } + + /** + * Returns the currently get {@link ScrimController}. + * @return + */ + public ScrimController getCurrentController() { + return mCurrentController; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/dreams/touch/scrim/dagger/ScrimModule.java b/packages/SystemUI/src/com/android/systemui/dreams/touch/scrim/dagger/ScrimModule.java new file mode 100644 index 000000000000..40bc0ea6e95e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/dreams/touch/scrim/dagger/ScrimModule.java @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.dreams.touch.scrim.dagger; + +import com.android.systemui.dreams.touch.scrim.BouncerScrimController; +import com.android.systemui.dreams.touch.scrim.BouncerlessScrimController; +import com.android.systemui.dreams.touch.scrim.ScrimController; + +import javax.inject.Named; + +import dagger.Module; +import dagger.Provides; + +/** + * Module for scrim related dependencies. + */ +@Module +public interface ScrimModule { + String BOUNCERLESS_SCRIM_CONTROLLER = "bouncerless_scrim_controller"; + String BOUNCER_SCRIM_CONTROLLER = "bouncer_scrim_controller"; + + /** */ + @Provides + @Named(BOUNCERLESS_SCRIM_CONTROLLER) + static ScrimController providesBouncerlessScrimController( + BouncerlessScrimController controller) { + return controller; + } + + /** */ + @Provides + @Named(BOUNCER_SCRIM_CONTROLLER) + static ScrimController providesBouncerScrimController( + BouncerScrimController controller) { + return controller; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java index 63179dac7b8c..5adb58bca886 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java @@ -77,6 +77,12 @@ public class CrossFadeHelper { */ public static void fadeOut(View view, float fadeOutAmount, boolean remap) { view.animate().cancel(); + + // Don't fade out if already not visible. + if (view.getAlpha() == 0.0f) { + return; + } + if (fadeOutAmount == 1.0f && view.getVisibility() != View.GONE) { view.setVisibility(View.INVISIBLE); } else if (view.getVisibility() == View.INVISIBLE) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java index 84c97862710f..6b095ffd3977 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/DreamOverlayContainerViewControllerTest.java @@ -36,6 +36,7 @@ import androidx.test.filters.SmallTest; import com.android.keyguard.BouncerPanelExpansionCalculator; import com.android.systemui.SysuiTestCase; import com.android.systemui.dreams.complication.ComplicationHostViewController; +import com.android.systemui.dreams.touch.scrim.BouncerlessScrimController; import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor; import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback; import com.android.systemui.statusbar.BlurUtils; @@ -88,6 +89,9 @@ public class DreamOverlayContainerViewControllerTest extends SysuiTestCase { DreamOverlayAnimationsController mAnimationsController; @Mock + BouncerlessScrimController mBouncerlessScrimController; + + @Mock DreamOverlayStateController mStateController; DreamOverlayContainerViewController mController; @@ -113,7 +117,8 @@ public class DreamOverlayContainerViewControllerTest extends SysuiTestCase { MILLIS_UNTIL_FULL_JITTER, mPrimaryBouncerCallbackInteractor, mAnimationsController, - mStateController); + mStateController, + mBouncerlessScrimController); } @Test diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java index f64179deec35..3a168d4e234b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/BouncerSwipeTouchHandlerTest.java @@ -41,12 +41,13 @@ import androidx.test.filters.SmallTest; import com.android.internal.logging.UiEventLogger; import com.android.systemui.SysuiTestCase; +import com.android.systemui.dreams.touch.scrim.ScrimController; +import com.android.systemui.dreams.touch.scrim.ScrimManager; import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants; import com.android.systemui.shade.ShadeExpansionChangeEvent; import com.android.systemui.shared.system.InputChannelCompat; import com.android.systemui.statusbar.NotificationShadeWindowController; import com.android.systemui.statusbar.phone.CentralSurfaces; -import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.wm.shell.animation.FlingAnimationUtils; import org.junit.Before; @@ -63,10 +64,13 @@ import java.util.Optional; @RunWith(AndroidTestingRunner.class) public class BouncerSwipeTouchHandlerTest extends SysuiTestCase { @Mock - StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; + CentralSurfaces mCentralSurfaces; @Mock - CentralSurfaces mCentralSurfaces; + ScrimManager mScrimManager; + + @Mock + ScrimController mScrimController; @Mock NotificationShadeWindowController mNotificationShadeWindowController; @@ -111,7 +115,7 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase { MockitoAnnotations.initMocks(this); mTouchHandler = new BouncerSwipeTouchHandler( mDisplayMetrics, - mStatusBarKeyguardViewManager, + mScrimManager, Optional.of(mCentralSurfaces), mNotificationShadeWindowController, mValueAnimatorCreator, @@ -121,6 +125,7 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase { TOUCH_REGION, mUiEventLogger); + when(mScrimManager.getCurrentController()).thenReturn(mScrimController); when(mCentralSurfaces.isBouncerShowing()).thenReturn(false); when(mCentralSurfaces.getDisplayHeight()).thenReturn((float) SCREEN_HEIGHT_PX); when(mValueAnimatorCreator.create(anyFloat(), anyFloat())).thenReturn(mValueAnimator); @@ -193,7 +198,7 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase { assertThat(gestureListener.onScroll(event1, event2, 0, distanceY)) .isTrue(); - verify(mStatusBarKeyguardViewManager, never()).onPanelExpansionChanged(any()); + verify(mScrimController, never()).expand(any()); } /** @@ -220,7 +225,7 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase { assertThat(gestureListener.onScroll(event1, event2, 0, distanceY)) .isTrue(); - verify(mStatusBarKeyguardViewManager, never()).onPanelExpansionChanged(any()); + verify(mScrimController, never()).expand(any()); } /** @@ -274,12 +279,12 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase { final MotionEvent event2 = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, direction == Direction.UP ? SCREEN_HEIGHT_PX - distanceY : distanceY, 0); - reset(mStatusBarKeyguardViewManager); + reset(mScrimController); assertThat(gestureListener.onScroll(event1, event2, 0, distanceY)) .isTrue(); // Ensure only called once - verify(mStatusBarKeyguardViewManager).onPanelExpansionChanged(any()); + verify(mScrimController).expand(any()); final float expansion = isBouncerInitiallyShowing ? percent : 1 - percent; final float dragDownAmount = event2.getY() - event1.getY(); @@ -288,7 +293,7 @@ public class BouncerSwipeTouchHandlerTest extends SysuiTestCase { ShadeExpansionChangeEvent event = new ShadeExpansionChangeEvent( expansion, /* expanded= */ false, /* tracking= */ true, dragDownAmount); - verify(mStatusBarKeyguardViewManager).onPanelExpansionChanged(event); + verify(mScrimController).expand(event); } /** diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java new file mode 100644 index 000000000000..79c535aea2d0 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/BouncerlessScrimControllerTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.dreams.touch.scrim; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; + +import android.os.PowerManager; +import android.testing.AndroidTestingRunner; + +import androidx.test.filters.SmallTest; + +import com.android.systemui.SysuiTestCase; +import com.android.systemui.shade.ShadeExpansionChangeEvent; +import com.android.systemui.util.concurrency.FakeExecutor; +import com.android.systemui.util.time.FakeSystemClock; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +public class BouncerlessScrimControllerTest extends SysuiTestCase { + @Mock + BouncerlessScrimController.Callback mCallback; + + @Mock + PowerManager mPowerManager; + + private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock()); + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void testWakeupOnSwipeOpen() { + final BouncerlessScrimController scrimController = + new BouncerlessScrimController(mExecutor, mPowerManager); + scrimController.addCallback(mCallback); + scrimController.expand(new ShadeExpansionChangeEvent(.5f, true, false, 0.0f)); + mExecutor.runAllReady(); + verify(mPowerManager).wakeUp(anyLong(), eq(PowerManager.WAKE_REASON_GESTURE), any()); + verify(mCallback).onWakeup(); + } + + @Test + public void testExpansionPropagation() { + final BouncerlessScrimController scrimController = + new BouncerlessScrimController(mExecutor, mPowerManager); + scrimController.addCallback(mCallback); + final ShadeExpansionChangeEvent expansionEvent = + new ShadeExpansionChangeEvent(0.5f, false, false, 0.0f); + scrimController.expand(expansionEvent); + mExecutor.runAllReady(); + verify(mCallback).onExpansion(eq(expansionEvent)); + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java new file mode 100644 index 000000000000..ac9822db85d6 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/touch/scrim/ScrimManagerTest.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.dreams.touch.scrim; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import android.testing.AndroidTestingRunner; + +import androidx.test.filters.SmallTest; + +import com.android.systemui.SysuiTestCase; +import com.android.systemui.statusbar.policy.KeyguardStateController; +import com.android.systemui.util.concurrency.FakeExecutor; +import com.android.systemui.util.time.FakeSystemClock; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +@SmallTest +@RunWith(AndroidTestingRunner.class) +public class ScrimManagerTest extends SysuiTestCase { + @Mock + ScrimController mBouncerlessScrimController; + + @Mock + ScrimController mBouncerScrimController; + + @Mock + KeyguardStateController mKeyguardStateController; + + @Mock + ScrimManager.Callback mCallback; + + private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock()); + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void testControllerSelection() { + when(mKeyguardStateController.canDismissLockScreen()).thenReturn(false); + ArgumentCaptor<KeyguardStateController.Callback> callbackCaptor = + ArgumentCaptor.forClass(KeyguardStateController.Callback.class); + final ScrimManager manager = new ScrimManager(mExecutor, mBouncerScrimController, + mBouncerlessScrimController, mKeyguardStateController); + verify(mKeyguardStateController).addCallback(callbackCaptor.capture()); + + assertThat(manager.getCurrentController()).isEqualTo(mBouncerScrimController); + when(mKeyguardStateController.canDismissLockScreen()).thenReturn(true); + callbackCaptor.getValue().onKeyguardShowingChanged(); + mExecutor.runAllReady(); + assertThat(manager.getCurrentController()).isEqualTo(mBouncerlessScrimController); + } + + @Test + public void testCallback() { + when(mKeyguardStateController.canDismissLockScreen()).thenReturn(false); + ArgumentCaptor<KeyguardStateController.Callback> callbackCaptor = + ArgumentCaptor.forClass(KeyguardStateController.Callback.class); + final ScrimManager manager = new ScrimManager(mExecutor, mBouncerScrimController, + mBouncerlessScrimController, mKeyguardStateController); + verify(mKeyguardStateController).addCallback(callbackCaptor.capture()); + + manager.addCallback(mCallback); + when(mKeyguardStateController.canDismissLockScreen()).thenReturn(true); + callbackCaptor.getValue().onKeyguardShowingChanged(); + mExecutor.runAllReady(); + verify(mCallback).onScrimControllerChanged(eq(mBouncerlessScrimController)); + } +} |