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.content.Context; 22import android.content.pm.ActivityInfo; 23import android.graphics.PixelFormat; 24import android.graphics.Canvas; 25import android.util.Log; 26import android.view.View; 27import android.view.ViewGroup; 28import android.view.ViewManager; 29import android.view.WindowManager; 30import android.widget.FrameLayout; 31 32/** 33 * Manages creating, showing, hiding and resetting the keyguard. Calls back 34 * via {@link com.android.internal.policy.impl.KeyguardViewCallback} to poke 35 * the wake lock and report that the keyguard is done, which is in turn, 36 * reported to this class by the current {@link KeyguardViewBase}. 37 */ 38public class KeyguardViewManager implements KeyguardWindowController { 39 private final static boolean DEBUG = false; 40 private static String TAG = "KeyguardViewManager"; 41 42 private final Context mContext; 43 private final ViewManager mViewManager; 44 private final KeyguardViewCallback mCallback; 45 private final KeyguardViewProperties mKeyguardViewProperties; 46 47 private final KeyguardUpdateMonitor mUpdateMonitor; 48 49 private WindowManager.LayoutParams mWindowLayoutParams; 50 private boolean mNeedsInput = false; 51 52 private FrameLayout mKeyguardHost; 53 private KeyguardViewBase mKeyguardView; 54 55 private boolean mScreenOn = false; 56 57 /** 58 * @param context Used to create views. 59 * @param viewManager Keyguard will be attached to this. 60 * @param callback Used to notify of changes. 61 */ 62 public KeyguardViewManager(Context context, ViewManager viewManager, 63 KeyguardViewCallback callback, KeyguardViewProperties keyguardViewProperties, KeyguardUpdateMonitor updateMonitor) { 64 mContext = context; 65 mViewManager = viewManager; 66 mCallback = callback; 67 mKeyguardViewProperties = keyguardViewProperties; 68 69 mUpdateMonitor = updateMonitor; 70 } 71 72 /** 73 * Helper class to host the keyguard view. 74 */ 75 private static class KeyguardViewHost extends FrameLayout { 76 private final KeyguardViewCallback mCallback; 77 78 private KeyguardViewHost(Context context, KeyguardViewCallback callback) { 79 super(context); 80 mCallback = callback; 81 } 82 83 @Override 84 protected void dispatchDraw(Canvas canvas) { 85 super.dispatchDraw(canvas); 86 mCallback.keyguardDoneDrawing(); 87 } 88 } 89 90 /** 91 * Show the keyguard. Will handle creating and attaching to the view manager 92 * lazily. 93 */ 94 public synchronized void show() { 95 if (DEBUG) Log.d(TAG, "show(); mKeyguardView==" + mKeyguardView); 96 97 if (mKeyguardHost == null) { 98 if (DEBUG) Log.d(TAG, "keyguard host is null, creating it..."); 99 100 mKeyguardHost = new KeyguardViewHost(mContext, mCallback); 101 102 final int stretch = ViewGroup.LayoutParams.MATCH_PARENT; 103 int flags = WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN 104 | WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER 105 | WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING 106 /*| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 107 | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR*/ ; 108 if (!mNeedsInput) { 109 flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 110 } 111 WindowManager.LayoutParams lp = new WindowManager.LayoutParams( 112 stretch, stretch, WindowManager.LayoutParams.TYPE_KEYGUARD, 113 flags, PixelFormat.TRANSLUCENT); 114 lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN; 115 lp.windowAnimations = com.android.internal.R.style.Animation_LockScreen; 116 lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; 117 lp.setTitle("Keyguard"); 118 mWindowLayoutParams = lp; 119 120 mViewManager.addView(mKeyguardHost, lp); 121 } 122 123 if (mKeyguardView == null) { 124 if (DEBUG) Log.d(TAG, "keyguard view is null, creating it..."); 125 mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this); 126 mKeyguardView.setId(R.id.lock_screen); 127 mKeyguardView.setCallback(mCallback); 128 129 final ViewGroup.LayoutParams lp = new FrameLayout.LayoutParams( 130 ViewGroup.LayoutParams.MATCH_PARENT, 131 ViewGroup.LayoutParams.MATCH_PARENT); 132 133 mKeyguardHost.addView(mKeyguardView, lp); 134 135 if (mScreenOn) { 136 mKeyguardView.onScreenTurnedOn(); 137 } 138 } 139 140 mKeyguardHost.setVisibility(View.VISIBLE); 141 mKeyguardView.requestFocus(); 142 } 143 144 public void setNeedsInput(boolean needsInput) { 145 mNeedsInput = needsInput; 146 if (mWindowLayoutParams != null) { 147 if (needsInput) { 148 mWindowLayoutParams.flags &= 149 ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 150 } else { 151 mWindowLayoutParams.flags |= 152 WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; 153 } 154 mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams); 155 } 156 } 157 158 /** 159 * Reset the state of the view. 160 */ 161 public synchronized void reset() { 162 if (DEBUG) Log.d(TAG, "reset()"); 163 if (mKeyguardView != null) { 164 mKeyguardView.reset(); 165 } 166 } 167 168 public synchronized void onScreenTurnedOff() { 169 if (DEBUG) Log.d(TAG, "onScreenTurnedOff()"); 170 mScreenOn = false; 171 if (mKeyguardView != null) { 172 mKeyguardView.onScreenTurnedOff(); 173 } 174 } 175 176 public synchronized void onScreenTurnedOn() { 177 if (DEBUG) Log.d(TAG, "onScreenTurnedOn()"); 178 mScreenOn = true; 179 if (mKeyguardView != null) { 180 mKeyguardView.onScreenTurnedOn(); 181 } 182 } 183 184 public synchronized void verifyUnlock() { 185 if (DEBUG) Log.d(TAG, "verifyUnlock()"); 186 show(); 187 mKeyguardView.verifyUnlock(); 188 } 189 190 /** 191 * A key has woken the device. We use this to potentially adjust the state 192 * of the lock screen based on the key. 193 * 194 * The 'Tq' suffix is per the documentation in {@link android.view.WindowManagerPolicy}. 195 * Be sure not to take any action that takes a long time; any significant 196 * action should be posted to a handler. 197 * 198 * @param keyCode The wake key. 199 */ 200 public boolean wakeWhenReadyTq(int keyCode) { 201 if (DEBUG) Log.d(TAG, "wakeWhenReady(" + keyCode + ")"); 202 if (mKeyguardView != null) { 203 mKeyguardView.wakeWhenReadyTq(keyCode); 204 return true; 205 } else { 206 Log.w(TAG, "mKeyguardView is null in wakeWhenReadyTq"); 207 return false; 208 } 209 } 210 211 /** 212 * Hides the keyguard view 213 */ 214 public synchronized void hide() { 215 if (DEBUG) Log.d(TAG, "hide()"); 216 if (mKeyguardHost != null) { 217 mKeyguardHost.setVisibility(View.GONE); 218 // Don't do this right away, so we can let the view continue to animate 219 // as it goes away. 220 if (mKeyguardView != null) { 221 final KeyguardViewBase lastView = mKeyguardView; 222 mKeyguardView = null; 223 mKeyguardHost.postDelayed(new Runnable() { 224 public void run() { 225 synchronized (KeyguardViewManager.this) { 226 lastView.cleanUp(); 227 mKeyguardHost.removeView(lastView); 228 } 229 } 230 }, 500); 231 } 232 } 233 } 234 235 /** 236 * @return Whether the keyguard is showing 237 */ 238 public synchronized boolean isShowing() { 239 return (mKeyguardHost != null && mKeyguardHost.getVisibility() == View.VISIBLE); 240 } 241} 242