2 上滑触摸事件
2.1 Touch down事件
2.2 Touch move事件
2.3 Touch up事件
用户抬起手指,产生touch up事件,PanelView接收到这个事件后会调用endMotionEvent,如果手指从down到up之间移动的距离达到一定阈值会调用onTrackingStopped,从而调出解锁界面;
private void endMotionEvent(MotionEvent event, float x, float y, boolean forceCancel) {
final boolean onKeyguard =
mStatusBarStateController.getState() == StatusBarState.KEYGUARD;
final boolean expand;
if (event.getActionMasked() == MotionEvent.ACTION_CANCEL || forceCancel) {
if (onKeyguard) {
expand = true;
} else {
expand = !mPanelClosedOnDown;
}
} else {
expand = flingExpands(vel, vectorVel, x, y);
}
...
fling(vel, expand, isFalseTouch(x, y, interactionType));
onTrackingStopped(expand);
mUpdateFlingOnLayout = expand && mPanelClosedOnDown && !mHasLayoutedSinceDown;
if (mUpdateFlingOnLayout) {
mUpdateFlingVelocity = vel;
}
...
}
这里复位mTracking,并将onTrackingStopped回调给
protected void onTrackingStopped(boolean expand) {
mTracking = false;
mBar.onTrackingStopped(expand);
notifyBarPanelExpansionChanged();
}
public void onTrackingStopped(boolean expand) {
mTracking = false;
}
3 上滑解锁流程
3.1 fling动画更新panelView高度
上滑解锁锁屏,PanelView的expansion fraction从 1f 变成0f,锁屏时钟,通知等从上部慢慢消失。
在endMotionEvent事件里面,调用了PanelViewController的fling动画
protected void fling(float vel, boolean expand, float collapseSpeedUpFactor,
boolean expandBecauseOfFalsing) {
cancelPeek();
float target = expand ? getMaxPanelHeight() : 0;
if (!expand) {
mClosing = true;
}
flingToHeight(vel, expand, target, collapseSpeedUpFactor, expandBecauseOfFalsing);
}
然后调用flingToHeight,走到createHeightAnimator里面
http://aospxref.com/android-13.0.0_r3/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java#setExpandedHeightInternal
private ValueAnimator createHeightAnimator(float targetHeight, float overshootAmount) {
float startExpansion = mOverExpansion;
ValueAnimator animator = ValueAnimator.ofFloat(mExpandedHeight, targetHeight);
animator.addUpdateListener(
animation -> {
if (overshootAmount > 0.0f
|| (targetHeight == 0.0f && startExpansion != 0)) {
final float expansion = MathUtils.lerp(
startExpansion,
mPanelFlingOvershootAmount * overshootAmount,
Interpolators.FAST_OUT_SLOW_IN.getInterpolation(
animator.getAnimatedFraction()));
setOverExpansionInternal(expansion, false );
}
setExpandedHeightInternal((float) animation.getAnimatedValue());
});
return animator;
}
在fling动画走onUpdateAnimator里面调用到setExpandedHeightInternal,
public void setExpandedHeightInternal(float h) {
if (isNaN(h)) {
Log.wtf(TAG, "ExpandedHeight set to NaN");
}
mNotificationShadeWindowController.batchApplyWindowLayoutParams(()-> {
if (mExpandLatencyTracking && h != 0f) {
DejankUtils.postAfterTraversal(
() -> mLatencyTracker.onActionEnd(LatencyTracker.ACTION_EXPAND_PANEL));
mExpandLatencyTracking = false;
}
float maxPanelHeight = getMaxPanelHeight();
if (mHeightAnimator == null) {
if (mTracking && !mInSplitShade) {
float overExpansionPixels = Math.max(0, h - maxPanelHeight);
setOverExpansionInternal(overExpansionPixels, true );
}
mExpandedHeight = Math.min(h, maxPanelHeight);
} else {
mExpandedHeight = h;
}
if (mExpandedHeight < 1f && mExpandedHeight != 0f && mClosing) {
mExpandedHeight = 0f;
if (mHeightAnimator != null) {
mHeightAnimator.end();
}
}
mExpansionDragDownAmountPx = h;
mExpandedFraction = Math.min(1f,
maxPanelHeight == 0 ? 0 : mExpandedHeight / maxPanelHeight);
onHeightUpdated(mExpandedHeight);
updatePanelExpansionAndVisibility();
});
}
最后调用updatePanelExpansionAndVisibility()
public void updatePanelExpansionAndVisibility() {
mPanelExpansionStateManager.onPanelExpansionChanged(
mExpandedFraction, isExpanded(), mTracking, mExpansionDragDownAmountPx);
updateVisibility();
}
updatePanelExpansionAndVisibility里面首先回调onPanelExpansionChanged,然后更新PanelView的可见性。
public void updateVisibility() {
mView.setVisibility(shouldPanelBeVisible() ? VISIBLE : INVISIBLE);
}
3.2 判断是否要走KeyguardDismiss流程
CentralSurfacesImpl收到onPanelExpansionChanged
http://aospxref.com/android-13.0.0_r3/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java#1412
private void onPanelExpansionChanged(PanelExpansionChangeEvent event) {
1413 float fraction = event.getFraction();
1414 boolean tracking = event.getTracking();
1415 dispatchPanelExpansionForKeyguardDismiss(fraction, tracking);
1416
1417 if (fraction == 0 || fraction == 1) {
1418 if (getNavigationBarView() != null) {
1419 getNavigationBarView().onStatusBarPanelStateChanged();
1420 }
1421 if (getNotificationPanelViewController() != null) {
1422 getNotificationPanelViewController().updateSystemUiStateFlags();
1423 }
1424 }
1425 }
之后调用dispatchPanelExpansionForKeyguardDismiss走KeyguardDismiss流程
private void dispatchPanelExpansionForKeyguardDismiss(float fraction, boolean trackingTouch) {
if (!isKeyguardShowing()
|| isOccluded()
|| !mKeyguardStateController.canDismissLockScreen()
|| mKeyguardViewMediator.isAnySimPinSecure()
|| (mNotificationPanelViewController.isQsExpanded() && trackingTouch)) {
return;
}
if (trackingTouch
|| mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehindOrWillBe()
|| mKeyguardUnlockAnimationController.isUnlockingWithSmartSpaceTransition()) {
mKeyguardStateController.notifyKeyguardDismissAmountChanged(
1f - fraction, trackingTouch);
}
}
这里走mKeyguardStateController.notifyKeyguardDismissAmountChanged(1f - fraction, trackingTouch)里面,然后走到KeyguardStateControllerImpl的notifyKeyguardDismissAmountChanged。
http://aospxref.com/android-13.0.0_r3/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java#366
public void notifyKeyguardDismissAmountChanged(float dismissAmount,
boolean dismissingFromTouch) {
mDismissAmount = dismissAmount;
mDismissingFromTouch = dismissingFromTouch;
new ArrayList<>(mCallbacks).forEach(Callback::onKeyguardDismissAmountChanged);
}
之后回调onKeyguardDismissAmountChanged。这里回调到KeyguardUnlockAnimationController的
http://aospxref.com/android-13.0.0_r3/xref/frameworks/base/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt#591
override fun onKeyguardDismissAmountChanged() {
if (!willHandleUnlockAnimation()) {
return
}
if (keyguardViewController.isShowing && !playingCannedUnlockAnimation) {
showOrHideSurfaceIfDismissAmountThresholdsReached()
if ((keyguardViewMediator.get().requestedShowSurfaceBehindKeyguard() ||
keyguardViewMediator.get()
.isAnimatingBetweenKeyguardAndSurfaceBehindOrWillBe) &&
!playingCannedUnlockAnimation) {
updateSurfaceBehindAppearAmount()
}
}
}
然后走到showOrHideSurfaceIfDismissAmountThresholdsReached,
private fun showOrHideSurfaceIfDismissAmountThresholdsReached() {
if (!featureFlags.isEnabled(Flags.NEW_UNLOCK_SWIPE_ANIMATION)) {
return
}
if (playingCannedUnlockAnimation) {
return
}
if (!keyguardStateController.isShowing) {
return
}
val dismissAmount = keyguardStateController.dismissAmount
if (dismissAmount >= DISMISS_AMOUNT_SHOW_SURFACE_THRESHOLD &&
!keyguardViewMediator.get().requestedShowSurfaceBehindKeyguard()) {
keyguardViewMediator.get().showSurfaceBehindKeyguard()
} else if (dismissAmount < DISMISS_AMOUNT_SHOW_SURFACE_THRESHOLD &&
keyguardViewMediator.get().requestedShowSurfaceBehindKeyguard()) {
keyguardViewMediator.get().hideSurfaceBehindKeyguard()
fadeOutSurfaceBehind()
}
finishKeyguardExitRemoteAnimationIfReachThreshold()
}
走到最后keyguardViewMediator.get().onKeyguardExitRemoteAnimationFinished(false /* cancelled */)
public void onKeyguardExitRemoteAnimationFinished(boolean cancelled) {
if (!mSurfaceBehindRemoteAnimationRunning && !mSurfaceBehindRemoteAnimationRequested) {
return;
}
mKeyguardViewControllerLazy.get().blockPanelExpansionFromCurrentTouch();
final boolean wasShowing = mShowing;
InteractionJankMonitor.getInstance().end(CUJ_LOCKSCREEN_UNLOCK_ANIMATION);
DejankUtils.postAfterTraversal(() -> {
onKeyguardExitFinished();
if (mKeyguardStateController.isDismissingFromSwipe() || wasShowing) {
mKeyguardUnlockAnimationControllerLazy.get().hideKeyguardViewAfterRemoteAnimation();
}
finishSurfaceBehindRemoteAnimation(cancelled);
mSurfaceBehindRemoteAnimationRequested = false;
mKeyguardStateController.notifyKeyguardGoingAway(false);
mUpdateMonitor.dispatchKeyguardDismissAnimationFinished();
});
mKeyguardUnlockAnimationControllerLazy.get().notifyFinishedKeyguardExitAnimation(
cancelled);
}
private void onKeyguardExitFinished() {
if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) {
playSounds(false);
}
setShowingLocked(false);
mWakeAndUnlocking = false;
mDismissCallbackRegistry.notifyDismissSucceeded();
resetKeyguardDonePendingLocked();
mHideAnimationRun = false;
adjustStatusBarLocked();
sendUserPresentBroadcast();
}
在onKeyguardExitFinished中会播放解锁声音,然后reset一些变量。
private void onKeyguardExitFinished() {
if (TelephonyManager.EXTRA_STATE_IDLE.equals(mPhoneState)) {
playSounds(false);
}
setShowingLocked(false);
mWakeAndUnlocking = false;
mDismissCallbackRegistry.notifyDismissSucceeded();
resetKeyguardDonePendingLocked();
mHideAnimationRun = false;
adjustStatusBarLocked();
sendUserPresentBroadcast();
}
然后调用KeyguardUnlockAnimationController对的hideKeyguardViewAfterRemoteAnimation走keyguard的hide流程。
fun hideKeyguardViewAfterRemoteAnimation() {
if (keyguardViewController.isShowing) {
keyguardViewController.hide(
surfaceBehindRemoteAnimationStartTime,
0
)
} else {
Log.e(TAG, "#hideKeyguardViewAfterRemoteAnimation called when keyguard view is not " +
"showing. Ignoring...")
}
}
3.3 keyguard的hide流程
StatusBarKeyguardViewManager的hide里面,然后是mCentralSurfaces.hideKeyguard();
@Override
public boolean hideKeyguard() {
mStatusBarStateController.setKeyguardRequested(false);
return updateIsKeyguard();
}
@Override
public boolean updateIsKeyguard() {
return updateIsKeyguard(false );
}
@Override
public boolean updateIsKeyguard(boolean forceStateChange) {
if (shouldBeKeyguard) {
if (mScreenOffAnimationController.isKeyguardShowDelayed()
|| (isGoingToSleep()
&& mScreenLifecycle.getScreenState() == ScreenLifecycle.SCREEN_TURNING_OFF)) {
} else {
showKeyguardImpl();
}
} else {
if (!mScreenOffAnimationController.isKeyguardHideDelayed()) {
return hideKeyguardImpl(forceStateChange);
}
}
}
这里走的是hideKeyguardImpl。
@Override
public boolean hideKeyguardImpl(boolean forceStateChange) {
}
hideKeyguardImpl里面首先会调用mStatusBarStateController.setState(StatusBarState.SHADE, forceStateChange)设置StatusBarState为SHADE,然后调用instantCollapseNotificationPanel
@Override
public void instantCollapseNotificationPanel() {
mNotificationPanelViewController.instantCollapse();
mShadeController.runPostCollapseRunnables();
}
这次又回到了PanelViewController,调用了instantCollapse,
public void instantCollapse() {
abortAnimations();
setExpandedFraction(0f);
if (mExpanding) {
notifyExpandingFinished();
}
if (mInstantExpanding) {
mInstantExpanding = false;
updatePanelExpansionAndVisibility();
}
}
然后走到setExpandedFraction(0f);,此时设置ExpandedFraction为0f了。然后再次回到了setExpandedHeightInternal
然后是updatePanelExpansionAndVisibility更新PanelView的可见性
public void updatePanelExpansionAndVisibility() {
mPanelExpansionStateManager.onPanelExpansionChanged(
mExpandedFraction, isExpanded(), mTracking, mExpansionDragDownAmountPx);
updateVisibility();
}
3.4 通知keyguard可见性改变
在onPanelExpansionChanged中,会走到StatusBarKeyguardViewManager的onPanelExpansionChanged里。
然后走到KeyguardBouncer的mBouncer.setExpansion。
public void setExpansion(float fraction) {
float oldExpansion = mExpansion;
mExpansion = fraction;
if (mKeyguardView != null && !mIsAnimatingAway) {
float alpha = MathUtils.map(ALPHA_EXPANSION_THRESHOLD, 1, 1, 0, fraction);
mKeyguardView.setAlpha(MathUtils.constrain(alpha, 0f, 1f));
mKeyguardView.setTranslationY(fraction * mKeyguardView.getHeight());
}
if (fraction == EXPANSION_VISIBLE && oldExpansion != EXPANSION_VISIBLE) {
onFullyShown();
mExpansionCallback.onFullyShown();
} else if (fraction == EXPANSION_HIDDEN && oldExpansion != EXPANSION_HIDDEN) {
onFullyHidden();
mExpansionCallback.onFullyHidden();
} else if (fraction != EXPANSION_VISIBLE && oldExpansion == EXPANSION_VISIBLE) {
mExpansionCallback.onStartingToHide();
if (mKeyguardView != null) {
mKeyguardView.onStartingToHide();
}
}
}
然后来到StatusBarKeyguardViewManager的onFullyShown
@Override
public void onFullyShown() {
mBouncerAnimating = false;
updateStates();
mCentralSurfaces.wakeUpIfDozing(SystemClock.uptimeMillis(),
mCentralSurfaces.getBouncerContainer(), "BOUNCER_VISIBLE");
}
之后再updateStates里面就会调用onKeyguardVisibilityChanged通知Keyguard可见性为false。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)