blob: 1f3c17692c7b6469a318ed54a2e27d84f61baa93 [file] [log] [blame]
Daniel Sandler69bdee72012-10-23 16:45:50 -04001/*
2 * Copyright (C) 2012 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
Jim Miller5ecd8112013-01-09 18:50:26 -080017package com.android.keyguard;
Daniel Sandler69bdee72012-10-23 16:45:50 -040018
19import android.content.Context;
Daniel Sandler69bdee72012-10-23 16:45:50 -040020import android.text.InputType;
Daniel Sandler69bdee72012-10-23 16:45:50 -040021import android.text.TextWatcher;
22import android.text.method.DigitsKeyListener;
Michael Jurka1254f2f2012-10-25 11:44:31 -070023import android.util.AttributeSet;
24import android.view.View;
Jorim Jaggi15a77f72014-05-28 16:20:03 +020025import android.view.ViewGroup;
Daniel Sandler69bdee72012-10-23 16:45:50 -040026import android.widget.TextView.OnEditorActionListener;
27
Daniel Sandler69bdee72012-10-23 16:45:50 -040028/**
29 * Displays a PIN pad for unlocking.
30 */
31public class KeyguardPINView extends KeyguardAbsKeyInputView
32 implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
33
Jorim Jaggi15a77f72014-05-28 16:20:03 +020034 private final AppearAnimationUtils mAppearAnimationUtils;
35 private ViewGroup mKeyguardBouncerFrame;
36 private ViewGroup mRow0;
37 private ViewGroup mRow1;
38 private ViewGroup mRow2;
39 private ViewGroup mRow3;
40 private View mDivider;
41
Daniel Sandler69bdee72012-10-23 16:45:50 -040042 public KeyguardPINView(Context context) {
43 this(context, null);
44 }
45
46 public KeyguardPINView(Context context, AttributeSet attrs) {
47 super(context, attrs);
Jorim Jaggi15a77f72014-05-28 16:20:03 +020048 mAppearAnimationUtils = new AppearAnimationUtils(context);
Daniel Sandler69bdee72012-10-23 16:45:50 -040049 }
50
51 protected void resetState() {
Danielle Millett1625e872012-11-01 15:00:12 -040052 if (KeyguardUpdateMonitor.getInstance(mContext).getMaxBiometricUnlockAttemptsReached()) {
53 mSecurityMessageDisplay.setMessage(R.string.faceunlock_multiple_failures, true);
54 } else {
55 mSecurityMessageDisplay.setMessage(R.string.kg_pin_instructions, false);
56 }
Daniel Sandler69bdee72012-10-23 16:45:50 -040057 mPasswordEntry.setEnabled(true);
58 }
59
60 @Override
Daniel Sandler8a26bf52012-10-30 13:29:50 -040061 protected int getPasswordTextViewId() {
62 return R.id.pinEntry;
63 }
64
65 @Override
Daniel Sandler69bdee72012-10-23 16:45:50 -040066 protected void onFinishInflate() {
67 super.onFinishInflate();
68
Jorim Jaggi15a77f72014-05-28 16:20:03 +020069 mKeyguardBouncerFrame = (ViewGroup) findViewById(R.id.keyguard_bouncer_frame);
70 mRow0 = (ViewGroup) findViewById(R.id.row0);
71 mRow1 = (ViewGroup) findViewById(R.id.row1);
72 mRow2 = (ViewGroup) findViewById(R.id.row2);
73 mRow3 = (ViewGroup) findViewById(R.id.row3);
74 mDivider = findViewById(R.id.divider);
Daniel Sandlerd5692742012-10-24 00:21:32 -040075 final View ok = findViewById(R.id.key_enter);
Daniel Sandler69bdee72012-10-23 16:45:50 -040076 if (ok != null) {
77 ok.setOnClickListener(new View.OnClickListener() {
78 @Override
79 public void onClick(View v) {
Daniel Sandler7bc8af32012-10-25 11:12:56 -040080 doHapticKeyClick();
Daniel Sandler6a64ac52012-11-01 11:58:13 -040081 if (mPasswordEntry.isEnabled()) {
82 verifyPasswordAndUnlock();
83 }
Daniel Sandler69bdee72012-10-23 16:45:50 -040084 }
85 });
alanv0cbbc572012-11-02 11:56:27 -070086 ok.setOnHoverListener(new LiftToActivateListener(getContext()));
Daniel Sandler69bdee72012-10-23 16:45:50 -040087 }
88
89 // The delete button is of the PIN keyboard itself in some (e.g. tablet) layouts,
90 // not a separate view
91 View pinDelete = findViewById(R.id.delete_button);
92 if (pinDelete != null) {
93 pinDelete.setVisibility(View.VISIBLE);
94 pinDelete.setOnClickListener(new OnClickListener() {
95 public void onClick(View v) {
Daniel Sandler6a64ac52012-11-01 11:58:13 -040096 // check for time-based lockouts
97 if (mPasswordEntry.isEnabled()) {
98 CharSequence str = mPasswordEntry.getText();
99 if (str.length() > 0) {
100 mPasswordEntry.setText(str.subSequence(0, str.length()-1));
101 }
Daniel Sandler69bdee72012-10-23 16:45:50 -0400102 }
Daniel Sandleracb60fb2012-10-25 10:46:37 -0400103 doHapticKeyClick();
104 }
105 });
106 pinDelete.setOnLongClickListener(new View.OnLongClickListener() {
107 public boolean onLongClick(View v) {
Daniel Sandler6a64ac52012-11-01 11:58:13 -0400108 // check for time-based lockouts
109 if (mPasswordEntry.isEnabled()) {
110 mPasswordEntry.setText("");
111 }
Daniel Sandleracb60fb2012-10-25 10:46:37 -0400112 doHapticKeyClick();
113 return true;
Daniel Sandler69bdee72012-10-23 16:45:50 -0400114 }
115 });
116 }
117
118 mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
119 mPasswordEntry.setInputType(InputType.TYPE_CLASS_NUMBER
120 | InputType.TYPE_NUMBER_VARIATION_PASSWORD);
121
122 mPasswordEntry.requestFocus();
123 }
Adam Cohen6fb841f2012-10-24 13:15:38 -0700124
125 @Override
126 public void showUsabilityHint() {
127 }
Daniel Sandler16d90922012-11-01 12:41:14 -0400128
129 @Override
130 public int getWrongPasswordStringId() {
131 return R.string.kg_wrong_pin;
132 }
Jorim Jaggic14f8292014-05-27 02:25:45 +0200133
134 @Override
135 public void startAppearAnimation() {
Jorim Jaggi15a77f72014-05-28 16:20:03 +0200136 enableClipping(false);
137 setTranslationY(mAppearAnimationUtils.getStartTranslation());
138 animate()
139 .setDuration(500)
140 .setInterpolator(mAppearAnimationUtils.getInterpolator())
141 .translationY(0);
142 mAppearAnimationUtils.startAppearAnimation(new View[][] {
143 new View[] {
144 mRow0, null, null
145 },
146 new View[] {
147 findViewById(R.id.key1), findViewById(R.id.key2), findViewById(R.id.key3)
148 },
149 new View[] {
150 findViewById(R.id.key4), findViewById(R.id.key5), findViewById(R.id.key6)
151 },
152 new View[] {
153 findViewById(R.id.key7), findViewById(R.id.key8), findViewById(R.id.key9)
154 },
155 new View[] {
156 null, findViewById(R.id.key0), findViewById(R.id.key_enter)
157 },
158 new View[] {
159 null, mEcaView, null
160 }},
161 new Runnable() {
162 @Override
163 public void run() {
164 enableClipping(true);
165 }
166 });
167 }
168
169 private void enableClipping(boolean enable) {
170 mKeyguardBouncerFrame.setClipToPadding(enable);
171 mKeyguardBouncerFrame.setClipChildren(enable);
172 mRow1.setClipToPadding(enable);
173 mRow2.setClipToPadding(enable);
174 mRow3.setClipToPadding(enable);
175 setClipChildren(enable);
Jorim Jaggic14f8292014-05-27 02:25:45 +0200176 }
Michael Jurka1254f2f2012-10-25 11:44:31 -0700177}