am c86e8dff: Merge "Fix WiFi stress test" into jb-mr1-dev

* commit 'c86e8dffd04804f7f975c80325bc3ae70e7e972a':
  Fix WiFi stress test
diff --git a/core/java/android/appwidget/AppWidgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
index fcecd04..d56556f 100644
--- a/core/java/android/appwidget/AppWidgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -144,6 +144,7 @@
             // We add padding to the AppWidgetHostView if necessary
             Rect padding = getDefaultPaddingForWidget(mContext, info.provider, null);
             setPadding(padding.left, padding.top, padding.right, padding.bottom);
+            setContentDescription(info.label);
         }
     }
 
diff --git a/core/java/com/android/internal/policy/IFaceLockCallback.aidl b/core/java/com/android/internal/policy/IFaceLockCallback.aidl
index eb902fd..280e4d5 100644
--- a/core/java/com/android/internal/policy/IFaceLockCallback.aidl
+++ b/core/java/com/android/internal/policy/IFaceLockCallback.aidl
@@ -22,6 +22,5 @@
     void unlock();
     void cancel();
     void reportFailedAttempt();
-    void exposeFallback();
     void pokeWakelock(int millis);
 }
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 6c5ed7e..7a76ab0 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -18,7 +18,6 @@
 
 
 import android.content.Context;
-import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -33,11 +32,9 @@
 import android.os.Parcelable;
 import android.os.SystemClock;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.HapticFeedbackConstants;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 
 import com.android.internal.R;
@@ -657,9 +654,11 @@
                 handleActionMove(event);
                 return true;
             case MotionEvent.ACTION_CANCEL:
