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