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