diff options
author | Jorim Jaggi <jjaggi@google.com> | 2014-05-26 20:44:51 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2014-05-26 20:44:52 +0000 |
commit | 7c1d454da1f052c634c6a95ed3805be34d322765 (patch) | |
tree | 7be90ff2156a02c8facb475c434b36f9cc46bb75 /packages | |
parent | 1dfc38058eebf31b185a893134dc3ce1aac6fc81 (diff) | |
parent | ecc798e6668046c2f67cf30c6ab1db2eba80cab1 (diff) | |
download | frameworks_base-7c1d454da1f052c634c6a95ed3805be34d322765.zip frameworks_base-7c1d454da1f052c634c6a95ed3805be34d322765.tar.gz frameworks_base-7c1d454da1f052c634c6a95ed3805be34d322765.tar.bz2 |
Merge "Improve scrim handling" into lmp-preview-dev
Diffstat (limited to 'packages')
10 files changed, 342 insertions, 93 deletions
diff --git a/packages/Keyguard/res/layout/keyguard_bouncer.xml b/packages/Keyguard/res/layout/keyguard_bouncer.xml index 975a139..489c5f5 100644 --- a/packages/Keyguard/res/layout/keyguard_bouncer.xml +++ b/packages/Keyguard/res/layout/keyguard_bouncer.xml @@ -18,12 +18,6 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - <View android:id="@+id/bouncer_background" - android:background="#cc000000" - android:clickable="true" - android:layout_width="match_parent" - android:layout_height="match_parent"/> - <include style="@style/BouncerSecurityContainer" layout="@layout/keyguard_simple_host_view" diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml index 26616cd..e84300d 100644 --- a/packages/SystemUI/res/layout/super_status_bar.xml +++ b/packages/SystemUI/res/layout/super_status_bar.xml @@ -26,6 +26,10 @@ android:fitsSystemWindows="true" android:descendantFocusability="afterDescendants"> + <View android:id="@+id/scrim_behind" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + <include layout="@layout/status_bar" android:layout_width="match_parent" android:layout_height="@dimen/status_bar_height" /> @@ -40,4 +44,8 @@ android:visibility="gone" /> </com.android.systemui.statusbar.phone.PanelHolder> + <View android:id="@+id/scrim_in_front" + android:layout_width="match_parent" + android:layout_height="match_parent" /> + </com.android.systemui.statusbar.phone.StatusBarWindowView> diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index 92e8391..4e37dbb 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -31,8 +31,6 @@ <drawable name="recents_callout_line">#99ffffff</drawable> <drawable name="notification_item_background_legacy_color">#ffaaaaaa</drawable> <drawable name="heads_up_notification_bg_pressed">#ff33B5E5</drawable> - <color name="notification_panel_scrim_color">#A0000000</color> - <color name="notification_panel_scrim_color_keyguard">#80000000</color> <color name="batterymeter_frame_color">#66FFFFFF</color><!-- 40% white --> <color name="batterymeter_charge_color">#FFFFFFFF</color> <color name="batterymeter_bolt_color">#FFFFFFFF</color> diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index e73e904..b2872fa 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -62,6 +62,7 @@ import com.android.keyguard.analytics.KeyguardAnalytics; import com.android.keyguard.analytics.Session; import com.android.systemui.SystemUI; import com.android.systemui.statusbar.phone.PhoneStatusBar; +import com.android.systemui.statusbar.phone.ScrimController; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; import com.android.systemui.statusbar.phone.StatusBarWindowManager; @@ -1316,9 +1317,10 @@ public class KeyguardViewMediator extends SystemUI { } public StatusBarKeyguardViewManager registerStatusBar(PhoneStatusBar phoneStatusBar, - ViewGroup container, StatusBarWindowManager statusBarWindowManager) { + ViewGroup container, StatusBarWindowManager statusBarWindowManager, + ScrimController scrimController) { mStatusBarKeyguardViewManager.registerStatusBar(phoneStatusBar, container, - statusBarWindowManager); + statusBarWindowManager, scrimController); return mStatusBarKeyguardViewManager; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index 5e9ce21..714ad06 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -29,18 +29,11 @@ import android.os.UserHandle; import android.provider.MediaStore; import android.util.AttributeSet; import android.util.Log; -import android.view.MotionEvent; import android.view.View; -import android.view.ViewConfiguration; import android.view.accessibility.AccessibilityManager; -import android.view.animation.AccelerateInterpolator; -import android.view.animation.DecelerateInterpolator; import android.widget.FrameLayout; import android.widget.ImageView; -import com.android.internal.widget.LockPatternUtils; -import com.android.keyguard.KeyguardUpdateMonitor; -import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.R; /** @@ -48,7 +41,8 @@ import com.android.systemui.R; * text. */ public class KeyguardBottomAreaView extends FrameLayout - implements SwipeAffordanceView.AffordanceListener { + implements SwipeAffordanceView.AffordanceListener, + UnlockMethodCache.OnUnlockMethodChangedListener { final static String TAG = "PhoneStatusBar/KeyguardBottomAreaView"; @@ -60,9 +54,7 @@ public class KeyguardBottomAreaView extends FrameLayout private PowerManager mPowerManager; private ActivityStarter mActivityStarter; - - private LockPatternUtils mLockPatternUtils; - private KeyguardUpdateMonitor mKeyguardUpdateMonitor; + private UnlockMethodCache mUnlockMethodCache; public KeyguardBottomAreaView(Context context) { super(context); @@ -89,13 +81,12 @@ public class KeyguardBottomAreaView extends FrameLayout mLockIcon = (ImageView) findViewById(R.id.lock_icon); mCameraButton.setAffordanceListener(this); mPhoneButton.setAffordanceListener(this); - mLockPatternUtils = new LockPatternUtils(getContext()); - mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(getContext()); - KeyguardUpdateMonitor.getInstance(getContext()).registerCallback(mCallback); watchForDevicePolicyChanges(); watchForAccessibilityChanges(); updateCameraVisibility(); updatePhoneVisibility(); + mUnlockMethodCache = UnlockMethodCache.getInstance(getContext()); + mUnlockMethodCache.addListener(this); updateTrust(); mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); } @@ -211,28 +202,14 @@ public class KeyguardBottomAreaView extends FrameLayout if (getVisibility() != VISIBLE) { return; } - int user = mLockPatternUtils.getCurrentUser(); - boolean trust = !mLockPatternUtils.isSecure() || - mKeyguardUpdateMonitor.getUserHasTrust(user); - - int iconRes = trust ? R.drawable.ic_lock_open_24dp : R.drawable.ic_lock_24dp; + int iconRes = mUnlockMethodCache.isMethodInsecure() + ? R.drawable.ic_lock_open_24dp + : R.drawable.ic_lock_24dp; mLockIcon.setImageResource(iconRes); } - final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() { - @Override - public void onScreenTurnedOn() { - updateTrust(); - } - - @Override - public void onUserSwitchComplete(int userId) { - updateTrust(); - } - - @Override - public void onTrustChanged(int userId) { - updateTrust(); - } - }; + @Override + public void onMethodSecureChanged(boolean methodSecure) { + updateTrust(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 3405c07..b36c2ef 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -372,6 +372,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; private ViewMediatorCallback mKeyguardViewMediatorCallback; + private ScrimController mScrimController; private final Runnable mAutohide = new Runnable() { @Override @@ -638,9 +639,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, SpeedBumpView speedBump = (SpeedBumpView) LayoutInflater.from(mContext).inflate( R.layout.status_bar_notification_speed_bump, mStackScroller, false); mStackScroller.setSpeedBumpView(speedBump); - mExpandedContents = mStackScroller; + mScrimController = new ScrimController(mStatusBarWindow.findViewById(R.id.scrim_behind), + mStatusBarWindow.findViewById(R.id.scrim_in_front)); + mStatusBarView.setScrimController(mScrimController); + mHeader = (StatusBarHeaderView) mStatusBarWindow.findViewById(R.id.header); mHeader.setActivityStarter(this); mKeyguardStatusView = mStatusBarWindow.findViewById(R.id.keyguard_status_view); @@ -775,7 +779,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private void startKeyguard() { KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class); mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this, - mStatusBarWindow, mStatusBarWindowManager); + mStatusBarWindow, mStatusBarWindowManager, mScrimController); mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback(); } @@ -1446,6 +1450,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, startActivityDismissingKeyguard(intent, false); } + public ScrimController getScrimController() { + return mScrimController; + } + /** * All changes to the status bar and notifications funnel through here and are batched. */ @@ -2771,10 +2779,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mKeyguardBottomArea.setVisibility(View.VISIBLE); mHeader.setKeyguardShowing(true); mNotificationPanel.setKeyguardShowing(true); + mScrimController.setKeyguardShowing(true); } else { mKeyguardBottomArea.setVisibility(View.GONE); mHeader.setKeyguardShowing(false); mNotificationPanel.setKeyguardShowing(false); + mScrimController.setKeyguardShowing(false); } updateStackScrollerState(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index 084bfcf..5fdf5bf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -36,21 +36,16 @@ public class PhoneStatusBarView extends PanelBar { private static final boolean DEBUG_GESTURES = true; PhoneStatusBar mBar; - int mScrimColor; - int mScrimColorKeyguard; - PanelView mFadingPanel = null; PanelView mLastFullyOpenedPanel = null; PanelView mNotificationPanel; - private boolean mShouldFade; private final PhoneStatusBarTransitions mBarTransitions; + private ScrimController mScrimController; public PhoneStatusBarView(Context context, AttributeSet attrs) { super(context, attrs); Resources res = getContext().getResources(); - mScrimColor = res.getColor(R.color.notification_panel_scrim_color); - mScrimColorKeyguard = res.getColor(R.color.notification_panel_scrim_color_keyguard); mBarTransitions = new PhoneStatusBarTransitions(this); } @@ -62,6 +57,10 @@ public class PhoneStatusBarView extends PanelBar { mBar = bar; } + public void setScrimController(ScrimController scrimController) { + mScrimController = scrimController; + } + @Override public void onFinishInflate() { mBarTransitions.init(); @@ -110,27 +109,11 @@ public class PhoneStatusBarView extends PanelBar { } @Override - public void startOpeningPanel(PanelView panel) { - super.startOpeningPanel(panel); - // we only want to start fading if this is the "first" or "last" panel, - // which is kind of tricky to determine - mShouldFade = (mFadingPanel == null || mFadingPanel.isFullyExpanded()); - if (DEBUG) { - Log.v(TAG, "start opening: " + panel + " shouldfade=" + mShouldFade); - } - mFadingPanel = panel; - } - - @Override public void onAllPanelsCollapsed() { super.onAllPanelsCollapsed(); // give animations time to settle mBar.makeExpandedInvisibleSoon(); - mFadingPanel = null; mLastFullyOpenedPanel = null; - if (mScrimColor != 0 && ActivityManager.isHighEndGfx() && mBar.mStatusBarWindow != null) { - mBar.mStatusBarWindow.setBackgroundColor(0); - } } @Override @@ -139,9 +122,7 @@ public class PhoneStatusBarView extends PanelBar { if (openPanel != mLastFullyOpenedPanel) { openPanel.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED); } - mFadingPanel = openPanel; mLastFullyOpenedPanel = openPanel; - mShouldFade = true; // now you own the fade, mister } @Override @@ -163,6 +144,7 @@ public class PhoneStatusBarView extends PanelBar { public void onTrackingStarted(PanelView panel) { super.onTrackingStarted(panel); mBar.onTrackingStarted(); + mScrimController.onTrackingStarted(); } @Override @@ -184,27 +166,7 @@ public class PhoneStatusBarView extends PanelBar { Log.v(TAG, "panelExpansionChanged: f=" + frac); } - if (panel == mFadingPanel && mScrimColor != 0 && ActivityManager.isHighEndGfx() - && mBar.mStatusBarWindow != null) { - if (mShouldFade) { - int scrimColor = (mBar.getBarState() == StatusBarState.KEYGUARD - || mBar.getBarState() == StatusBarState.SHADE_LOCKED) - ? mScrimColorKeyguard - : mScrimColor; - frac = mPanelExpandedFractionSum; // don't judge me - // let's start this 20% of the way down the screen - frac = frac * 1.2f - 0.2f; - if (frac <= 0) { - mBar.mStatusBarWindow.setBackgroundColor(0); - } else { - // woo, special effects - final float k = (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2f)))); - // attenuate background color alpha by k - final int color = (int) ((scrimColor >>> 24) * k) << 24 | (scrimColor & 0xFFFFFF); - mBar.mStatusBarWindow.setBackgroundColor(color); - } - } - } + mScrimController.setPanelExpansion(frac); // fade out the panel as it gets buried into the status bar to avoid overdrawing the // status bar on the last frame of a close animation diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java new file mode 100644 index 0000000..95255d5 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.systemui.statusbar.phone; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ValueAnimator; +import android.content.res.Resources; +import android.graphics.Color; +import android.graphics.drawable.ColorDrawable; +import android.view.View; +import android.view.ViewTreeObserver; +import android.view.animation.AccelerateInterpolator; +import android.view.animation.AnimationUtils; +import android.view.animation.DecelerateInterpolator; +import android.view.animation.Interpolator; +import android.view.animation.LinearInterpolator; + +/** + * Controls both the scrim behind the notifications and in front of the notifications (when a + * security method gets shown). + */ +public class ScrimController implements ViewTreeObserver.OnPreDrawListener { + + private static final float SCRIM_BEHIND_ALPHA = 0.62f; + private static final float SCRIM_BEHIND_ALPHA_KEYGUARD = 0.5f; + private static final float SCRIM_IN_FRONT_ALPHA = 0.75f; + private static final long ANIMATION_DURATION = 220; + + private final View mScrimBehind; + private final View mScrimInFront; + private final UnlockMethodCache mUnlockMethodCache; + + private boolean mKeyguardShowing; + private float mFraction; + + private boolean mDarkenWhileDragging; + private boolean mBouncerShowing; + private boolean mAnimateChange; + private boolean mUpdatePending; + + private final Interpolator mInterpolator = new DecelerateInterpolator(); + + public ScrimController(View scrimBehind, View scrimInFront) { + mScrimBehind = scrimBehind; + mScrimInFront = scrimInFront; + mUnlockMethodCache = UnlockMethodCache.getInstance(scrimBehind.getContext()); + } + + public void setKeyguardShowing(boolean showing) { + mKeyguardShowing = showing; + scheduleUpdate(); + } + + public void onTrackingStarted() { + mDarkenWhileDragging = !mUnlockMethodCache.isMethodInsecure(); + } + + public void setPanelExpansion(float fraction) { + mFraction = fraction; + scheduleUpdate(); + } + + public void setBouncerShowing(boolean showing) { + mBouncerShowing = showing; + mAnimateChange = true; + scheduleUpdate(); + } + + private void scheduleUpdate() { + if (mUpdatePending) return; + mScrimBehind.getViewTreeObserver().addOnPreDrawListener(this); + mUpdatePending = true; + } + + private void updateScrims() { + if (!mKeyguardShowing) { + updateScrimNormal(); + setScrimInFrontColor(0); + } else { + updateScrimKeyguard(); + } + mAnimateChange = false; + } + + private void updateScrimKeyguard() { + if (mBouncerShowing) { + setScrimInFrontColor(SCRIM_IN_FRONT_ALPHA); + setScrimBehindColor(0f); + } else if (mDarkenWhileDragging) { + float behindFraction = Math.max(0, Math.min(mFraction, 1)); + float fraction = 1 - behindFraction; + setScrimInFrontColor(fraction * SCRIM_IN_FRONT_ALPHA); + setScrimBehindColor(behindFraction * SCRIM_BEHIND_ALPHA_KEYGUARD); + } else { + setScrimInFrontColor(0f); + setScrimBehindColor(SCRIM_BEHIND_ALPHA_KEYGUARD); + } + } + + private void updateScrimNormal() { + float frac = mFraction; + // let's start this 20% of the way down the screen + frac = frac * 1.2f - 0.2f; + if (frac <= 0) { + setScrimBehindColor(0); + } else { + // woo, special effects + final float k = (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2f)))); + setScrimBehindColor(k * SCRIM_BEHIND_ALPHA); + } + } + + private void setScrimBehindColor(float alpha) { + setScrimColor(mScrimBehind, alpha); + } + + private void setScrimInFrontColor(float alpha) { + setScrimColor(mScrimInFront, alpha); + if (alpha == 0f) { + mScrimInFront.setClickable(false); + } else { + + // Eat touch events. + mScrimInFront.setClickable(true); + } + } + + private void setScrimColor(View scrim, float alpha) { + int color = Color.argb((int) (alpha * 255), 0, 0, 0); + if (mAnimateChange) { + startScrimAnimation(scrim, color); + } else { + scrim.setBackgroundColor(color); + } + } + + private void startScrimAnimation(final View scrim, int targetColor) { + int current = getBackgroundAlpha(scrim); + int target = Color.alpha(targetColor); + if (current == targetColor) { + return; + } + ValueAnimator anim = ValueAnimator.ofInt(current, target); + anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + int value = (int) animation.getAnimatedValue(); + scrim.setBackgroundColor(Color.argb(value, 0, 0, 0)); + } + }); + anim.setInterpolator(mInterpolator); + anim.setDuration(ANIMATION_DURATION); + anim.start(); + } + + private int getBackgroundAlpha(View scrim) { + if (scrim.getBackground() instanceof ColorDrawable) { + ColorDrawable drawable = (ColorDrawable) scrim.getBackground(); + return Color.alpha(drawable.getColor()); + } else { + return 0; + } + } + + @Override + public boolean onPreDraw() { + mScrimBehind.getViewTreeObserver().removeOnPreDrawListener(this); + mUpdatePending = false; + updateScrims(); + return true; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index 3f76d26..c3430c3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -45,6 +45,7 @@ public class StatusBarKeyguardViewManager { private LockPatternUtils mLockPatternUtils; private ViewMediatorCallback mViewMediatorCallback; private PhoneStatusBar mPhoneStatusBar; + private ScrimController mScrimController; private ViewGroup mContainer; private StatusBarWindowManager mStatusBarWindowManager; @@ -68,10 +69,12 @@ public class StatusBarKeyguardViewManager { } public void registerStatusBar(PhoneStatusBar phoneStatusBar, - ViewGroup container, StatusBarWindowManager statusBarWindowManager) { + ViewGroup container, StatusBarWindowManager statusBarWindowManager, + ScrimController scrimController) { mPhoneStatusBar = phoneStatusBar; mContainer = container; mStatusBarWindowManager = statusBarWindowManager; + mScrimController = scrimController; mBouncer = new KeyguardBouncer(mContext, mViewMediatorCallback, mLockPatternUtils, mStatusBarWindowManager, container); } @@ -252,6 +255,7 @@ public class StatusBarKeyguardViewManager { if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) { mStatusBarWindowManager.setBouncerShowing(bouncerShowing); mPhoneStatusBar.setBouncerShowing(bouncerShowing); + mScrimController.setBouncerShowing(bouncerShowing); } KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java new file mode 100644 index 0000000..bfd657b --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ + +package com.android.systemui.statusbar.phone; + +import android.content.Context; + +import com.android.internal.widget.LockPatternUtils; +import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.keyguard.KeyguardUpdateMonitorCallback; + +import java.util.ArrayList; + +/** + * Caches whether the current unlock method is insecure, taking trust into account. This information + * might be a little bit out of date and should not be used for actual security decisions; it should + * be only used for visual indications. + */ +public class UnlockMethodCache { + + private static UnlockMethodCache sInstance; + + private final LockPatternUtils mLockPatternUtils; + private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; + private final ArrayList<OnUnlockMethodChangedListener> mListeners = new ArrayList<>(); + private boolean mMethodInsecure; + + private UnlockMethodCache(Context ctx) { + mLockPatternUtils = new LockPatternUtils(ctx); + mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(ctx); + KeyguardUpdateMonitor.getInstance(ctx).registerCallback(mCallback); + updateMethodSecure(true /* updateAlways */); + } + + public static UnlockMethodCache getInstance(Context context) { + if (sInstance == null) { + sInstance = new UnlockMethodCache(context); + } + return sInstance; + } + + /** + * @return whether the current security method is secure, i. e. the bouncer will be shown + */ + public boolean isMethodInsecure() { + return mMethodInsecure; + } + + public void addListener(OnUnlockMethodChangedListener listener) { + mListeners.add(listener); + } + + public void removeListener(OnUnlockMethodChangedListener listener) { + mListeners.remove(listener); + } + + private void updateMethodSecure(boolean updateAlways) { + int user = mLockPatternUtils.getCurrentUser(); + boolean methodInsecure = !mLockPatternUtils.isSecure() || + mKeyguardUpdateMonitor.getUserHasTrust(user); + boolean changed = methodInsecure != mMethodInsecure; + if (changed || updateAlways) { + mMethodInsecure = methodInsecure; + notifyListeners(mMethodInsecure); + } + } + + private void notifyListeners(boolean secure) { + for (OnUnlockMethodChangedListener listener : mListeners) { + listener.onMethodSecureChanged(secure); + } + } + + private final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() { + @Override + public void onUserSwitchComplete(int userId) { + updateMethodSecure(false /* updateAlways */); + } + + @Override + public void onTrustChanged(int userId) { + updateMethodSecure(false /* updateAlways */); + } + + @Override + public void onScreenTurnedOn() { + updateMethodSecure(false /* updateAlways */); + } + }; + + public static interface OnUnlockMethodChangedListener { + void onMethodSecureChanged(boolean methodSecure); + } +} |