-                resetPattern();
-                mPatternInProgress = false;
-                notifyPatternCleared();
+                if (mPatternInProgress) {
+                    mPatternInProgress = false;
+                    resetPattern();
+                    notifyPatternCleared();
+                }
                 if (PROFILE_DRAWING) {
                     if (mDrawingProfilingStarted) {
                         Debug.stopMethodTracing();
@@ -826,7 +825,7 @@
             mPatternInProgress = true;
             mPatternDisplayMode = DisplayMode.Correct;
             notifyPatternStarted();
-        } else {
+        } else if (mPatternInProgress) {
             mPatternInProgress = false;
             notifyPatternCleared();
         }
diff --git a/core/res/res/drawable-hdpi/kg_security_lock_focused.png b/core/res/res/drawable-hdpi/kg_security_lock_focused.png
new file mode 100644
index 0000000..9a82799
--- /dev/null
+++ b/core/res/res/drawable-hdpi/kg_security_lock_focused.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_security_lock_normal.png b/core/res/res/drawable-hdpi/kg_security_lock_normal.png
new file mode 100644
index 0000000..d608707
--- /dev/null
+++ b/core/res/res/drawable-hdpi/kg_security_lock_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/kg_security_lock_pressed.png b/core/res/res/drawable-hdpi/kg_security_lock_pressed.png
new file mode 100644
index 0000000..7ca995d
--- /dev/null
+++ b/core/res/res/drawable-hdpi/kg_security_lock_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_security_lock_focused.png b/core/res/res/drawable-mdpi/kg_security_lock_focused.png
new file mode 100644
index 0000000..c3608f9
--- /dev/null
+++ b/core/res/res/drawable-mdpi/kg_security_lock_focused.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_security_lock_normal.png b/core/res/res/drawable-mdpi/kg_security_lock_normal.png
new file mode 100644
index 0000000..7957c79
--- /dev/null
+++ b/core/res/res/drawable-mdpi/kg_security_lock_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/kg_security_lock_pressed.png b/core/res/res/drawable-mdpi/kg_security_lock_pressed.png
new file mode 100644
index 0000000..41715f5
--- /dev/null
+++ b/core/res/res/drawable-mdpi/kg_security_lock_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_security_lock_focused.png b/core/res/res/drawable-xhdpi/kg_security_lock_focused.png
new file mode 100644
index 0000000..db22016
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/kg_security_lock_focused.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_security_lock_normal.png b/core/res/res/drawable-xhdpi/kg_security_lock_normal.png
new file mode 100644
index 0000000..17ebb5f
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/kg_security_lock_normal.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/kg_security_lock_pressed.png b/core/res/res/drawable-xhdpi/kg_security_lock_pressed.png
new file mode 100644
index 0000000..186b6ff
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/kg_security_lock_pressed.png
Binary files differ
diff --git a/core/res/res/drawable/keyguard_expand_challenge_handle.xml b/core/res/res/drawable/keyguard_expand_challenge_handle.xml
new file mode 100644
index 0000000..3e0780b
--- /dev/null
+++ b/core/res/res/drawable/keyguard_expand_challenge_handle.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2012 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_focused="true" android:drawable="@drawable/kg_security_lock_focused" />
+    <item android:state_pressed="true" android:drawable="@drawable/kg_security_lock_pressed" />
+    <item android:drawable="@drawable/kg_security_lock_normal" />
+</selector>
diff --git a/core/res/res/layout-port/keyguard_host_view.xml b/core/res/res/layout-port/keyguard_host_view.xml
index a3c8105..bba1b04 100644
--- a/core/res/res/layout-port/keyguard_host_view.xml
+++ b/core/res/res/layout-port/keyguard_host_view.xml
@@ -31,8 +31,7 @@
     <com.android.internal.policy.impl.keyguard.SlidingChallengeLayout
         android:id="@+id/sliding_layout"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        androidprv:dragIcon="@drawable/kg_security_lock">
+        android:layout_height="match_parent">
 
         <FrameLayout
             android:layout_width="match_parent"
@@ -68,6 +67,17 @@
                 android:gravity="center">
             </com.android.internal.policy.impl.keyguard.KeyguardSecurityViewFlipper>
         </com.android.internal.policy.impl.keyguard.KeyguardSecurityContainer>
+
+        <ImageButton
+              android:layout_width="wrap_content"
+              android:layout_height="wrap_content"
+              androidprv:layout_childType="expandChallengeHandle"
+              android:focusable="true"
+              android:background="@null"
+              android:src="@drawable/keyguard_expand_challenge_handle"
+              android:scaleType="center"
+              android:contentDescription="@string/keyguard_accessibility_expand_lock_area" />
+
     </com.android.internal.policy.impl.keyguard.SlidingChallengeLayout>
 </com.android.internal.policy.impl.keyguard.KeyguardHostView>
 
diff --git a/core/res/res/layout/keyguard_add_widget.xml b/core/res/res/layout/keyguard_add_widget.xml
index fd5e565..db166ac 100644
--- a/core/res/res/layout/keyguard_add_widget.xml
+++ b/core/res/res/layout/keyguard_add_widget.xml
@@ -27,6 +27,7 @@
     <FrameLayout
             android:layout_width="match_parent"
             android:layout_height="match_parent"
+            android:contentDescription="@string/keyguard_accessibility_widget_empty_slot"
             >
         <ImageView
             android:id="@+id/keyguard_add_widget_view"
@@ -35,6 +36,7 @@
             android:layout_height="wrap_content"
             android:layout_gravity="center"
             android:padding="24dp"
-            android:src="@drawable/kg_add_widget" />
+            android:src="@drawable/kg_add_widget"
+            android:contentDescription="@string/keyguard_accessibility_add_widget"/>
     </FrameLayout>
 </com.android.internal.policy.impl.keyguard.KeyguardWidgetFrame>
diff --git a/core/res/res/layout/keyguard_emergency_carrier_area.xml b/core/res/res/layout/keyguard_emergency_carrier_area.xml
index 655b77d..52adc04 100644
--- a/core/res/res/layout/keyguard_emergency_carrier_area.xml
+++ b/core/res/res/layout/keyguard_emergency_carrier_area.xml
@@ -25,7 +25,8 @@
     android:orientation="vertical"
     android:gravity="center"
     android:layout_gravity="center_horizontal"
-    android:layout_alignParentBottom="true">
+    android:layout_alignParentBottom="true"
+    android:clickable="true">
 
     <com.android.internal.policy.impl.keyguard.CarrierText
         android:layout_width="wrap_content"
diff --git a/core/res/res/layout/keyguard_face_unlock_view.xml b/core/res/res/layout/keyguard_face_unlock_view.xml
index 976d0c6..39e8f31 100644
--- a/core/res/res/layout/keyguard_face_unlock_view.xml
+++ b/core/res/res/layout/keyguard_face_unlock_view.xml
@@ -23,7 +23,8 @@
     android:id="@+id/keyguard_face_unlock_view"
     android:orientation="vertical"
     android:layout_width="match_parent"
-    android:layout_height="match_parent">
+    android:layout_height="match_parent"
+    android:contentDescription="@string/keyguard_accessibility_face_unlock">
 
     <include layout="@layout/keyguard_message_area"
         android:layout_width="match_parent"
diff --git a/core/res/res/layout/keyguard_glow_pad_view.xml b/core/res/res/layout/keyguard_glow_pad_view.xml
index a416a77..ef1c133 100644
--- a/core/res/res/layout/keyguard_glow_pad_view.xml
+++ b/core/res/res/layout/keyguard_glow_pad_view.xml
@@ -27,7 +27,7 @@
     android:layout_gravity="center"
     android:orientation="horizontal"
     android:gravity="@integer/kg_selector_gravity"
-    android:focusable="true"
+    android:contentDescription="@string/keyguard_accessibility_slide_area"
 
     prvandroid:targetDrawables="@array/lockscreen_targets_unlock_only"
     prvandroid:targetDescriptions="@array/lockscreen_target_descriptions_unlock_only"
diff --git a/core/res/res/layout/keyguard_message_area.xml b/core/res/res/layout/keyguard_message_area.xml
index 9f11a2c..37463cf 100644
--- a/core/res/res/layout/keyguard_message_area.xml
+++ b/core/res/res/layout/keyguard_message_area.xml
@@ -28,5 +28,6 @@
     android:ellipsize="marquee"
     android:textAppearance="?android:attr/textAppearance"
     android:textSize="@dimen/kg_status_line_font_size"
-    android:textColor="?android:attr/textColorSecondary" />
+    android:textColor="?android:attr/textColorSecondary"
+    android:clickable="true" />
 
diff --git a/core/res/res/layout/keyguard_password_view.xml b/core/res/res/layout/keyguard_password_view.xml
index b6faf5b..a054d07 100644
--- a/core/res/res/layout/keyguard_password_view.xml
+++ b/core/res/res/layout/keyguard_password_view.xml
@@ -23,6 +23,7 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:gravity="bottom"
+    android:contentDescription="@string/keyguard_accessibility_password_unlock"
     >
 
     <Space
diff --git a/core/res/res/layout/keyguard_pattern_view.xml b/core/res/res/layout/keyguard_pattern_view.xml
index 0f6256a..5ebc000 100644
--- a/core/res/res/layout/keyguard_pattern_view.xml
+++ b/core/res/res/layout/keyguard_pattern_view.xml
@@ -26,7 +26,8 @@
     android:orientation="vertical"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:gravity="center_horizontal">
+    android:gravity="center_horizontal"
+    android:contentDescription="@string/keyguard_accessibility_pattern_unlock">
 
     <FrameLayout
         android:layout_width="match_parent"
@@ -55,7 +56,8 @@
                 android:layout_marginBottom="4dip"
                 android:layout_marginStart="8dip"
                 android:layout_gravity="center_horizontal"
-                android:gravity="center" />
+                android:gravity="center"
+                android:contentDescription="@string/keyguard_accessibility_pattern_area" />
 
             <include layout="@layout/keyguard_emergency_carrier_area"
                 android:id="@+id/keyguard_selector_fade_container"
diff --git a/core/res/res/layout/keyguard_pin_view.xml b/core/res/res/layout/keyguard_pin_view.xml
index 2529196..29e69f3 100644
--- a/core/res/res/layout/keyguard_pin_view.xml
+++ b/core/res/res/layout/keyguard_pin_view.xml
@@ -24,6 +24,7 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     android:orientation="vertical"
+    android:contentDescription="@string/keyguard_accessibility_pin_unlock"
     >
     <include layout="@layout/keyguard_message_area"
         android:layout_width="match_parent"
diff --git a/core/res/res/layout/keyguard_selector_view.xml b/core/res/res/layout/keyguard_selector_view.xml
index 7403408..941e78e 100644
--- a/core/res/res/layout/keyguard_selector_view.xml
+++ b/core/res/res/layout/keyguard_selector_view.xml
@@ -26,7 +26,8 @@
     android:layout_height="match_parent"
     android:clipChildren="false"
     android:clipToPadding="false"
-    android:orientation="vertical">
+    android:orientation="vertical"
+    android:contentDescription="@string/keyguard_accessibility_slide_unlock">
 
     <FrameLayout
         android:layout_width="match_parent"
diff --git a/core/res/res/layout/keyguard_status_view.xml b/core/res/res/layout/keyguard_status_view.xml
index 9532a88..7467928 100644
--- a/core/res/res/layout/keyguard_status_view.xml
+++ b/core/res/res/layout/keyguard_status_view.xml
@@ -31,12 +31,13 @@
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:gravity="center_horizontal|top"
-        android:contentDescription="@*android:string/keyguard_accessibility_status">
+        android:contentDescription="@android:string/keyguard_accessibility_status">
 
         <LinearLayout android:layout_width="match_parent"
                       android:layout_height="wrap_content"
                       android:layout_gravity="center_horizontal|top"
-                      android:orientation="vertical">
+                      android:orientation="vertical"
+                      android:focusable="true">
             <com.android.internal.policy.impl.keyguard.ClockView
                 android:id="@+id/clock_view"
                 android:layout_width="wrap_content"
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 627099c..0964af0 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5800,13 +5800,11 @@
         <enum name="scrim" value="4" />
         <!-- The home for widgets. All widgets will be descendents of this. -->
         <enum name="widgets" value="5" />
+        <!-- This is a handle that is used for expanding the
+             security challenge container when it is collapsed. -->
+        <enum name="expandChallengeHandle" value="6" />
     </attr>
 
-    <declare-styleable name="SlidingChallengeLayout">
-        <attr name="dragHandle" format="reference" />
-        <attr name="dragIcon" format="reference" />
-    </declare-styleable>
-
     <declare-styleable name="SlidingChallengeLayout_Layout">
         <attr name="layout_childType" />
     </declare-styleable>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 5af60c8..05b3068 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -555,10 +555,26 @@
   <java-symbol type="string" name="keyboardview_keycode_enter" />
   <java-symbol type="string" name="keyboardview_keycode_mode_change" />
   <java-symbol type="string" name="keyboardview_keycode_shift" />
+  <java-symbol type="string" name="keyguard_accessibility_add_widget" />
+  <java-symbol type="string" name="keyguard_accessibility_camera" />
+  <java-symbol type="string" name="keyguard_accessibility_expand_lock_area" />
+  <java-symbol type="string" name="keyguard_accessibility_face_unlock" />
   <java-symbol type="string" name="keygaurd_accessibility_media_controls" />
+  <java-symbol type="string" name="keyguard_accessibility_pattern_area" />
+  <java-symbol type="string" name="keyguard_accessibility_pattern_unlock" />
+  <java-symbol type="string" name="keyguard_accessibility_password_unlock" />
+  <java-symbol type="string" name="keyguard_accessibility_pin_unlock" />
+  <java-symbol type="string" name="keyguard_accessibility_slide_area" />
+  <java-symbol type="string" name="keyguard_accessibility_slide_unlock" />
   <java-symbol type="string" name="keyguard_accessibility_status" />
   <java-symbol type="string" name="keyguard_accessibility_user_selector" />
-  <java-symbol type="string" name="keyguard_accessibility_widget_changed" />
+  <java-symbol type="string" name="keyguard_accessibility_widget" />
+  <java-symbol type="string" name="keyguard_accessibility_widget_deleted" />
+  <java-symbol type="string" name="keyguard_accessibility_widget_empty_slot" />
+  <java-symbol type="string" name="keyguard_accessibility_widget_reorder_start" />
+  <java-symbol type="string" name="keyguard_accessibility_widget_reorder_end" />
+  <java-symbol type="string" name="keyguard_accessibility_unlock_area_collapsed" />
+  <java-symbol type="string" name="keyguard_accessibility_unlock_area_expanded" />
   <java-symbol type="string" name="kilobyteShort" />
   <java-symbol type="string" name="last_month" />
   <java-symbol type="string" name="launchBrowserDefault" />
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java b/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java
index 3dd0a8f..7f5d66f 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/CameraWidgetFrame.java
@@ -34,6 +34,7 @@
 import android.widget.ImageView;
 import android.widget.ImageView.ScaleType;
 
+import com.android.internal.R;
 import com.android.internal.policy.impl.keyguard.KeyguardActivityLauncher.CameraWidgetInfo;
 
 public class CameraWidgetFrame extends KeyguardWidgetFrame implements View.OnClickListener {
@@ -107,6 +108,8 @@
                 FrameLayout.LayoutParams.MATCH_PARENT,
                 FrameLayout.LayoutParams.MATCH_PARENT));
         preview.setScaleType(ScaleType.FIT_CENTER);
