[DO NOT MERGE] Fix intent launch from notification

When tapped some notifications, especially work profile ones, were not
launching correctly. The action after bouncer dismiss was being
cleared by an onVisibilityChanged callback before the authentication
path had a chance to complete and start the intent.

Also add more tracing

Fixes: 227354876
Test: manually, atest StatusBarKeyguardViewManagerTest
Change-Id: I6f3e28a44827a87cc08c7b3685bb9bf1c54ce8e3
This commit is contained in:
Matt Pietal
2022-04-11 10:43:05 -04:00
parent 331f163d20
commit ace85513ed
2 changed files with 92 additions and 72 deletions

View File

@@ -23,6 +23,7 @@ import android.content.Context;
import android.content.res.ColorStateList;
import android.hardware.biometrics.BiometricSourceType;
import android.os.Handler;
import android.os.Trace;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Log;
@@ -164,58 +165,66 @@ public class KeyguardBouncer {
// In split system user mode, we never unlock system user.
return;
}
ensureView();
mIsScrimmed = isScrimmed;
// On the keyguard, we want to show the bouncer when the user drags up, but it's
// not correct to end the falsing session. We still need to verify if those touches
// are valid.
// Later, at the end of the animation, when the bouncer is at the top of the screen,
// onFullyShown() will be called and FalsingManager will stop recording touches.
if (isScrimmed) {
setExpansion(EXPANSION_VISIBLE);
}
try {
Trace.beginSection("KeyguardBouncer#show");
if (resetSecuritySelection) {
// showPrimarySecurityScreen() updates the current security method. This is needed in
// case we are already showing and the current security method changed.
showPrimarySecurityScreen();
}
ensureView();
mIsScrimmed = isScrimmed;
if (mContainer.getVisibility() == View.VISIBLE || mShowingSoon) {
return;
}
// On the keyguard, we want to show the bouncer when the user drags up, but it's
// not correct to end the falsing session. We still need to verify if those touches
// are valid.
// Later, at the end of the animation, when the bouncer is at the top of the screen,
// onFullyShown() will be called and FalsingManager will stop recording touches.
if (isScrimmed) {
setExpansion(EXPANSION_VISIBLE);
}
final int activeUserId = KeyguardUpdateMonitor.getCurrentUser();
final boolean isSystemUser =
if (resetSecuritySelection) {
// showPrimarySecurityScreen() updates the current security method. This is needed
// in case we are already showing and the current security method changed.
showPrimarySecurityScreen();
}
if (mContainer.getVisibility() == View.VISIBLE || mShowingSoon) {
return;
}
final int activeUserId = KeyguardUpdateMonitor.getCurrentUser();
final boolean isSystemUser =
UserManager.isSplitSystemUser() && activeUserId == UserHandle.USER_SYSTEM;
final boolean allowDismissKeyguard = !isSystemUser && activeUserId == keyguardUserId;
final boolean allowDismissKeyguard = !isSystemUser && activeUserId == keyguardUserId;
// If allowed, try to dismiss the Keyguard. If no security auth (password/pin/pattern) is
// set, this will dismiss the whole Keyguard. Otherwise, show the bouncer.
if (allowDismissKeyguard && mKeyguardViewController.dismiss(activeUserId)) {
return;
}
// If allowed, try to dismiss the Keyguard. If no security auth (password/pin/pattern)
// is set, this will dismiss the whole Keyguard. Otherwise, show the bouncer.
if (allowDismissKeyguard && mKeyguardViewController.dismiss(activeUserId)) {
return;
}
// This condition may indicate an error on Android, so log it.
if (!allowDismissKeyguard) {
Log.w(TAG, "User can't dismiss keyguard: " + activeUserId + " != " + keyguardUserId);
}
// This condition may indicate an error on Android, so log it.
if (!allowDismissKeyguard) {
Log.w(TAG, "User can't dismiss keyguard: " + activeUserId + " != "
+ keyguardUserId);
}
mShowingSoon = true;
mShowingSoon = true;
// Split up the work over multiple frames.
DejankUtils.removeCallbacks(mResetRunnable);
if (mKeyguardStateController.isFaceAuthEnabled() && !needsFullscreenBouncer()
// Split up the work over multiple frames.
DejankUtils.removeCallbacks(mResetRunnable);
if (mKeyguardStateController.isFaceAuthEnabled() && !needsFullscreenBouncer()
&& !mKeyguardUpdateMonitor.userNeedsStrongAuth()
&& !mKeyguardBypassController.getBypassEnabled()) {
mHandler.postDelayed(mShowRunnable, BOUNCER_FACE_DELAY);
} else {
DejankUtils.postAfterTraversal(mShowRunnable);
}
mHandler.postDelayed(mShowRunnable, BOUNCER_FACE_DELAY);
} else {
DejankUtils.postAfterTraversal(mShowRunnable);
}
mCallback.onBouncerVisiblityChanged(true /* shown */);
dispatchStartingToShow();
mCallback.onBouncerVisiblityChanged(true /* shown */);
dispatchStartingToShow();
} finally {
Trace.endSection();
}
}
public boolean isScrimmed() {
@@ -317,6 +326,7 @@ public class KeyguardBouncer {
}
public void hide(boolean destroyView) {
Trace.beginSection("KeyguardBouncer#hide");
if (isShowing()) {
SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED,
SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__HIDDEN);
@@ -338,6 +348,7 @@ public class KeyguardBouncer {
// be slow because of AM lock contention during unlocking. We can delay it a bit.
mHandler.postDelayed(mRemoveViewRunnable, 50);
}
Trace.endSection();
}
/**

View File

@@ -164,7 +164,6 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
@Override
public void onVisibilityChanged(boolean isVisible) {
if (!isVisible) {
cancelPostAuthActions();
mCentralSurfaces.setBouncerHiddenFraction(KeyguardBouncer.EXPANSION_HIDDEN);
}
if (mAlternateAuthInterceptor != null) {
@@ -502,42 +501,52 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
public void dismissWithAction(OnDismissAction r, Runnable cancelAction,
boolean afterKeyguardGone, String message) {
if (mShowing) {
cancelPendingWakeupAction();
// If we're dozing, this needs to be delayed until after we wake up - unless we're
// wake-and-unlocking, because there dozing will last until the end of the transition.
if (mDozing && !isWakeAndUnlocking()) {
mPendingWakeupAction = new DismissWithActionRequest(
r, cancelAction, afterKeyguardGone, message);
return;
}
try {
Trace.beginSection("StatusBarKeyguardViewManager#dismissWithAction");
cancelPendingWakeupAction();
// If we're dozing, this needs to be delayed until after we wake up - unless we're
// wake-and-unlocking, because there dozing will last until the end of the
// transition.
if (mDozing && !isWakeAndUnlocking()) {
mPendingWakeupAction = new DismissWithActionRequest(
r, cancelAction, afterKeyguardGone, message);
return;
}
mAfterKeyguardGoneAction = r;
mKeyguardGoneCancelAction = cancelAction;
mDismissActionWillAnimateOnKeyguard = r != null && r.willRunAnimationOnKeyguard();
mAfterKeyguardGoneAction = r;
mKeyguardGoneCancelAction = cancelAction;
mDismissActionWillAnimateOnKeyguard = r != null && r.willRunAnimationOnKeyguard();
// If there is an an alternate auth interceptor (like the UDFPS), show that one instead
// of the bouncer.
if (shouldShowAltAuth()) {
if (!afterKeyguardGone) {
mBouncer.setDismissAction(mAfterKeyguardGoneAction, mKeyguardGoneCancelAction);
// If there is an an alternate auth interceptor (like the UDFPS), show that one
// instead of the bouncer.
if (shouldShowAltAuth()) {
if (!afterKeyguardGone) {
mBouncer.setDismissAction(mAfterKeyguardGoneAction,
mKeyguardGoneCancelAction);
mAfterKeyguardGoneAction = null;
mKeyguardGoneCancelAction = null;
}
updateAlternateAuthShowing(
mAlternateAuthInterceptor.showAlternateAuthBouncer());
return;
}
if (afterKeyguardGone) {
// we'll handle the dismiss action after keyguard is gone, so just show the
// bouncer
mBouncer.show(false /* resetSecuritySelection */);
} else {
// after authentication success, run dismiss action with the option to defer
// hiding the keyguard based on the return value of the OnDismissAction
mBouncer.showWithDismissAction(mAfterKeyguardGoneAction,
mKeyguardGoneCancelAction);
// bouncer will handle the dismiss action, so we no longer need to track it here
mAfterKeyguardGoneAction = null;
mKeyguardGoneCancelAction = null;
}
updateAlternateAuthShowing(mAlternateAuthInterceptor.showAlternateAuthBouncer());
return;
}
if (afterKeyguardGone) {
// we'll handle the dismiss action after keyguard is gone, so just show the bouncer
mBouncer.show(false /* resetSecuritySelection */);
} else {
// after authentication success, run dismiss action with the option to defer
// hiding the keyguard based on the return value of the OnDismissAction
mBouncer.showWithDismissAction(mAfterKeyguardGoneAction, mKeyguardGoneCancelAction);
// bouncer will handle the dismiss action, so we no longer need to track it here
mAfterKeyguardGoneAction = null;
mKeyguardGoneCancelAction = null;
} finally {
Trace.endSection();
}
}
updateStates();