Merge "Fade out UFPS icon when launching an app over it (1/2)"

This commit is contained in:
TreeHugger Robot
2022-01-10 13:28:40 +00:00
committed by Android (Google) Code Review
10 changed files with 122 additions and 24 deletions

View File

@@ -39,5 +39,5 @@ android_library {
],
manifest: "AndroidManifest.xml",
kotlincflags: ["-Xjvm-default=enable"],
}

View File

@@ -95,6 +95,9 @@ class ActivityLaunchAnimator(
*/
var callback: Callback? = null
/** The set of [Listener] that should be notified of any animation started by this animator. */
private val listeners = LinkedHashSet<Listener>()
/**
* Start an intent and animate the opening window. The intent will be started by running
* [intentStarter], which should use the provided [RemoteAnimationAdapter] and return the launch
@@ -214,6 +217,16 @@ class ActivityLaunchAnimator(
}
}
/** Add a [Listener] that can listen to launch animations. */
fun addListener(listener: Listener) {
listeners.add(listener)
}
/** Remove a [Listener]. */
fun removeListener(listener: Listener) {
listeners.remove(listener)
}
/** Create a new animation [Runner] controlled by [controller]. */
@VisibleForTesting
fun createRunner(controller: Controller): Runner = Runner(controller)
@@ -234,13 +247,27 @@ class ActivityLaunchAnimator(
/** Hide the keyguard and animate using [runner]. */
fun hideKeyguardWithAnimation(runner: IRemoteAnimationRunner)
/** Enable/disable window blur so they don't overlap with the window launch animation **/
fun setBlursDisabledForAppLaunch(disabled: Boolean)
/* Get the background color of [task]. */
fun getBackgroundColor(task: TaskInfo): Int
}
interface Listener {
/** Called when an activity launch animation started. */
@JvmDefault
fun onLaunchAnimationStart() {}
/**
* Called when an activity launch animation is finished. This will be called if and only if
* [onLaunchAnimationStart] was called earlier.
*/
@JvmDefault
fun onLaunchAnimationEnd() {}
/** Called when an activity launch animation made progress. */
@JvmDefault
fun onLaunchAnimationProgress(linearProgress: Float) {}
}
/**
* A controller that takes care of applying the animation to an expanding view.
*
@@ -396,12 +423,12 @@ class ActivityLaunchAnimator(
val delegate = this.controller
val controller = object : LaunchAnimator.Controller by delegate {
override fun onLaunchAnimationStart(isExpandingFullyAbove: Boolean) {
callback.setBlursDisabledForAppLaunch(true)
listeners.forEach { it.onLaunchAnimationStart() }
delegate.onLaunchAnimationStart(isExpandingFullyAbove)
}
override fun onLaunchAnimationEnd(isExpandingFullyAbove: Boolean) {
callback.setBlursDisabledForAppLaunch(false)
listeners.forEach { it.onLaunchAnimationEnd() }
iCallback?.invoke()
delegate.onLaunchAnimationEnd(isExpandingFullyAbove)
}
@@ -413,6 +440,7 @@ class ActivityLaunchAnimator(
) {
applyStateToWindow(window, state)
navigationBar?.let { applyStateToNavigationBar(it, state, linearProgress) }
listeners.forEach { it.onLaunchAnimationProgress(linearProgress) }
delegate.onLaunchAnimationProgress(state, progress, linearProgress)
}
}

View File

@@ -53,6 +53,7 @@ import android.view.accessibility.AccessibilityManager;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.LatencyTracker;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeReceiver;
@@ -130,6 +131,7 @@ public class UdfpsController implements DozeReceiver {
// Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple
// sensors, this, in addition to a lot of the code here, will be updated.
@VisibleForTesting final FingerprintSensorPropertiesInternal mSensorProps;
@NonNull private final ActivityLaunchAnimator mActivityLaunchAnimator;
// Tracks the velocity of a touch to help filter out the touches that move too fast.
@Nullable private VelocityTracker mVelocityTracker;
@@ -198,7 +200,8 @@ public class UdfpsController implements DozeReceiver {
mLockscreenShadeTransitionController, mConfigurationController,
mSystemClock, mKeyguardStateController,
mUnlockedScreenOffAnimationController, mSensorProps, mHbmProvider,
reason, callback, UdfpsController.this::onTouch)));
reason, callback, UdfpsController.this::onTouch,
mActivityLaunchAnimator)));
}
@Override
@@ -487,7 +490,8 @@ public class UdfpsController implements DozeReceiver {
@NonNull SystemClock systemClock,
@NonNull UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
@NonNull SystemUIDialogManager dialogManager,
@NonNull LatencyTracker latencyTracker) {
@NonNull LatencyTracker latencyTracker,
@NonNull ActivityLaunchAnimator activityLaunchAnimator) {
mContext = context;
mExecution = execution;
mVibrator = vibrator;
@@ -516,6 +520,7 @@ public class UdfpsController implements DozeReceiver {
mSystemClock = systemClock;
mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
mLatencyTracker = latencyTracker;
mActivityLaunchAnimator = activityLaunchAnimator;
mSensorProps = findFirstUdfps();
// At least one UDFPS sensor exists

View File

@@ -41,6 +41,7 @@ import android.view.accessibility.AccessibilityManager.TouchExplorationStateChan
import androidx.annotation.LayoutRes
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.R
import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.LockscreenShadeTransitionController
@@ -81,7 +82,8 @@ class UdfpsControllerOverlay(
private var hbmProvider: UdfpsHbmProvider,
@ShowReason val requestReason: Int,
private val controllerCallback: IUdfpsOverlayControllerCallback,
private val onTouch: (View, MotionEvent, Boolean) -> Boolean
private val onTouch: (View, MotionEvent, Boolean) -> Boolean,
private val activityLaunchAnimator: ActivityLaunchAnimator
) {
/** The view, when [isShowing], or null. */
var overlayView: UdfpsView? = null
@@ -200,7 +202,8 @@ class UdfpsControllerOverlay(
keyguardStateController,
unlockedScreenOffAnimationController,
dialogManager,
controller
controller,
activityLaunchAnimator
)
}
BiometricOverlayConstants.REASON_AUTH_BP -> {

View File

@@ -25,6 +25,7 @@ import android.view.MotionEvent;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.R;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
@@ -55,6 +56,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
@NonNull private final UdfpsController mUdfpsController;
@NonNull private final UnlockedScreenOffAnimationController
mUnlockedScreenOffAnimationController;
@NonNull private final ActivityLaunchAnimator mActivityLaunchAnimator;
private boolean mShowingUdfpsBouncer;
private boolean mUdfpsRequested;
@@ -66,6 +68,8 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
private long mLastUdfpsBouncerShowTime = -1;
private float mStatusBarExpansion;
private boolean mLaunchTransitionFadingAway;
private boolean mIsLaunchingActivity;
private float mActivityLaunchProgress;
/**
* hidden amount of pin/pattern/password bouncer
@@ -88,7 +92,8 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
@NonNull KeyguardStateController keyguardStateController,
@NonNull UnlockedScreenOffAnimationController unlockedScreenOffAnimationController,
@NonNull SystemUIDialogManager systemUIDialogManager,
@NonNull UdfpsController udfpsController) {
@NonNull UdfpsController udfpsController,
@NonNull ActivityLaunchAnimator activityLaunchAnimator) {
super(view, statusBarStateController, panelExpansionStateManager, systemUIDialogManager,
dumpManager);
mKeyguardViewManager = statusBarKeyguardViewManager;
@@ -99,6 +104,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
mKeyguardStateController = keyguardStateController;
mUdfpsController = udfpsController;
mUnlockedScreenOffAnimationController = unlockedScreenOffAnimationController;
mActivityLaunchAnimator = activityLaunchAnimator;
}
@Override
@@ -136,6 +142,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
mKeyguardViewManager.setAlternateAuthInterceptor(mAlternateAuthInterceptor);
mLockScreenShadeTransitionController.setUdfpsKeyguardViewController(this);
mUnlockedScreenOffAnimationController.addCallback(mUnlockedScreenOffCallback);
mActivityLaunchAnimator.addListener(mActivityLaunchAnimatorListener);
}
@Override
@@ -153,6 +160,7 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
mLockScreenShadeTransitionController.setUdfpsKeyguardViewController(null);
}
mUnlockedScreenOffAnimationController.removeCallback(mUnlockedScreenOffCallback);
mActivityLaunchAnimator.removeListener(mActivityLaunchAnimatorListener);
}
@Override
@@ -294,6 +302,12 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
0f, 255f);
if (!mShowingUdfpsBouncer) {
alpha *= (1.0f - mTransitionToFullShadeProgress);
// Fade out the icon if we are animating an activity launch over the lockscreen and the
// activity didn't request the UDFPS.
if (mIsLaunchingActivity && !mUdfpsRequested) {
alpha *= (1.0f - mActivityLaunchProgress);
}
}
mView.setUnpausedAlpha(alpha);
}
@@ -426,4 +440,26 @@ public class UdfpsKeyguardViewController extends UdfpsAnimationViewController<Ud
private final UnlockedScreenOffAnimationController.Callback mUnlockedScreenOffCallback =
(linear, eased) -> mStateListener.onDozeAmountChanged(linear, eased);
private final ActivityLaunchAnimator.Listener mActivityLaunchAnimatorListener =
new ActivityLaunchAnimator.Listener() {
@Override
public void onLaunchAnimationStart() {
mIsLaunchingActivity = true;
mActivityLaunchProgress = 0f;
updateAlpha();
}
@Override
public void onLaunchAnimationEnd() {
mIsLaunchingActivity = false;
updateAlpha();
}
@Override
public void onLaunchAnimationProgress(float linearProgress) {
mActivityLaunchProgress = linearProgress;
updateAlpha();
}
};
}

View File

@@ -1412,7 +1412,8 @@ public class StatusBar extends CoreStartable implements
private void setUpPresenter() {
// Set up the initial notification state.
mActivityLaunchAnimator.setCallback(mKeyguardHandler);
mActivityLaunchAnimator.setCallback(mActivityLaunchAnimatorCallback);
mActivityLaunchAnimator.addListener(mActivityLaunchAnimatorListener);
mNotificationAnimationProvider = new NotificationLaunchAnimatorControllerProvider(
mNotificationShadeWindowViewController,
mStackScrollerController.getNotificationListContainer(),
@@ -4393,7 +4394,7 @@ public class StatusBar extends CoreStartable implements
}
};
private final ActivityLaunchAnimator.Callback mKeyguardHandler =
private final ActivityLaunchAnimator.Callback mActivityLaunchAnimatorCallback =
new ActivityLaunchAnimator.Callback() {
@Override
public boolean isOnKeyguard() {
@@ -4411,11 +4412,6 @@ public class StatusBar extends CoreStartable implements
mMainExecutor.execute(() -> mKeyguardViewMediator.hideWithAnimation(runner));
}
@Override
public void setBlursDisabledForAppLaunch(boolean disabled) {
mKeyguardViewMediator.setBlursDisabledForAppLaunch(disabled);
}
@Override
public int getBackgroundColor(TaskInfo task) {
if (!mStartingSurfaceOptional.isPresent()) {
@@ -4427,6 +4423,19 @@ public class StatusBar extends CoreStartable implements
}
};
private final ActivityLaunchAnimator.Listener mActivityLaunchAnimatorListener =
new ActivityLaunchAnimator.Listener() {
@Override
public void onLaunchAnimationStart() {
mKeyguardViewMediator.setBlursDisabledForAppLaunch(true);
}
@Override
public void onLaunchAnimationEnd() {
mKeyguardViewMediator.setBlursDisabledForAppLaunch(false);
}
};
private final DemoMode mDemoModeCallback = new DemoMode() {
@Override
public void onDemoModeFinished() {

View File

@@ -21,13 +21,12 @@ import android.widget.LinearLayout
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertNotNull
import junit.framework.Assert.assertNull
import junit.framework.Assert.assertTrue
import junit.framework.AssertionFailedError
import kotlin.concurrent.thread
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@@ -40,6 +39,7 @@ import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.Spy
import org.mockito.junit.MockitoJUnit
import kotlin.concurrent.thread
@SmallTest
@RunWith(AndroidTestingRunner::class)
@@ -48,6 +48,7 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() {
private val launchContainer = LinearLayout(mContext)
private val launchAnimator = LaunchAnimator(TEST_TIMINGS, TEST_INTERPOLATORS)
@Mock lateinit var callback: ActivityLaunchAnimator.Callback
@Mock lateinit var listener: ActivityLaunchAnimator.Listener
@Spy private val controller = TestLaunchAnimatorController(launchContainer)
@Mock lateinit var iCallback: IRemoteAnimationFinishedCallback
@Mock lateinit var failHandler: Log.TerribleFailureHandler
@@ -59,6 +60,12 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() {
fun setup() {
activityLaunchAnimator = ActivityLaunchAnimator(launchAnimator)
activityLaunchAnimator.callback = callback
activityLaunchAnimator.addListener(listener)
}
@After
fun tearDown() {
activityLaunchAnimator.removeListener(listener)
}
private fun startIntentWithAnimation(
@@ -177,7 +184,7 @@ class ActivityLaunchAnimatorTest : SysuiTestCase() {
val runner = activityLaunchAnimator.createRunner(controller)
runner.onAnimationStart(0, arrayOf(fakeWindow()), emptyArray(), emptyArray(), iCallback)
waitForIdleSync()
verify(callback).setBlursDisabledForAppLaunch(eq(true))
verify(listener).onLaunchAnimationStart()
verify(controller).onLaunchAnimationStart(anyBoolean())
}

View File

@@ -37,6 +37,7 @@ import androidx.test.filters.SmallTest
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.LockscreenShadeTransitionController
@@ -89,6 +90,7 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
@Mock private lateinit var udfpsController: UdfpsController
@Mock private lateinit var udfpsView: UdfpsView
@Mock private lateinit var udfpsEnrollView: UdfpsEnrollView
@Mock private lateinit var activityLaunchAnimator: ActivityLaunchAnimator
private val sensorProps = SensorLocationInternal("", 10, 100, 20)
.asFingerprintSensorProperties()
@@ -118,7 +120,7 @@ class UdfpsControllerOverlayTest : SysuiTestCase() {
keyguardUpdateMonitor, dialogManager, dumpManager, transitionController,
configurationController, systemClock, keyguardStateController,
unlockedScreenOffAnimationController, sensorProps, hbmProvider, reason,
controllerCallback, onTouch)
controllerCallback, onTouch, activityLaunchAnimator)
block()
}

View File

@@ -58,6 +58,7 @@ import com.android.internal.util.LatencyTracker;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.plugins.FalsingManager;
@@ -180,6 +181,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
private TypedArray mBrightnessBacklight;
@Mock
private SystemUIDialogManager mSystemUIDialogManager;
@Mock
private ActivityLaunchAnimator mActivityLaunchAnimator;
// Capture listeners so that they can be used to send events
@Captor private ArgumentCaptor<IUdfpsOverlayController> mOverlayCaptor;
@@ -252,7 +255,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
mSystemClock,
mUnlockedScreenOffAnimationController,
mSystemUIDialogManager,
mLatencyTracker);
mLatencyTracker,
mActivityLaunchAnimator);
verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
mOverlayController = mOverlayCaptor.getValue();
verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());

View File

@@ -36,6 +36,7 @@ import androidx.test.filters.SmallTest;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -96,6 +97,8 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
private SystemUIDialogManager mDialogManager;
@Mock
private UdfpsController mUdfpsController;
@Mock
private ActivityLaunchAnimator mActivityLaunchAnimator;
private FakeSystemClock mSystemClock = new FakeSystemClock();
private UdfpsKeyguardViewController mController;
@@ -134,7 +137,8 @@ public class UdfpsKeyguardViewControllerTest extends SysuiTestCase {
mKeyguardStateController,
mUnlockedScreenOffAnimationController,
mDialogManager,
mUdfpsController);
mUdfpsController,
mActivityLaunchAnimator);
}
@Test