127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi/*
227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi * Copyright (C) 2015 The Android Open Source Project
327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi *
427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi * Licensed under the Apache License, Version 2.0 (the "License");
527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi * you may not use this file except in compliance with the License.
627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi * You may obtain a copy of the License at
727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi *
827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi *      http://www.apache.org/licenses/LICENSE-2.0
927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi *
1027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi * Unless required by applicable law or agreed to in writing, software
1127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi * distributed under the License is distributed on an "AS IS" BASIS,
1227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi * See the License for the specific language governing permissions and
1427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi * limitations under the License
1527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi */
1627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
1727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggipackage com.android.systemui.statusbar.phone;
1827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
1927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggiimport android.content.Context;
206ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinekimport android.content.res.Configuration;
2127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggiimport android.graphics.drawable.AnimatedVectorDrawable;
2227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggiimport android.graphics.drawable.Drawable;
2327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggiimport android.graphics.drawable.InsetDrawable;
2427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggiimport android.util.AttributeSet;
2527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggiimport android.view.View;
26c99d9a95643c514ee0a671f023359931df443077Selim Cinekimport android.view.accessibility.AccessibilityNodeInfo;
2727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
2827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggiimport com.android.keyguard.KeyguardUpdateMonitor;
2927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggiimport com.android.systemui.R;
3027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggiimport com.android.systemui.statusbar.KeyguardAffordanceView;
3127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggiimport com.android.systemui.statusbar.policy.AccessibilityController;
3227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
3327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi/**
3427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi * Manages the different states and animations of the unlock icon.
3527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi */
3627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggipublic class LockIcon extends KeyguardAffordanceView {
3727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
38f6103695f8870941c27a940b7438e4ff1e49cbe9Jorim Jaggi    private static final int FP_DRAW_OFF_TIMEOUT = 800;
39f6103695f8870941c27a940b7438e4ff1e49cbe9Jorim Jaggi
4027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private static final int STATE_LOCKED = 0;
4127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private static final int STATE_LOCK_OPEN = 1;
4227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private static final int STATE_FACE_UNLOCK = 2;
4327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private static final int STATE_FINGERPRINT = 3;
4427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private static final int STATE_FINGERPRINT_ERROR = 4;
4527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
4627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private int mLastState = 0;
470d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi    private boolean mLastDeviceInteractive;
4827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private boolean mTransientFpError;
490d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi    private boolean mDeviceInteractive;
50f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi    private boolean mScreenOn;
51f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi    private boolean mLastScreenOn;
526ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek    private TrustDrawable mTrustDrawable;
5327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private final UnlockMethodCache mUnlockMethodCache;
5427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private AccessibilityController mAccessibilityController;
55c99d9a95643c514ee0a671f023359931df443077Selim Cinek    private boolean mHasFingerPrintIcon;
566ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek    private int mDensity;
5727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
58f6103695f8870941c27a940b7438e4ff1e49cbe9Jorim Jaggi    private final Runnable mDrawOffTimeout = () -> update(true /* forceUpdate */);
59f6103695f8870941c27a940b7438e4ff1e49cbe9Jorim Jaggi
60582b57f984a3ed87265ff5724b35349224605ac9Jorim Jaggi    public LockIcon(Context context, AttributeSet attrs) {
6127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        super(context, attrs);
6227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        mTrustDrawable = new TrustDrawable(context);
6327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        setBackground(mTrustDrawable);
6427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        mUnlockMethodCache = UnlockMethodCache.getInstance(context);
6527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
6627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
6727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    @Override
68582b57f984a3ed87265ff5724b35349224605ac9Jorim Jaggi    protected void onVisibilityChanged(View changedView, int visibility) {
6927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        super.onVisibilityChanged(changedView, visibility);
7027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        if (isShown()) {
7127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            mTrustDrawable.start();
7227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        } else {
7327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            mTrustDrawable.stop();
7427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        }
7527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
7627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
7727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    @Override
7827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    protected void onDetachedFromWindow() {
7927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        super.onDetachedFromWindow();
8027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        mTrustDrawable.stop();
8127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
8227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
8327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    public void setTransientFpError(boolean transientFpError) {
8427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        mTransientFpError = transientFpError;
8527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        update();
8627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
8727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
880d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi    public void setDeviceInteractive(boolean deviceInteractive) {
890d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi        mDeviceInteractive = deviceInteractive;
90864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi        update();
91864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi    }
92864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi
93f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi    public void setScreenOn(boolean screenOn) {
94f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi        mScreenOn = screenOn;
95f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi        update();
96f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi    }
97f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi
986ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek    @Override
996ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek    protected void onConfigurationChanged(Configuration newConfig) {
1006ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek        super.onConfigurationChanged(newConfig);
1016ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek        final int density = newConfig.densityDpi;
1026ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek        if (density != mDensity) {
1036ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek            mDensity = density;
1046ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek            mTrustDrawable.stop();
1056ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek            mTrustDrawable = new TrustDrawable(getContext());
1066ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek            setBackground(mTrustDrawable);
1076ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek            update();
1086ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek        }
1096ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek    }
1106ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek
11127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    public void update() {
1126ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek        update(false /* force */);
1136ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek    }
1146ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek
1156ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek    public void update(boolean force) {
1160d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi        boolean visible = isShown()
1170d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi                && KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive();
11827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        if (visible) {
11927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            mTrustDrawable.start();
12027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        } else {
12127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            mTrustDrawable.stop();
12227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        }
12327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        int state = getState();
12427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        boolean anyFingerprintIcon = state == STATE_FINGERPRINT || state == STATE_FINGERPRINT_ERROR;
125c384198529870946249a79166fd0a42c1823bf09Selim Cinek        boolean useAdditionalPadding = anyFingerprintIcon;
126c384198529870946249a79166fd0a42c1823bf09Selim Cinek        boolean trustHidden = anyFingerprintIcon;
127f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi        if (state != mLastState || mDeviceInteractive != mLastDeviceInteractive
1286ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek                || mScreenOn != mLastScreenOn || force) {
129f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi            boolean isAnim = true;
1300d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi            int iconRes = getAnimationResForTransition(mLastState, state, mLastDeviceInteractive,
131f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                    mDeviceInteractive, mLastScreenOn, mScreenOn);
132864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi            if (iconRes == R.drawable.lockscreen_fingerprint_draw_off_animation) {
133864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi                anyFingerprintIcon = true;
134c384198529870946249a79166fd0a42c1823bf09Selim Cinek                useAdditionalPadding = true;
135c384198529870946249a79166fd0a42c1823bf09Selim Cinek                trustHidden = true;
136c384198529870946249a79166fd0a42c1823bf09Selim Cinek            } else if (iconRes == R.drawable.trusted_state_to_error_animation) {
137c384198529870946249a79166fd0a42c1823bf09Selim Cinek                anyFingerprintIcon = true;
138c384198529870946249a79166fd0a42c1823bf09Selim Cinek                useAdditionalPadding = false;
139c384198529870946249a79166fd0a42c1823bf09Selim Cinek                trustHidden = true;
140c384198529870946249a79166fd0a42c1823bf09Selim Cinek            } else if (iconRes == R.drawable.error_to_trustedstate_animation) {
141c384198529870946249a79166fd0a42c1823bf09Selim Cinek                anyFingerprintIcon = true;
142c384198529870946249a79166fd0a42c1823bf09Selim Cinek                useAdditionalPadding = false;
143c384198529870946249a79166fd0a42c1823bf09Selim Cinek                trustHidden = false;
144864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi            }
14527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            if (iconRes == -1) {
146f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                iconRes = getIconForState(state, mScreenOn, mDeviceInteractive);
147f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                isAnim = false;
14827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            }
14927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            Drawable icon = mContext.getDrawable(iconRes);
150864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi            final AnimatedVectorDrawable animation = icon instanceof AnimatedVectorDrawable
151864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi                    ? (AnimatedVectorDrawable) icon
152864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi                    : null;
15327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            int iconHeight = getResources().getDimensionPixelSize(
15427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                    R.dimen.keyguard_affordance_icon_height);
15527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            int iconWidth = getResources().getDimensionPixelSize(
15627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                    R.dimen.keyguard_affordance_icon_width);
15727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            if (!anyFingerprintIcon && (icon.getIntrinsicHeight() != iconHeight
15827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                    || icon.getIntrinsicWidth() != iconWidth)) {
15927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                icon = new IntrinsicSizeDrawable(icon, iconWidth, iconHeight);
16027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            }
161c384198529870946249a79166fd0a42c1823bf09Selim Cinek            setPaddingRelative(0, 0, 0, useAdditionalPadding
16227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                    ? getResources().getDimensionPixelSize(
16327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                    R.dimen.fingerprint_icon_additional_padding)
16427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                    : 0);
16527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            setRestingAlpha(
16627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                    anyFingerprintIcon ? 1f : KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT);
16727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            setImageDrawable(icon);
168c99d9a95643c514ee0a671f023359931df443077Selim Cinek            String contentDescription = getResources().getString(anyFingerprintIcon
169c99d9a95643c514ee0a671f023359931df443077Selim Cinek                    ? R.string.accessibility_unlock_button_fingerprint
170c99d9a95643c514ee0a671f023359931df443077Selim Cinek                    : R.string.accessibility_unlock_button);
171c99d9a95643c514ee0a671f023359931df443077Selim Cinek            setContentDescription(contentDescription);
172c99d9a95643c514ee0a671f023359931df443077Selim Cinek            mHasFingerPrintIcon = anyFingerprintIcon;
173f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi            if (animation != null && isAnim) {
17423bb84b03eb8d5a1bc6e170dbea78680d9d74c82Jorim Jaggi                animation.forceAnimationOnUI();
175f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                animation.start();
17627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            }
177f6103695f8870941c27a940b7438e4ff1e49cbe9Jorim Jaggi
178f6103695f8870941c27a940b7438e4ff1e49cbe9Jorim Jaggi            if (iconRes == R.drawable.lockscreen_fingerprint_draw_off_animation) {
179f6103695f8870941c27a940b7438e4ff1e49cbe9Jorim Jaggi                removeCallbacks(mDrawOffTimeout);
180f6103695f8870941c27a940b7438e4ff1e49cbe9Jorim Jaggi                postDelayed(mDrawOffTimeout, FP_DRAW_OFF_TIMEOUT);
181f6103695f8870941c27a940b7438e4ff1e49cbe9Jorim Jaggi            } else {
182f6103695f8870941c27a940b7438e4ff1e49cbe9Jorim Jaggi                removeCallbacks(mDrawOffTimeout);
183f6103695f8870941c27a940b7438e4ff1e49cbe9Jorim Jaggi            }
184f6103695f8870941c27a940b7438e4ff1e49cbe9Jorim Jaggi
185864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi            mLastState = state;
1860d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi            mLastDeviceInteractive = mDeviceInteractive;
187f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi            mLastScreenOn = mScreenOn;
18827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        }
18927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
19027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        // Hide trust circle when fingerprint is running.
191c384198529870946249a79166fd0a42c1823bf09Selim Cinek        boolean trustManaged = mUnlockMethodCache.isTrustManaged() && !trustHidden;
19227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        mTrustDrawable.setTrustManaged(trustManaged);
19327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        updateClickability();
19427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
19527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
19627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private void updateClickability() {
19727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        if (mAccessibilityController == null) {
19827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            return;
19927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        }
20027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        boolean clickToUnlock = mAccessibilityController.isTouchExplorationEnabled();
20116093fe3f0d824731a53a264a132504deb08421aJorim Jaggi        boolean clickToForceLock = mUnlockMethodCache.isTrustManaged()
20227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                && !mAccessibilityController.isAccessibilityEnabled();
20316093fe3f0d824731a53a264a132504deb08421aJorim Jaggi        boolean longClickToForceLock = mUnlockMethodCache.isTrustManaged()
20427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                && !clickToForceLock;
20527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        setClickable(clickToForceLock || clickToUnlock);
20627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        setLongClickable(longClickToForceLock);
20727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        setFocusable(mAccessibilityController.isAccessibilityEnabled());
20827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
20927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
210c99d9a95643c514ee0a671f023359931df443077Selim Cinek    @Override
211c99d9a95643c514ee0a671f023359931df443077Selim Cinek    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
212c99d9a95643c514ee0a671f023359931df443077Selim Cinek        super.onInitializeAccessibilityNodeInfo(info);
213c99d9a95643c514ee0a671f023359931df443077Selim Cinek        if (mHasFingerPrintIcon) {
214c99d9a95643c514ee0a671f023359931df443077Selim Cinek            // Avoid that the button description is also spoken
215c99d9a95643c514ee0a671f023359931df443077Selim Cinek            info.setClassName(LockIcon.class.getName());
216c99d9a95643c514ee0a671f023359931df443077Selim Cinek            AccessibilityNodeInfo.AccessibilityAction unlock
217c99d9a95643c514ee0a671f023359931df443077Selim Cinek                    = new AccessibilityNodeInfo.AccessibilityAction(
218c99d9a95643c514ee0a671f023359931df443077Selim Cinek                    AccessibilityNodeInfo.ACTION_CLICK,
219c99d9a95643c514ee0a671f023359931df443077Selim Cinek                    getContext().getString(R.string.accessibility_unlock_without_fingerprint));
220c99d9a95643c514ee0a671f023359931df443077Selim Cinek            info.addAction(unlock);
221c99d9a95643c514ee0a671f023359931df443077Selim Cinek        }
222c99d9a95643c514ee0a671f023359931df443077Selim Cinek    }
223c99d9a95643c514ee0a671f023359931df443077Selim Cinek
22427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    public void setAccessibilityController(AccessibilityController accessibilityController) {
22527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        mAccessibilityController = accessibilityController;
22627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
22727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
228f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi    private int getIconForState(int state, boolean screenOn, boolean deviceInteractive) {
22927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        switch (state) {
23027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            case STATE_LOCKED:
23127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                return R.drawable.ic_lock_24dp;
23227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            case STATE_LOCK_OPEN:
23327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                return R.drawable.ic_lock_open_24dp;
23427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            case STATE_FACE_UNLOCK:
23527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                return com.android.internal.R.drawable.ic_account_circle;
23627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            case STATE_FINGERPRINT:
237f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                // If screen is off and device asleep, use the draw on animation so the first frame
238f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                // gets drawn.
239f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                return screenOn && deviceInteractive
240f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                        ? R.drawable.ic_fingerprint
241f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                        : R.drawable.lockscreen_fingerprint_draw_on_animation;
24227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            case STATE_FINGERPRINT_ERROR:
24327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                return R.drawable.ic_fingerprint_error;
24427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            default:
24527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                throw new IllegalArgumentException();
24627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        }
24727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
24827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
249f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi    private int getAnimationResForTransition(int oldState, int newState,
250f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi            boolean oldDeviceInteractive, boolean deviceInteractive,
251f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi            boolean oldScreenOn, boolean screenOn) {
25227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        if (oldState == STATE_FINGERPRINT && newState == STATE_FINGERPRINT_ERROR) {
253864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi            return R.drawable.lockscreen_fingerprint_fp_to_error_state_animation;
254c384198529870946249a79166fd0a42c1823bf09Selim Cinek        } else if (oldState == STATE_LOCK_OPEN && newState == STATE_FINGERPRINT_ERROR) {
255c384198529870946249a79166fd0a42c1823bf09Selim Cinek            return R.drawable.trusted_state_to_error_animation;
256c384198529870946249a79166fd0a42c1823bf09Selim Cinek        } else if (oldState == STATE_FINGERPRINT_ERROR && newState == STATE_LOCK_OPEN) {
257c384198529870946249a79166fd0a42c1823bf09Selim Cinek            return R.drawable.error_to_trustedstate_animation;
258864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi        } else if (oldState == STATE_FINGERPRINT_ERROR && newState == STATE_FINGERPRINT) {
259864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi            return R.drawable.lockscreen_fingerprint_error_state_to_fp_animation;
2602a46d6857172e6f9dfedb150f7eda8dba65eaf91Selim Cinek        } else if (oldState == STATE_FINGERPRINT && newState == STATE_LOCK_OPEN
261e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek                && !mUnlockMethodCache.isTrusted()) {
262864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi            return R.drawable.lockscreen_fingerprint_draw_off_animation;
263f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi        } else if (newState == STATE_FINGERPRINT && (!oldScreenOn && screenOn && deviceInteractive
264f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                || screenOn && !oldDeviceInteractive && deviceInteractive)) {
265864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi            return R.drawable.lockscreen_fingerprint_draw_on_animation;
26627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        } else {
26727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            return -1;
26827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        }
26927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
27027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
27127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private int getState() {
2721fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek        KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
2731fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek        boolean fingerprintRunning = updateMonitor.isFingerprintDetectionRunning();
2741fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek        boolean unlockingAllowed = updateMonitor.isUnlockingWithFingerprintAllowed();
275c384198529870946249a79166fd0a42c1823bf09Selim Cinek        if (mTransientFpError) {
27627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            return STATE_FINGERPRINT_ERROR;
277c384198529870946249a79166fd0a42c1823bf09Selim Cinek        } else if (mUnlockMethodCache.canSkipBouncer()) {
278c384198529870946249a79166fd0a42c1823bf09Selim Cinek            return STATE_LOCK_OPEN;
27927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        } else if (mUnlockMethodCache.isFaceUnlockRunning()) {
28027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            return STATE_FACE_UNLOCK;
281e07cbaf53c545fc7176cebfe14096cabb677798aAdrian Roos        } else if (fingerprintRunning && unlockingAllowed) {
282e07cbaf53c545fc7176cebfe14096cabb677798aAdrian Roos            return STATE_FINGERPRINT;
28327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        } else {
28427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            return STATE_LOCKED;
28527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        }
28627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
28727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
28827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    /**
28927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi     * A wrapper around another Drawable that overrides the intrinsic size.
29027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi     */
29127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private static class IntrinsicSizeDrawable extends InsetDrawable {
29227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
29327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        private final int mIntrinsicWidth;
29427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        private final int mIntrinsicHeight;
29527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
29627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        public IntrinsicSizeDrawable(Drawable drawable, int intrinsicWidth, int intrinsicHeight) {
29727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            super(drawable, 0);
29827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            mIntrinsicWidth = intrinsicWidth;
29927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            mIntrinsicHeight = intrinsicHeight;
30027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        }
30127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
30227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        @Override
30327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        public int getIntrinsicWidth() {
30427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            return mIntrinsicWidth;
30527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        }
30627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
30727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        @Override
30827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        public int getIntrinsicHeight() {
30927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            return mIntrinsicHeight;
31027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        }
31127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
31227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi}
313