+        preview.setContentDescription(preview.getContext().getString(
+                R.string.keyguard_accessibility_camera));
         CameraWidgetFrame cameraWidgetFrame = new CameraWidgetFrame(context, callbacks, launcher);
         cameraWidgetFrame.addView(preview);
         cameraWidgetFrame.mWidgetView = widgetView;
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java b/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java
index faf0ca0..9858c77 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/FaceUnlock.java
@@ -57,8 +57,7 @@
     private final int MSG_UNLOCK = 2;
     private final int MSG_CANCEL = 3;
     private final int MSG_REPORT_FAILED_ATTEMPT = 4;
-    private final int MSG_EXPOSE_FALLBACK = 5;
-    private final int MSG_POKE_WAKELOCK = 6;
+    private final int MSG_POKE_WAKELOCK = 5;
 
     // TODO: This was added for the purpose of adhering to what the biometric interface expects
     // the isRunning() function to return.  However, it is probably not necessary to have both
@@ -220,9 +219,6 @@
             case MSG_REPORT_FAILED_ATTEMPT:
                 handleReportFailedAttempt();
                 break;
-            case MSG_EXPOSE_FALLBACK:
-                handleExposeFallback();
-                break;
             case MSG_POKE_WAKELOCK:
                 handlePokeWakelock(msg.arg1);
                 break;
