/** * Starts the biometric unlock if it should be started based on a number of factors. If it should * not be started, it either goes to the back up, or remains showing to prepare for it being * started later. */ private void maybeStartBiometricUnlock() { log("maybeStartBiometricUnlock() is called."); if (mBiometricUnlock != null) { KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext); final boolean backupIsTimedOut = (monitor.getFailedUnlockAttempts() >= LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT); final boolean mediaPlaying = AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0) || AudioSystem.isStreamActive(AudioSystem.STREAM_ALARM, 0); boolean isBouncerVisibleToUser; synchronized (mIsBouncerVisibleToUserLock) { isBouncerVisibleToUser = mIsBouncerVisibleToUser; } // Don't start it if the bouncer is not showing, but keep this view up because we want // it here and ready for when the bouncer does show. if (!isBouncerVisibleToUser) { if (mediaPlaying) { log( "maybeStartBiometricUnlock() - isBouncerVisibleToUser is false" + " && mediaPlaying is true, call mBiometricUnlock.stopAndShowBackup()"); mBiometricUnlock.stopAndShowBackup(); } else { log( "maybeStartBiometricUnlock() - isBouncerVisibleToUser is false," + " call mBiometricUnlock.stop()"); mBiometricUnlock.stop(); // It shouldn't be running but calling this can't hurt. } return; } // Although these same conditions are handled in KeyguardSecurityModel, they are still // necessary here. When a tablet is rotated 90 degrees, a configuration change is // triggered and everything is torn down and reconstructed. That means // KeyguardSecurityModel gets a chance to take care of the logic and doesn't even // reconstruct KeyguardFaceUnlockView if the biometric unlock should be suppressed. // However, for a 180 degree rotation, no configuration change is triggered, so only // the logic here is capable of suppressing Face Unlock. if (monitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE && monitor.isAlternateUnlockEnabled() && !monitor.getMaxBiometricUnlockAttemptsReached() && !backupIsTimedOut && !mediaPlaying) { mBiometricUnlock.start(); } else { log("maybeStartBiometricUnlock() - call stopAndShowBackup()"); mBiometricUnlock.stopAndShowBackup(); } } }
/** Configures echo cancellation and noise suppression effects. */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN) private void configureEffects() { if (!AndroidUtils.hasAPI(16)) return; AudioSystem audioSystem = AudioSystem.getAudioSystem(AudioSystem.LOCATOR_PROTOCOL_AUDIORECORD); // Creates echo canceler if available if (AcousticEchoCanceler.isAvailable()) { AcousticEchoCanceler echoCanceller = AcousticEchoCanceler.create(audioRecord.getAudioSessionId()); if (echoCanceller != null) { echoCanceller.setEnableStatusListener(this); echoCanceller.setEnabled(audioSystem.isEchoCancel()); logger.info("Echo cancellation: " + echoCanceller.getEnabled()); } } // Automatic gain control if (AutomaticGainControl.isAvailable()) { AutomaticGainControl agc = AutomaticGainControl.create(audioRecord.getAudioSessionId()); if (agc != null) { agc.setEnableStatusListener(this); agc.setEnabled(audioSystem.isAutomaticGainControl()); logger.info("Auto gain control: " + agc.getEnabled()); } } // Creates noise suppressor if available if (NoiseSuppressor.isAvailable()) { NoiseSuppressor noiseSuppressor = NoiseSuppressor.create(audioRecord.getAudioSessionId()); if (noiseSuppressor != null) { noiseSuppressor.setEnableStatusListener(this); noiseSuppressor.setEnabled(audioSystem.isDenoise()); logger.info("Noise suppressor: " + noiseSuppressor.getEnabled()); } } }