Fix problem where input wasn't being requested

This fixes a bug where input wasn't being enabled when the security
method changed.  The solution is to propagate changes back to the parent

Add missing copyright header to simplified keyguard view.

Bugs 12135931, 12879769

Change-Id: I0fc6cf8ef3b628c96a045797a5b9cdecd3a1007a
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
index 563aa0b..7ac94bd 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
@@ -400,8 +400,7 @@
     }
 
     @Override
-    protected boolean dismiss(boolean authenticated) {
-        // TODO Auto-generated method stub
+    public boolean dismiss(boolean authenticated) {
         boolean finished = super.dismiss(authenticated);
         if (!finished) {
             mViewStateManager.showBouncer(true);
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
index ea92b64..0f62100 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -44,8 +44,9 @@
 
     // Used to notify the container when something interesting happens.
     public interface SecurityCallback {
-        public void dismiss(boolean authenticated);
+        public boolean dismiss(boolean authenticated);
         public void userActivity(long timeout);
+        public void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput);
         public void finish();
     }
 
@@ -293,18 +294,12 @@
         showSecurityScreen(backup);
     }
 
-    private boolean showNextSecurityScreenIfPresent() {
-        SecurityMode securityMode = mSecurityModel.getSecurityMode();
-        // Allow an alternate, such as biometric unlock
-        securityMode = mSecurityModel.getAlternateFor(securityMode);
-        if (SecurityMode.None == securityMode) {
-            return false;
-        } else {
-            showSecurityScreen(securityMode); // switch to the alternate security view
-            return true;
-        }
-    }
-
+    /**
+     * Shows the next security screen if there is one.
+     * @param authenticated true if the user entered the correct authentication
+     * @param authenticated
+     * @return true if keyguard is done
+     */
     boolean showNextSecurityScreenOrFinish(boolean authenticated) {
         if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")");
         boolean finish = false;
@@ -386,6 +381,7 @@
         }
 
         mCurrentSecuritySelection = securityMode;
