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;
32f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbalimport com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener;
3327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
3427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi/**
3527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi * Manages the different states and animations of the unlock icon.
3627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi */
37f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbalpublic class LockIcon extends KeyguardAffordanceView implements OnUserInfoChangedListener {
3827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
398dea48c87e2f3792732533ed4a28bb724f8106a7Jorim Jaggi    private static final int FP_DRAW_OFF_TIMEOUT = 800;
408dea48c87e2f3792732533ed4a28bb724f8106a7Jorim Jaggi
4127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private static final int STATE_LOCKED = 0;
4227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private static final int STATE_LOCK_OPEN = 1;
4327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private static final int STATE_FACE_UNLOCK = 2;
4427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private static final int STATE_FINGERPRINT = 3;
4527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private static final int STATE_FINGERPRINT_ERROR = 4;
4627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
4727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private int mLastState = 0;
480d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi    private boolean mLastDeviceInteractive;
4927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private boolean mTransientFpError;
500d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi    private boolean mDeviceInteractive;
51f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi    private boolean mScreenOn;
52f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi    private boolean mLastScreenOn;
53f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal    private Drawable mUserAvatarIcon;
546ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek    private TrustDrawable mTrustDrawable;
5527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private final UnlockMethodCache mUnlockMethodCache;
5627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private AccessibilityController mAccessibilityController;
57c99d9a95643c514ee0a671f023359931df443077Selim Cinek    private boolean mHasFingerPrintIcon;
58bfe6dcf3fc7e531e0634b96dadea73830a75ba30Bingyu Zhang    private boolean mHasFaceUnlockIcon;
596ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek    private int mDensity;
6027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
618dea48c87e2f3792732533ed4a28bb724f8106a7Jorim Jaggi    private final Runnable mDrawOffTimeout = () -> update(true /* forceUpdate */);
628dea48c87e2f3792732533ed4a28bb724f8106a7Jorim Jaggi
63582b57f984a3ed87265ff5724b35349224605ac9Jorim Jaggi    public LockIcon(Context context, AttributeSet attrs) {
6427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        super(context, attrs);
6527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        mTrustDrawable = new TrustDrawable(context);
6627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        setBackground(mTrustDrawable);
6727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        mUnlockMethodCache = UnlockMethodCache.getInstance(context);
6827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
6927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
7027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    @Override
71582b57f984a3ed87265ff5724b35349224605ac9Jorim Jaggi    protected void onVisibilityChanged(View changedView, int visibility) {
7227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        super.onVisibilityChanged(changedView, visibility);
7327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        if (isShown()) {
7427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            mTrustDrawable.start();
7527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        } else {
7627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            mTrustDrawable.stop();
7727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        }
7827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
7927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
8027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    @Override
8127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    protected void onDetachedFromWindow() {
8227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        super.onDetachedFromWindow();
8327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        mTrustDrawable.stop();
8427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
8527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
86f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal    @Override
87f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal    public void onUserInfoChanged(String name, Drawable picture, String userAccount) {
88f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal        mUserAvatarIcon = picture;
89f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal        update();
90f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal    }
91f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal
9227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    public void setTransientFpError(boolean transientFpError) {
9327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        mTransientFpError = transientFpError;
9427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        update();
9527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
9627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
970d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi    public void setDeviceInteractive(boolean deviceInteractive) {
980d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi        mDeviceInteractive = deviceInteractive;
99864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi        update();
100864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi    }
101864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi
102f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi    public void setScreenOn(boolean screenOn) {
103f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi        mScreenOn = screenOn;
104f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi        update();
105f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi    }
106f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi
1076ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek    @Override
1086ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek    protected void onConfigurationChanged(Configuration newConfig) {
1096ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek        super.onConfigurationChanged(newConfig);
1106ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek        final int density = newConfig.densityDpi;
1116ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek        if (density != mDensity) {
1126ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek            mDensity = density;
1136ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek            mTrustDrawable.stop();
1146ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek            mTrustDrawable = new TrustDrawable(getContext());
1156ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek            setBackground(mTrustDrawable);
1166ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek            update();
1176ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek        }
1186ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek    }
1196ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek
12027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    public void update() {
1216ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek        update(false /* force */);
1226ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek    }
1236ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek
1246ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek    public void update(boolean force) {
1250d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi        boolean visible = isShown()
1260d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi                && KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive();
12727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        if (visible) {
12827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            mTrustDrawable.start();
12927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        } else {
13027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            mTrustDrawable.stop();
13127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        }
13227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        int state = getState();
13327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        boolean anyFingerprintIcon = state == STATE_FINGERPRINT || state == STATE_FINGERPRINT_ERROR;
134bfe6dcf3fc7e531e0634b96dadea73830a75ba30Bingyu Zhang        mHasFaceUnlockIcon = state == STATE_FACE_UNLOCK;
135c384198529870946249a79166fd0a42c1823bf09Selim Cinek        boolean useAdditionalPadding = anyFingerprintIcon;
136c384198529870946249a79166fd0a42c1823bf09Selim Cinek        boolean trustHidden = anyFingerprintIcon;
137f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi        if (state != mLastState || mDeviceInteractive != mLastDeviceInteractive
1386ebba59aadb287105d4a4bdbf7d1c7851f4fe210Selim Cinek                || mScreenOn != mLastScreenOn || force) {
139f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal            int iconAnimRes =
140f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal                getAnimationResForTransition(mLastState, state, mLastDeviceInteractive,
141f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                    mDeviceInteractive, mLastScreenOn, mScreenOn);
142f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal            boolean isAnim = iconAnimRes != -1;
143f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal            if (iconAnimRes == R.drawable.lockscreen_fingerprint_draw_off_animation) {
144864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi                anyFingerprintIcon = true;
145c384198529870946249a79166fd0a42c1823bf09Selim Cinek                useAdditionalPadding = true;
146c384198529870946249a79166fd0a42c1823bf09Selim Cinek                trustHidden = true;
147f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal            } else if (iconAnimRes == R.drawable.trusted_state_to_error_animation) {
148c384198529870946249a79166fd0a42c1823bf09Selim Cinek                anyFingerprintIcon = true;
149c384198529870946249a79166fd0a42c1823bf09Selim Cinek                useAdditionalPadding = false;
150c384198529870946249a79166fd0a42c1823bf09Selim Cinek                trustHidden = true;
151f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal            } else if (iconAnimRes == R.drawable.error_to_trustedstate_animation) {
152c384198529870946249a79166fd0a42c1823bf09Selim Cinek                anyFingerprintIcon = true;
153c384198529870946249a79166fd0a42c1823bf09Selim Cinek                useAdditionalPadding = false;
154c384198529870946249a79166fd0a42c1823bf09Selim Cinek                trustHidden = false;
155864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi            }
156f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal
157f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal            Drawable icon;
158f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal            if (isAnim) {
159f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal                // Load the animation resource.
160f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal                icon = mContext.getDrawable(iconAnimRes);
161f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal            } else {
162f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal                // Load the static icon resource based on the current state.
163f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal                icon = getIconForState(state, mScreenOn, mDeviceInteractive);
16427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            }
165f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal
166864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi            final AnimatedVectorDrawable animation = icon instanceof AnimatedVectorDrawable
167864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi                    ? (AnimatedVectorDrawable) icon
168864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi                    : null;
16927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            int iconHeight = getResources().getDimensionPixelSize(
17027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                    R.dimen.keyguard_affordance_icon_height);
17127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            int iconWidth = getResources().getDimensionPixelSize(
17227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                    R.dimen.keyguard_affordance_icon_width);
17327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            if (!anyFingerprintIcon && (icon.getIntrinsicHeight() != iconHeight
17427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                    || icon.getIntrinsicWidth() != iconWidth)) {
17527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                icon = new IntrinsicSizeDrawable(icon, iconWidth, iconHeight);
17627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            }
177c384198529870946249a79166fd0a42c1823bf09Selim Cinek            setPaddingRelative(0, 0, 0, useAdditionalPadding
17827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                    ? getResources().getDimensionPixelSize(
17927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                    R.dimen.fingerprint_icon_additional_padding)
18027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                    : 0);
18127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            setRestingAlpha(
18227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                    anyFingerprintIcon ? 1f : KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT);
183b0ddf871309621af3a40308031b1e84555add392Evan Laird            setImageDrawable(icon, false);
184bfe6dcf3fc7e531e0634b96dadea73830a75ba30Bingyu Zhang            if (mHasFaceUnlockIcon) {
185bfe6dcf3fc7e531e0634b96dadea73830a75ba30Bingyu Zhang                announceForAccessibility(getContext().getString(
186bfe6dcf3fc7e531e0634b96dadea73830a75ba30Bingyu Zhang                    R.string.accessibility_scanning_face));
187bfe6dcf3fc7e531e0634b96dadea73830a75ba30Bingyu Zhang            }
188bfe6dcf3fc7e531e0634b96dadea73830a75ba30Bingyu Zhang
189c99d9a95643c514ee0a671f023359931df443077Selim Cinek            mHasFingerPrintIcon = anyFingerprintIcon;
190f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi            if (animation != null && isAnim) {
19123bb84b03eb8d5a1bc6e170dbea78680d9d74c82Jorim Jaggi                animation.forceAnimationOnUI();
192f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                animation.start();
19327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            }
1948dea48c87e2f3792732533ed4a28bb724f8106a7Jorim Jaggi
195f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal            if (iconAnimRes == R.drawable.lockscreen_fingerprint_draw_off_animation) {
1968dea48c87e2f3792732533ed4a28bb724f8106a7Jorim Jaggi                removeCallbacks(mDrawOffTimeout);
1978dea48c87e2f3792732533ed4a28bb724f8106a7Jorim Jaggi                postDelayed(mDrawOffTimeout, FP_DRAW_OFF_TIMEOUT);
1988dea48c87e2f3792732533ed4a28bb724f8106a7Jorim Jaggi            } else {
1998dea48c87e2f3792732533ed4a28bb724f8106a7Jorim Jaggi                removeCallbacks(mDrawOffTimeout);
2008dea48c87e2f3792732533ed4a28bb724f8106a7Jorim Jaggi            }
2018dea48c87e2f3792732533ed4a28bb724f8106a7Jorim Jaggi
202864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi            mLastState = state;
2030d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi            mLastDeviceInteractive = mDeviceInteractive;
204f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi            mLastScreenOn = mScreenOn;
20527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        }
20627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
20727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        // Hide trust circle when fingerprint is running.
208c384198529870946249a79166fd0a42c1823bf09Selim Cinek        boolean trustManaged = mUnlockMethodCache.isTrustManaged() && !trustHidden;
20927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        mTrustDrawable.setTrustManaged(trustManaged);
21027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        updateClickability();
21127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
21227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
21327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private void updateClickability() {
21427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        if (mAccessibilityController == null) {
21527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            return;
21627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        }
217a94e9648ae9c958d850043e7805dcadfb5acd700Adrian Roos        boolean clickToUnlock = mAccessibilityController.isAccessibilityEnabled();
21816093fe3f0d824731a53a264a132504deb08421aJorim Jaggi        boolean clickToForceLock = mUnlockMethodCache.isTrustManaged()
219a94e9648ae9c958d850043e7805dcadfb5acd700Adrian Roos                && !clickToUnlock;
22016093fe3f0d824731a53a264a132504deb08421aJorim Jaggi        boolean longClickToForceLock = mUnlockMethodCache.isTrustManaged()
22127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                && !clickToForceLock;
22227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        setClickable(clickToForceLock || clickToUnlock);
22327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        setLongClickable(longClickToForceLock);
22427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        setFocusable(mAccessibilityController.isAccessibilityEnabled());
22527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
22627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
227c99d9a95643c514ee0a671f023359931df443077Selim Cinek    @Override
228c99d9a95643c514ee0a671f023359931df443077Selim Cinek    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
229c99d9a95643c514ee0a671f023359931df443077Selim Cinek        super.onInitializeAccessibilityNodeInfo(info);
230c99d9a95643c514ee0a671f023359931df443077Selim Cinek        if (mHasFingerPrintIcon) {
231c99d9a95643c514ee0a671f023359931df443077Selim Cinek            AccessibilityNodeInfo.AccessibilityAction unlock
232c99d9a95643c514ee0a671f023359931df443077Selim Cinek                    = new AccessibilityNodeInfo.AccessibilityAction(
233c99d9a95643c514ee0a671f023359931df443077Selim Cinek                    AccessibilityNodeInfo.ACTION_CLICK,
234c99d9a95643c514ee0a671f023359931df443077Selim Cinek                    getContext().getString(R.string.accessibility_unlock_without_fingerprint));
235c99d9a95643c514ee0a671f023359931df443077Selim Cinek            info.addAction(unlock);
236947c77cb821fd99f95a62ad99924780b2163dbd7Selim Cinek            info.setHintText(getContext().getString(
237947c77cb821fd99f95a62ad99924780b2163dbd7Selim Cinek                    R.string.accessibility_waiting_for_fingerprint));
238bfe6dcf3fc7e531e0634b96dadea73830a75ba30Bingyu Zhang        } else if (mHasFaceUnlockIcon){
239bfe6dcf3fc7e531e0634b96dadea73830a75ba30Bingyu Zhang            //Avoid 'button' to be spoken for scanning face
240bfe6dcf3fc7e531e0634b96dadea73830a75ba30Bingyu Zhang            info.setClassName(LockIcon.class.getName());
241bfe6dcf3fc7e531e0634b96dadea73830a75ba30Bingyu Zhang            info.setContentDescription(getContext().getString(
242bfe6dcf3fc7e531e0634b96dadea73830a75ba30Bingyu Zhang                R.string.accessibility_scanning_face));
243c99d9a95643c514ee0a671f023359931df443077Selim Cinek        }
244c99d9a95643c514ee0a671f023359931df443077Selim Cinek    }
245c99d9a95643c514ee0a671f023359931df443077Selim Cinek
24627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    public void setAccessibilityController(AccessibilityController accessibilityController) {
24727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        mAccessibilityController = accessibilityController;
24827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
24927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
250f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal    private Drawable getIconForState(int state, boolean screenOn, boolean deviceInteractive) {
251f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal        int iconRes;
25227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        switch (state) {
25327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            case STATE_LOCKED:
254f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal                iconRes = R.drawable.ic_lock_24dp;
255f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal                break;
25627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            case STATE_LOCK_OPEN:
257f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal                if (mUnlockMethodCache.isTrustManaged() && mUnlockMethodCache.isTrusted()
258f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal                    && mUserAvatarIcon != null) {
259f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal                    return mUserAvatarIcon;
260f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal                } else {
261f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal                    iconRes = R.drawable.ic_lock_open_24dp;
262f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal                }
263f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal                break;
26427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            case STATE_FACE_UNLOCK:
265334f95471473f6871cb19b6121d122a5557a85d8Lucas Dupin                iconRes = R.drawable.ic_face_unlock;
266f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal                break;
26727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            case STATE_FINGERPRINT:
268f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                // If screen is off and device asleep, use the draw on animation so the first frame
269f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                // gets drawn.
270f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal                iconRes = screenOn && deviceInteractive
271f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                        ? R.drawable.ic_fingerprint
272f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                        : R.drawable.lockscreen_fingerprint_draw_on_animation;
273f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal                break;
27427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            case STATE_FINGERPRINT_ERROR:
275f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal                iconRes = R.drawable.ic_fingerprint_error;
276f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal                break;
27727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            default:
27827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi                throw new IllegalArgumentException();
27927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        }
280f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal
281f50284c60a2d7d1121766d684bce34090cdf10cfZachary Iqbal        return mContext.getDrawable(iconRes);
28227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
28327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
284f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi    private int getAnimationResForTransition(int oldState, int newState,
285f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi            boolean oldDeviceInteractive, boolean deviceInteractive,
286f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi            boolean oldScreenOn, boolean screenOn) {
28727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        if (oldState == STATE_FINGERPRINT && newState == STATE_FINGERPRINT_ERROR) {
288864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi            return R.drawable.lockscreen_fingerprint_fp_to_error_state_animation;
289c384198529870946249a79166fd0a42c1823bf09Selim Cinek        } else if (oldState == STATE_LOCK_OPEN && newState == STATE_FINGERPRINT_ERROR) {
290c384198529870946249a79166fd0a42c1823bf09Selim Cinek            return R.drawable.trusted_state_to_error_animation;
291c384198529870946249a79166fd0a42c1823bf09Selim Cinek        } else if (oldState == STATE_FINGERPRINT_ERROR && newState == STATE_LOCK_OPEN) {
292c384198529870946249a79166fd0a42c1823bf09Selim Cinek            return R.drawable.error_to_trustedstate_animation;
293864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi        } else if (oldState == STATE_FINGERPRINT_ERROR && newState == STATE_FINGERPRINT) {
294864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi            return R.drawable.lockscreen_fingerprint_error_state_to_fp_animation;
2952a46d6857172e6f9dfedb150f7eda8dba65eaf91Selim Cinek        } else if (oldState == STATE_FINGERPRINT && newState == STATE_LOCK_OPEN
296e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek                && !mUnlockMethodCache.isTrusted()) {
297864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi            return R.drawable.lockscreen_fingerprint_draw_off_animation;
298f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi        } else if (newState == STATE_FINGERPRINT && (!oldScreenOn && screenOn && deviceInteractive
299f1518da4512dcf350fd808a5288634f534bca1bbJorim Jaggi                || screenOn && !oldDeviceInteractive && deviceInteractive)) {
300864e64bacee1d09b60c1c8741b7195cf6ce7aa22Jorim Jaggi            return R.drawable.lockscreen_fingerprint_draw_on_animation;
30127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        } else {
30227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            return -1;
30327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        }
30427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
30527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
30627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private int getState() {
3071fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek        KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
3081fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek        boolean fingerprintRunning = updateMonitor.isFingerprintDetectionRunning();
3091fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek        boolean unlockingAllowed = updateMonitor.isUnlockingWithFingerprintAllowed();
310c384198529870946249a79166fd0a42c1823bf09Selim Cinek        if (mTransientFpError) {
31127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            return STATE_FINGERPRINT_ERROR;
312c384198529870946249a79166fd0a42c1823bf09Selim Cinek        } else if (mUnlockMethodCache.canSkipBouncer()) {
313c384198529870946249a79166fd0a42c1823bf09Selim Cinek            return STATE_LOCK_OPEN;
31427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        } else if (mUnlockMethodCache.isFaceUnlockRunning()) {
31527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            return STATE_FACE_UNLOCK;
316e07cbaf53c545fc7176cebfe14096cabb677798aAdrian Roos        } else if (fingerprintRunning && unlockingAllowed) {
317e07cbaf53c545fc7176cebfe14096cabb677798aAdrian Roos            return STATE_FINGERPRINT;
31827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        } else {
31927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            return STATE_LOCKED;
32027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        }
32127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
32227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
32327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    /**
32427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi     * A wrapper around another Drawable that overrides the intrinsic size.
32527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi     */
32627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    private static class IntrinsicSizeDrawable extends InsetDrawable {
32727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
32827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        private final int mIntrinsicWidth;
32927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        private final int mIntrinsicHeight;
33027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
33127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        public IntrinsicSizeDrawable(Drawable drawable, int intrinsicWidth, int intrinsicHeight) {
33227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            super(drawable, 0);
33327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            mIntrinsicWidth = intrinsicWidth;
33427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            mIntrinsicHeight = intrinsicHeight;
33527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        }
33627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
33727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        @Override
33827267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        public int getIntrinsicWidth() {
33927267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            return mIntrinsicWidth;
34027267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        }
34127267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi
34227267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        @Override
34327267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        public int getIntrinsicHeight() {
34427267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi            return mIntrinsicHeight;
34527267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi        }
34627267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi    }
34727267d6869a4e970e7575f36d0de75e8cb663952Jorim Jaggi}
348