1 /*
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 
17 package com.android.keyguard;
18 
19 import android.content.Context;
20 import android.util.AttributeSet;
21 import android.view.View;
22 import android.view.ViewGroup;
23 import android.view.animation.AnimationUtils;
24 
25 import com.android.settingslib.animation.AppearAnimationUtils;
26 import com.android.settingslib.animation.DisappearAnimationUtils;
27 import com.android.systemui.R;
28 
29 /**
30  * Displays a PIN pad for unlocking.
31  */
32 public class KeyguardPINView extends KeyguardPinBasedInputView {
33 
34     private final AppearAnimationUtils mAppearAnimationUtils;
35     private final DisappearAnimationUtils mDisappearAnimationUtils;
36     private final DisappearAnimationUtils mDisappearAnimationUtilsLocked;
37     private ViewGroup mContainer;
38     private ViewGroup mRow0;
39     private ViewGroup mRow1;
40     private ViewGroup mRow2;
41     private ViewGroup mRow3;
42     private View mDivider;
43     private int mDisappearYTranslation;
44     private View[][] mViews;
45     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
46 
KeyguardPINView(Context context)47     public KeyguardPINView(Context context) {
48         this(context, null);
49     }
50 
KeyguardPINView(Context context, AttributeSet attrs)51     public KeyguardPINView(Context context, AttributeSet attrs) {
52         super(context, attrs);
53         mAppearAnimationUtils = new AppearAnimationUtils(context);
54         mDisappearAnimationUtils = new DisappearAnimationUtils(context,
55                 125, 0.6f /* translationScale */,
56                 0.45f /* delayScale */, AnimationUtils.loadInterpolator(
57                         mContext, android.R.interpolator.fast_out_linear_in));
58         mDisappearAnimationUtilsLocked = new DisappearAnimationUtils(context,
59                 (long) (125 * KeyguardPatternView.DISAPPEAR_MULTIPLIER_LOCKED),
60                 0.6f /* translationScale */,
61                 0.45f /* delayScale */, AnimationUtils.loadInterpolator(
62                         mContext, android.R.interpolator.fast_out_linear_in));
63         mDisappearYTranslation = getResources().getDimensionPixelSize(
64                 R.dimen.disappear_y_translation);
65         mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
66     }
67 
68     @Override
resetState()69     protected void resetState() {
70         super.resetState();
71         if (mSecurityMessageDisplay != null) {
72             mSecurityMessageDisplay.setMessage("");
73         }
74     }
75 
76     @Override
getPasswordTextViewId()77     protected int getPasswordTextViewId() {
78         return R.id.pinEntry;
79     }
80 
81     @Override
onFinishInflate()82     protected void onFinishInflate() {
83         super.onFinishInflate();
84 
85         mContainer = findViewById(R.id.container);
86         mRow0 = findViewById(R.id.row0);
87         mRow1 = findViewById(R.id.row1);
88         mRow2 = findViewById(R.id.row2);
89         mRow3 = findViewById(R.id.row3);
90         mDivider = findViewById(R.id.divider);
91         mViews = new View[][]{
92                 new View[]{
93                         mRow0, null, null
94                 },
95                 new View[]{
96                         findViewById(R.id.key1), findViewById(R.id.key2),
97                         findViewById(R.id.key3)
98                 },
99                 new View[]{
100                         findViewById(R.id.key4), findViewById(R.id.key5),
101                         findViewById(R.id.key6)
102                 },
103                 new View[]{
104                         findViewById(R.id.key7), findViewById(R.id.key8),
105                         findViewById(R.id.key9)
106                 },
107                 new View[]{
108                         findViewById(R.id.delete_button), findViewById(R.id.key0),
109                         findViewById(R.id.key_enter)
110                 },
111                 new View[]{
112                         null, mEcaView, null
113                 }};
114 
115         View cancelBtn = findViewById(R.id.cancel_button);
116         if (cancelBtn != null) {
117             cancelBtn.setOnClickListener(view -> {
118                 mCallback.reset();
119                 mCallback.onCancelClicked();
120             });
121         }
122     }
123 
124     @Override
showUsabilityHint()125     public void showUsabilityHint() {
126     }
127 
128     @Override
getWrongPasswordStringId()129     public int getWrongPasswordStringId() {
130         return R.string.kg_wrong_pin;
131     }
132 
133     @Override
startAppearAnimation()134     public void startAppearAnimation() {
135         enableClipping(false);
136         setAlpha(1f);
137         setTranslationY(mAppearAnimationUtils.getStartTranslation());
138         AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 500 /* duration */,
139                 0, mAppearAnimationUtils.getInterpolator());
140         mAppearAnimationUtils.startAnimation2d(mViews,
141                 new Runnable() {
142                     @Override
143                     public void run() {
144                         enableClipping(true);
145                     }
146                 });
147     }
148 
149     @Override
startDisappearAnimation(final Runnable finishRunnable)150     public boolean startDisappearAnimation(final Runnable finishRunnable) {
151         enableClipping(false);
152         setTranslationY(0);
153         AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 280 /* duration */,
154                 mDisappearYTranslation, mDisappearAnimationUtils.getInterpolator());
155         DisappearAnimationUtils disappearAnimationUtils = mKeyguardUpdateMonitor
156                 .needsSlowUnlockTransition()
157                         ? mDisappearAnimationUtilsLocked
158                         : mDisappearAnimationUtils;
159         disappearAnimationUtils.startAnimation2d(mViews,
160                 new Runnable() {
161                     @Override
162                     public void run() {
163                         enableClipping(true);
164                         if (finishRunnable != null) {
165                             finishRunnable.run();
166                         }
167                     }
168                 });
169         return true;
170     }
171 
enableClipping(boolean enable)172     private void enableClipping(boolean enable) {
173         mContainer.setClipToPadding(enable);
174         mContainer.setClipChildren(enable);
175         mRow1.setClipToPadding(enable);
176         mRow2.setClipToPadding(enable);
177         mRow3.setClipToPadding(enable);
178         setClipChildren(enable);
179     }
180 
181     @Override
hasOverlappingRendering()182     public boolean hasOverlappingRendering() {
183         return false;
184     }
185 }
186