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 17 package com.android.internal.policy.impl.keyguard_obsolete; 18 19 import com.android.internal.R; 20 21 import android.app.ActivityManager; 22 import android.content.Context; 23 import android.content.pm.ActivityInfo; 24 import android.content.res.Resources; 25 import android.graphics.PixelFormat; 26 import android.graphics.Canvas; 27 import android.os.IBinder; 28 import android.os.SystemProperties; 29 import android.util.Log; 30 import android.view.View; 31 import android.view.ViewGroup; 32 import android.view.ViewManager; 33 import android.view.WindowManager; 34 import android.widget.FrameLayout; 35 36 import 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 */ 44 public 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_SLIPPERY 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()) { 127 flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; 128 } 129 WindowManager.LayoutParams lp = new WindowManager.LayoutParams( 130 stretch, stretch, WindowManager.LayoutParams.TYPE_KEYGUARD, 131 flags, PixelFormat.TRANSLUCENT); 132 lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; 133 lp.windowAnimations = com.android.internal.R.style.Animation_LockScreen; 134 if (ActivityManager.isHighEndGfx()) { 135 lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; 136 lp.privateFlags |= 137 WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED; 138 } 139 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY; 140 lp.setTitle("Keyguard"); 141 mWindowLayoutParams = lp; 142 143 mViewManager.addView(mKeyguardHost, lp); 144 } 145 146 if (enableScreenRotation) { 147 if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen On!"); 148 mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER; 149 } else { 150 if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen Off!"); 151 mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; 152 } 153 154 mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams); 155 156 if (mKeyguardView == null) { 157 if (DEBUG) Log.d(TAG, "keyguard view is null, creating it..."); 158 mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mCallback, 159 mUpdateMonitor, this); 160 mKeyguardView.setId(R.id.lock_screen); 161 162 final ViewGroup.LayoutParams lp = new FrameLayout.LayoutParams( 163 ViewGroup.LayoutParams.MATCH_PARENT, 164 ViewGroup.LayoutParams.MATCH_PARENT); 165 166 mKeyguardHost.addView(mKeyguardView, lp); 167 168 if (mScreenOn) { 169 mKeyguardView.show(); 170 } 171 } 172 173 // Disable aspects of the system/status/navigation bars that are not appropriate or 174 // useful for the lockscreen but can be re-shown by dialogs or SHOW_WHEN_LOCKED activities. 175 // Other disabled bits are handled by the KeyguardViewMediator talking directly to the 176 // status bar service. 177 int visFlags = 178 ( View.STATUS_BAR_DISABLE_BACK 179 | View.STATUS_BAR_DISABLE_HOME 180 ); 181 Log.v(TAG, "KGVM: Set visibility on " + mKeyguardHost + " to " + visFlags); 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 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