diff options
Diffstat (limited to 'packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java')
-rw-r--r-- | packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java | 575 |
1 files changed, 0 insertions, 575 deletions
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java deleted file mode 100644 index 5b35ba8..0000000 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java +++ /dev/null @@ -1,575 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.keyguard; - -import android.graphics.Bitmap; -import android.graphics.drawable.BitmapDrawable; - -import com.android.internal.policy.IKeyguardShowCallback; -import com.android.internal.widget.LockPatternUtils; -import com.android.keyguard.analytics.KeyguardAnalytics; - -import org.xmlpull.v1.XmlPullParser; - -import android.app.ActivityManager; -import android.content.ContentResolver; -import android.content.Context; -import android.content.pm.ActivityInfo; -import android.content.res.Configuration; -import android.content.res.Resources; -import android.graphics.Canvas; -import android.graphics.ColorFilter; -import android.graphics.PixelFormat; -import android.graphics.PorterDuff; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.os.IBinder; -import android.os.Parcelable; -import android.os.RemoteException; -import android.os.SystemProperties; -import android.provider.Settings; -import android.util.Log; -import android.util.Slog; -import android.util.SparseArray; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewManager; -import android.view.WindowManager; -import android.widget.FrameLayout; - -/** - * Manages creating, showing, hiding and resetting the keyguard. Calls back - * via {@link KeyguardViewMediator.ViewMediatorCallback} to poke - * the wake lock and report that the keyguard is done, which is in turn, - * reported to this class by the current {@link KeyguardViewBase}. - */ -public class KeyguardViewManager { - private final static boolean DEBUG = KeyguardViewMediator.DEBUG; - private static String TAG = "KeyguardViewManager"; - public final static String IS_SWITCHING_USER = "is_switching_user"; - - // Delay dismissing keyguard to allow animations to complete. - private static final int HIDE_KEYGUARD_DELAY = 500; - - // Timeout used for keypresses - static final int DIGIT_PRESS_WAKE_MILLIS = 5000; - private static final boolean ENABLE_SIMPLE_KEYGUARD = false; - - private final Context mContext; - private final ViewManager mViewManager; - private final KeyguardViewMediator.ViewMediatorCallback mViewMediatorCallback; - private final KeyguardAnalytics.Callback mAnalyticsCallback; - - private WindowManager.LayoutParams mWindowLayoutParams; - private boolean mNeedsInput = false; - - private ViewManagerHost mKeyguardHost; - private KeyguardViewBase mKeyguardView; - - private boolean mScreenOn = false; - private LockPatternUtils mLockPatternUtils; - - private KeyguardUpdateMonitorCallback mBackgroundChanger = new KeyguardUpdateMonitorCallback() { - @Override - public void onSetBackground(Bitmap bmp) { - mKeyguardHost.setCustomBackground(bmp != null ? - new BitmapDrawable(mContext.getResources(), bmp) : null); - updateShowWallpaper(bmp == null); - } - }; - - public interface ShowListener { - void onShown(IBinder windowToken); - }; - - /** - * @param context Used to create views. - * @param viewManager Keyguard will be attached to this. - * @param callback Used to notify of changes. - * @param lockPatternUtils - */ - public KeyguardViewManager(Context context, ViewManager viewManager, - KeyguardViewMediator.ViewMediatorCallback callback, - LockPatternUtils lockPatternUtils, KeyguardAnalytics.Callback analyticsCallback) { - mContext = context; - mViewManager = viewManager; - mViewMediatorCallback = callback; - mLockPatternUtils = lockPatternUtils; - mAnalyticsCallback = analyticsCallback; - } - - /** - * Show the keyguard. Will handle creating and attaching to the view manager - * lazily. - */ - public synchronized void show(Bundle options) { - if (DEBUG) Log.d(TAG, "show(); mKeyguardView==" + mKeyguardView); - if (mAnalyticsCallback != null) { - mAnalyticsCallback.onShow(); - } - - boolean enableScreenRotation = shouldEnableScreenRotation(); - - maybeCreateKeyguardLocked(enableScreenRotation, false, options); - maybeEnableScreenRotation(enableScreenRotation); - - // Disable common aspects of the system/status/navigation bars that are not appropriate or - // useful on any keyguard screen but can be re-shown by dialogs or SHOW_WHEN_LOCKED - // activities. Other disabled bits are handled by the KeyguardViewMediator talking - // directly to the status bar service. - int visFlags = View.STATUS_BAR_DISABLE_HOME; - if (shouldEnableTranslucentDecor()) { - mWindowLayoutParams.flags |= WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS - | WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION; - } - if (DEBUG) Log.v(TAG, "show:setSystemUiVisibility(" + Integer.toHexString(visFlags)+")"); - mKeyguardHost.setSystemUiVisibility(visFlags); - - mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams); - mKeyguardHost.setVisibility(View.VISIBLE); - mKeyguardView.show(); - mKeyguardView.requestFocus(); - } - - private boolean shouldEnableScreenRotation() { - Resources res = mContext.getResources(); - return SystemProperties.getBoolean("lockscreen.rot_override",false) - || res.getBoolean(R.bool.config_enableLockScreenRotation); - } - - private boolean shouldEnableTranslucentDecor() { - Resources res = mContext.getResources(); - return res.getBoolean(R.bool.config_enableLockScreenTranslucentDecor); - } - - class ViewManagerHost extends FrameLayout { - private static final int BACKGROUND_COLOR = 0x70000000; - - private Drawable mCustomBackground; - - // This is a faster way to draw the background on devices without hardware acceleration - private final Drawable mBackgroundDrawable = new Drawable() { - @Override - public void draw(Canvas canvas) { - if (mCustomBackground != null) { - final Rect bounds = mCustomBackground.getBounds(); - final int vWidth = getWidth(); - final int vHeight = getHeight(); - - final int restore = canvas.save(); - canvas.translate(-(bounds.width() - vWidth) / 2, - -(bounds.height() - vHeight) / 2); - mCustomBackground.draw(canvas); - canvas.restoreToCount(restore); - } else { - canvas.drawColor(BACKGROUND_COLOR, PorterDuff.Mode.SRC); - } - } - - @Override - public void setAlpha(int alpha) { - } - - @Override - public void setColorFilter(ColorFilter cf) { - } - - @Override - public int getOpacity() { - return PixelFormat.TRANSLUCENT; - } - }; - - public ViewManagerHost(Context context) { - super(context); - setBackground(mBackgroundDrawable); - } - - public void setCustomBackground(Drawable d) { - mCustomBackground = d; - if (d != null) { - d.setColorFilter(BACKGROUND_COLOR, PorterDuff.Mode.SRC_OVER); - } - computeCustomBackgroundBounds(); - invalidate(); - } - - private void computeCustomBackgroundBounds() { - if (mCustomBackground == null) return; // Nothing to do - if (!isLaidOut()) return; // We'll do this later - - final int bgWidth = mCustomBackground.getIntrinsicWidth(); - final int bgHeight = mCustomBackground.getIntrinsicHeight(); - final int vWidth = getWidth(); - final int vHeight = getHeight(); - - final float bgAspect = (float) bgWidth / bgHeight; - final float vAspect = (float) vWidth / vHeight; - - if (bgAspect > vAspect) { - mCustomBackground.setBounds(0, 0, (int) (vHeight * bgAspect), vHeight); - } else { - mCustomBackground.setBounds(0, 0, vWidth, (int) (vWidth / bgAspect)); - } - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - computeCustomBackgroundBounds(); - } - - @Override - protected void onConfigurationChanged(Configuration newConfig) { - super.onConfigurationChanged(newConfig); - if (mKeyguardHost.getVisibility() == View.VISIBLE) { - // only propagate configuration messages if we're currently showing - maybeCreateKeyguardLocked(shouldEnableScreenRotation(), true, null); - } else { - if (DEBUG) Log.v(TAG, "onConfigurationChanged: view not visible"); - } - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - if (mKeyguardView != null) { - // Always process back and menu keys, regardless of focus - if (event.getAction() == KeyEvent.ACTION_DOWN) { - int keyCode = event.getKeyCode(); - if (keyCode == KeyEvent.KEYCODE_BACK && mKeyguardView.handleBackKey()) { - return true; - } else if (keyCode == KeyEvent.KEYCODE_MENU && mKeyguardView.handleMenuKey()) { - return true; - } - } - // Always process media keys, regardless of focus - if (mKeyguardView.dispatchKeyEvent(event)) { - return true; - } - } - return super.dispatchKeyEvent(event); - } - - @Override - public boolean dispatchTouchEvent(MotionEvent ev) { - boolean result = false; - if (mAnalyticsCallback != null) { - result = mAnalyticsCallback.onTouchEvent(ev, getWidth(), getHeight()) || result; - } - return super.dispatchTouchEvent(ev) || result; - } - } - - SparseArray<Parcelable> mStateContainer = new SparseArray<Parcelable>(); - private int mCurrentLayout; - - private void maybeCreateKeyguardLocked(boolean enableScreenRotation, boolean force, - Bundle options) { - if (mKeyguardHost != null) { - mKeyguardHost.saveHierarchyState(mStateContainer); - } - - if (mKeyguardHost == null) { - if (DEBUG) Log.d(TAG, "keyguard host is null, creating it..."); - - mKeyguardHost = new ViewManagerHost(mContext); - - int flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN - | WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR - | WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN - | WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; - - if (!mNeedsInput) { - flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; - } - - final int stretch = ViewGroup.LayoutParams.MATCH_PARENT; - final int type = WindowManager.LayoutParams.TYPE_KEYGUARD; - WindowManager.LayoutParams lp = new WindowManager.LayoutParams( - stretch, stretch, type, flags, PixelFormat.TRANSLUCENT); - lp.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE; - lp.windowAnimations = R.style.Animation_LockScreen; - lp.screenOrientation = enableScreenRotation ? - ActivityInfo.SCREEN_ORIENTATION_USER : ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; - - if (ActivityManager.isHighEndGfx()) { - lp.flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED; - lp.privateFlags |= - WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED; - } - lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY; - lp.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY; - lp.setTitle("Keyguard"); - mWindowLayoutParams = lp; - mViewManager.addView(mKeyguardHost, lp); - - KeyguardUpdateMonitor.getInstance(mContext).registerCallback(mBackgroundChanger); - } - - if (force || mKeyguardView == null) { - mKeyguardHost.setCustomBackground(null); - mKeyguardHost.removeAllViews(); - int layout = (allowNotificationsOnSecureKeyguard() && ENABLE_SIMPLE_KEYGUARD) - ? R.layout.keyguard_simple_host_view - : R.layout.keyguard_host_view; - if (mCurrentLayout != layout) { - mStateContainer.clear(); // don't restore to the wrong view hierarchy - mCurrentLayout = layout; - } - mKeyguardView = inflateKeyguardView(options, layout); - mKeyguardView.requestFocus(); - } - updateUserActivityTimeoutInWindowLayoutParams(); - mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams); - - mKeyguardHost.restoreHierarchyState(mStateContainer); - } - - private boolean allowNotificationsOnSecureKeyguard() { - ContentResolver cr = mContext.getContentResolver(); - return Settings.Global.getInt(cr, Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS, 0) == 1; - } - - private KeyguardViewBase inflateKeyguardView(Bundle options, int layoutId) { - View v = mKeyguardHost.findViewById(R.id.keyguard_host_view); - if (v != null) { - mKeyguardHost.removeView(v); - } - final LayoutInflater inflater = LayoutInflater.from(mContext); - View view = inflater.inflate(layoutId, mKeyguardHost, true); - KeyguardViewBase keyguard = (KeyguardViewBase) view.findViewById(R.id.keyguard_host_view); - keyguard.setLockPatternUtils(mLockPatternUtils); - keyguard.setViewMediatorCallback(mViewMediatorCallback); - keyguard.onUserSwitching(options != null && options.getBoolean(IS_SWITCHING_USER)); - keyguard.onCreateOptions(options); - return keyguard; - } - - public void updateUserActivityTimeout() { - updateUserActivityTimeoutInWindowLayoutParams(); - mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams); - } - - private void updateUserActivityTimeoutInWindowLayoutParams() { - // Use the user activity timeout requested by the keyguard view, if any. - if (mKeyguardView != null) { - long timeout = mKeyguardView.getUserActivityTimeout(); - if (timeout >= 0) { - mWindowLayoutParams.userActivityTimeout = timeout; - return; - } - } - - // Otherwise, use the default timeout. - mWindowLayoutParams.userActivityTimeout = KeyguardViewMediator.AWAKE_INTERVAL_DEFAULT_MS; - } - - private void maybeEnableScreenRotation(boolean enableScreenRotation) { - // TODO: move this outside - if (enableScreenRotation) { - if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen On!"); - mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_USER; - } else { - if (DEBUG) Log.d(TAG, "Rotation sensor for lock screen Off!"); - mWindowLayoutParams.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_NOSENSOR; - } - mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams); - } - - void updateShowWallpaper(boolean show) { - if (show) { - mWindowLayoutParams.flags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; - } else { - mWindowLayoutParams.flags &= ~WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER; - } - mWindowLayoutParams.format = show ? PixelFormat.TRANSLUCENT : PixelFormat.OPAQUE; - - mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams); - } - - public void setNeedsInput(boolean needsInput) { - mNeedsInput = needsInput; - if (mWindowLayoutParams != null) { - if (needsInput) { - mWindowLayoutParams.flags &= - ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; - } else { - mWindowLayoutParams.flags |= - WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; - } - - try { - mViewManager.updateViewLayout(mKeyguardHost, mWindowLayoutParams); - } catch (java.lang.IllegalArgumentException e) { - // TODO: Ensure this method isn't called on views that are changing... - Log.w(TAG,"Can't update input method on " + mKeyguardHost + " window not attached"); - } - } - } - - /** - * Reset the state of the view. - */ - public synchronized void reset(Bundle options) { - if (DEBUG) Log.d(TAG, "reset()"); - // User might have switched, check if we need to go back to keyguard - // TODO: It's preferable to stay and show the correct lockscreen or unlock if none - maybeCreateKeyguardLocked(shouldEnableScreenRotation(), true, options); - } - - public synchronized void onScreenTurnedOff() { - if (DEBUG) Log.d(TAG, "onScreenTurnedOff()"); - mScreenOn = false; - if (mKeyguardView != null) { - mKeyguardView.onScreenTurnedOff(); - } - } - - public synchronized void onScreenTurnedOn(final IKeyguardShowCallback callback) { - if (DEBUG) Log.d(TAG, "onScreenTurnedOn()"); - mScreenOn = true; - - // If keyguard is not showing, we need to inform PhoneWindowManager with a null - // token so it doesn't wait for us to draw... - final IBinder token = isShowing() ? mKeyguardHost.getWindowToken() : null; - - if (DEBUG && token == null) Slog.v(TAG, "send wm null token: " - + (mKeyguardHost == null ? "host was null" : "not showing")); - - if (mKeyguardView != null) { - mKeyguardView.onScreenTurnedOn(); - - // Caller should wait for this window to be shown before turning - // on the screen. - if (callback != null) { - if (mKeyguardHost.getVisibility() == View.VISIBLE) { - // Keyguard may be in the process of being shown, but not yet - // updated with the window manager... give it a chance to do so. - mKeyguardHost.post(new Runnable() { - @Override - public void run() { - try { - callback.onShown(token); - } catch (RemoteException e) { - Slog.w(TAG, "Exception calling onShown():", e); - } - } - }); - } else { - try { - callback.onShown(token); - } catch (RemoteException e) { - Slog.w(TAG, "Exception calling onShown():", e); - } - } - } - } else if (callback != null) { - try { - callback.onShown(token); - } catch (RemoteException e) { - Slog.w(TAG, "Exception calling onShown():", e); - } - } - if (mAnalyticsCallback != null) { - mAnalyticsCallback.onScreenOn(); - } - } - - public synchronized void verifyUnlock() { - if (DEBUG) Log.d(TAG, "verifyUnlock()"); - show(null); - mKeyguardView.verifyUnlock(); - } - - /** - * Hides the keyguard view - */ - public synchronized void hide() { - if (DEBUG) Log.d(TAG, "hide()"); - - if (mAnalyticsCallback != null) { - mAnalyticsCallback.onHide(); - } - - if (mKeyguardHost != null) { - mKeyguardHost.setVisibility(View.GONE); - - // We really only want to preserve keyguard state for configuration changes. Hence - // we should clear state of widgets (e.g. Music) when we hide keyguard so it can - // start with a fresh state when we return. - mStateContainer.clear(); - - // Don't do this right away, so we can let the view continue to animate - // as it goes away. - if (mKeyguardView != null) { - final KeyguardViewBase lastView = mKeyguardView; - mKeyguardView = null; - mKeyguardHost.postDelayed(new Runnable() { - @Override - public void run() { - synchronized (KeyguardViewManager.this) { - lastView.cleanUp(); - // Let go of any large bitmaps. - mKeyguardHost.setCustomBackground(null); - updateShowWallpaper(true); - mKeyguardHost.removeView(lastView); - mViewMediatorCallback.keyguardGone(); - } - } - }, HIDE_KEYGUARD_DELAY); - } - } - } - - /** - * Dismisses the keyguard by going to the next screen or making it gone. - */ - public synchronized void dismiss() { - if (mScreenOn) { - mKeyguardView.dismiss(); - } - } - - /** - * @return Whether the keyguard is showing - */ - public synchronized boolean isShowing() { - return (mKeyguardHost != null && mKeyguardHost.getVisibility() == View.VISIBLE); - } - - public void showAssistant() { - if (mKeyguardView != null) { - mKeyguardView.showAssistant(); - } - } - - public void dispatch(MotionEvent event) { - if (mKeyguardView != null) { - mKeyguardView.onExternalMotionEvent(event); - } - } - - public void launchCamera() { - if (mKeyguardView != null) { - mKeyguardView.launchCamera(); - } - } -} |