KeyguardServiceDelegate.java revision caf24fc2c4bb9747eb80138bf3ce0be067851749
1package com.android.internal.policy.impl.keyguard; 2 3import android.content.ComponentName; 4import android.content.Context; 5import android.content.Intent; 6import android.content.ServiceConnection; 7import android.content.pm.ActivityInfo; 8import android.graphics.PixelFormat; 9import android.os.Bundle; 10import android.os.IBinder; 11import android.os.RemoteException; 12import android.os.UserHandle; 13import android.util.Log; 14import android.util.Slog; 15import android.view.KeyEvent; 16import android.view.View; 17import android.view.ViewGroup; 18import android.view.WindowManager; 19import android.view.WindowManagerPolicy.OnKeyguardExitResult; 20 21import com.android.internal.policy.IKeyguardExitCallback; 22import com.android.internal.policy.IKeyguardShowCallback; 23import com.android.internal.policy.IKeyguardService; 24import com.android.internal.widget.LockPatternUtils; 25 26/** 27 * A local class that keeps a cache of keyguard state that can be restored in the event 28 * keyguard crashes. It currently also allows runtime-selectable 29 * local or remote instances of keyguard. 30 */ 31public class KeyguardServiceDelegate { 32 // TODO: propagate changes to these to {@link KeyguardTouchDelegate} 33 public static final String KEYGUARD_PACKAGE = "com.android.keyguard"; 34 public static final String KEYGUARD_CLASS = "com.android.keyguard.KeyguardService"; 35 36 private static final String TAG = "KeyguardServiceDelegate"; 37 private static final boolean DEBUG = true; 38 protected KeyguardServiceWrapper mKeyguardService; 39 private View mScrim; // shown if keyguard crashes 40 private KeyguardState mKeyguardState = new KeyguardState(); 41 42 /* package */ static final class KeyguardState { 43 boolean showing; 44 boolean showingAndNotHidden; 45 boolean inputRestricted; 46 boolean hidden; 47 boolean secure; 48 boolean dreaming; 49 boolean systemIsReady; 50 public boolean enabled; 51 public boolean dismissable; 52 public int offReason; 53 public int currentUser; 54 public boolean screenIsOn; 55 }; 56 57 public interface ShowListener { 58 public void onShown(IBinder windowToken); 59 } 60 61 // A delegate class to map a particular invocation with a ShowListener object. 62 private final class KeyguardShowDelegate extends IKeyguardShowCallback.Stub { 63 private ShowListener mShowListener; 64 65 KeyguardShowDelegate(ShowListener showListener) { 66 mShowListener = showListener; 67 } 68 69 @Override 70 public void onShown(IBinder windowToken) throws RemoteException { 71 if (DEBUG) Log.v(TAG, "**** SHOWN CALLED ****"); 72 if (mShowListener != null) { 73 mShowListener.onShown(windowToken); 74 } 75 hideScrim(); 76 } 77 }; 78 79 // A delegate class to map a particular invocation with an OnKeyguardExitResult object. 80 private final class KeyguardExitDelegate extends IKeyguardExitCallback.Stub { 81 private OnKeyguardExitResult mOnKeyguardExitResult; 82 83 KeyguardExitDelegate(OnKeyguardExitResult onKeyguardExitResult) { 84 mOnKeyguardExitResult = onKeyguardExitResult; 85 } 86 87 @Override 88 public void onKeyguardExitResult(boolean success) throws RemoteException { 89 if (DEBUG) Log.v(TAG, "**** onKeyguardExitResult(" + success +") CALLED ****"); 90 if (mOnKeyguardExitResult != null) { 91 mOnKeyguardExitResult.onKeyguardExitResult(success); 92 } 93 } 94 }; 95 96 public KeyguardServiceDelegate(Context context, LockPatternUtils lockPatternUtils) { 97 Intent intent = new Intent(); 98 intent.setClassName(KEYGUARD_PACKAGE, KEYGUARD_CLASS); 99 mScrim = createScrim(context); 100 if (!context.bindServiceAsUser(intent, mKeyguardConnection, 101 Context.BIND_AUTO_CREATE, UserHandle.OWNER)) { 102 if (DEBUG) Log.v(TAG, "*** Keyguard: can't bind to " + KEYGUARD_CLASS); 103 } else { 104 if (DEBUG) Log.v(TAG, "*** Keyguard started"); 105 } 106 } 107 108 private final ServiceConnection mKeyguardConnection = new ServiceConnection() { 109 @Override 110 public void onServiceConnected(ComponentName name, IBinder service) { 111 if (DEBUG) Log.v(TAG, "*** Keyguard connected (yay!)"); 112 mKeyguardService = new KeyguardServiceWrapper( 113 IKeyguardService.Stub.asInterface(service)); 114 if (mKeyguardState.systemIsReady) { 115 // If the system is ready, it means keyguard crashed and restarted. 116 mKeyguardService.onSystemReady(); 117 // This is used to hide the scrim once keyguard displays. 118 mKeyguardService.onScreenTurnedOn(new KeyguardShowDelegate(null)); 119 } 120 } 121 122 @Override 123 public void onServiceDisconnected(ComponentName name) { 124 if (DEBUG) Log.v(TAG, "*** Keyguard disconnected (boo!)"); 125 mKeyguardService = null; 126 } 127 128 }; 129 130 public boolean isShowing() { 131 if (mKeyguardService != null) { 132 mKeyguardState.showing = mKeyguardService.isShowing(); 133 } 134 return mKeyguardState.showing; 135 } 136 137 public boolean isShowingAndNotHidden() { 138 if (mKeyguardService != null) { 139 mKeyguardState.showingAndNotHidden = mKeyguardService.isShowingAndNotHidden(); 140 } 141 return mKeyguardState.showingAndNotHidden; 142 } 143 144 public boolean isInputRestricted() { 145 if (mKeyguardService != null) { 146 mKeyguardState.inputRestricted = mKeyguardService.isInputRestricted(); 147 } 148 return mKeyguardState.inputRestricted; 149 } 150 151 public void verifyUnlock(final OnKeyguardExitResult onKeyguardExitResult) { 152 if (mKeyguardService != null) { 153 mKeyguardService.verifyUnlock(new KeyguardExitDelegate(onKeyguardExitResult)); 154 } 155 } 156 157 public void keyguardDone(boolean authenticated, boolean wakeup) { 158 if (mKeyguardService != null) { 159 mKeyguardService.keyguardDone(authenticated, wakeup); 160 } 161 } 162 163 public void setHidden(boolean isHidden) { 164 if (mKeyguardService != null) { 165 mKeyguardService.setHidden(isHidden); 166 } 167 mKeyguardState.hidden = isHidden; 168 } 169 170 public void dismiss() { 171 if (mKeyguardService != null) { 172 mKeyguardService.dismiss(); 173 } 174 } 175 176 public boolean isSecure() { 177 if (mKeyguardService != null) { 178 mKeyguardState.secure = mKeyguardService.isSecure(); 179 } 180 return mKeyguardState.secure; 181 } 182 183 public void onDreamingStarted() { 184 if (mKeyguardService != null) { 185 mKeyguardService.onDreamingStarted(); 186 } 187 mKeyguardState.dreaming = true; 188 } 189 190 public void onDreamingStopped() { 191 if (mKeyguardService != null) { 192 mKeyguardService.onDreamingStopped(); 193 } 194 mKeyguardState.dreaming = false; 195 } 196 197 public void onScreenTurnedOn(final ShowListener showListener) { 198 if (mKeyguardService != null) { 199 if (DEBUG) Log.v(TAG, "onScreenTurnedOn(showListener = " + showListener + ")"); 200 mKeyguardService.onScreenTurnedOn(new KeyguardShowDelegate(showListener)); 201 } else { 202 // try again when we establish a connection 203 Slog.w(TAG, "onScreenTurnedOn(): no keyguard service!"); 204 // This shouldn't happen, but if it does, invoke the listener immediately 205 // to avoid a dark screen... 206 showListener.onShown(null); 207 } 208 mKeyguardState.screenIsOn = true; 209 } 210 211 public void onScreenTurnedOff(int why) { 212 if (mKeyguardService != null) { 213 mKeyguardService.onScreenTurnedOff(why); 214 } 215 mKeyguardState.offReason = why; 216 mKeyguardState.screenIsOn = false; 217 } 218 219 public void setKeyguardEnabled(boolean enabled) { 220 if (mKeyguardService != null) { 221 mKeyguardService.setKeyguardEnabled(enabled); 222 } 223 mKeyguardState.enabled = enabled; 224 } 225 226 public boolean isDismissable() { 227 if (mKeyguardService != null) { 228 mKeyguardState.dismissable = mKeyguardService.isDismissable(); 229 } 230 return mKeyguardState.dismissable; 231 } 232 233 public void onSystemReady() { 234 if (mKeyguardService != null) { 235 mKeyguardService.onSystemReady(); 236 } else { 237 if (DEBUG) Log.v(TAG, "onSystemReady() called before keyguard service was ready"); 238 mKeyguardState.systemIsReady = true; 239 } 240 } 241 242 public void doKeyguardTimeout(Bundle options) { 243 if (mKeyguardService != null) { 244 mKeyguardService.doKeyguardTimeout(options); 245 } 246 } 247 248 public void showAssistant() { 249 if (mKeyguardService != null) { 250 mKeyguardService.showAssistant(); 251 } 252 } 253 254 public void setCurrentUser(int newUserId) { 255 if (mKeyguardService != null) { 256 mKeyguardService.setCurrentUser(newUserId); 257 } 258 mKeyguardState.currentUser = newUserId; 259 } 260 261 private static final View createScrim(Context context) { 262 View view = new View(context); 263 264 int flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 265 | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR 266 | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN 267 | WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER 268 ; 269 270 final int stretch = ViewGroup.LayoutParams.MATCH_PARENT; 271 final int type = WindowManager.LayoutParams.TYPE_KEYGUARD_SCRIM; 272 WindowManager.LayoutParams lp = new WindowManager.LayoutParams( 273 stretch, stretch, type, flags, PixelFormat.TRANSLUCENT); 274 lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; 275 lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; 276 lp.setTitle("KeyguardScrim"); 277 WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 278 wm.addView(view, lp); 279 view.setVisibility(View.GONE); 280 // Disable pretty much everything in statusbar until keyguard comes back and we know 281 // the state of the world. 282 view.setSystemUiVisibility(View.STATUS_BAR_DISABLE_HOME 283 | View.STATUS_BAR_DISABLE_BACK 284 | View.STATUS_BAR_DISABLE_RECENT 285 | View.STATUS_BAR_DISABLE_EXPAND 286 | View.STATUS_BAR_DISABLE_SEARCH); 287 return view; 288 } 289 290 public void showScrim() { 291 mScrim.post(new Runnable() { 292 @Override 293 public void run() { 294 mScrim.setVisibility(View.VISIBLE); 295 } 296 }); 297 } 298 299 public void hideScrim() { 300 mScrim.post(new Runnable() { 301 @Override 302 public void run() { 303 mScrim.setVisibility(View.GONE); 304 } 305 }); 306 } 307 308} 309