Home | History | Annotate | Download | only in phone
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License
     15  */
     16 
     17 package com.android.systemui.statusbar.phone;
     18 
     19 import android.content.Context;
     20 import android.os.Trace;
     21 
     22 import com.android.internal.widget.LockPatternUtils;
     23 import com.android.keyguard.KeyguardUpdateMonitor;
     24 import com.android.keyguard.KeyguardUpdateMonitorCallback;
     25 
     26 import java.util.ArrayList;
     27 
     28 /**
     29  * Caches whether the current unlock method is insecure, taking trust into account. This information
     30  * might be a little bit out of date and should not be used for actual security decisions; it should
     31  * be only used for visual indications.
     32  */
     33 public class UnlockMethodCache {
     34 
     35     private static UnlockMethodCache sInstance;
     36 
     37     private final LockPatternUtils mLockPatternUtils;
     38     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
     39     private final ArrayList<OnUnlockMethodChangedListener> mListeners = new ArrayList<>();
     40     /** Whether the user configured a secure unlock method (PIN, password, etc.) */
     41     private boolean mSecure;
     42     /** Whether the unlock method is currently insecure (insecure method or trusted environment) */
     43     private boolean mCanSkipBouncer;
     44     private boolean mTrustManaged;
     45     private boolean mFaceUnlockRunning;
     46     private boolean mTrusted;
     47 
     48     private UnlockMethodCache(Context ctx) {
     49         mLockPatternUtils = new LockPatternUtils(ctx);
     50         mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(ctx);
     51         KeyguardUpdateMonitor.getInstance(ctx).registerCallback(mCallback);
     52         update(true /* updateAlways */);
     53     }
     54 
     55     public static UnlockMethodCache getInstance(Context context) {
     56         if (sInstance == null) {
     57             sInstance = new UnlockMethodCache(context);
     58         }
     59         return sInstance;
     60     }
     61 
     62     /**
     63      * @return whether the user configured a secure unlock method like PIN, password, etc.
     64      */
     65     public boolean isMethodSecure() {
     66         return mSecure;
     67     }
     68 
     69     public boolean isTrusted() {
     70         return mTrusted;
     71     }
     72 
     73     /**
     74      * @return whether the lockscreen is currently insecure, and the bouncer won't be shown
     75      */
     76     public boolean canSkipBouncer() {
     77         return mCanSkipBouncer;
     78     }
     79 
     80     public void addListener(OnUnlockMethodChangedListener listener) {
     81         mListeners.add(listener);
     82     }
     83 
     84     public void removeListener(OnUnlockMethodChangedListener listener) {
     85         mListeners.remove(listener);
     86     }
     87 
     88     private void update(boolean updateAlways) {
     89         Trace.beginSection("UnlockMethodCache#update");
     90         int user = KeyguardUpdateMonitor.getCurrentUser();
     91         boolean secure = mLockPatternUtils.isSecure(user);
     92         boolean canSkipBouncer = !secure ||  mKeyguardUpdateMonitor.getUserCanSkipBouncer(user);
     93         boolean trustManaged = mKeyguardUpdateMonitor.getUserTrustIsManaged(user);
     94         boolean trusted = mKeyguardUpdateMonitor.getUserHasTrust(user);
     95         boolean faceUnlockRunning = mKeyguardUpdateMonitor.isFaceUnlockRunning(user)
     96                 && trustManaged;
     97         boolean changed = secure != mSecure || canSkipBouncer != mCanSkipBouncer ||
     98                 trustManaged != mTrustManaged  || faceUnlockRunning != mFaceUnlockRunning;
     99         if (changed || updateAlways) {
    100             mSecure = secure;
    101             mCanSkipBouncer = canSkipBouncer;
    102             mTrusted = trusted;
    103             mTrustManaged = trustManaged;
    104             mFaceUnlockRunning = faceUnlockRunning;
    105             notifyListeners();
    106         }
    107         Trace.endSection();
    108     }
    109 
    110     private void notifyListeners() {
    111         for (OnUnlockMethodChangedListener listener : mListeners) {
    112             listener.onUnlockMethodStateChanged();
    113         }
    114     }
    115 
    116     private final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
    117         @Override
    118         public void onUserSwitchComplete(int userId) {
    119             update(false /* updateAlways */);
    120         }
    121 
    122         @Override
    123         public void onTrustChanged(int userId) {
    124             update(false /* updateAlways */);
    125         }
    126 
    127         @Override
    128         public void onTrustManagedChanged(int userId) {
    129             update(false /* updateAlways */);
    130         }
    131 
    132         @Override
    133         public void onStartedWakingUp() {
    134             update(false /* updateAlways */);
    135         }
    136 
    137         @Override
    138         public void onFingerprintAuthenticated(int userId) {
    139             Trace.beginSection("KeyguardUpdateMonitorCallback#onFingerprintAuthenticated");
    140             if (!mKeyguardUpdateMonitor.isUnlockingWithFingerprintAllowed()) {
    141                 Trace.endSection();
    142                 return;
    143             }
    144             update(false /* updateAlways */);
    145             Trace.endSection();
    146         }
    147 
    148         @Override
    149         public void onFaceUnlockStateChanged(boolean running, int userId) {
    150             update(false /* updateAlways */);
    151         }
    152 
    153         @Override
    154         public void onStrongAuthStateChanged(int userId) {
    155             update(false /* updateAlways */);
    156         }
    157 
    158         @Override
    159         public void onScreenTurnedOff() {
    160             update(false /* updateAlways */);
    161         }
    162 
    163         @Override
    164         public void onKeyguardVisibilityChanged(boolean showing) {
    165             update(false /* updateAlways */);
    166         }
    167     };
    168 
    169     public boolean isTrustManaged() {
    170         return mTrustManaged;
    171     }
    172 
    173     public boolean isFaceUnlockRunning() {
    174         return mFaceUnlockRunning;
    175     }
    176 
    177     public static interface OnUnlockMethodChangedListener {
    178         void onUnlockMethodStateChanged();
    179     }
    180 }
    181