+        mSecurityCallback.onSecurityModeChanged(securityMode, newView.needsInput());
     }
 
     private KeyguardSecurityViewFlipper getFlipper() {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimpleHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimpleHostView.java
index d980964..cf983cb 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimpleHostView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimpleHostView.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2014 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.content.Context;
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
index 337beae..78f4506 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
@@ -56,7 +56,7 @@
  * Handles intercepting of media keys that still work when the keyguard is
  * showing.
  */
-public abstract class KeyguardViewBase extends FrameLayout {
+public abstract class KeyguardViewBase extends FrameLayout implements SecurityCallback {
 
     private AudioManager mAudioManager;
     private TelephonyManager mTelephonyManager = null;
@@ -104,22 +104,7 @@
                 (KeyguardSecurityContainer) findViewById(R.id.keyguard_security_container);
         mLockPatternUtils = new LockPatternUtils(mContext);
         mSecurityContainer.setLockPatternUtils(mLockPatternUtils);
-        mSecurityContainer.setSecurityCallback(new SecurityCallback() {
-            @Override
-            public void userActivity(long timeout) {
-                KeyguardViewBase.this.userActivity(timeout);
-            }
-
-            @Override
-            public void dismiss(boolean authenticated) {
-                KeyguardViewBase.this.dismiss(authenticated);
-            }
-
-            @Override
-            public void finish() {
-                KeyguardViewBase.this.finish();
-            }
-        });
+        mSecurityContainer.setSecurityCallback(this);
         mSecurityContainer.showPrimarySecurityScreen(false);
         // mSecurityContainer.updateSecurityViews(false /* not bouncing */);
         setBackButtonEnabled(false);
@@ -140,14 +125,6 @@
         dismiss(false);
     }
 
-    protected boolean dismiss(boolean authenticated) {
-        boolean finished = getSecurityContainer().showNextSecurityScreenOrFinish(authenticated);
-        if (!finished) {
-            updateAfterSecuritySelection();
-        }
-        return finished;
-    }
-
     private void setBackButtonEnabled(boolean enabled) {
         setSystemUiVisibility(enabled ?
                 getSystemUiVisibility() & ~View.STATUS_BAR_DISABLE_BACK :
@@ -180,27 +157,31 @@
         mSecurityContainer.announceCurrentSecurityMethod();
     }
 
-    private void updateAfterSecuritySelection() {
-        // Enable or disable the back button based on security mode
-        if (getSecurityContainer().getSecurityMode() == SecurityMode.Account
-                && !mLockPatternUtils.isPermanentlyLocked()) {
-            // we're showing account as a backup, provide a way to get back to primary
-            setBackButtonEnabled(true);
-        }
+    protected KeyguardSecurityContainer getSecurityContainer() {
+        return mSecurityContainer;
+    }
 
+    /**
+     * Extend display timeout
+     * @param timeout duration to delay timeout, in ms.
+     */
+    @Override
+    public void userActivity(long timeout) {
         if (mViewMediatorCallback != null) {
-            mViewMediatorCallback.setNeedsInput(getSecurityContainer().needsInput());
+            mViewMediatorCallback.userActivity(timeout);
         }
     }
 
-    protected KeyguardSecurityContainer getSecurityContainer() {
-        return mSecurityContainer;
+    @Override
+    public boolean dismiss(boolean authenticated) {
+        return mSecurityContainer.showNextSecurityScreenOrFinish(authenticated);
     }
 
     /**
      * Authentication has happened and it's time to dismiss keyguard. This function
      * should clean up and inform KeyguardViewMediator.
      */
+    @Override
     public void finish() {
         // If the alternate unlock was suppressed, it can now be safely
         // enabled because the user has left keyguard.
@@ -222,17 +203,20 @@
         }
     }
 
-    /**
-     * Extend display timeout
-     * @param timeout duration to delay timeout, in ms.
-     */
-    protected void userActivity(long timeout) {
+    @Override
+    public void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput) {
+        // Enable or disable the back button based on security mode
+        if (securityMode == SecurityMode.Account && !mLockPatternUtils.isPermanentlyLocked()) {
+            // we're showing account as a backup, provide a way to get back to primary
+            setBackButtonEnabled(true);
+        }
+
         if (mViewMediatorCallback != null) {
-            mViewMediatorCallback.userActivity(timeout);
+            mViewMediatorCallback.setNeedsInput(needsInput);
         }
     }
 
-    protected void userActivity() {
+    public void userActivity() {
         if (mViewMediatorCallback != null) {
             mViewMediatorCallback.userActivity();
         }
@@ -281,7 +265,7 @@
      * The result will be propogated back via {@link KeyguardViewCallback#keyguardDone(boolean)}
      */
     public void verifyUnlock() {
-        SecurityMode securityMode = getSecurityContainer().getSecurityMode();
+        SecurityMode securityMode = mSecurityContainer.getSecurityMode();
         if (securityMode == KeyguardSecurityModel.SecurityMode.None) {
             if (mViewMediatorCallback != null) {
                 mViewMediatorCallback.keyguardDone(true);
@@ -452,6 +436,8 @@
     public void setViewMediatorCallback(
             KeyguardViewMediator.ViewMediatorCallback viewMediatorCallback) {
         mViewMediatorCallback = viewMediatorCallback;
+        // Update ViewMediator with the current input method requirements
+        mViewMediatorCallback.setNeedsInput(mSecurityContainer.needsInput());
     }
 
     protected KeyguardActivityLauncher getActivityLauncher() {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
index 775eb08..baf520e 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewManager.java
@@ -26,6 +26,7 @@
 
 import android.app.ActivityManager;
 import android.appwidget.AppWidgetManager;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.pm.ActivityInfo;
 import android.content.res.Configuration;
@@ -41,6 +42,7 @@
 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;
@@ -69,7 +71,6 @@
 
     // Timeout used for keypresses
     static final int DIGIT_PRESS_WAKE_MILLIS = 5000;
-    private static final int HOST_LAYOUT = R.layout.keyguard_simple_host_view;
 
     private final Context mContext;
     private final ViewManager mViewManager;
@@ -263,6 +264,7 @@
     }
 
     SparseArray<Parcelable> mStateContainer = new SparseArray<Parcelable>();
+    private int mCurrentLayout;
 
     private void maybeCreateKeyguardLocked(boolean enableScreenRotation, boolean force,
             Bundle options) {
@@ -310,7 +312,14 @@
         if (force || mKeyguardView == null) {
             mKeyguardHost.setCustomBackground(null);
             mKeyguardHost.removeAllViews();
-            inflateKeyguardView(options);
+            int layout = allowNotificationsOnSecureKeyguard()
+                    ? 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();
@@ -319,31 +328,24 @@
         mKeyguardHost.restoreHierarchyState(mStateContainer);
     }
 
-    private void inflateKeyguardView(Bundle options) {
+    private boolean allowNotificationsOnSecureKeyguard() {
+        ContentResolver cr = mContext.getContentResolver();
+        return Settings.Secure.getInt(cr, Settings.Secure.LOCK_SCREEN_ALLOW_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(HOST_LAYOUT, mKeyguardHost, true);
-        mKeyguardView = (KeyguardViewBase) view.findViewById(R.id.keyguard_host_view);
-        mKeyguardView.setLockPatternUtils(mLockPatternUtils);
-        mKeyguardView.setViewMediatorCallback(mViewMediatorCallback);
-        mKeyguardView.onUserSwitching(options != null && options.getBoolean(IS_SWITCHING_USER));
-
-        // HACK
-        // The keyguard view will have set up window flags in onFinishInflate before we set
-        // the view mediator callback. Make sure it knows the correct IME state.
-        if (mViewMediatorCallback != null) {
-            KeyguardPasswordView kpv = (KeyguardPasswordView) mKeyguardView.findViewById(
-                    R.id.keyguard_password_view);
-
-            if (kpv != null) {
-                mViewMediatorCallback.setNeedsInput(kpv.needsInput());
-            }
-        }
-
-        mKeyguardView.onCreateOptions(options);
+        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() {