@@ -310,6 +306,10 @@
      */
     void handleCancel() {
         if (DEBUG) Log.d(TAG, "handleCancel()");
+        // We are going to the backup method, so we don't want to see Face Unlock again until the
+        // next time the user visits keyguard.
+        KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(false);
+
         mKeyguardScreenCallback.showBackupSecurity();
         stop();
         mKeyguardScreenCallback.userActivity(BACKUP_LOCK_TIMEOUT);
@@ -320,17 +320,11 @@
      */
     void handleReportFailedAttempt() {
         if (DEBUG) Log.d(TAG, "handleReportFailedAttempt()");
-        mKeyguardScreenCallback.reportFailedUnlockAttempt();
-    }
+        // We are going to the backup method, so we don't want to see Face Unlock again until the
+        // next time the user visits keyguard.
+        KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(false);
 
-    /**
-     * Hides the Face Unlock view to expose the backup lock.  Called when the Face Unlock service UI
-     * is started, indicating there is no need to continue displaying the underlying view because
-     * the service UI is now covering the backup lock.
-     */
-    void handleExposeFallback() {
-        if (DEBUG) Log.d(TAG, "handleExposeFallback()");
-        // No longer required because face unlock doesn't cover backup unlock.
+        mKeyguardScreenCallback.reportFailedUnlockAttempt();
     }
 
     /**
@@ -443,16 +437,6 @@
         }
 
         /**
-         * Called when the Face Unlock service starts displaying the UI, indicating that the backup
-         * unlock can be exposed because the Face Unlock service is now covering the backup with its
-         * UI.
-         */
-        public void exposeFallback() {
-            if (DEBUG) Log.d(TAG, "exposeFallback()");
-            mHandler.sendEmptyMessage(MSG_EXPOSE_FALLBACK);
-        }
-
-        /**
          * Called when Face Unlock wants to keep the screen alive and active for a specific amount
          * of time.
          */
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
index 3b2ded2..045c9aa 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardHostView.java
@@ -49,6 +49,7 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.WindowManager;
+import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.animation.AnimationUtils;
 import android.widget.RemoteViews.OnClickHandler;
 
@@ -115,8 +116,7 @@
 
         // The following enables the MENU key to work for testing automation
         mEnableMenuKey = shouldEnableMenuKey();
-        setFocusable(true);
-        setFocusableInTouchMode(true);
+        mViewStateManager = new KeyguardViewStateManager();
     }
 
     @Override
