KeyguardViewManager.java revision 305c78cce649056643641c51f12f2b6d2eb839f3
1/* 2 * Copyright (C) 2007 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 17package com.android.internal.policy.impl; 18 19import com.android.internal.R; 20 21import android.app.ActivityManager; 22import android.content.Context; 23import android.content.pm.ActivityInfo; 24import android.content.res.Resources; 25import android.graphics.PixelFormat; 26import android.graphics.Canvas; 27import android.os.IBinder; 28import android.os.SystemProperties; 29import android.util.Log; 30import android.view.View; 31import android.view.ViewGroup; 32import android.view.ViewManager; 33import android.view.WindowManager; 34import android.widget.FrameLayout; 35 36import android.graphics.Color; 37 38/** 39 * Manages creating, showing, hiding and resetting the keyguard. Calls back 40 * via {@link com.android.internal.policy.impl.KeyguardViewCallback} to poke 41 * the wake lock and report that the keyguard is done, which is in turn, 42 * reported to this class by the current {@link KeyguardViewBase}. 43 */ 44public class KeyguardViewManager implements KeyguardWindowController { 45 private final static boolean DEBUG = false; 46 private static String TAG = "KeyguardViewManager"; 47 48 private final Context mContext; 49 private final ViewManager mViewManager; 50 private final KeyguardViewCallback mCallback; 51 private final KeyguardViewProperties mKeyguardViewProperties; 52 53 private final KeyguardUpdateMonitor mUpdateMonitor; 54 55 private WindowManager.LayoutParams mWindowLayoutParams; 56 private boolean mNeedsInput = false; 57 58 private FrameLayout mKeyguardHost; 59 private KeyguardViewBase mKeyguardView; 60 61 private boolean mScreenOn = false; 62 63 public interface ShowListener { 64 void onShown(IBinder windowToken); 65 }; 66 67 /** 68 * @param context Used to create views. 69 * @param viewManager Keyguard will be attached to this. 70 * @param callback Used to notify of changes. 71 */ 72 public KeyguardViewManager(Context context, ViewManager viewManager, 73 KeyguardViewCallback callback, KeyguardViewProperties keyguardViewProperties, 74 KeyguardUpdateMonitor updateMonitor) { 75 mContext = context; 76 mViewManager = viewManager; 77 mCallback = callback; 78 mKeyguardViewProperties = keyguardViewProperties; 79 80 mUpdateMonitor = updateMonitor; 81 } 82 83 /** 84 * Helper class to host the keyguard view. 85 */ 86 private static class KeyguardViewHost extends FrameLayout { 87 private final KeyguardViewCallback mCallback; 88 89 private KeyguardViewHost(Context context, KeyguardViewCallback callback) { 90 super(context); 91 mCallback = callback; 92 } 93 94 @Override 95 protected void dispatchDraw(Canvas canvas) { 96 super.dispatchDraw(canvas); 97 mCallback.keyguardDoneDrawing(); 98 } 99 } 100 101 /** 102 * Show the keyguard. Will handle creating and attaching to the view manager 103 * lazily. 104 */ 105 public synchronized void show() { 106 if (DEBUG) Log.d(TAG, "show(); mKeyguardView==" + mKeyguardView); 107 108 Resources res = mContext.getResources(); 109 boolean enableScreenRotation = 110 SystemProperties.getBoolean("lockscreen.rot_override",false) 111 || res.getBoolean(R.bool.config_enableLockScreenRotation); 112 if (mKeyguardHost == null) { 113 if (DEBUG) Log.d(TAG, "keyguard host is null, creating it..."); 114 115 mKeyguardHost = new KeyguardViewHost(mContext, mCallback); 116 117 final int stretch = ViewGroup.LayoutParams.MATCH_PARENT; 118 int flags = WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN 119 | WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER 120 | WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING 121 /*| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 122 | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR*/ ; 123 if (!mNeedsInput) { 124 flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 125 } 126 if (ActivityManager.isHighEndGfx(((WindowManager)mContext.getSystemService( 127 Context.WINDOW_SERVICE)).getDefaultDisplay())) { 128 flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; 129 } 130 WindowManager.LayoutParams lp = new WindowManager.LayoutParams( 131 stretch, stretch, WindowManager.LayoutParams.TYPE_KEYGUARD, 132 flags, PixelFormat.TRANSLUCENT); 133 lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; 134 lp.windowAnimations = com.android.internal.R.style.Animation_LockScreen; 135 if (ActivityManager.isHighEndGfx(((WindowManager)mContext.getSystemService( 136 Context.WINDOW_SERVICE)).getDefaultDisplay())) { 137 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; 138 lp.privateFlags |= 139 WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED; 140 } 141 lp.setTitle("Keyguard"); 142 mWindowLayoutParams = lp; 143 144 mViewManager.addView(mKeyguardHost, lp); 145 } 146 147 if (enableScreenRotation) { 148 if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen On!"); 149 mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR; 150 } else { 151 if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen Off!"); 152 mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; 153 } 154 155 mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams); 156 157 if (mKeyguardView == null) { 158 if (DEBUG) Log.d(TAG, "keyguard view is null, creating it..."); 159 mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this); 160 mKeyguardView.setId(R.id.lock_screen); 161 mKeyguardView.setCallback(mCallback); 162 163 final ViewGroup.LayoutParams lp = new FrameLayout.LayoutParams( 164 ViewGroup.LayoutParams.MATCH_PARENT, 165 ViewGroup.LayoutParams.MATCH_PARENT); 166 167 mKeyguardHost.addView(mKeyguardView, lp); 168 169 if (mScreenOn) { 170 mKeyguardView.show(); 171 } 172 } 173 174 // Disable aspects of the system/status/navigation bars that are not appropriate or 175 // useful for the lockscreen but can be re-shown by dialogs or SHOW_WHEN_LOCKED activities. 176 // Other disabled bits are handled by the KeyguardViewMediator talking directly to the 177 // status bar service. 178 int visFlags = 179 ( View.STATUS_BAR_DISABLE_BACK 180 | View.STATUS_BAR_DISABLE_HOME 181 ); 182 mKeyguardHost.setSystemUiVisibility(visFlags); 183 184 mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams); 185 mKeyguardHost.setVisibility(View.VISIBLE); 186 mKeyguardView.requestFocus(); 187 } 188 189 public void setNeedsInput(boolean needsInput) { 190 mNeedsInput = needsInput; 191 if (mWindowLayoutParams != null) { 192 if (needsInput) { 193 mWindowLayoutParams.flags &= 194 ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 195 } else { 196 mWindowLayoutParams.flags |= 197 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 198 } 199 mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams); 200 } 201 } 202 203 /** 204 * Reset the state of the view. 205 */ 206 public synchronized void reset() { 207 if (DEBUG) Log.d(TAG, "reset()"); 208 if (mKeyguardView != null) { 209 mKeyguardView.reset(); 210 } 211 } 212 213 public synchronized void onScreenTurnedOff() { 214 if (DEBUG) Log.d(TAG, "onScreenTurnedOff()"); 215 mScreenOn = false; 216 if (mKeyguardView != null) { 217 mKeyguardView.onScreenTurnedOff(); 218 } 219 } 220 221 public synchronized void onScreenTurnedOn( 222 final KeyguardViewManager.ShowListener showListener) { 223 if (DEBUG) Log.d(TAG, "onScreenTurnedOn()"); 224 mScreenOn = true; 225 if (mKeyguardView != null) { 226 mKeyguardView.onScreenTurnedOn(); 227 228 // Caller should wait for this window to be shown before turning 229 // on the screen. 230 if (mKeyguardHost.getVisibility() == View.VISIBLE) { 231 // Keyguard may be in the process of being shown, but not yet 232 // updated with the window manager... give it a chance to do so. 233 mKeyguardHost.post(new Runnable() { 234 @Override public void run() { 235 if (mKeyguardHost.getVisibility() == View.VISIBLE) { 236 showListener.onShown(mKeyguardHost.getWindowToken()); 237 } else { 238 showListener.onShown(null); 239 } 240 } 241 }); 242 } else { 243 showListener.onShown(null); 244 } 245 } else { 246 showListener.onShown(null); 247 } 248 } 249 250 public synchronized void verifyUnlock() { 251 if (DEBUG) Log.d(TAG, "verifyUnlock()"); 252 show(); 253 mKeyguardView.verifyUnlock(); 254 } 255 256 /** 257 * A key has woken the device. We use this to potentially adjust the state 258 * of the lock screen based on the key. 259 * 260 * The 'Tq' suffix is per the documentation in {@link android.view.WindowManagerPolicy}. 261 * Be sure not to take any action that takes a long time; any significant 262 * action should be posted to a handler. 263 * 264 * @param keyCode The wake key. May be {@link KeyEvent#KEYCODE_UNKNOWN} if waking 265 * for a reason other than a key press. 266 */ 267 public boolean wakeWhenReadyTq(int keyCode) { 268 if (DEBUG) Log.d(TAG, "wakeWhenReady(" + keyCode + ")"); 269 if (mKeyguardView != null) { 270 mKeyguardView.wakeWhenReadyTq(keyCode); 271 return true; 272 } else { 273 Log.w(TAG, "mKeyguardView is null in wakeWhenReadyTq"); 274 return false; 275 } 276 } 277 278 /** 279 * Hides the keyguard view 280 */ 281 public synchronized void hide() { 282 if (DEBUG) Log.d(TAG, "hide()"); 283 284 if (mKeyguardHost != null) { 285 mKeyguardHost.setVisibility(View.GONE); 286 // Don't do this right away, so we can let the view continue to animate 287 // as it goes away. 288 if (mKeyguardView != null) { 289 final KeyguardViewBase lastView = mKeyguardView; 290 mKeyguardView = null; 291 mKeyguardHost.postDelayed(new Runnable() { 292 public void run() { 293 synchronized (KeyguardViewManager.this) { 294 lastView.cleanUp(); 295 mKeyguardHost.removeView(lastView); 296 } 297 } 298 }, 500); 299 } 300 } 301 } 302 303 /** 304 * @return Whether the keyguard is showing 305 */ 306 public synchronized boolean isShowing() { 307 return (mKeyguardHost != null && mKeyguardHost.getVisibility() == View.VISIBLE); 308 } 309} 310