1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.biometrics; 18 19 import android.annotation.NonNull; 20 import android.content.Context; 21 import android.util.AttributeSet; 22 23 import com.android.internal.widget.LockPatternChecker; 24 import com.android.internal.widget.LockPatternUtils; 25 import com.android.internal.widget.LockPatternView; 26 import com.android.internal.widget.LockscreenCredential; 27 import com.android.internal.widget.VerifyCredentialResponse; 28 import com.android.systemui.R; 29 30 import java.util.List; 31 32 /** 33 * Pattern UI 34 */ 35 public class AuthCredentialPatternView extends AuthCredentialView { 36 37 private LockPatternView mLockPatternView; 38 39 private class UnlockPatternListener implements LockPatternView.OnPatternListener { 40 41 @Override onPatternStart()42 public void onPatternStart() { 43 44 } 45 46 @Override onPatternCleared()47 public void onPatternCleared() { 48 49 } 50 51 @Override onPatternCellAdded(List<LockPatternView.Cell> pattern)52 public void onPatternCellAdded(List<LockPatternView.Cell> pattern) { 53 54 } 55 56 @Override onPatternDetected(List<LockPatternView.Cell> pattern)57 public void onPatternDetected(List<LockPatternView.Cell> pattern) { 58 if (mPendingLockCheck != null) { 59 mPendingLockCheck.cancel(false); 60 } 61 62 mLockPatternView.setEnabled(false); 63 64 if (pattern.size() < LockPatternUtils.MIN_PATTERN_REGISTER_FAIL) { 65 // Pattern size is less than the minimum, do not count it as a failed attempt. 66 onPatternVerified(VerifyCredentialResponse.ERROR, 0 /* timeoutMs */); 67 return; 68 } 69 70 try (LockscreenCredential credential = LockscreenCredential.createPattern(pattern)) { 71 // Request LockSettingsService to return the Gatekeeper Password in the 72 // VerifyCredentialResponse so that we can request a Gatekeeper HAT with the 73 // Gatekeeper Password and operationId. 74 mPendingLockCheck = LockPatternChecker.verifyCredential( 75 mLockPatternUtils, 76 credential, 77 mEffectiveUserId, 78 LockPatternUtils.VERIFY_FLAG_REQUEST_GK_PW_HANDLE, 79 this::onPatternVerified); 80 } 81 } 82 onPatternVerified(@onNull VerifyCredentialResponse response, int timeoutMs)83 private void onPatternVerified(@NonNull VerifyCredentialResponse response, int timeoutMs) { 84 AuthCredentialPatternView.this.onCredentialVerified(response, timeoutMs); 85 if (timeoutMs > 0) { 86 mLockPatternView.setEnabled(false); 87 } else { 88 mLockPatternView.setEnabled(true); 89 } 90 } 91 } 92 93 @Override onErrorTimeoutFinish()94 protected void onErrorTimeoutFinish() { 95 super.onErrorTimeoutFinish(); 96 mLockPatternView.setEnabled(true); 97 } 98 AuthCredentialPatternView(Context context, AttributeSet attrs)99 public AuthCredentialPatternView(Context context, AttributeSet attrs) { 100 super(context, attrs); 101 } 102 103 @Override onAttachedToWindow()104 protected void onAttachedToWindow() { 105 super.onAttachedToWindow(); 106 mLockPatternView = findViewById(R.id.lockPattern); 107 mLockPatternView.setOnPatternListener(new UnlockPatternListener()); 108 mLockPatternView.setInStealthMode( 109 !mLockPatternUtils.isVisiblePatternEnabled(mUserId)); 110 mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled()); 111 } 112 } 113