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