Merge "Hide KeyguardMessageArea if empty" into mnc-dev
diff --git a/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml
index 9b55e5b..3ea22e9 100644
--- a/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml
+++ b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml
@@ -26,8 +26,7 @@
     android:orientation="vertical"
     android:gravity="center"
     android:layout_gravity="center_horizontal"
-    android:layout_alignParentBottom="true"
-    android:clickable="true">
+    android:layout_alignParentBottom="true">
 
     <com.android.keyguard.CarrierText
         android:id="@+id/carrier_text"
diff --git a/packages/Keyguard/res/layout/keyguard_message_area.xml b/packages/Keyguard/res/layout/keyguard_message_area.xml
index a709e98..46aa39d 100644
--- a/packages/Keyguard/res/layout/keyguard_message_area.xml
+++ b/packages/Keyguard/res/layout/keyguard_message_area.xml
@@ -29,5 +29,5 @@
     android:textAppearance="?android:attr/textAppearance"
     android:textSize="@dimen/kg_status_line_font_size"
     android:textColor="?android:attr/textColorSecondary"
-    android:clickable="true" />
+    android:focusable="true" />
 
diff --git a/packages/Keyguard/res/layout/keyguard_pattern_view.xml b/packages/Keyguard/res/layout/keyguard_pattern_view.xml
index 61480650..0f5431e 100644
--- a/packages/Keyguard/res/layout/keyguard_pattern_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_pattern_view.xml
@@ -65,6 +65,8 @@
                 android:layout_gravity="center_horizontal"
                 android:gravity="center"
                 android:contentDescription="@string/keyguard_accessibility_pattern_area"
