Home | History | Annotate | Download | only in impl
      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;
     18 
     19 import com.android.internal.R;
     20 
     21 import android.content.Context;
     22 import android.content.pm.ActivityInfo;
     23 import android.graphics.PixelFormat;
     24 import android.graphics.Canvas;
     25 import android.util.Log;
     26 import android.view.View;
     27 import android.view.ViewGroup;
     28 import android.view.ViewManager;
     29 import android.view.WindowManager;
     30 import 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  */
     38 public 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                             mKeyguardHost.removeView(lastView);
    227                             lastView.cleanUp();
    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