@@ -150,8 +150,6 @@
 
     @Override
     protected void onFinishInflate() {
-        mViewStateManager = new KeyguardViewStateManager();
-
         // Grab instances of and make any necessary changes to the main layouts. Create
         // view state manager and wire up necessary listeners / callbacks.
         mAppWidgetContainer = (KeyguardWidgetPager) findViewById(R.id.app_widget_container);
@@ -423,8 +421,8 @@
     void showPrimarySecurityScreen(boolean turningOff) {
         SecurityMode securityMode = mSecurityModel.getSecurityMode();
         if (DEBUG) Log.v(TAG, "showPrimarySecurityScreen(turningOff=" + turningOff + ")");
-        if (!turningOff && KeyguardUpdateMonitor.getInstance(mContext).isAlternateUnlockEnabled()
-                && !KeyguardUpdateMonitor.getInstance(mContext).getIsFirstBoot()) {
+        if (!turningOff &&
+                KeyguardUpdateMonitor.getInstance(mContext).isAlternateUnlockEnabled()) {
             // If we're not turning off, then allow biometric alternate.
             // We'll reload it when the device comes back on.
             securityMode = mSecurityModel.getAlternateFor(securityMode);
@@ -500,7 +498,6 @@
             // If the alternate unlock was suppressed, it can now be safely
             // enabled because the user has left keyguard.
             KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
-            KeyguardUpdateMonitor.getInstance(mContext).setIsFirstBoot(false);
 
             // If there's a pending runnable because the user interacted with a widget
             // and we're leaving keyguard, then run it.
@@ -712,6 +709,9 @@
     @Override
     public void onScreenTurnedOff() {
         if (DEBUG) Log.d(TAG, "screen off, instance " + Integer.toHexString(hashCode()));
+        // Once the screen turns off, we no longer consider this to be first boot and we want the
+        // biometric unlock to start next time keyguard is shown.
+        KeyguardUpdateMonitor.getInstance(mContext).setAlternateUnlockEnabled(true);
         saveStickyWidgetIndex();
         showPrimarySecurityScreen(true);
         getSecurityView(mCurrentSecuritySelection).onPause();
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
index 316825a2..68e761a 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardUpdateMonitor.java
@@ -200,7 +200,6 @@
             }
         }
     };
-    private boolean mIsFirstBoot;
 
     /**
      * When we receive a
@@ -778,12 +777,4 @@
                 || simState == IccCardConstants.State.PUK_REQUIRED
                 || simState == IccCardConstants.State.PERM_DISABLED);
     }
-
-    public void setIsFirstBoot(boolean b) {
-        mIsFirstBoot = b;
-    }
-    
-    public boolean getIsFirstBoot() {
-        return mIsFirstBoot;
-    }
 }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
index 53cbb39..fe4ac5b 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardViewMediator.java
@@ -522,7 +522,6 @@
 
             // Disable alternate unlock right after boot until things have settled.
             mUpdateMonitor.setAlternateUnlockEnabled(false);
-            mUpdateMonitor.setIsFirstBoot(true);
 
             doKeyguardLocked();
         }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
index 667b2d6..b023573 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/KeyguardWidgetPager.java
@@ -21,7 +21,6 @@
 import android.animation.ObjectAnimator;
 import android.animation.PropertyValuesHolder;
 import android.animation.TimeInterpolator;
-import android.appwidget.AppWidgetHostView;
 import android.content.Context;
 import android.content.res.Resources;
 import android.os.Handler;
@@ -32,6 +31,8 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.View.OnLongClickListener;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
 import android.view.ViewGroup;
 import android.widget.FrameLayout;
 
@@ -134,6 +135,14 @@
             KeyguardWidgetFrame newWidgetPage = getWidgetPageAt(newPageIndex);
             if (newWidgetPage != null) {
                 newWidgetPage.onActive(true);
+                newWidgetPage.requestAccessibilityFocus();
+            }
+            if (mParent != null && AccessibilityManager.getInstance(mContext).isEnabled()) {
+                AccessibilityEvent event = AccessibilityEvent.obtain(
+                        AccessibilityEvent.TYPE_VIEW_SCROLLED);
+                onInitializeAccessibilityEvent(event);
+                onPopulateAccessibilityEvent(event);
+                mParent.requestSendAccessibilityEvent(this, event);
             }
         }
         if (mViewStateManager != null) {
@@ -141,6 +150,13 @@
         }
     }
 
+    @Override
+    public void sendAccessibilityEvent(int eventType) {
+        if (eventType != AccessibilityEvent.TYPE_VIEW_SCROLLED || isPageMoving()) {
+            super.sendAccessibilityEvent(eventType);
+        }
+    }
+
     private void userActivity() {
         if (mCallbacks != null) {
             mCallbacks.onUserActivityTimeoutChanged();
@@ -227,10 +243,6 @@
             // The framework adds a default padding to AppWidgetHostView. We don't need this padding
             // for the Keyguard, so we override it to be 0.
             widget.setPadding(0,  0, 0, 0);
-            if (widget instanceof AppWidgetHostView) {
-                AppWidgetHostView awhv = (AppWidgetHostView) widget;
-                widget.setContentDescription(awhv.getAppWidgetInfo().label);
-            }
             frame.addView(widget, lp);
         } else {
             frame = (KeyguardWidgetFrame) widget;
@@ -245,6 +257,15 @@
         } else {
             addView(frame, pageIndex, pageLp);
         }
+
+        // Update the frame content description.
+        View content = (widget == frame) ?  frame.getContent() : widget;
+        if (content != null) {
+            String contentDescription = mContext.getString(
+                com.android.internal.R.string.keyguard_accessibility_widget,
+                content.getContentDescription());
+            frame.setContentDescription(contentDescription);
+        }
     }
 
     /**
@@ -361,22 +382,6 @@
     }
 
     @Override
-    public String getCurrentPageDescription() {
-        final int nextPageIndex = getNextPage();
-        if (nextPageIndex >= 0 && nextPageIndex < getChildCount()) {
-            KeyguardWidgetFrame frame = getWidgetPageAt(nextPageIndex);
-            CharSequence title = frame.getChildAt(0).getContentDescription();
-            if (title == null) {
-                title = "";
-            }
-            return mContext.getString(
-                    com.android.internal.R.string.keyguard_accessibility_widget_changed,
-                    title, nextPageIndex + 1, getChildCount());
-        }
-        return super.getCurrentPageDescription();
-    }
-
-    @Override
     protected void overScroll(float amount) {
         acceleratedOverScroll(amount);
     }
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java b/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
index c93b11a..6eeada5 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/PagedView.java
@@ -539,27 +539,12 @@
             if (mTouchState == TOUCH_STATE_REST) {
                 pageEndMoving();
             }
-
             onPostReorderingAnimationCompleted();
-
-            // Notify the user when the page changes
-            AccessibilityManager accessibilityManager = (AccessibilityManager)
-                    getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
-            if (accessibilityManager.isEnabled()) {
-                AccessibilityEvent ev =
-                    AccessibilityEvent.obtain(AccessibilityEvent.TYPE_VIEW_SCROLLED);
-                ev.getText().add(getCurrentPageDescription());
-                sendAccessibilityEventUnchecked(ev);
-            }
             return true;
         }
         return false;
     }
 
-    public String getCurrentPageDescription() {
-        return "";
-    }
-
     @Override
     public void computeScroll() {
         computeScrollHelper();
@@ -2013,6 +1998,11 @@
     }
 
     protected void onStartReordering() {
+        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+            announceForAccessibility(mContext.getString(
+                    R.string.keyguard_accessibility_widget_reorder_start));
+        }
+
         // Set the touch state to reordering (allows snapping to pages, dragging a child, etc.)
         mTouchState = TOUCH_STATE_REORDERING;
         mIsReordering = true;
@@ -2033,6 +2023,10 @@
     }
 
     protected void onEndReordering() {
+        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+            announceForAccessibility(mContext.getString(
+                    R.string.keyguard_accessibility_widget_reorder_end));
+        }
         mIsReordering = false;
     }
 
@@ -2298,6 +2292,7 @@
     }
 
     /* Accessibility */
+
     @Override
     public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
         super.onInitializeAccessibilityNodeInfo(info);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
index 2e735a0..a0b11c1 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard/SlidingChallengeLayout.java
@@ -29,12 +29,14 @@
 import android.util.AttributeSet;
 import android.util.FloatProperty;
 import android.util.Log;
+import android.util.MathUtils;
 import android.util.Property;
 import android.view.MotionEvent;
 import android.view.VelocityTracker;
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.ViewGroup;
+import android.view.accessibility.AccessibilityManager;
 import android.view.animation.Interpolator;
 import android.widget.Scroller;
 
@@ -56,18 +58,15 @@
     private static final int DRAG_HANDLE_OPEN_ABOVE = 8; // dp
     private static final int DRAG_HANDLE_OPEN_BELOW = 0; // dp
 
-    private static final boolean OPEN_ON_CLICK = true;
-
     private static final int HANDLE_ANIMATE_DURATION = 200; // ms
 
     // Drawn to show the drag handle in closed state; crossfades to the challenge view
     // when challenge is fully visible
-    private Drawable mHandleDrawable;
     private Drawable mFrameDrawable;
-    private Drawable mDragIconDrawable;
     private boolean mEdgeCaptured;
 
     // Initialized during measurement from child layoutparams
+    private View mExpandChallengeView;
     private View mChallengeView;
     private View mScrimView;
     private View mWidgetsView;
@@ -113,6 +112,7 @@
                                        // that should remain on-screen
 
     private int mTouchSlop;
+    private int mTouchSlopSquare;
 
     float mHandleAlpha;
     float mFrameAlpha;
@@ -184,6 +184,15 @@
         }
     };
 
