1 /* 2 * Copyright (C) 2013 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.server.policy.keyguard; 18 19 import android.app.ActivityManager; 20 import android.content.Context; 21 import android.os.RemoteException; 22 import android.os.ServiceManager; 23 import android.security.keystore.IKeystoreService; 24 import android.util.Slog; 25 26 import com.android.internal.policy.IKeyguardService; 27 import com.android.internal.policy.IKeyguardStateCallback; 28 import com.android.internal.widget.LockPatternUtils; 29 30 import java.io.PrintWriter; 31 32 /** 33 * Maintains a cached copy of Keyguard's state. 34 * @hide 35 */ 36 public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { 37 private static final String TAG = "KeyguardStateMonitor"; 38 39 // These cache the current state of Keyguard to improve performance and avoid deadlock. After 40 // Keyguard changes its state, it always triggers a layout in window manager. Because 41 // IKeyguardStateCallback is synchronous and because these states are declared volatile, it's 42 // guaranteed that window manager picks up the new state all the time in the layout caused by 43 // the state change of Keyguard. To be extra safe, assume most restrictive values until Keyguard 44 // tells us the actual value. 45 private volatile boolean mIsShowing = true; 46 private volatile boolean mSimSecure = true; 47 private volatile boolean mInputRestricted = true; 48 private volatile boolean mTrusted = false; 49 private volatile boolean mHasLockscreenWallpaper = false; 50 51 private int mCurrentUserId; 52 53 private final LockPatternUtils mLockPatternUtils; 54 private final StateCallback mCallback; 55 56 IKeystoreService mKeystoreService; 57 KeyguardStateMonitor(Context context, IKeyguardService service, StateCallback callback)58 public KeyguardStateMonitor(Context context, IKeyguardService service, StateCallback callback) { 59 mLockPatternUtils = new LockPatternUtils(context); 60 mCurrentUserId = ActivityManager.getCurrentUser(); 61 mCallback = callback; 62 63 mKeystoreService = IKeystoreService.Stub.asInterface(ServiceManager 64 .getService("android.security.keystore")); 65 66 try { 67 service.addStateMonitorCallback(this); 68 } catch (RemoteException e) { 69 Slog.w(TAG, "Remote Exception", e); 70 } 71 } 72 isShowing()73 public boolean isShowing() { 74 return mIsShowing; 75 } 76 isSecure(int userId)77 public boolean isSecure(int userId) { 78 return mLockPatternUtils.isSecure(userId) || mSimSecure; 79 } 80 isInputRestricted()81 public boolean isInputRestricted() { 82 return mInputRestricted; 83 } 84 isTrusted()85 public boolean isTrusted() { 86 return mTrusted; 87 } 88 hasLockscreenWallpaper()89 public boolean hasLockscreenWallpaper() { 90 return mHasLockscreenWallpaper; 91 } 92 93 @Override // Binder interface onShowingStateChanged(boolean showing)94 public void onShowingStateChanged(boolean showing) { 95 mIsShowing = showing; 96 97 mCallback.onShowingChanged(); 98 int retry = 2; 99 while (retry > 0) { 100 try { 101 mKeystoreService.onKeyguardVisibilityChanged(showing, mCurrentUserId); 102 break; 103 } catch (RemoteException e) { 104 if (retry == 2) { 105 Slog.w(TAG, "Error informing keystore of screen lock. Keystore may have died" 106 + " -> refreshing service token and retrying"); 107 mKeystoreService = IKeystoreService.Stub.asInterface(ServiceManager 108 .getService("android.security.keystore")); 109 } else { 110 Slog.e(TAG, "Error informing keystore of screen lock after retrying once", e); 111 } 112 --retry; 113 } 114 } 115 } 116 117 @Override // Binder interface onSimSecureStateChanged(boolean simSecure)118 public void onSimSecureStateChanged(boolean simSecure) { 119 mSimSecure = simSecure; 120 } 121 setCurrentUser(int userId)122 public synchronized void setCurrentUser(int userId) { 123 mCurrentUserId = userId; 124 } 125 getCurrentUser()126 private synchronized int getCurrentUser() { 127 return mCurrentUserId; 128 } 129 130 @Override // Binder interface onInputRestrictedStateChanged(boolean inputRestricted)131 public void onInputRestrictedStateChanged(boolean inputRestricted) { 132 mInputRestricted = inputRestricted; 133 } 134 135 @Override // Binder interface onTrustedChanged(boolean trusted)136 public void onTrustedChanged(boolean trusted) { 137 mTrusted = trusted; 138 mCallback.onTrustedChanged(); 139 } 140 141 @Override // Binder interface onHasLockscreenWallpaperChanged(boolean hasLockscreenWallpaper)142 public void onHasLockscreenWallpaperChanged(boolean hasLockscreenWallpaper) { 143 mHasLockscreenWallpaper = hasLockscreenWallpaper; 144 } 145 146 public interface StateCallback { onTrustedChanged()147 void onTrustedChanged(); onShowingChanged()148 void onShowingChanged(); 149 } 150 dump(String prefix, PrintWriter pw)151 public void dump(String prefix, PrintWriter pw) { 152 pw.println(prefix + TAG); 153 prefix += " "; 154 pw.println(prefix + "mIsShowing=" + mIsShowing); 155 pw.println(prefix + "mSimSecure=" + mSimSecure); 156 pw.println(prefix + "mInputRestricted=" + mInputRestricted); 157 pw.println(prefix + "mTrusted=" + mTrusted); 158 pw.println(prefix + "mCurrentUserId=" + mCurrentUserId); 159 } 160 } 161