KeyguardViewManager.java revision 3fa8a454f61c772036f5f38661d1a077fd3d8388
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_HARDWARE_ACCELERATED
107                    | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED_SYSTEM
108                    /*| WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
109                    | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR*/ ;
110            if (!mNeedsInput) {
111                flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
112            }
113            WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
114                    stretch, stretch, WindowManager.LayoutParams.TYPE_KEYGUARD,
115                    flags, PixelFormat.TRANSLUCENT);
116            lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN;
117            lp.windowAnimations = com.android.internal.R.style.Animation_LockScreen;
118
119            // TODO: Sometimes we get the wrong value for the sensor resource we use to configure
120            // this.  However, the current UI design has LockScreen always respond to orientation so
121            // we don't need this for the time-being.
122            //
123            // For reference, the configuration variable is R.bool.config_enableLockScreenRotation
124            lp.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR;
125            lp.setTitle("Keyguard");
126            mWindowLayoutParams = lp;
127
128            mViewManager.addView(mKeyguardHost, lp);
129        }
130
131        if (mKeyguardView == null) {
132            if (DEBUG) Log.d(TAG, "keyguard view is null, creating it...");
133            mKeyguardView = mKeyguardViewProperties.createKeyguardView(mContext, mUpdateMonitor, this);
134            mKeyguardView.setId(R.id.lock_screen);
135            mKeyguardView.setCallback(mCallback);
136
137            final ViewGroup.LayoutParams lp = new FrameLayout.LayoutParams(
138                    ViewGroup.LayoutParams.MATCH_PARENT,
139                    ViewGroup.LayoutParams.MATCH_PARENT);
140
141            mKeyguardHost.addView(mKeyguardView, lp);
142
143            if (mScreenOn) {
144                mKeyguardView.onScreenTurnedOn();
145            }
146        }
147        mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
148        mKeyguardHost.setVisibility(View.VISIBLE);
149        mKeyguardView.requestFocus();
150    }
151
152    public void setNeedsInput(boolean needsInput) {
153        mNeedsInput = needsInput;
154        if (mWindowLayoutParams != null) {
155            if (needsInput) {
156                mWindowLayoutParams.flags &=
157                    ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
158            } else {
159                mWindowLayoutParams.flags |=
160                    WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
161            }
162            mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams);
163        }
164    }
165
166    /**
167     * Reset the state of the view.
168     */
169    public synchronized void reset() {
170        if (DEBUG) Log.d(TAG, "reset()");
171        if (mKeyguardView != null) {
172            mKeyguardView.reset();
173        }
174    }
175
176    public synchronized void onScreenTurnedOff() {
177        if (DEBUG) Log.d(TAG, "onScreenTurnedOff()");
178        mScreenOn = false;
179        if (mKeyguardView != null) {
180            mKeyguardView.onScreenTurnedOff();
181        }
182    }
183
184    public synchronized void onScreenTurnedOn() {
185        if (DEBUG) Log.d(TAG, "onScreenTurnedOn()");
186        mScreenOn = true;
187        if (mKeyguardView != null) {
188            mKeyguardView.onScreenTurnedOn();
189        }
190    }
191
192    public synchronized void verifyUnlock() {
193        if (DEBUG) Log.d(TAG, "verifyUnlock()");
194        show();
195        mKeyguardView.verifyUnlock();
196    }
197
198    /**
199     * A key has woken the device.  We use this to potentially adjust the state
200     * of the lock screen based on the key.
201     *
202     * The 'Tq' suffix is per the documentation in {@link android.view.WindowManagerPolicy}.
203     * Be sure not to take any action that takes a long time; any significant
204     * action should be posted to a handler.
205     *
206     * @param keyCode The wake key.  May be {@link KeyEvent#KEYCODE_UNKNOWN} if waking
207     * for a reason other than a key press.
208     */
209    public boolean wakeWhenReadyTq(int keyCode) {
210        if (DEBUG) Log.d(TAG, "wakeWhenReady(" + keyCode + ")");
211        if (mKeyguardView != null) {
212            mKeyguardView.wakeWhenReadyTq(keyCode);
213            return true;
214        } else {
215            Log.w(TAG, "mKeyguardView is null in wakeWhenReadyTq");
216            return false;
217        }
218    }
219
220    /**
221     * Hides the keyguard view
222     */
223    public synchronized void hide() {
224        if (DEBUG) Log.d(TAG, "hide()");
225        if (mKeyguardHost != null) {
226            mKeyguardHost.setVisibility(View.GONE);
227            // Don't do this right away, so we can let the view continue to animate
228            // as it goes away.
229            if (mKeyguardView != null) {
230                final KeyguardViewBase lastView = mKeyguardView;
231                mKeyguardView = null;
232                mKeyguardHost.postDelayed(new Runnable() {
233                    public void run() {
234                        synchronized (KeyguardViewManager.this) {
235                            lastView.cleanUp();
236                            mKeyguardHost.removeView(lastView);
237                        }
238                    }
239                }, 500);
240            }
241        }
242    }
243
244    /**
245     * @return Whether the keyguard is showing
246     */
247    public synchronized boolean isShowing() {
248        return (mKeyguardHost != null && mKeyguardHost.getVisibility() == View.VISIBLE);
249    }
250}
251