+    private final OnClickListener mExpandChallengeClickListener = new OnClickListener() {
+        @Override
+        public void onClick(View v) {
+            if (!isChallengeShowing()) {
+                showChallenge(true);
+            }
+        }
+    };
+
     /**
      * Listener interface that reports changes in scroll state of the challenge area.
      */
@@ -235,13 +244,6 @@
     public SlidingChallengeLayout(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
 
-        final TypedArray a = context.obtainStyledAttributes(attrs,
-                R.styleable.SlidingChallengeLayout, defStyle, 0);
-        setDragDrawables(a.getDrawable(R.styleable.SlidingChallengeLayout_dragHandle),
-                a.getDrawable(R.styleable.SlidingChallengeLayout_dragIcon));
-
-        a.recycle();
-
         mScroller = new Scroller(context, sMotionInterpolator);
 
         final ViewConfiguration vc = ViewConfiguration.get(context);
@@ -252,6 +254,7 @@
         mDragHandleEdgeSlop = res.getDimensionPixelSize(R.dimen.kg_edge_swipe_region_size);
 
         mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
+        mTouchSlopSquare = mTouchSlop * mTouchSlop;
 
         final float density = res.getDisplayMetrics().density;
 
@@ -267,15 +270,6 @@
         setWillNotDraw(false);
     }
 
