Android指纹开发过程中遇到一些边界的问题记录.
[1] 指纹息屏解锁,唤醒屏幕,Power键按下,无黑屏(息屏)
log如下:
01-02 08:11:51.792 1155 1379 D WindowManager: PhoneWindowManager interceptPowerKeyDown event=KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_POWER, scanCode=116, metaState=0, flags=0x8, repeatCount=0, eventTime=40905389, downTime=40905389, deviceId=5, source=0x101, displayId=-1 }, interactive=true
01-02 08:11:51.940 1155 1379 D WindowManager: powerPress: eventTime=40905389 interactive=true count=1 beganFromNonInteractive=false mShortPressOnPowerBehavior=1
01-02 08:11:51.940 1155 1379 I PowerManagerService: Going to sleep due to power_button (uid 1000)... // Power键息屏
01-02 08:11:51.944 1643 10639 D KeyguardViewMediator: onStartedGoingToSleep(2)
01-02 08:11:53.072 1643 1643 V BiometricUnlockController: startWakeAndUnlock(1)
01-02 08:11:53.072 1643 1643 I BiometricUnlockController: bio wakelock: Authenticated, waking up...
01-02 08:11:53.073 1155 2120 I PowerManagerService: Waking up from Asleep (uid=10072, reason=WAKE_REASON_GESTURE, details=android.policy:BIOMETRIC)... // 指纹解锁发起唤醒屏幕
01-02 08:11:53.089 1155 1155 I WindowManager: Started waking up... (why=ON_BECAUSE_OF_USER)
01-02 08:11:53.500 1155 1155 I WindowManager: Finished waking up... (why=ON_BECAUSE_OF_USER)
01-02 08:11:53.531 1155 1379 D WindowManager: PhoneWindowManager interceptPowerKeyDown event=KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_POWER, scanCode=116, metaState=0, flags=0x8, repeatCount=0, eventTime=40907128, downTime=40907128, deviceId=5, source=0x101, displayId=-1 }, interactive=true
01-02 08:11:53.706 1155 1379 D WindowManager: powerPress: eventTime=40907128 interactive=true count=1 beganFromNonInteractive=false mShortPressOnPowerBehavior=1
01-02 08:11:53.706 1155 1379 I WindowManager: Sleep from power button suppressed. Time since gesture: 634ms // // Power键被消化,无事件响应
01-02 08:11:58.244 1155 1379 D WindowManager: PhoneWindowManager interceptPowerKeyDown event=KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_POWER, scanCode=116, metaState=0, flags=0x8, repeatCount=0, eventTime=40911840, downTime=40911840, deviceId=5, source=0x101, displayId=-1 }, interactive=true
01-02 08:11:58.449 1155 1379 D WindowManager: powerPress: eventTime=40911840 interactive=true count=1 beganFromNonInteractive=false mShortPressOnPowerBehavior=1
01-02 08:11:58.449 1155 1379 I PowerManagerService: Going to sleep due to power_button (uid 1000)... // Power键息屏
01-02 08:11:58.458 1643 18577 D KeyguardViewMediator: onStartedGoingToSleep(2)
01-02 08:11:59.768 1643 1643 V BiometricUnlockController: startWakeAndUnlock(1)
01-02 08:11:59.769 1643 1643 I BiometricUnlockController: bio wakelock: Authenticated, waking up...
01-02 08:11:59.770 1155 4570 I PowerManagerService: Waking up from Asleep (uid=10072, reason=WAKE_REASON_GESTURE, details=android.policy:BIOMETRIC)... //指纹解锁发起唤醒屏幕
01-02 08:11:59.789 1155 1155 I WindowManager: Started waking up... (why=ON_BECAUSE_OF_USER)
01-02 08:12:00.140 1155 1379 D WindowManager: PhoneWindowManager interceptPowerKeyDown event=KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_POWER, scanCode=116, metaState=0, flags=0x8, repeatCount=0, eventTime=40913718, downTime=40913718, deviceId=5, source=0x101, displayId=-1 }, interactive=true
01-02 08:12:00.151 1155 1155 I WindowManager: Finished waking up... (why=ON_BECAUSE_OF_USER)
01-02 08:12:00.313 1155 1379 D WindowManager: powerPress: eventTime=40913718 interactive=true count=1 beganFromNonInteractive=false mShortPressOnPowerBehavior=1
01-02 08:12:00.313 1155 1379 I WindowManager: Sleep from power button suppressed. Time since gesture: 545ms // // Power键被消化,无事件响应
01-02 08:12:05.715 1155 1379 D WindowManager: PhoneWindowManager interceptPowerKeyDown event=KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_POWER, scanCode=116, metaState=0, flags=0x8, repeatCount=0, eventTime=40919310, downTime=40919310, deviceId=5, source=0x101, displayId=-1 }, interactive=true
01-02 08:12:05.856 1155 1379 D WindowManager: powerPress: eventTime=40919310 interactive=true count=1 beganFromNonInteractive=false mShortPressOnPowerBehavior=1
01-02 08:12:05.856 1155 1379 I PowerManagerService: Going to sleep due to power_button (uid 1000)... // Power键息屏
01-02 08:12:05.873 1643 10639 D KeyguardViewMediator: onStartedGoingToSleep(2)
01-02 08:12:06.905 1643 1643 V BiometricUnlockController: startWakeAndUnlock(1)
01-02 08:12:06.905 1643 1643 I BiometricUnlockController: bio wakelock: Authenticated, waking up...
01-02 08:12:06.905 1155 1929 I PowerManagerService: Waking up from Asleep (uid=10072, reason=WAKE_REASON_GESTURE, details=android.policy:BIOMETRIC)... //指纹解锁发起唤醒屏幕
01-02 08:12:06.920 1155 1155 I WindowManager: Started waking up... (why=ON_BECAUSE_OF_USER)
01-02 08:12:06.982 1155 1379 D WindowManager: PhoneWindowManager interceptPowerKeyDown event=KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_POWER, scanCode=116, metaState=0, flags=0x8, repeatCount=0, eventTime=40920561, downTime=40920561, deviceId=5, source=0x101, displayId=-1 }, interactive=true
01-02 08:12:07.244 1155 1155 I WindowManager: Finished waking up... (why=ON_BECAUSE_OF_USER)
01-02 08:12:07.993 1155 1379 D WindowManager: PhoneWindowManager interceptPowerKeyDown event=KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_POWER, scanCode=116, metaState=0, flags=0x8, repeatCount=0, eventTime=40921590, downTime=40921590, deviceId=5, source=0x101, displayId=-1 }, interactive=true
01-02 08:12:08.154 1155 1379 D WindowManager: powerPress: eventTime=40921590 interactive=true count=1 beganFromNonInteractive=false mShortPressOnPowerBehavior=1
01-02 08:12:08.154 1155 1379 I PowerManagerService: Going to sleep due to power_button (uid 1000)... // Power键息屏
01-02 08:12:08.162 1643 10639 D KeyguardViewMediator: onStartedGoingToSleep(2)
01-02 08:12:09.579 1155 1379 D WindowManager: PhoneWindowManager interceptPowerKeyDown event=KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_POWER, scanCode=116, metaState=0, flags=0x8, repeatCount=0, eventTime=40923175, downTime=40923175, deviceId=5, source=0x101, displayId=-1 }, interactive=false
01-02 08:12:09.585 1155 1379 I PowerManagerService: Waking up from Asleep (uid=1000, reason=WAKE_REASON_POWER_BUTTON, details=android.policy:POWER)... // Power键唤醒点亮屏幕,然后指纹亮屏解锁
01-02 08:12:09.617 1155 1155 I WindowManager: Started waking up... (why=ON_BECAUSE_OF_USER)
01-02 08:12:09.856 1155 1155 I WindowManager: Finished waking up... (why=ON_BECAUSE_OF_USER)
01-02 08:12:10.647 1643 1643 V BiometricUnlockController: startWakeAndUnlock(5)
01-02 08:12:11.193 1155 1379 D WindowManager: PhoneWindowManager interceptPowerKeyDown event=KeyEvent { action=ACTION_DOWN, keyCode=KEYCODE_POWER, scanCode=116, metaState=0, flags=0x8, repeatCount=0, eventTime=40924785, downTime=40924785, deviceId=5, source=0x101, displayId=-1 }, interactive=true
01-02 08:12:11.399 1155 1379 D WindowManager: powerPress: eventTime=40924785 interactive=true count=1 beganFromNonInteractive=false mShortPressOnPowerBehavior=1
01-02 08:12:11.399 1155 1379 I PowerManagerService: Going to sleep due to power_button (uid 1000)... // // Power键息屏
01-02 08:12:11.413 1643 1874 D KeyguardViewMediator: onStartedGoingToSleep(2)
01-02 08:12:14.384 1643 1643 V BiometricUnlockController: startWakeAndUnlock(1)
/frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
private static final int POWER_BUTTON_SUPPRESSION_DELAY_DEFAULT_MILLIS = 800;
/**
* Sends the device to sleep as a result of a power button press.
*
* @return True if the was device was sent to sleep, false if sleep was suppressed.
*/
private boolean goToSleepFromPowerButton(long eventTime, int flags) {
// Before we actually go to sleep, we check the last wakeup reason.
// If the device very recently woke up from a gesture (like user lifting their device)
// then ignore the sleep instruction. This is because users have developed
// a tendency to hit the power button immediately when they pick up their device, and we
// don't want to put the device back to sleep in those cases.
final PowerManager.WakeData lastWakeUp = mPowerManagerInternal.getLastWakeup();
if (lastWakeUp != null && lastWakeUp.wakeReason == PowerManager.WAKE_REASON_GESTURE) {
final int gestureDelayMillis = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE,
POWER_BUTTON_SUPPRESSION_DELAY_DEFAULT_MILLIS);
final long now = SystemClock.uptimeMillis();
if (mPowerButtonSuppressionDelayMillis > 0
&& (now < lastWakeUp.wakeTime + mPowerButtonSuppressionDelayMillis)) {
Slog.i(TAG, "Sleep from power button suppressed. Time since gesture: "
+ (now - lastWakeUp.wakeTime) + "ms");
return false;
}
}
goToSleep(eventTime, PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, flags);
return true;
}
由以上代码可知,这个间隔时间是可以指定设置的,默认为800ms,优先从Settings.Gloabal.POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE取。
/**
* The amount of time to suppress "power-off" from the power button after the device has
* woken due to a gesture (lifting the phone). Since users have learned to hit the power
* button immediately when lifting their device, it can cause the device to turn off if a
* gesture has just woken the device. This value tells us the milliseconds to wait after
* a gesture before "power-off" via power-button is functional again. A value of 0 is no
* delay, and reverts to the old behavior.
*
* @hide
*/
public static final String POWER_BUTTON_SUPPRESSION_DELAY_AFTER_GESTURE_WAKE =
"power_button_suppression_delay_after_gesture_wake";
[2] Power键按下后(息屏,需要等待1.2s左右指纹才开始激活指纹解锁监听)
现象上来说,Power按下去,需要约1.2s后触摸指纹才有反应(才能做出响应),在这时间之内触摸指纹模组,无任何反馈,比如震动。
有些朋友特别喜欢,或者偶尔习惯性Power误息屏后希望立马触摸指纹亮屏解锁,恢复之前状态。
Android Q如下修改引起, {Android R已经对此做出改善}.
Android P -> Q 变化是, mUpdateMonitor.setKeyguardGoingAway(false /* goingAway */);从handleStartKeyguardExitAnimation()挪到了handleShow(Bundle options)。
即:从亮屏解锁到Launcher时 推迟 到了 Power(或亮屏超时)息屏时,修改这个状态。
指纹可申请的条件也发生了如下变化:
Android P:
//Android P:
private boolean shouldListenForFingerprint() {
return (mKeyguardIsVisible || !mDeviceInteractive ||
(mBouncer && !mKeyguardGoingAway) || mGoingToSleep ||
shouldListenForFingerprintAssistant() || (mKeyguardOccluded && mIsDreaming))
&& !mSwitchingUser && !isFingerprintDisabled(getCurrentUser())
&& !mKeyguardGoingAway;
}
Android Q & R :
// Android Q&R
private boolean shouldListenForFingerprint() {
// Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
// instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
final boolean shouldListen = (mKeyguardIsVisible || !mDeviceInteractive ||
(mBouncer && !mKeyguardGoingAway) || mGoingToSleep ||
shouldListenForFingerprintAssistant() || (mKeyguardOccluded && mIsDreaming))
&& !mSwitchingUser && !isFingerprintDisabled(getCurrentUser())
&& (!mKeyguardGoingAway || !mDeviceInteractive) && mIsPrimaryUser;
return shouldListen;
}
但是android R重新考量了Q上的修改,把mUpdateMonitor.setKeyguardGoingAway(false /* goingAway */);这个动作稍稍再提前了一点点。
即:挪到Power键息屏onStartedGogingToSleep回调里边。
// Andoid R
/**
* Called to let us know the screen was turned off.
* @param why either {@link WindowManagerPolicyConstants#OFF_BECAUSE_OF_USER} or
* {@link WindowManagerPolicyConstants#OFF_BECAUSE_OF_TIMEOUT}.
*/
public void onStartedGoingToSleep(int why) {
if (DEBUG) Log.d(TAG, "onStartedGoingToSleep(" + why + ")");
synchronized (this) {
mDeviceInteractive = false;
mGoingToSleep = true;
// Reset keyguard going away state so we can start listening for fingerprint. We
// explicitly DO NOT want to call mStatusBarWindowController.setKeyguardGoingAway(false)
// here, since that will mess with the device lock state.
mUpdateMonitor.setKeyguardGoingAway(false); //挪位至此,还给出了特别注释
// Lock immediately based on setting if secure (user has a pin/pattern/password).
// This also "locks" the device when not secure to provide easy access to the
// camera while preventing unwanted input.
int currentUser = KeyguardUpdateMonitor.getCurrentUser();
final boolean lockImmediately =
mLockPatternUtils.getPowerButtonInstantlyLocks(currentUser)
|| !mLockPatternUtils.isSecure(currentUser);
long timeout = getLockTimeout(KeyguardUpdateMonitor.getCurrentUser());
mLockLater = false;
if (mExitSecureCallback != null) {
if (DEBUG) Log.d(TAG, "pending exit secure callback cancelled");
try {
mExitSecureCallback.onKeyguardExitResult(false);
} catch (RemoteException e) {
Slog.w(TAG, "Failed to call onKeyguardExitResult(false)", e);
}
mExitSecureCallback = null;
if (!mExternallyEnabled) {
hideLocked();
}
} else if (mShowing) {
mPendingReset = true;
} else if ((why == WindowManagerPolicyConstants.OFF_BECAUSE_OF_TIMEOUT && timeout > 0)
|| (why == WindowManagerPolicyConstants.OFF_BECAUSE_OF_USER && !lockImmediately)) {
doKeyguardLaterLocked(timeout);
mLockLater = true;
} else if (!mLockPatternUtils.isLockScreenDisabled(currentUser)) {
mPendingLock = true;
}
if (mPendingLock) {
playSounds(true);
}
}
mUpdateMonitor.dispatchStartedGoingToSleep(why);
notifyStartedGoingToSleep();
}
如此,Android R上,fingerprint可申请激活 在Power键按下后,从1066ms缩短到100ms内。
05-21 11:07:00.747 11231 11317 D WindowManager: powerPress: eventTime=80993579 interactive=true count=1 beganFromNonInteractive=false mShortPressOnPowerBehavior=1
05-21 11:07:00.749 11231 11317 I PowerManagerService: Going to sleep due to power_button (uid 1000)...
05-21 11:07:00.762 11231 11266 I PowerManagerService: Sleeping (uid 1000)...
05-21 11:07:00.785 10003 19610 D KeyguardViewMediator: onStartedGoingToSleep(2) //Android R时间点
05-21 11:07:00.802 10003 19610 D KeyguardViewMediator: notifyStartedGoingToSleep
05-21 11:07:00.845 757 847 I 757 847 [sunwave-hal] : (3224) 'getAuthenticatorId' enter.mAuthenticatorId = 0x76be8fe17f51a916.
05-21 11:07:00.851 10003 10003 D KeyguardUpdateMonitor: fingerprintRunningState: 1 //进入运行状态
05-21 11:07:00.851 11231 11231 I sysui_multi_action: [757,804,799,fingerprint_token,801,0,802,1]
05-21 11:07:00.851 10003 10003 D KeyguardViewMediator: handleNotifyStartedGoingToSleep
05-21 11:07:00.852 11231 11231 V FingerprintService: startAuthentication(com.android.systemui)
05-21 11:07:00.854 11231 11231 V FingerprintService: starting client AuthenticationClientImpl(com.android.systemui) targetUserId: 0 currentUserId: 0 cookie: 0/0
05-21 11:07:00.856 757 847 D android.hardware.biometrics.fingerprint@2.1-service: BiometricsFingerprint::authenticate(opid, gid)
05-21 11:07:00.856 757 847 I 757 847 [sunwave-hal] : (3605) 'authenticate' enter.operation_id(sid) = 0x0000000000000000.gid 0
05-21 11:07:00.895 757 887 I 757 887 [sunwave-ca-device] : (735) got device interrupt, signal the semaphore.
05-21 11:07:00.896 757 909 I 757 909 [sunwave-hal] : (2205) got the device interrupt. 0
05-21 11:07:00.992 757 847 I 757 847 [sunwave-client] : (90) ---8<---- TA LOG BEGINS ---------
05-21 11:07:00.992 757 847 I 757 847 [sunwave-ta-core] : (284) sf_auth, fingers num:2
05-21 11:07:00.992 757 847 I 757 847 [sunwave-ta-core] : (304) g_context.device_state1 is SF_DEVICE_STAT_WAITING_TOUCH
05-21 11:07:00.992 757 847 I 757 847 [sunwave-ic8271] : (2789) enter DEVICE_EXIT mode.
05-21 11:07:00.992 757 847 I 757 847 [sunwave-ic8271] : (2774) enter WAIT_AND_SCAN mode.
05-21 11:07:00.992 757 847 I 757 847 [sunwave-ic8271] : (4364) fgr_cur.sum is 167(0xa7), base is 165(0xa5)
05-21 11:07:00.992 757 847 I chatty : uid=1000(system) HwBinder:757_1 identical 1 line
05-21 11:07:00.992 757 847 I 757 847 [sunwave-ic8271] : (4364) fgr_cur.sum is 167(0xa7), base is 165(0xa5)
05-21 11:07:00.992 757 847 I 757 847 [sunwave-ta-core] : (330) g_context.device_state2 is SF_DEVICE_STAT_WAITING_IMAGE
05-21 11:07:00.992 757 847 I 757 847 [sunwave-client] : (107) --------- TA LOG FINISH ---->8---
05-21 11:07:00.993 11231 11231 W FingerprintService: client com.android.systemui is authenticating...
05-21 11:07:00.994 757 909 I 757 909 [sunwave-hal] : (2241) Optimize:curr 900000,expect 3
05-21 11:07:01.007 757 909 I 757 909 [sunwave-client] : (90) ---8<---- TA LOG BEGINS ---------
05-21 11:07:01.007 757 909 I 757 909 [sunwave-ta-core] : (1802) 'sf_interrupt_query'
05-21 11:07:01.007 757 909 I 757 909 [sunwave-ta-core] : (1805) rst_cnt: 1
05-21 11:07:01.007 757 909 I 757 909 [sunwave-ic8271] : (2827) int: 0x00
05-21 11:07:01.007 757 909 I 757 909 [sunwave-ic8271] : (4364) fgr_cur.sum is 167(0xa7), base is 165(0xa5)
05-21 11:07:01.007 757 909 I 757 909 [sunwave-ta-core] : (1824) SF_DEVICE_STAT_BUSY
05-21 11:07:01.007 757 909 I 757 909 [sunwave-ta-core] : (1849) query int status: device SF_DEVICE_STAT_WAITING_IMAGE, irq SF_DEVICE_STAT_BUSY.
05-21 11:07:01.007 757 909 I 757 909 [sunwave-client] : (107) --------- TA LOG FINISH ---->8---
05-21 11:07:01.008 757 909 I 757 909 [sunwave-client] : (90) ---8<---- TA LOG BEGINS ---------
05-21 11:07:01.008 757 909 I 757 909 [sunwave-ta-core] : (1859) 'sf_interrupt_process'
05-21 11:07:01.008 757 909 I 757 909 [sunwave-ta-core] : (1860) int stat:SF_DEVICE_STAT_BUSY.
05-21 11:07:01.008 757 909 I 757 909 [sunwave-client] : (107) --------- TA LOG FINISH ---->8---
05-21 11:07:01.008 757 909 I 757 909 [sunwave-hal] : (2461) trans->respond.err: Unexpected interrupt
05-21 11:07:01.009 757 909 I 757 909 [sunwave-hal] : (2176) Optimize:curr 2001000,expect 5
05-21 11:07:01.009 757 909 I 757 909 [sunwave-hal] : (2189) wait for device interrupt....state_hal is: SF_HAL_STATE_AUTHENTICATE
05-21 11:07:01.257 11231 11266 I DisplayPowerController: Blocking screen off
05-21 11:07:01.258 11231 11386 W LightsService: Brightness is not valid: NaN
05-21 11:07:01.259 11231 11266 I DisplayPowerController: Unblocked screen off after 2 ms
05-21 11:07:01.292 11231 11266 I dvm_lock_sample: [system_server,1,PowerManagerService,32,ActivityTaskManagerService.java,5534,com.android.server.wm.ActivityTaskManagerInternal$SleepToken com.android.server.wm.ActivityTaskManagerService.acquireSleepToken(java.lang.String, int),TaskSnapshotController.java,567,void com.android.server.wm.TaskSnapshotController.lambda$screenTurningOff$3$TaskSnapshotController(com.android.server.policy.WindowManagerPolicy$ScreenOffListener),6]
05-21 11:07:01.342 10003 19610 D KeyguardViewMediator: notifyScreenTurnedOff
05-21 11:07:01.343 10003 10003 D KeyguardViewMediator: handleNotifyScreenTurnedOff
05-21 11:07:01.358 11231 11266 V DisplayPowerController: Brightness [-1.0] reason changing to: 'screen_off', previous reason: 'manual'.
05-21 11:07:01.460 11231 11251 I DisplayManagerService: Display device changed state: "Built-in Screen", OFF
05-21 11:07:01.569 11838 11863 D StrictMode: StrictMode policy violation: android.os.strictmode.IncorrectContextUseViolation: Visual services, such as WindowManager, WallpaperService or LayoutInflater should be accessed from Activity or other visual Context. Use an Activity or a Context created with Context#createWindowContext(int, Bundle), which are adjusted to the configuration and visual bounds of an area on screen.
05-21 11:07:01.569 11838 11863 D StrictMode: Caused by: java.lang.IllegalAccessException: Tried to access visual service WindowManager from a non-visual Context.
05-21 11:07:01.570 11838 11863 E ContextImpl: Tried to access visual service WindowManager from a non-visual Context. Visual services, such as WindowManager, WallpaperService or LayoutInflater should be accessed from Activity or other visual Context. Use an Activity or a Context created with Context#createWindowContext(int, Bundle), which are adjusted to the configuration and visual bounds of an area on screen.
05-21 11:07:01.570 11838 11863 E ContextImpl: java.lang.IllegalAccessException: Tried to access visual service WindowManager from a non-visual Context.
05-21 11:07:01.736 757 887 I 757 887 [sunwave-ca-device] : (752) uevent: got screen OFF event.'SCREEN_STATUS=OFF'.
05-21 11:07:01.737 757 907 I 757 907 [sunwave-hal] : (920) 'screenOnOffMonitoringThread' screen_on = 0
05-21 11:07:01.765 11231 11231 I screen_toggled: 0
05-21 11:07:01.773 10003 19610 D KeyguardViewMediator: onFinishedGoingToSleep(2)
05-21 11:07:01.774 10003 19610 D KeyguardViewMediator: notifyFinishedGoingToSleep
05-21 11:07:01.788 10003 19610 D KeyguardViewMediator: doKeyguard: showing the lock screen
05-21 11:07:01.788 10003 19610 D KeyguardViewMediator: showLocked
05-21 11:07:01.801 10003 10003 D KeyguardViewMediator: handleNotifyFinishedGoingToSleep
05-21 11:07:01.813 10003 10003 D KeyguardViewMediator: handleShow // Android Q时间点
05-21 11:07:01.852 10003 10033 D KeyguardViewMediator: updateActivityLockScreenState(true, false)
05-21 11:07:01.898 10003 10003 E AndroidRuntime: at com.android.systemui.keyguard.KeyguardViewMediator.handleShow(KeyguardViewMediator.java:1858)
05-21 11:07:01.898 10003 10003 E AndroidRuntime: at com.android.systemui.keyguard.KeyguardViewMediator.access$3200(KeyguardViewMediator.java:152)
05-21 11:07:01.898 10003 10003 E AndroidRuntime: at com.android.systemui.keyguard.KeyguardViewMediator$6.handleMessage(KeyguardViewMediator.java:1610)
05-21 11:07:02.085 11231 14182 E FingerprintService: Lockout reset callback binder died
05-21 11:07:02.093 11231 12104 I WindowManager: WIN DEATH: Window{3cc2be8 u0 StatusBar}
05-21 11:07:02.118 11231 9766 E FingerprintService: Binder died, cancelling client
[3] 指纹解锁Notification PanelView无法消失
现象上来说,两种情况:
情况1,是指纹解锁的同时按下Power键,看到锁屏上锁已经打开(真实锁已解)但是PanelView不消失,需要Swipe滑一下才能看到Launcher, 见《指纹解锁Notification PanelView无法消失》。
情况2,锁屏亮屏情况下,手指轻微向上滑动锁屏界面,另一手指触摸指纹解锁,PenelView也不消失,需要Swipe滑一下才能见到Launcher.
二者最终现象是一样的,只是这复现路径不一致.
这里主要介绍情况2.
亮屏微微向上滑动屏幕,指纹解锁,发现PanelView无法消失
cat fingerprint_cannot_unlock_keyguard_touchScreen_ab_1.log| grep -iE "PanelView: setExpandedHeightInternal|Startwakeandunlock|PanelView: notifyExpanding|PanelView: onTouchEvent:|expand = "
05-13 09:11:11.503 1404 1404 D PanelView: onTouchEvent: action_move -12.49231,true,16,true,false,false
05-13 09:11:11.520 1404 1404 D PanelView: onTouchEvent: x:516.28296, y:1084.822mInitialTouchX:515.28436, mInitialTouchY:1098.3136
05-13 09:11:11.520 1404 1404 D PanelView: onTouchEvent: action_move -13.491577,true,16,true,false,false
05-13 09:11:11.556 1404 1404 D PanelView: onTouchEvent: x:516.28296, y:1082.4893mInitialTouchX:515.28436, mInitialTouchY:1098.3136
05-13 09:11:11.556 1404 1404 D PanelView: onTouchEvent: action_move -15.824341,true,16,true,false,false
05-13 09:11:11.588 1404 1404 D PanelView: onTouchEvent: x:516.28296, y:1082.3236mInitialTouchX:515.28436, mInitialTouchY:1098.3136
05-13 09:11:11.588 1404 1404 D PanelView: onTouchEvent: action_move -15.98999,true,16,true,false,false
05-13 09:11:11.603 1404 1404 D PanelView: onTouchEvent: x:516.28296, y:1081.3242mInitialTouchX:515.28436, mInitialTouchY:1098.3136 //纵向滑动超过16个单位触发进入expanding状态 notifyExpandingStarted
05-13 09:11:11.603 1404 1404 D PanelView: onTouchEvent: action_move -16.98938,true,16,true,false,false
05-13 09:11:11.603 1404 1404 D PanelView: onTouchEvent: xdy
05-13 09:11:11.604 1404 1404 D PanelView: notifyExpandingStarted: mExpanding:false
05-13 09:11:11.607 1404 1404 D PanelView: setExpandedHeightInternal: h:785.0
05-13 09:11:11.628 1404 1404 V BiometricUnlockController: startWakeAndUnlock(5)
05-13 09:11:11.629 1404 1404 D PanelView: setExpandedHeightInternal: h:0.0
05-13 09:11:11.637 1404 1404 D PanelView: notifyExpandingFinished: mExpanding: true
05-13 09:11:11.637 1404 1404 D PanelView: at com.android.systemui.statusbar.phone.BiometricUnlockController.startWakeAndUnlock(BiometricUnlockController.java:537)
05-13 09:11:11.647 1404 1404 D PanelView: onTouchEvent: x:516.28296, y:1080.3248mInitialTouchX:516.28296, mInitialTouchY:1081.3242
05-13 09:11:11.647 1404 1404 D PanelView: onTouchEvent: action_move -0.99938965,true,16,true,true,false
05-13 09:11:11.647 1404 1404 D PanelView: setExpandedHeightInternal: h:784.0006
05-13 09:11:11.685 1404 1404 D PanelView: onTouchEvent: x:516.28296, y:1079.3254mInitialTouchX:516.28296, mInitialTouchY:1081.3242
05-13 09:11:11.685 1404 1404 D PanelView: onTouchEvent: action_move -1.9987793,true,16,true,true,false
05-13 09:11:11.685 1404 1404 D PanelView: setExpandedHeightInternal: h:783.0012
05-13 09:11:11.851 1404 1404 D PanelView: onTouchEvent: x:516.28296, y:1078.326mInitialTouchX:516.28296, mInitialTouchY:1081.3242
05-13 09:11:11.852 1404 1404 D PanelView: onTouchEvent: action_move -2.998169,true,16,true,true,false
05-13 09:11:11.852 1404 1404 D PanelView: setExpandedHeightInternal: h:782.00183
05-13 09:11:11.857 1404 1404 D PanelView: expand = true , target = 784.0 //抬手创建动画 ValueAnimator animator = createHeightAnimator(target);
05-13 09:11:11.858 1404 1404 D PanelView: setExpandedHeightInternal: h:782.00183
05-13 09:11:11.868 1404 1404 D PanelView: setExpandedHeightInternal: h:782.00183
05-13 09:11:11.884 1404 1404 D PanelView: setExpandedHeightInternal: h:782.04785
05-13 09:11:11.900 1404 1404 D PanelView: setExpandedHeightInternal: h:782.1205
05-13 09:11:11.917 1404 1404 D PanelView: setExpandedHeightInternal: h:782.23804
05-13 09:11:11.934 1404 1404 D PanelView: setExpandedHeightInternal: h:782.4189
05-13 09:11:11.950 1404 1404 D PanelView: setExpandedHeightInternal: h:782.64264
05-13 09:11:11.967 1404 1404 D PanelView: setExpandedHeightInternal: h:782.9018
05-13 09:11:11.983 1404 1404 D PanelView: setExpandedHeightInternal: h:783.1399
05-13 09:11:12.000 1404 1404 D PanelView: setExpandedHeightInternal: h:783.32275
05-13 09:11:12.017 1404 1404 D PanelView: setExpandedHeightInternal: h:783.4774
05-13 09:11:12.033 1404 1404 D PanelView: setExpandedHeightInternal: h:783.60547
05-13 09:11:12.050 1404 1404 D PanelView: setExpandedHeightInternal: h:783.6982
05-13 09:11:12.066 1404 1404 D PanelView: setExpandedHeightInternal: h:783.77655
05-13 09:11:12.083 1404 1404 D PanelView: setExpandedHeightInternal: h:783.8358
05-13 09:11:12.100 1404 1404 D PanelView: setExpandedHeightInternal: h:783.8858
05-13 09:11:12.116 1404 1404 D PanelView: setExpandedHeightInternal: h:783.9247
05-13 09:11:12.133 1404 1404 D PanelView: setExpandedHeightInternal: h:783.9531
05-13 09:11:12.149 1404 1404 D PanelView: setExpandedHeightInternal: h:783.9745
05-13 09:11:12.166 1404 1404 D PanelView: setExpandedHeightInternal: h:783.98724
05-13 09:11:12.183 1404 1404 D PanelView: setExpandedHeightInternal: h:783.9959
05-13 09:11:12.200 1404 1404 D PanelView: setExpandedHeightInternal: h:783.99976
05-13 09:11:12.216 1404 1404 D PanelView: setExpandedHeightInternal: h:784.0
05-13 09:11:12.220 1404 1404 D PanelView: notifyExpandingFinished: mExpanding: false
经过多轮debug可以发现,每次复现均在startWakeAndUnlock(5)即亮屏解锁,你多滑动一点,就变成startWakeAndUnlock(6),即dismiss bouncer。
这两个模式之间的差别在哪?
就在于这一点点的轻微的滑动,轻微滑动屏幕高度超过一定阈值,即为dimiss bouncer,因为此时认为是已经bouncer部分展示出来了。
// Android Q
private int calculateMode(BiometricSourceType biometricSourceType) {
boolean unlockingAllowed = mUpdateMonitor.isUnlockingWithBiometricAllowed();
boolean deviceDreaming = mUpdateMonitor.isDreaming();
boolean faceStayingOnKeyguard = biometricSourceType == BiometricSourceType.FACE
&& !mFaceDismissesKeyguard;
if (!mUpdateMonitor.isDeviceInteractive()) {
if (!mStatusBarKeyguardViewManager.isShowing()) {
return MODE_ONLY_WAKE;
} else if (mDozeScrimController.isPulsing() && unlockingAllowed) {
return faceStayingOnKeyguard ? MODE_NONE : MODE_WAKE_AND_UNLOCK_PULSING;
} else if (unlockingAllowed || !mUnlockMethodCache.isMethodSecure()) {
return MODE_WAKE_AND_UNLOCK;
} else {
return MODE_SHOW_BOUNCER;
}
}
if (unlockingAllowed && deviceDreaming && !faceStayingOnKeyguard) {
return MODE_WAKE_AND_UNLOCK_FROM_DREAM;
}
if (mStatusBarKeyguardViewManager.isShowing()) {
if ((mStatusBarKeyguardViewManager.isBouncerShowing()
|| mStatusBarKeyguardViewManager.isBouncerPartiallyVisible()) /// partially visible
&& unlockingAllowed) {
return MODE_DISMISS_BOUNCER; // here
} else if (unlockingAllowed) {
return faceStayingOnKeyguard ? MODE_ONLY_WAKE : MODE_UNLOCK;
} else if (!mStatusBarKeyguardViewManager.isBouncerShowing()) {
return MODE_SHOW_BOUNCER;
}
}
return MODE_NONE;
}
static final float EXPANSION_HIDDEN = 1f;
static final float EXPANSION_VISIBLE = 0f;
public boolean isPartiallyVisible() {
Log.d(TAG, "isPartiallyVisible: mShowingSoon:" + mShowingSoon + ",mRoot.getVisibility(): " + (mRoot != null && mRoot.getVisibility() == View.VISIBLE) + ",mExpansion:" + mExpansion + ",isAnimatingAway():" + isAnimatingAway());
return (mShowingSoon || (mRoot != null && mRoot.getVisibility() == View.VISIBLE))
&& mExpansion != EXPANSION_HIDDEN && !isAnimatingAway();
}
据log显示,影响Partially visible的关键变量是,mExpansion。
最终定位到的关键是:
如上log所示的那个h,(785.0f对应 hidden,只要这个数小于785.0f就已经是部分显示了).
从以上log可知滑动的高度,16个像素高度就认为是有效滑动,开始处理滑动事件。
那么边界条件就呼之欲出了。
1.手指滑动16个像素高度(屏幕高度的1%),保持“暂时不动”;
2.此时指纹authed事件消息刚刚好到,识别到解锁模式为5。
注:
1.“暂时不动”的意思是,刚好此时开始触发滑动响应,在未触发下一次减小刷新h时,来了指纹消息计算解锁模式, 这需要触摸指纹时机跟滑动手指的时机配合的相当好,因为条件还是很苛刻的。
2.样机真实屏幕像素高度是:1600(屏幕分辨率:720x1600).