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