-    public void setDragDrawables(Drawable handle, Drawable icon) {
-        mHandleDrawable = handle;
-        mDragIconDrawable = icon;
-    }
-
-    public void setDragIconDrawable(Drawable d) {
-        mDragIconDrawable = d;
-    }
-
     public void showHandle(boolean visible) {
         if (visible) {
             if (mHandleAnimation != null) {
@@ -469,7 +463,27 @@
     }
 
     private void setChallengeShowing(boolean showChallenge) {
+        if (mChallengeShowing == showChallenge) {
+            return;
+        }
         mChallengeShowing = showChallenge;
+        if (mChallengeShowing) {
+            mExpandChallengeView.setVisibility(View.INVISIBLE);
+            mChallengeView.setVisibility(View.VISIBLE);
+            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+                mChallengeView.requestAccessibilityFocus();
+                mChallengeView.announceForAccessibility(mContext.getString(
+                        R.string.keyguard_accessibility_unlock_area_expanded));
+            }
+        } else {
+            mExpandChallengeView.setVisibility(View.VISIBLE);
+            mChallengeView.setVisibility(View.INVISIBLE);
+            if (AccessibilityManager.getInstance(mContext).isEnabled()) {
+                mExpandChallengeView.requestAccessibilityFocus();
+                mChallengeView.announceForAccessibility(mContext.getString(
+                        R.string.keyguard_accessibility_unlock_area_collapsed));
+            }
+        }
     }
 
     /**
@@ -573,12 +587,12 @@
                 for (int i = 0; i < count; i++) {
                     final float x = ev.getX(i);
                     final float y = ev.getY(i);
-
-                    if (!mIsBouncing &&
-                            (isInDragHandle(x, y) || crossedDragHandle(x, y, mGestureStartY) ||
-                            (isInChallengeView(x, y) &&
-                                (mScrollState == SCROLL_STATE_SETTLING || !mChallengeShowing))) &&
-                            mActivePointerId == INVALID_POINTER) {
+                    if (!mIsBouncing && mActivePointerId == INVALID_POINTER
+                            && ((isInDragHandle(x, y) && MathUtils.sq(x - mGestureStartX)
+                                    + MathUtils.sq(y - mGestureStartY) > mTouchSlopSquare)
+                               || crossedDragHandle(x, y, mGestureStartY)
+                               || (isInChallengeView(x, y) && (mScrollState == SCROLL_STATE_SETTLING
+                                       || !mChallengeShowing)))) {
                         mActivePointerId = ev.getPointerId(i);
                         mGestureStartX = x;
                         mGestureStartY = y;
@@ -634,12 +648,7 @@
                     break;
                 }
             case MotionEvent.ACTION_UP:
-                if (OPEN_ON_CLICK
-                        && isInDragHandle(mGestureStartX, mGestureStartY)
-                        && Math.abs(ev.getX() - mGestureStartX) <= mTouchSlop
-                        && Math.abs(ev.getY() - mGestureStartY) <= mTouchSlop) {
-                    showChallenge(true);
-                } else if (mDragging) {
+                if (mDragging) {
                     mVelocityTracker.computeCurrentVelocity(1000, mMaxVelocity);
                     showChallenge((int) mVelocityTracker.getYVelocity(mActivePointerId));
                 }
@@ -749,19 +758,19 @@
     }
 
     private boolean isInChallengeView(float x, float y) {
-        if (mChallengeView == null) return false;
-
-        return x >= mChallengeView.getLeft() && y >= mChallengeView.getTop() &&
-                x < mChallengeView.getRight() && y < mChallengeView.getBottom();
+        return isPointInView(x, y, mChallengeView);
     }
 
     private boolean isInDragHandle(float x, float y) {
-        if (mChallengeView == null) return false;
+        return isPointInView(x, y, mExpandChallengeView);
+    }
 
-        return x >= mDragHandleEdgeSlop &&
-                y >= mChallengeView.getTop() - getDragHandleSizeAbove() &&
-                x < getWidth() - mDragHandleEdgeSlop &&
-                y < mChallengeView.getTop() + getDragHandleSizeBelow();
+    private boolean isPointInView(float x, float y, View view) {
+        if (view == null) {
+            return false;
+        }
+        return x >= view.getLeft() && y >= view.getTop()
+                && x < view.getRight() && y < view.getBottom();
     }
 
     private boolean crossedDragHandle(float x, float y, float initialY) {
@@ -786,7 +795,9 @@
 
         // Find one and only one challenge view.
         final View oldChallengeView = mChallengeView;
+        final View oldExpandChallengeView = mChallengeView;
         mChallengeView = null;
+        mExpandChallengeView = null;
         final int count = getChildCount();
 
         // First iteration through the children finds special children and sets any associated
@@ -794,7 +805,6 @@
         for (int i = 0; i < count; i++) {
             final View child = getChildAt(i);
             final LayoutParams lp = (LayoutParams) child.getLayoutParams();
-
             if (lp.childType == LayoutParams.CHILD_TYPE_CHALLENGE) {
                 if (mChallengeView != null) {
                     throw new IllegalStateException(
@@ -806,31 +816,42 @@
                 }
                 // We're going to play silly games with the frame's background drawable later.
                 mFrameDrawable = mChallengeView.getBackground();
-
                 if (!mHasLayout) {
                     // Set up the margin correctly based on our content for the first run.
                     mHasGlowpad = child.findViewById(R.id.keyguard_selector_view) != null;
                     lp.leftMargin = lp.rightMargin = getChallengeMargin(true);
                 }
+            } else if (lp.childType == LayoutParams.CHILD_TYPE_EXPAND_CHALLENGE_HANDLE) {
+                if (mExpandChallengeView != null) {
+                    throw new IllegalStateException(
+                            "There may only be one child with layout_childType"
+                            + "=\"expandChallengeHandle\"");
+                }
+                mExpandChallengeView = child;
+                if (mExpandChallengeView != oldExpandChallengeView) {
+                    mExpandChallengeView.setVisibility(mChallengeShowing ? INVISIBLE : VISIBLE);
+                    mExpandChallengeView.setOnClickListener(mExpandChallengeClickListener);
+                }
             } else if (lp.childType == LayoutParams.CHILD_TYPE_SCRIM) {
                 setScrimView(child);
             } else if (lp.childType == LayoutParams.CHILD_TYPE_WIDGETS) {
                 mWidgetsView = child;
             }
-
-            if (child.getVisibility() == GONE) continue;
         }
 
         // We want to measure the challenge view first, since the KeyguardWidgetPager
         // needs to do things its measure pass that are dependent on the challenge view
         // having been measured.
-        if (mChallengeView != null) {
+        if (mChallengeView != null && mChallengeView.getVisibility() != View.GONE) {
             measureChildWithMargins(mChallengeView, widthSpec, 0, heightSpec, 0);
         }
 
         // Measure the rest of the children
         for (int i = 0; i < count; i++) {
             final View child = getChildAt(i);
+            if (child.getVisibility() == GONE) {
+                continue;
+            }
             // Don't measure the challenge view twice!
             if (child != mChallengeView) {
                 measureChildWithMargins(child, widthSpec, 0, heightSpec, 0);
@@ -869,6 +890,8 @@
                         * (1 - mChallengeOffset));
                 child.setAlpha(getChallengeAlpha());
                 child.layout(left, bottom - childHeight, left + childWidth, bottom);
+            } else if (lp.childType == LayoutParams.CHILD_TYPE_EXPAND_CHALLENGE_HANDLE) {
+                child.layout(0, b - mChallengeBottomBound, width, b);
             } else {
                 // Non-challenge views lay out from the upper left, layered.
                 child.layout(paddingLeft + lp.leftMargin,
@@ -886,6 +909,21 @@
         }
     }
 
+    @Override
+    public void draw(Canvas c) {
+        super.draw(c);
+        if (DEBUG) {
+            final Paint debugPaint = new Paint();
+            debugPaint.setColor(0x40FF00CC);
+            // show the isInDragHandle() rect
+            c.drawRect(mDragHandleEdgeSlop,
+                    mChallengeView.getTop() - getDragHandleSizeAbove(),
+                    getWidth() - mDragHandleEdgeSlop,
+                    mChallengeView.getTop() + getDragHandleSizeBelow(),
+                    debugPaint);
+        }
+    }
+
     public void computeScroll() {
         super.computeScroll();
 
@@ -906,65 +944,6 @@
         }
     }
 
-    @Override
-    public void draw(Canvas c) {
-        super.draw(c);
-
-        final Paint debugPaint;
-        if (DEBUG) {
-            debugPaint = new Paint();
-            debugPaint.setColor(0x40FF00CC);
-            // show the isInDragHandle() rect
-            c.drawRect(mDragHandleEdgeSlop,
-                    mChallengeView.getTop() - getDragHandleSizeAbove(),
-                    getWidth() - mDragHandleEdgeSlop,
-                    mChallengeView.getTop() + getDragHandleSizeBelow(),
-                    debugPaint);
-        }
-
-        if (mChallengeView != null && mHandleAlpha > 0) {
-            final int top = mChallengeView.getTop();
-            final int handleHeight;
-            final int challengeLeft = mChallengeView.getLeft();
-            final int challengeRight = mChallengeView.getRight();
-            if (mHandleDrawable != null) {
-                handleHeight = mHandleDrawable.getIntrinsicHeight();
-                mHandleDrawable.setBounds(challengeLeft, top, challengeRight, top + handleHeight);
-                mHandleDrawable.setAlpha((int) (mHandleAlpha * 0xFF));
-                mHandleDrawable.draw(c);
-            } else {
-                handleHeight = 0;
-            }
-
-            if (DEBUG) {
-                // now show the actual drag handle
-                debugPaint.setStyle(Paint.Style.STROKE);
-                debugPaint.setStrokeWidth(1);
-                debugPaint.setColor(0xFF80FF00);
-                c.drawRect(challengeLeft, top, challengeRight, top + handleHeight, debugPaint);
-            }
-
-            if (mDragIconDrawable != null) {
-                final int closedTop = getLayoutBottom() - mDragHandleClosedBelow;
-                final int iconWidth = mDragIconDrawable.getIntrinsicWidth();
-                final int iconHeight = mDragIconDrawable.getIntrinsicHeight();
-                final int iconLeft = (challengeLeft + challengeRight - iconWidth) / 2;
-                final int iconTop = closedTop +
-                        (mDragHandleClosedBelow - mDragHandleClosedAbove - iconHeight) / 2;
-                mDragIconDrawable.setBounds(iconLeft, iconTop, iconLeft + iconWidth,
-                        iconTop + iconHeight);
-                mDragIconDrawable.setAlpha((int) (mHandleAlpha * 0xFF));
-                mDragIconDrawable.draw(c);
-
-                if (DEBUG) {
-                    debugPaint.setColor(0xFF00FF00);
-                    c.drawRect(iconLeft, iconTop, iconLeft + iconWidth,
-                        iconTop + iconHeight, debugPaint);
-                }
-            }
-        }
-    }
-
     public int getMaxChallengeTop() {
         if (mChallengeView == null) return 0;
 
@@ -1096,6 +1075,7 @@
         public static final int CHILD_TYPE_CHALLENGE = 2;
         public static final int CHILD_TYPE_SCRIM = 4;
         public static final int CHILD_TYPE_WIDGETS = 5;
+        public static final int CHILD_TYPE_EXPAND_CHALLENGE_HANDLE = 6;
 
         public LayoutParams() {
             this(MATCH_PARENT, WRAP_CONTENT);
diff --git a/policy/src/com/android/internal/policy/impl/keyguard_obsolete/FaceUnlock.java b/policy/src/com/android/internal/policy/impl/keyguard_obsolete/FaceUnlock.java
index e4d9215..e4768e2 100644
--- a/policy/src/com/android/internal/policy/impl/keyguard_obsolete/FaceUnlock.java
+++ b/policy/src/com/android/internal/policy/impl/keyguard_obsolete/FaceUnlock.java
@@ -61,7 +61,7 @@
     private final int MSG_UNLOCK = 4;
     private final int MSG_CANCEL = 5;
     private final int MSG_REPORT_FAILED_ATTEMPT = 6;
-    private final int MSG_EXPOSE_FALLBACK = 7;
+    //private final int MSG_EXPOSE_FALLBACK = 7;
     private final int MSG_POKE_WAKELOCK = 8;
 
     // TODO: This was added for the purpose of adhering to what the biometric interface expects
@@ -258,9 +258,9 @@
             case MSG_REPORT_FAILED_ATTEMPT:
                 handleReportFailedAttempt();
                 break;
-            case MSG_EXPOSE_FALLBACK:
-                handleExposeFallback();
-                break;
+                //case MSG_EXPOSE_FALLBACK:
+                //handleExposeFallback();
+                //break;
             case MSG_POKE_WAKELOCK:
                 handlePokeWakelock(msg.arg1);
                 break;
@@ -401,14 +401,14 @@
      * is started, indicating there is no need to continue displaying the underlying view because
      * the service UI is now covering the backup lock.
      */
-    void handleExposeFallback() {
-        if (DEBUG) Log.d(TAG, "handleExposeFallback()");
-        if (mFaceUnlockView != null) {
-            mFaceUnlockView.setVisibility(View.INVISIBLE);
-        } else {
-            Log.e(TAG, "mFaceUnlockView is null in handleExposeFallback()");
-        }
-    }
+    //void handleExposeFallback() {
+    //    if (DEBUG) Log.d(TAG, "handleExposeFallback()");
+    //    if (mFaceUnlockView != null) {
+    //        mFaceUnlockView.setVisibility(View.INVISIBLE);
+    //    } else {
+    //        Log.e(TAG, "mFaceUnlockView is null in handleExposeFallback()");
+    //    }
+    //}
 
     /**
      * Pokes the wakelock to keep the screen alive and active for a specific amount of time.
@@ -534,11 +534,11 @@
          * unlock can be exposed because the Face Unlock service is now covering the backup with its
          * UI.
          **/
-        @Override
-        public void exposeFallback() {
-            if (DEBUG) Log.d(TAG, "exposeFallback()");
-            mHandler.sendEmptyMessage(MSG_EXPOSE_FALLBACK);
-        }
+        //@Override
+        //public void exposeFallback() {
+        //    if (DEBUG) Log.d(TAG, "exposeFallback()");
+        //    mHandler.sendEmptyMessage(MSG_EXPOSE_FALLBACK);
+        //}
 
         /**
          * Called when Face Unlock wants to keep the screen alive and active for a specific amount
diff --git a/services/java/com/android/server/accessibility/TouchExplorer.java b/services/java/com/android/server/accessibility/TouchExplorer.java
index dcf87350..18b46fb 100644
--- a/services/java/com/android/server/accessibility/TouchExplorer.java
+++ b/services/java/com/android/server/accessibility/TouchExplorer.java
@@ -584,6 +584,7 @@
                             // a given distance perform a drag.
                             mCurrentState = STATE_DRAGGING;
                             mDraggingPointerId = pointerId;
+                            event.setEdgeFlags(receivedTracker.getLastReceivedDownEdgeFlags());
                             sendMotionEvent(event, MotionEvent.ACTION_DOWN, pointerIdBits,
                                     policyFlags);
                         } else {
@@ -1752,6 +1753,9 @@
         // Which pointers are down.
         private int mReceivedPointersDown;
 
+        // The edge flags of the last received down event.
+        private int mLastReceivedDownEdgeFlags;
+
         // Which down pointers are active.
         private int mActivePointers;
 
@@ -1947,6 +1951,13 @@
         }
 
         /**
+         * @return The edge flags of the last received down event.
+         */
+        public int getLastReceivedDownEdgeFlags() {
+            return mLastReceivedDownEdgeFlags;
+        }
+
+        /**
          * @return Whether the last received pointer that went up was active.
          */
         public boolean wasLastReceivedUpPointerActive() {
@@ -1995,6 +2006,8 @@
             mLastReceivedUpPointerDownX = 0;
             mLastReceivedUpPointerDownX = 0;
 
+            mLastReceivedDownEdgeFlags = event.getEdgeFlags();
+
             mReceivedPointersDown |= pointerFlag;
             mReceivedPointerDownX[pointerId] = event.getX(pointerIndex);
             mReceivedPointerDownY[pointerId] = event.getY(pointerIndex);