KeyguardBouncer.java revision 4e0880e395d37af03b1d635b847aa58569888277
1/*
2 * Copyright (C) 2014 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.systemui.statusbar.phone;
18
19import android.content.Context;
20import android.os.SystemClock;
21import android.view.KeyEvent;
22import android.view.LayoutInflater;
23import android.view.View;
24import android.view.ViewGroup;
25import android.view.animation.AnimationUtils;
26import android.view.animation.Interpolator;
27import android.view.animation.LinearInterpolator;
28
29import com.android.internal.widget.LockPatternUtils;
30import com.android.keyguard.KeyguardViewBase;
31import com.android.keyguard.R;
32import com.android.keyguard.ViewMediatorCallback;
33import com.android.systemui.keyguard.KeyguardViewMediator;
34
35import static com.android.keyguard.KeyguardHostView.OnDismissAction;
36import static com.android.keyguard.KeyguardSecurityModel.*;
37
38/**
39 * A class which manages the bouncer on the lockscreen.
40 */
41public class KeyguardBouncer {
42
43    private Context mContext;
44    private ViewMediatorCallback mCallback;
45    private LockPatternUtils mLockPatternUtils;
46    private ViewGroup mContainer;
47    private StatusBarWindowManager mWindowManager;
48    private KeyguardViewBase mKeyguardView;
49    private ViewGroup mRoot;
50    private Interpolator mFadeOutInterpolator = new LinearInterpolator();
51    private boolean mFadingOut;
52
53    public KeyguardBouncer(Context context, ViewMediatorCallback callback,
54            LockPatternUtils lockPatternUtils, StatusBarWindowManager windowManager,
55            ViewGroup container) {
56        mContext = context;
57        mCallback = callback;
58        mLockPatternUtils = lockPatternUtils;
59        mContainer = container;
60        mWindowManager = windowManager;
61    }
62
63    public void show() {
64        ensureView();
65        if (mRoot.getVisibility() == View.VISIBLE) {
66            return;
67        }
68
69        // Try to dismiss the Keyguard. If no security pattern is set, this will dismiss the whole
70        // Keyguard. If we need to authenticate, show the bouncer.
71        if (!mKeyguardView.dismiss()) {
72            mRoot.setVisibility(View.VISIBLE);
73            mKeyguardView.onResume();
74            mKeyguardView.startAppearAnimation();
75        }
76    }
77
78    public void showWithDismissAction(OnDismissAction r) {
79        ensureView();
80        mKeyguardView.setOnDismissAction(r);
81        show();
82    }
83
84    public void hide(boolean destroyView) {
85        if (mKeyguardView != null) {
86            mKeyguardView.cleanUp();
87        }
88        if (destroyView) {
89            removeView();
90        } else if (mRoot != null) {
91            mRoot.setVisibility(View.INVISIBLE);
92        }
93    }
94
95    public void animateHide(long delay, long duration) {
96        if (isShowing()) {
97            mFadingOut = true;
98            mKeyguardView.animate()
99                    .alpha(0)
100                    .withLayer()
101
102                    // Make it disappear faster, as the focus should be on the activity behind.
103                    .setDuration(duration / 2)
104                    .setInterpolator(mFadeOutInterpolator)
105                    .setStartDelay(delay)
106                    .withEndAction(new Runnable() {
107                        @Override
108                        public void run() {
109                            mFadingOut = false;
110                            hide(true /* destroyView */);
111                        }
112                    });
113        } else {
114            hide(true /* destroyView */);
115        }
116    }
117
118    /**
119     * Reset the state of the view.
120     */
121    public void reset() {
122        inflateView();
123    }
124
125    public void onScreenTurnedOff() {
126        if (mKeyguardView != null && mRoot != null && mRoot.getVisibility() == View.VISIBLE) {
127            mKeyguardView.onPause();
128        }
129    }
130
131    public long getUserActivityTimeout() {
132        if (mKeyguardView != null) {
133            long timeout = mKeyguardView.getUserActivityTimeout();
134            if (timeout >= 0) {
135                return timeout;
136            }
137        }
138        return KeyguardViewMediator.AWAKE_INTERVAL_DEFAULT_MS;
139    }
140
141    public boolean isShowing() {
142        return mRoot != null && mRoot.getVisibility() == View.VISIBLE && !mFadingOut;
143    }
144
145    public void prepare() {
146        ensureView();
147    }
148
149    private void ensureView() {
150        if (mRoot == null) {
151            inflateView();
152        }
153    }
154
155    private void inflateView() {
156        removeView();
157        mRoot = (ViewGroup) LayoutInflater.from(mContext).inflate(R.layout.keyguard_bouncer, null);
158        mKeyguardView = (KeyguardViewBase) mRoot.findViewById(R.id.keyguard_host_view);
159        mKeyguardView.setLockPatternUtils(mLockPatternUtils);
160        mKeyguardView.setViewMediatorCallback(mCallback);
161        mContainer.addView(mRoot, mContainer.getChildCount());
162        mRoot.setVisibility(View.INVISIBLE);
163        mRoot.setSystemUiVisibility(View.STATUS_BAR_DISABLE_HOME);
164    }
165
166    private void removeView() {
167        if (mRoot != null && mRoot.getParent() == mContainer) {
168            mContainer.removeView(mRoot);
169            mRoot = null;
170        }
171    }
172
173    public boolean onBackPressed() {
174        return mKeyguardView != null && mKeyguardView.handleBackKey();
175    }
176
177    /**
178     * @return True if and only if the current security method should be shown before showing
179     *         the notifications on Keyguard, like SIM PIN/PUK.
180     */
181    public boolean needsFullscreenBouncer() {
182        if (mKeyguardView != null) {
183            SecurityMode mode = mKeyguardView.getSecurityMode();
184            return mode == SecurityMode.SimPin
185                    || mode == SecurityMode.SimPuk;
186        }
187        return false;
188    }
189
190    public boolean isSecure() {
191        return mKeyguardView == null || mKeyguardView.getSecurityMode() != SecurityMode.None;
192    }
193
194    public boolean onMenuPressed() {
195        ensureView();
196        if (mKeyguardView.handleMenuKey()) {
197
198            // We need to show it in case it is secure. If not, it will get dismissed in any case.
199            mRoot.setVisibility(View.VISIBLE);
200            mKeyguardView.requestFocus();
201            mKeyguardView.onResume();
202            return true;
203        } else {
204            return false;
205        }
206    }
207
208    public boolean interceptMediaKey(KeyEvent event) {
209        ensureView();
210        return mKeyguardView.interceptMediaKey(event);
211    }
212}
213