1dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller/*
2dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Copyright (C) 2012 The Android Open Source Project
3dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller *
4dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Licensed under the Apache License, Version 2.0 (the "License");
5dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * you may not use this file except in compliance with the License.
6dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * You may obtain a copy of the License at
7dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller *
8dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller *      http://www.apache.org/licenses/LICENSE-2.0
9dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller *
10dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Unless required by applicable law or agreed to in writing, software
11dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * distributed under the License is distributed on an "AS IS" BASIS,
12dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * See the License for the specific language governing permissions and
14dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * limitations under the License.
15dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller */
165ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Millerpackage com.android.keyguard;
17dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
18ea03be1056d44328b96559702791bdac2a466002Jason Monkimport static com.android.internal.util.LatencyTracker.ACTION_CHECK_CREDENTIAL;
19ea03be1056d44328b96559702791bdac2a466002Jason Monkimport static com.android.internal.util.LatencyTracker.ACTION_CHECK_CREDENTIAL_UNLOCKED;
20ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi
21dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.content.Context;
225737534abab477cf32b4dd0aa7a72f70ede0502cJim Millerimport android.graphics.Rect;
236e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xiaimport android.os.AsyncTask;
24dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.os.CountDownTimer;
25dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.os.SystemClock;
263018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinekimport android.text.TextUtils;
27dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.util.AttributeSet;
28dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.util.Log;
29dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.view.MotionEvent;
30dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.view.View;
313018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinekimport android.view.ViewGroup;
3298f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggiimport android.view.animation.AnimationUtils;
333018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinekimport android.view.animation.Interpolator;
343af630c8d18bcf4b23a5a308917319dd04cc8ed2Jim Millerimport android.widget.LinearLayout;
35dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
36ea03be1056d44328b96559702791bdac2a466002Jason Monkimport com.android.internal.util.LatencyTracker;
376e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xiaimport com.android.internal.widget.LockPatternChecker;
38dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport com.android.internal.widget.LockPatternUtils;
39dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport com.android.internal.widget.LockPatternView;
405673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggiimport com.android.settingslib.animation.AppearAnimationCreator;
415673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggiimport com.android.settingslib.animation.AppearAnimationUtils;
425673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggiimport com.android.settingslib.animation.DisappearAnimationUtils;
43dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
44dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport java.util.List;
45dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
463018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinekpublic class KeyguardPatternView extends LinearLayout implements KeyguardSecurityView,
4772b46d429cbab54af962c25ffe087c5f927f7340Andrew Lee        AppearAnimationCreator<LockPatternView.CellState>,
4872b46d429cbab54af962c25ffe087c5f927f7340Andrew Lee        EmergencyButton.EmergencyButtonCallback {
49dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
50dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private static final String TAG = "SecurityPatternView";
515cf17879a31b7b78c09ec50b727f921840dcf783Jorim Jaggi    private static final boolean DEBUG = KeyguardConstants.DEBUG;
52dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
53dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    // how long before we clear the wrong pattern
54dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private static final int PATTERN_CLEAR_TIMEOUT_MS = 2000;
55dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
56dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    // how long we stay awake after each key beyond MIN_PATTERN_BEFORE_POKE_WAKELOCK
57dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private static final int UNLOCK_PATTERN_WAKE_INTERVAL_MS = 7000;
58dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
59dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    // how many cells the user has to cross before we poke the wakelock
60dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private static final int MIN_PATTERN_BEFORE_POKE_WAKELOCK = 2;
61dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
62e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi    // How much we scale up the duration of the disappear animation when the current user is locked
63e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi    public static final float DISAPPEAR_MULTIPLIER_LOCKED = 1.5f;
64e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi
657c11f8b4659c3444d5037b756b6e5f45a2ea61a6Adrian Roos    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
663018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek    private final AppearAnimationUtils mAppearAnimationUtils;
67f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek    private final DisappearAnimationUtils mDisappearAnimationUtils;
68e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi    private final DisappearAnimationUtils mDisappearAnimationUtilsLocked;
697c11f8b4659c3444d5037b756b6e5f45a2ea61a6Adrian Roos
70dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private CountDownTimer mCountdownTimer = null;
71dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private LockPatternUtils mLockPatternUtils;
726e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia    private AsyncTask<?, ?, ?> mPendingLockCheck;
73dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private LockPatternView mLockPatternView;
74dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private KeyguardSecurityCallback mCallback;
75dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
76dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    /**
77dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller     * Keeps track of the last time we poked the wake lock during dispatching of the touch event.
78dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller     * Initialized to something guaranteed to make us poke the wakelock when the user starts
79dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller     * drawing the pattern.
80dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller     * @see #dispatchTouchEvent(android.view.MotionEvent)
81dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller     */
82dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private long mLastPokeTime = -UNLOCK_PATTERN_WAKE_INTERVAL_MS;
83dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
84dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    /**
85dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller     * Useful for clearing out the wrong pattern after a delay
86dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller     */
87dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private Runnable mCancelPatternRunnable = new Runnable() {
8851e3a672e01d6e9ce4b19ec20d9b62ae8e35fc85Jim Miller        @Override
89dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public void run() {
90dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            mLockPatternView.clearPattern();
91dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
92dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    };
935737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller    private Rect mTempRect = new Rect();
943122fa85b2f18c0a89f5fe1ef0942c530a271843Selim Cinek    private KeyguardMessageArea mSecurityMessageDisplay;
95c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren    private View mEcaView;
966b88cdfba770efc5722338c240ccaada13d7b0d4Jorim Jaggi    private ViewGroup mContainer;
9776a1623afc170a13923b68f3256057d8adeb7937Jorim Jaggi    private int mDisappearYTranslation;
98dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
99dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    enum FooterMode {
100dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        Normal,
101dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        ForgotLockPattern,
102dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        VerifyUnlocked
103dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
104dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
105dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public KeyguardPatternView(Context context) {
106dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        this(context, null);
107dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
108dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
109dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public KeyguardPatternView(Context context, AttributeSet attrs) {
110dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super(context, attrs);
1117c11f8b4659c3444d5037b756b6e5f45a2ea61a6Adrian Roos        mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
11298f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi        mAppearAnimationUtils = new AppearAnimationUtils(context,
113f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek                AppearAnimationUtils.DEFAULT_APPEAR_DURATION, 1.5f /* translationScale */,
114f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek                2.0f /* delayScale */, AnimationUtils.loadInterpolator(
11598f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi                        mContext, android.R.interpolator.linear_out_slow_in));
116f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek        mDisappearAnimationUtils = new DisappearAnimationUtils(context,
117f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek                125, 1.2f /* translationScale */,
11894f6f0610147de16aae7c39f97f21ee31591dd6fJorim Jaggi                0.6f /* delayScale */, AnimationUtils.loadInterpolator(
119f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek                        mContext, android.R.interpolator.fast_out_linear_in));
120e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi        mDisappearAnimationUtilsLocked = new DisappearAnimationUtils(context,
121e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi                (long) (125 * DISAPPEAR_MULTIPLIER_LOCKED), 1.2f /* translationScale */,
122e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi                0.6f /* delayScale */, AnimationUtils.loadInterpolator(
123e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi                mContext, android.R.interpolator.fast_out_linear_in));
12476a1623afc170a13923b68f3256057d8adeb7937Jorim Jaggi        mDisappearYTranslation = getResources().getDimensionPixelSize(
12576a1623afc170a13923b68f3256057d8adeb7937Jorim Jaggi                R.dimen.disappear_y_translation);
126dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
127dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
12851e3a672e01d6e9ce4b19ec20d9b62ae8e35fc85Jim Miller    @Override
129dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void setKeyguardCallback(KeyguardSecurityCallback callback) {
130dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mCallback = callback;
131dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
132dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
13351e3a672e01d6e9ce4b19ec20d9b62ae8e35fc85Jim Miller    @Override
134dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void setLockPatternUtils(LockPatternUtils utils) {
135dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mLockPatternUtils = utils;
136dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
137dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
138dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
139dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    protected void onFinishInflate() {
140dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        super.onFinishInflate();
141dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mLockPatternUtils = mLockPatternUtils == null
142dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                ? new LockPatternUtils(mContext) : mLockPatternUtils;
143dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
14451efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette        mLockPatternView = findViewById(R.id.lockPatternView);
145dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mLockPatternView.setSaveEnabled(false);
146dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mLockPatternView.setOnPatternListener(new UnlockPatternListener());
147dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
148dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        // vibrate mode will be the same for the life of this screen
149dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
150dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
1513122fa85b2f18c0a89f5fe1ef0942c530a271843Selim Cinek        mSecurityMessageDisplay =
1523122fa85b2f18c0a89f5fe1ef0942c530a271843Selim Cinek                (KeyguardMessageArea) KeyguardMessageArea.findSecurityMessageDisplay(this);
153c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren        mEcaView = findViewById(R.id.keyguard_selector_fade_container);
15451efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette        mContainer = findViewById(R.id.container);
15572b46d429cbab54af962c25ffe087c5f927f7340Andrew Lee
15651efddbd3bb304de2dd47fa8cd1114ac555958bbAlan Viverette        EmergencyButton button = findViewById(R.id.emergency_call_button);
157f98f7b969b55fe517eda9cebcd645309badccae8Andrew Lee        if (button != null) {
158f98f7b969b55fe517eda9cebcd645309badccae8Andrew Lee            button.setCallback(this);
159f98f7b969b55fe517eda9cebcd645309badccae8Andrew Lee        }
16044e4d82d2ec27c812e90ff1ece7573e68fac60b1Jian Jin
16144e4d82d2ec27c812e90ff1ece7573e68fac60b1Jian Jin        View cancelBtn = findViewById(R.id.cancel_button);
16244e4d82d2ec27c812e90ff1ece7573e68fac60b1Jian Jin        if (cancelBtn != null) {
16344e4d82d2ec27c812e90ff1ece7573e68fac60b1Jian Jin            cancelBtn.setOnClickListener(view -> {
16444e4d82d2ec27c812e90ff1ece7573e68fac60b1Jian Jin                mCallback.reset();
16544e4d82d2ec27c812e90ff1ece7573e68fac60b1Jian Jin            });
16644e4d82d2ec27c812e90ff1ece7573e68fac60b1Jian Jin        }
16772b46d429cbab54af962c25ffe087c5f927f7340Andrew Lee    }
16872b46d429cbab54af962c25ffe087c5f927f7340Andrew Lee
16951e3a672e01d6e9ce4b19ec20d9b62ae8e35fc85Jim Miller    @Override
17072b46d429cbab54af962c25ffe087c5f927f7340Andrew Lee    public void onEmergencyButtonClickedWhenInCall() {
17172b46d429cbab54af962c25ffe087c5f927f7340Andrew Lee        mCallback.reset();
172dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
173dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
174dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
175d2b82f70fede8c2ec4de34d8e6462ed4ece13c56Jim Miller    public boolean onTouchEvent(MotionEvent ev) {
176d2b82f70fede8c2ec4de34d8e6462ed4ece13c56Jim Miller        boolean result = super.onTouchEvent(ev);
177dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        // as long as the user is entering a pattern (i.e sending a touch event that was handled
178dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        // by this screen), keep poking the wake lock so that the screen will stay on.
179dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        final long elapsed = SystemClock.elapsedRealtime() - mLastPokeTime;
180dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        if (result && (elapsed > (UNLOCK_PATTERN_WAKE_INTERVAL_MS - 100))) {
181dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            mLastPokeTime = SystemClock.elapsedRealtime();
182dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
1835737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        mTempRect.set(0, 0, 0, 0);
1845737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        offsetRectIntoDescendantCoords(mLockPatternView, mTempRect);
1855737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        ev.offsetLocation(mTempRect.left, mTempRect.top);
1865737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        result = mLockPatternView.dispatchTouchEvent(ev) || result;
1875737534abab477cf32b4dd0aa7a72f70ede0502cJim Miller        ev.offsetLocation(-mTempRect.left, -mTempRect.top);
188dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        return result;
189dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
190dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
19151e3a672e01d6e9ce4b19ec20d9b62ae8e35fc85Jim Miller    @Override
192dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void reset() {
193dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        // reset lock pattern
19417fdb13a600e366ac1166e8dfe82b9b428041e29Toni Barzic        mLockPatternView.setInStealthMode(!mLockPatternUtils.isVisiblePatternEnabled(
19517fdb13a600e366ac1166e8dfe82b9b428041e29Toni Barzic                KeyguardUpdateMonitor.getCurrentUser()));
196dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mLockPatternView.enableInput();
197dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mLockPatternView.setEnabled(true);
198dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mLockPatternView.clearPattern();
199dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
200dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        // if the user is currently locked out, enforce it.
2018150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos        long deadline = mLockPatternUtils.getLockoutAttemptDeadline(
202d6aa6cb0cc8c70a30434048e25e14643b1645755Adrian Roos                KeyguardUpdateMonitor.getCurrentUser());
203dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        if (deadline != 0) {
204dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            handleAttemptLockout(deadline);
205dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        } else {
2061625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett            displayDefaultSecurityMessage();
207dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
208dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
209dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
2101625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett    private void displayDefaultSecurityMessage() {
211db327e9f5976f8f184ae105e672ea4bda4a0af48Adrian Roos        mSecurityMessageDisplay.setMessage("");
2121625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett    }
2131625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett
2146fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen    @Override
2156fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen    public void showUsabilityHint() {
2166fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen    }
2176fb841fa219eaae3e87f2fdc05e105d7a1813c42Adam Cohen
218dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    /** TODO: hook this up */
219dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void cleanUp() {
220dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        if (DEBUG) Log.v(TAG, "Cleanup() called on " + this);
221dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mLockPatternUtils = null;
222dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mLockPatternView.setOnPatternListener(null);
223dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
224dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
225dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private class UnlockPatternListener implements LockPatternView.OnPatternListener {
226dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
22751e3a672e01d6e9ce4b19ec20d9b62ae8e35fc85Jim Miller        @Override
228dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public void onPatternStart() {
229dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            mLockPatternView.removeCallbacks(mCancelPatternRunnable);
230db327e9f5976f8f184ae105e672ea4bda4a0af48Adrian Roos            mSecurityMessageDisplay.setMessage("");
231dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
232dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
23351e3a672e01d6e9ce4b19ec20d9b62ae8e35fc85Jim Miller        @Override
234dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public void onPatternCleared() {
235dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
236dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
23751e3a672e01d6e9ce4b19ec20d9b62ae8e35fc85Jim Miller        @Override
238dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        public void onPatternCellAdded(List<LockPatternView.Cell> pattern) {
239b690f0d5023fcf144f2701058d5a6f88d66cc97aJorim Jaggi            mCallback.userActivity();
240dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
241dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
24251e3a672e01d6e9ce4b19ec20d9b62ae8e35fc85Jim Miller        @Override
2436e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia        public void onPatternDetected(final List<LockPatternView.Cell> pattern) {
2446e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia            mLockPatternView.disableInput();
2456e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia            if (mPendingLockCheck != null) {
2466e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia                mPendingLockCheck.cancel(false);
2476e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia            }
2486e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia
249ce64cea38389a75def2f3d933a007515af288714Xiyuan Xia            final int userId = KeyguardUpdateMonitor.getCurrentUser();
2502397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales            if (pattern.size() < LockPatternUtils.MIN_PATTERN_REGISTER_FAIL) {
2512397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales                mLockPatternView.enableInput();
252ce64cea38389a75def2f3d933a007515af288714Xiyuan Xia                onPatternChecked(userId, false, 0, false /* not valid - too short */);
2532397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales                return;
2542397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales            }
2552397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales
256ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi            if (LatencyTracker.isEnabled(mContext)) {
257ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi                LatencyTracker.getInstance(mContext).onActionStart(ACTION_CHECK_CREDENTIAL);
258ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi                LatencyTracker.getInstance(mContext).onActionStart(ACTION_CHECK_CREDENTIAL_UNLOCKED);
259ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi            }
2606e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia            mPendingLockCheck = LockPatternChecker.checkPattern(
2616e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia                    mLockPatternUtils,
2626e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia                    pattern,
263ce64cea38389a75def2f3d933a007515af288714Xiyuan Xia                    userId,
2646e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia                    new LockPatternChecker.OnCheckCallback() {
265e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi
266e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi                        @Override
267e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi                        public void onEarlyMatched() {
268ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi                            if (LatencyTracker.isEnabled(mContext)) {
269ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi                                LatencyTracker.getInstance(mContext).onActionEnd(
270ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi                                        ACTION_CHECK_CREDENTIAL);
271ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi                            }
272e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi                            onPatternChecked(userId, true /* matched */, 0 /* timeoutMs */,
273e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi                                    true /* isValidPattern */);
274e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi                        }
275e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi
2766e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia                        @Override
2772397427cb1a0bad8a42e6a342dcf29b31e40a234Andres Morales                        public void onChecked(boolean matched, int timeoutMs) {
278ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi                            if (LatencyTracker.isEnabled(mContext)) {
279ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi                                LatencyTracker.getInstance(mContext).onActionEnd(
280ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi                                        ACTION_CHECK_CREDENTIAL_UNLOCKED);
281ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi                            }
2826e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia                            mLockPatternView.enableInput();
2836e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia                            mPendingLockCheck = null;
284e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi                            if (!matched) {
285e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi                                onPatternChecked(userId, false /* matched */, timeoutMs,
286e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi                                        true /* isValidPattern */);
287e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi                            }
2886e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia                        }
289ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi
290ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi                        @Override
291ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi                        public void onCancelled() {
292ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi                            // We already got dismissed with the early matched callback, so we
293ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi                            // cancelled the check. However, we still need to note down the latency.
294ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi                            if (LatencyTracker.isEnabled(mContext)) {
295ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi                                LatencyTracker.getInstance(mContext).onActionEnd(
296ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi                                        ACTION_CHECK_CREDENTIAL_UNLOCKED);
297ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi                            }
298ed3032b6b89a9ea72c211b0e973e2d0540bdc86dJorim Jaggi                        }
2996e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia                    });
30051e3a672e01d6e9ce4b19ec20d9b62ae8e35fc85Jim Miller            if (pattern.size() > MIN_PATTERN_BEFORE_POKE_WAKELOCK) {
30151e3a672e01d6e9ce4b19ec20d9b62ae8e35fc85Jim Miller                mCallback.userActivity();
30251e3a672e01d6e9ce4b19ec20d9b62ae8e35fc85Jim Miller            }
3036e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia        }
3046e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia
305ce64cea38389a75def2f3d933a007515af288714Xiyuan Xia        private void onPatternChecked(int userId, boolean matched, int timeoutMs,
306ce64cea38389a75def2f3d933a007515af288714Xiyuan Xia                boolean isValidPattern) {
307ce64cea38389a75def2f3d933a007515af288714Xiyuan Xia            boolean dismissKeyguard = KeyguardUpdateMonitor.getCurrentUser() == userId;
3086e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia            if (matched) {
309ce64cea38389a75def2f3d933a007515af288714Xiyuan Xia                mCallback.reportUnlockAttempt(userId, true, 0);
310ce64cea38389a75def2f3d933a007515af288714Xiyuan Xia                if (dismissKeyguard) {
311ce64cea38389a75def2f3d933a007515af288714Xiyuan Xia                    mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Correct);
3128702ca7e2d6a1a66e580d039a1f662cfb94ee4acVadim Tryshev                    mCallback.dismiss(true, userId);
313ce64cea38389a75def2f3d933a007515af288714Xiyuan Xia                }
314dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            } else {
315dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                mLockPatternView.setDisplayMode(LockPatternView.DisplayMode.Wrong);
31651e3a672e01d6e9ce4b19ec20d9b62ae8e35fc85Jim Miller                if (isValidPattern) {
317ce64cea38389a75def2f3d933a007515af288714Xiyuan Xia                    mCallback.reportUnlockAttempt(userId, false, timeoutMs);
31851e3a672e01d6e9ce4b19ec20d9b62ae8e35fc85Jim Miller                    if (timeoutMs > 0) {
31951e3a672e01d6e9ce4b19ec20d9b62ae8e35fc85Jim Miller                        long deadline = mLockPatternUtils.setLockoutAttemptDeadline(
320ce64cea38389a75def2f3d933a007515af288714Xiyuan Xia                                userId, timeoutMs);
32151e3a672e01d6e9ce4b19ec20d9b62ae8e35fc85Jim Miller                        handleAttemptLockout(deadline);
32251e3a672e01d6e9ce4b19ec20d9b62ae8e35fc85Jim Miller                    }
32351e3a672e01d6e9ce4b19ec20d9b62ae8e35fc85Jim Miller                }
32451e3a672e01d6e9ce4b19ec20d9b62ae8e35fc85Jim Miller                if (timeoutMs == 0) {
325db327e9f5976f8f184ae105e672ea4bda4a0af48Adrian Roos                    mSecurityMessageDisplay.setMessage(R.string.kg_wrong_pattern);
326dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                    mLockPatternView.postDelayed(mCancelPatternRunnable, PATTERN_CLEAR_TIMEOUT_MS);
327dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                }
328dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
329dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
330dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
331dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
332dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private void handleAttemptLockout(long elapsedRealtimeDeadline) {
333dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mLockPatternView.clearPattern();
334dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mLockPatternView.setEnabled(false);
335dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        final long elapsedRealtime = SystemClock.elapsedRealtime();
3365be868c590257f6cdccc19770051bf54552216dfHidenari Koshimae        final long secondsInFuture = (long) Math.ceil(
3375be868c590257f6cdccc19770051bf54552216dfHidenari Koshimae                (elapsedRealtimeDeadline - elapsedRealtime) / 1000.0);
3385be868c590257f6cdccc19770051bf54552216dfHidenari Koshimae        mCountdownTimer = new CountDownTimer(secondsInFuture * 1000, 1000) {
339dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
340dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            @Override
341dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            public void onTick(long millisUntilFinished) {
3425be868c590257f6cdccc19770051bf54552216dfHidenari Koshimae                final int secondsRemaining = (int) Math.round(millisUntilFinished / 1000.0);
343e01c5e1afbe319a72e075eb0e57d421b137a2bbbKevin Chyn                mSecurityMessageDisplay.setMessage(mContext.getResources().getQuantityString(
344e01c5e1afbe319a72e075eb0e57d421b137a2bbbKevin Chyn                                R.plurals.kg_too_many_failed_attempts_countdown,
345e01c5e1afbe319a72e075eb0e57d421b137a2bbbKevin Chyn                                secondsRemaining, secondsRemaining));
346dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
347dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
348dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            @Override
349dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            public void onFinish() {
350dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                mLockPatternView.setEnabled(true);
3511625e87e600e8d0752d2f5e1318151a694f1be3eDanielle Millett                displayDefaultSecurityMessage();
352dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
353dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
354dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }.start();
355dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
356dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
357dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
358dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public boolean needsInput() {
359dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        return false;
360dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
361dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
362dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
363dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public void onPause() {
364dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        if (mCountdownTimer != null) {
365dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            mCountdownTimer.cancel();
366dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            mCountdownTimer = null;
367dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
3686e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia        if (mPendingLockCheck != null) {
3696e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia            mPendingLockCheck.cancel(false);
3706e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia            mPendingLockCheck = null;
3716e38058908d6e49a241e384cd7023d9ac0927afbXiyuan Xia        }
372dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
373dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
374dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
375a042ac90640c0c3fd3c5349083b86bbfd6319b64Chris Wren    public void onResume(int reason) {
376dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
377dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
378dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    @Override
379dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    public KeyguardSecurityCallback getCallback() {
380dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        return mCallback;
381dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
382dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
383c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren    @Override
3843122fa85b2f18c0a89f5fe1ef0942c530a271843Selim Cinek    public void showPromptReason(int reason) {
3853122fa85b2f18c0a89f5fe1ef0942c530a271843Selim Cinek        switch (reason) {
3863122fa85b2f18c0a89f5fe1ef0942c530a271843Selim Cinek            case PROMPT_REASON_RESTART:
387db327e9f5976f8f184ae105e672ea4bda4a0af48Adrian Roos                mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_restart_pattern);
3883122fa85b2f18c0a89f5fe1ef0942c530a271843Selim Cinek                break;
38925b4d4b280c6aa07656328bd9dd90977781d00e1Jorim Jaggi            case PROMPT_REASON_TIMEOUT:
390db327e9f5976f8f184ae105e672ea4bda4a0af48Adrian Roos                mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_timeout_pattern);
39125b4d4b280c6aa07656328bd9dd90977781d00e1Jorim Jaggi                break;
392d6d253a5a1e9cd29e1059262206ef9beb8e49fe5Adrian Roos            case PROMPT_REASON_DEVICE_ADMIN:
393db327e9f5976f8f184ae105e672ea4bda4a0af48Adrian Roos                mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_device_admin);
394d6d253a5a1e9cd29e1059262206ef9beb8e49fe5Adrian Roos                break;
395d6d253a5a1e9cd29e1059262206ef9beb8e49fe5Adrian Roos            case PROMPT_REASON_USER_REQUEST:
396db327e9f5976f8f184ae105e672ea4bda4a0af48Adrian Roos                mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_user_request);
397d6d253a5a1e9cd29e1059262206ef9beb8e49fe5Adrian Roos                break;
398c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos            case PROMPT_REASON_NONE:
399c13723f22e476b4558061942c001ee62eaca79e4Adrian Roos                break;
4003122fa85b2f18c0a89f5fe1ef0942c530a271843Selim Cinek            default:
401db327e9f5976f8f184ae105e672ea4bda4a0af48Adrian Roos                mSecurityMessageDisplay.setMessage(R.string.kg_prompt_reason_timeout_pattern);
40225b4d4b280c6aa07656328bd9dd90977781d00e1Jorim Jaggi                break;
4033122fa85b2f18c0a89f5fe1ef0942c530a271843Selim Cinek        }
4043122fa85b2f18c0a89f5fe1ef0942c530a271843Selim Cinek    }
4053122fa85b2f18c0a89f5fe1ef0942c530a271843Selim Cinek
4063122fa85b2f18c0a89f5fe1ef0942c530a271843Selim Cinek    @Override
407c80c67e7bc96691b6e3700bac49e819ad52db0aeLucas Dupin    public void showMessage(CharSequence message, int color) {
408cfafe4ea6ff1610c24d94a9a9ecc7df6b841518cSelim Cinek        mSecurityMessageDisplay.setNextMessageColor(color);
409db327e9f5976f8f184ae105e672ea4bda4a0af48Adrian Roos        mSecurityMessageDisplay.setMessage(message);
410cfafe4ea6ff1610c24d94a9a9ecc7df6b841518cSelim Cinek    }
411cfafe4ea6ff1610c24d94a9a9ecc7df6b841518cSelim Cinek
412cfafe4ea6ff1610c24d94a9a9ecc7df6b841518cSelim Cinek    @Override
413c14f829506a5273e8022b461db2d61038b18ac4bJorim Jaggi    public void startAppearAnimation() {
4143018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        enableClipping(false);
415fb28c0e129896b17e4906b873bf44eb103ac2a8dJorim Jaggi        setAlpha(1f);
41676a1623afc170a13923b68f3256057d8adeb7937Jorim Jaggi        setTranslationY(mAppearAnimationUtils.getStartTranslation());
417613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi        AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */, 500 /* duration */,
418613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                0, mAppearAnimationUtils.getInterpolator());
4195673353559453ecb57fc767b4e7500dd46e44079Jorim Jaggi        mAppearAnimationUtils.startAnimation2d(
4203018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                mLockPatternView.getCellStates(),
4213018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                new Runnable() {
4223018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                    @Override
4233018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                    public void run() {
4243018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                        enableClipping(true);
4253018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                    }
4263018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                },
4273018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                this);
4283122fa85b2f18c0a89f5fe1ef0942c530a271843Selim Cinek        if (!TextUtils.isEmpty(mSecurityMessageDisplay.getText())) {
4293122fa85b2f18c0a89f5fe1ef0942c530a271843Selim Cinek            mAppearAnimationUtils.createAnimation(mSecurityMessageDisplay, 0,
43098f8530af3bb8636b7b173443c90686c485205d6Jorim Jaggi                    AppearAnimationUtils.DEFAULT_APPEAR_DURATION,
4313018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                    mAppearAnimationUtils.getStartTranslation(),
432f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek                    true /* appearing */,
4333018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                    mAppearAnimationUtils.getInterpolator(),
4343018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek                    null /* finishRunnable */);
4353018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        }
4363018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek    }
4373018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek
43876a1623afc170a13923b68f3256057d8adeb7937Jorim Jaggi    @Override
439f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek    public boolean startDisappearAnimation(final Runnable finishRunnable) {
440031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi        float durationMultiplier = mKeyguardUpdateMonitor.needsSlowUnlockTransition()
441031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi                ? DISAPPEAR_MULTIPLIER_LOCKED
442031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi                : 1f;
44376a1623afc170a13923b68f3256057d8adeb7937Jorim Jaggi        mLockPatternView.clearPattern();
444f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek        enableClipping(false);
445f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek        setTranslationY(0);
446e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi        AppearAnimationUtils.startTranslationYAnimation(this, 0 /* delay */,
447e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi                (long) (300 * durationMultiplier),
448613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                -mDisappearAnimationUtils.getStartTranslation(),
449613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                mDisappearAnimationUtils.getInterpolator());
450e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi
451031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi        DisappearAnimationUtils disappearAnimationUtils = mKeyguardUpdateMonitor
452031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi                .needsSlowUnlockTransition()
453031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi                        ? mDisappearAnimationUtilsLocked
454031f79560f65499281bbb500c36e57724d7b514aJorim Jaggi                        : mDisappearAnimationUtils;
455e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi        disappearAnimationUtils.startAnimation2d(mLockPatternView.getCellStates(),
456e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi                () -> {
457e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi                    enableClipping(true);
458e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi                    if (finishRunnable != null) {
459e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi                        finishRunnable.run();
460f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek                    }
461f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek                }, KeyguardPatternView.this);
4623122fa85b2f18c0a89f5fe1ef0942c530a271843Selim Cinek        if (!TextUtils.isEmpty(mSecurityMessageDisplay.getText())) {
4633122fa85b2f18c0a89f5fe1ef0942c530a271843Selim Cinek            mDisappearAnimationUtils.createAnimation(mSecurityMessageDisplay, 0,
464e8fde5d9666eea10307cbc27f4b1a94d3cbb4ec9Jorim Jaggi                    (long) (200 * durationMultiplier),
465f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek                    - mDisappearAnimationUtils.getStartTranslation() * 3,
466f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek                    false /* appearing */,
467f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek                    mDisappearAnimationUtils.getInterpolator(),
468f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek                    null /* finishRunnable */);
469f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek        }
47076a1623afc170a13923b68f3256057d8adeb7937Jorim Jaggi        return true;
47176a1623afc170a13923b68f3256057d8adeb7937Jorim Jaggi    }
47276a1623afc170a13923b68f3256057d8adeb7937Jorim Jaggi
4733018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek    private void enableClipping(boolean enable) {
4743018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        setClipChildren(enable);
4756b88cdfba770efc5722338c240ccaada13d7b0d4Jorim Jaggi        mContainer.setClipToPadding(enable);
4766b88cdfba770efc5722338c240ccaada13d7b0d4Jorim Jaggi        mContainer.setClipChildren(enable);
4773018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek    }
4783018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek
4793018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek    @Override
4803018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek    public void createAnimation(final LockPatternView.CellState animatedCell, long delay,
481f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek            long duration, float translationY, final boolean appearing,
482f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek            Interpolator interpolator,
4833018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek            final Runnable finishListener) {
484613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi        mLockPatternView.startCellStateAnimation(animatedCell,
485613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                1f, appearing ? 1f : 0f, /* alpha */
486613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                appearing ? translationY : 0f, appearing ? 0f : translationY, /* translation */
487613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                appearing ? 0f : 1f, 1f /* scale */,
488613f55fbbb23249d7c65e3f1fe8c943c4459b41aJorim Jaggi                delay, duration, interpolator, finishListener);
4893018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        if (finishListener != null) {
4903018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek            // Also animate the Emergency call
491f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek            mAppearAnimationUtils.createAnimation(mEcaView, delay, duration, translationY,
492f9c0e8f02f3483d6aa9e762c97a2c02ea50eeb02Selim Cinek                    appearing, interpolator, null);
4933018197cf0dff5a9061f6065a8ecc108a0866dabSelim Cinek        }
494c14f829506a5273e8022b461db2d61038b18ac4bJorim Jaggi    }
49576a1623afc170a13923b68f3256057d8adeb7937Jorim Jaggi
49676a1623afc170a13923b68f3256057d8adeb7937Jorim Jaggi    @Override
49776a1623afc170a13923b68f3256057d8adeb7937Jorim Jaggi    public boolean hasOverlappingRendering() {
49876a1623afc170a13923b68f3256057d8adeb7937Jorim Jaggi        return false;
49976a1623afc170a13923b68f3256057d8adeb7937Jorim Jaggi    }
5007d847b037525075cdff92d5e52665d9a9761a8e9Phil Weaver
5017d847b037525075cdff92d5e52665d9a9761a8e9Phil Weaver    @Override
5027d847b037525075cdff92d5e52665d9a9761a8e9Phil Weaver    public CharSequence getTitle() {
5037d847b037525075cdff92d5e52665d9a9761a8e9Phil Weaver        return getContext().getString(
5047d847b037525075cdff92d5e52665d9a9761a8e9Phil Weaver                com.android.internal.R.string.keyguard_accessibility_pattern_unlock);
5057d847b037525075cdff92d5e52665d9a9761a8e9Phil Weaver    }
506c0ae9e67ebe6f1298800feaed1b43e867139a904Chris Wren}
507