+                android:focusable="true"
+                android:focusableInTouchMode="true"
                 android:clipChildren="false"
                 android:clipToPadding="false" />
 
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index 4edc1c9..aa99a7b 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -86,7 +86,7 @@
     @Override
     protected void onFinishInflate() {
         mLockPatternUtils = new LockPatternUtils(mContext);
-        mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
+        mSecurityMessageDisplay = KeyguardMessageArea.findSecurityMessageDisplay(this);
         mEcaView = findViewById(R.id.keyguard_selector_fade_container);
 
         EmergencyButton button = (EmergencyButton) findViewById(R.id.emergency_call_button);
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
index 40fd920..301b171 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
@@ -16,27 +16,21 @@
 
 package com.android.keyguard;
 
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.SystemClock;
 import android.text.TextUtils;
 import android.util.AttributeSet;
-import android.util.MutableInt;
 import android.view.View;
 import android.widget.TextView;
 
 import java.lang.ref.WeakReference;
 
-import com.android.internal.widget.LockPatternUtils;
-
 /***
  * Manages a number of views inside of the given layout. See below for a list of widgets.
  */
-class KeyguardMessageArea extends TextView {
+class KeyguardMessageArea extends TextView implements SecurityMessageDisplay {
     /** Handler token posted with accessibility announcement runnables. */
     private static final Object ANNOUNCE_TOKEN = new Object();
 
@@ -46,96 +40,23 @@
      */
     private static final long ANNOUNCEMENT_DELAY = 250;
 
-    static final int SECURITY_MESSAGE_DURATION = 5000;
-    protected static final int FADE_DURATION = 750;
+    private static final int SECURITY_MESSAGE_DURATION = 5000;
 
-    private static final String TAG = "KeyguardMessageArea";
-
-    // is the bouncer up?
-    boolean mShowingBouncer = false;
-
-    KeyguardUpdateMonitor mUpdateMonitor;
+    private final KeyguardUpdateMonitor mUpdateMonitor;
+    private final Handler mHandler;
 
     // Timeout before we reset the message to show charging/owner info
     long mTimeout = SECURITY_MESSAGE_DURATION;
-
-    private Handler mHandler;
-
     CharSequence mMessage;
-    boolean mShowingMessage;
-    private CharSequence mSeparator;
-    private LockPatternUtils mLockPatternUtils;
 
-    Runnable mClearMessageRunnable = new Runnable() {
+    private final Runnable mClearMessageRunnable = new Runnable() {
         @Override
         public void run() {
             mMessage = null;
-            mShowingMessage = false;
-            if (mShowingBouncer) {
-                hideMessage(FADE_DURATION, true);
-            } else {
-                update();
-            }
+            update();
         }
     };
 
-    public static class Helper implements SecurityMessageDisplay {
-        KeyguardMessageArea mMessageArea;
-        Helper(View v) {
-            mMessageArea = (KeyguardMessageArea) v.findViewById(R.id.keyguard_message_area);
-            if (mMessageArea == null) {
-                throw new RuntimeException("Can't find keyguard_message_area in " + v.getClass());
-            }
-        }
-
-        @Override
-        public void setMessage(CharSequence msg, boolean important) {
-            if (!TextUtils.isEmpty(msg) && important) {
-                mMessageArea.mMessage = msg;
-                mMessageArea.securityMessageChanged();
-            } else {
-                mMessageArea.clearMessage();
-            }
-        }
-
-        @Override
-        public void setMessage(int resId, boolean important) {
-            if (resId != 0 && important) {
-                mMessageArea.mMessage = mMessageArea.getContext().getResources().getText(resId);
-                mMessageArea.securityMessageChanged();
-            } else {
-                mMessageArea.clearMessage();
-            }
-        }
-
-        @Override
-        public void setMessage(int resId, boolean important, Object... formatArgs) {
-            if (resId != 0 && important) {
-                mMessageArea.mMessage = mMessageArea.getContext().getString(resId, formatArgs);
-                mMessageArea.securityMessageChanged();
-            } else {
-                mMessageArea.clearMessage();
-            }
-        }
-
-        @Override
-        public void showBouncer(int duration) {
-            mMessageArea.hideMessage(duration, false);
-            mMessageArea.mShowingBouncer = true;
-        }
-
-        @Override
-        public void hideBouncer(int duration) {
-            mMessageArea.showMessage(duration);
-            mMessageArea.mShowingBouncer = false;
-        }
-
-        @Override
-        public void setTimeout(int timeoutMs) {
-            mMessageArea.mTimeout = timeoutMs;
-        }
-    }
-
     private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
         public void onScreenTurnedOff(int why) {
             setSelected(false);
@@ -153,28 +74,64 @@
         super(context, attrs);
         setLayerType(LAYER_TYPE_HARDWARE, null); // work around nested unclipped SaveLayer bug
 
-        mLockPatternUtils = new LockPatternUtils(context);
-
-        // Registering this callback immediately updates the battery state, among other things.
         mUpdateMonitor = KeyguardUpdateMonitor.getInstance(getContext());
         mUpdateMonitor.registerCallback(mInfoCallback);
         mHandler = new Handler(Looper.myLooper());
 
-        mSeparator = getResources().getString(
-                com.android.internal.R.string.kg_text_message_separator);
-
         update();
     }
 
     @Override
+    public void setMessage(CharSequence msg, boolean important) {
+        if (!TextUtils.isEmpty(msg) && important) {
+            securityMessageChanged(msg);
+        } else {
+            clearMessage();
+        }
+    }
+
+    @Override
+    public void setMessage(int resId, boolean important) {
+        if (resId != 0 && important) {
+            CharSequence message = getContext().getResources().getText(resId);
+            securityMessageChanged(message);
+        } else {
+            clearMessage();
+        }
+    }
+
+    @Override
+    public void setMessage(int resId, boolean important, Object... formatArgs) {
+        if (resId != 0 && important) {
+            String message = getContext().getString(resId, formatArgs);
+            securityMessageChanged(message);
+        } else {
+            clearMessage();
+        }
+    }
+
+    @Override
+    public void setTimeout(int timeoutMs) {
+        mTimeout = timeoutMs;
+    }
+
+    public static SecurityMessageDisplay findSecurityMessageDisplay(View v) {
+        KeyguardMessageArea messageArea = (KeyguardMessageArea) v.findViewById(
+                R.id.keyguard_message_area);
+        if (messageArea == null) {
+            throw new RuntimeException("Can't find keyguard_message_area in " + v.getClass());
+        }
+        return messageArea;
+    }
+
+    @Override
     protected void onFinishInflate() {
         final boolean screenOn = KeyguardUpdateMonitor.getInstance(mContext).isScreenOn();
         setSelected(screenOn); // This is required to ensure marquee works
     }
 
-    public void securityMessageChanged() {
-        setAlpha(1f);
-        mShowingMessage = true;
+    private void securityMessageChanged(CharSequence message) {
+        mMessage = message;
         update();
         mHandler.removeCallbacks(mClearMessageRunnable);
         if (mTimeout > 0) {
@@ -185,61 +142,18 @@
                 (SystemClock.uptimeMillis() + ANNOUNCEMENT_DELAY));
     }
 
-    public void clearMessage() {
+    private void clearMessage() {
         mHandler.removeCallbacks(mClearMessageRunnable);
         mHandler.post(mClearMessageRunnable);
     }
 
-    /**
-     * Update the status lines based on these rules:
-     * AlarmStatus: Alarm state always gets it's own line.
-     * Status1 is shared between help, battery status and generic unlock instructions,
-     * prioritized in that order.
-     * @param showStatusLines status lines are shown if true
-     */
-    void update() {
-        MutableInt icon = new MutableInt(0);
-        CharSequence status = getCurrentMessage();
-        setCompoundDrawablesWithIntrinsicBounds(icon.value, 0, 0, 0);
+    private void update() {
+        CharSequence status = mMessage;
+        setVisibility(TextUtils.isEmpty(status) ? INVISIBLE : VISIBLE);
         setText(status);
     }
 
 
-    CharSequence getCurrentMessage() {
-        return mShowingMessage ? mMessage : null;
-    }
-
-    private void hideMessage(int duration, boolean thenUpdate) {
-        if (duration > 0) {
-            Animator anim = ObjectAnimator.ofFloat(this, "alpha", 0f);
-            anim.setDuration(duration);
-            if (thenUpdate) {
-                anim.addListener(new AnimatorListenerAdapter() {
-                        @Override
-                            public void onAnimationEnd(Animator animation) {
-                            update();
-                        }
-                });
-            }
-            anim.start();
-        } else {
-            setAlpha(0f);
-            if (thenUpdate) {
-                update();
-            }
-        }
-    }
-
-    private void showMessage(int duration) {
-        if (duration > 0) {
-            Animator anim = ObjectAnimator.ofFloat(this, "alpha", 1f);
-            anim.setDuration(duration);
-            anim.start();
-        } else {
-            setAlpha(1f);
-        }
-    }
-
     /**
      * Runnable used to delay accessibility announcements.
      */
@@ -247,7 +161,7 @@
         private final WeakReference<View> mHost;
         private final CharSequence mTextToAnnounce;
 
-        public AnnounceRunnable(View host, CharSequence textToAnnounce) {
+        AnnounceRunnable(View host, CharSequence textToAnnounce) {
             mHost = new WeakReference<View>(host);
             mTextToAnnounce = textToAnnounce;
         }
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
index ed595c0..a9b2978 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
@@ -129,7 +129,6 @@
 
         mLockPatternView = (LockPatternView) findViewById(R.id.lockPatternView);
         mLockPatternView.setSaveEnabled(false);
-        mLockPatternView.setFocusable(false);
         mLockPatternView.setOnPatternListener(new UnlockPatternListener());
 
         // stealth mode will be the same for the life of this screen
@@ -139,9 +138,7 @@
         // vibrate mode will be the same for the life of this screen
         mLockPatternView.setTactileFeedbackEnabled(mLockPatternUtils.isTactileFeedbackEnabled());
 
-        setFocusableInTouchMode(true);
-
-        mSecurityMessageDisplay = new KeyguardMessageArea.Helper(this);
+        mSecurityMessageDisplay = KeyguardMessageArea.findSecurityMessageDisplay(this);
         mEcaView = findViewById(R.id.keyguard_selector_fade_container);
         mContainer = (ViewGroup) findViewById(R.id.container);
         mHelpMessage = (KeyguardMessageArea) findViewById(R.id.keyguard_message_area);
diff --git a/packages/Keyguard/src/com/android/keyguard/SecurityMessageDisplay.java b/packages/Keyguard/src/com/android/keyguard/SecurityMessageDisplay.java
index e2f91e3..b38cfd5 100644
--- a/packages/Keyguard/src/com/android/keyguard/SecurityMessageDisplay.java
+++ b/packages/Keyguard/src/com/android/keyguard/SecurityMessageDisplay.java
@@ -24,8 +24,4 @@
     public void setMessage(int resId, boolean important, Object... formatArgs);
 
     public void setTimeout(int timeout_ms);
-
-    public void showBouncer(int animationDuration);
-
-    public void hideBouncer(int animationDuration);
 }