Enable fingerprint sensor navigation to invoke QuickSettings
- rename "FP_NAV" to more generic "SYSTEM_NAVIGATION"

Fixes bug 28869612

Change-Id: I321240ee54506633d63a29e987b8d8638c652391
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
index 7b23c80..419c91b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java
@@ -23,6 +23,7 @@
 import android.os.IBinder;
 import android.os.Message;
 import android.util.Pair;
+import android.view.KeyEvent;
 
 import com.android.internal.os.SomeArgs;
 import com.android.internal.statusbar.IStatusBar;
@@ -75,6 +76,7 @@
     private static final int MSG_TOGGLE_APP_SPLIT_SCREEN       = 30 << MSG_SHIFT;
     private static final int MSG_APP_TRANSITION_FINISHED       = 31 << MSG_SHIFT;
     private static final int MSG_DISMISS_KEYBOARD_SHORTCUTS    = 32 << MSG_SHIFT;
+    private static final int MSG_HANDLE_SYSNAV_KEY             = 33 << MSG_SHIFT;
 
     public static final int FLAG_EXCLUDE_NONE = 0;
     public static final int FLAG_EXCLUDE_SEARCH_PANEL = 1 << 0;
@@ -129,6 +131,8 @@
         void addQsTile(ComponentName tile);
         void remQsTile(ComponentName tile);
         void clickTile(ComponentName tile);
+
+        void handleSystemNavigationKey(int arg1);
     }
 
     public CommandQueue(Callbacks callbacks) {
@@ -388,6 +392,13 @@
         }
     }
 
+    @Override
+    public void handleSystemNavigationKey(int key) {
+        synchronized (mLock) {
+            mHandler.obtainMessage(MSG_HANDLE_SYSNAV_KEY, key, 0).sendToTarget();
+        }
+    }
+
     private final class H extends Handler {
         public void handleMessage(Message msg) {
             final int what = msg.what & MSG_MASK;
@@ -503,6 +514,9 @@
                 case MSG_TOGGLE_APP_SPLIT_SCREEN:
                     mCallbacks.toggleSplitScreen();
                     break;
+                case MSG_HANDLE_SYSNAV_KEY:
+                    mCallbacks.handleSystemNavigationKey(msg.arg1);
+                    break;
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 5064d8e..4b82279 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1296,7 +1296,7 @@
         }
     }
 
-    private void flingSettings(float vel, boolean expand) {
+    public void flingSettings(float vel, boolean expand) {
         flingSettings(vel, expand, null, false /* isClick */);
     }
 
@@ -1390,10 +1390,14 @@
         return maxHeight;
     }
 
-    private boolean isInSettings() {
+    public boolean isInSettings() {
         return mQsExpanded;
     }
 
+    public boolean isExpanding() {
+        return mIsExpanding;
+    }
+
     @Override
     protected void onHeightUpdated(float expandedHeight) {
         if (!mQsExpanded || mQsExpandImmediate || mIsExpanding && mQsExpandedWhenExpandingStarted) {
@@ -2108,6 +2112,7 @@
         onEmptySpaceClick(x);
     }
 
+    @Override
     protected boolean onMiddleClicked() {
         switch (mStatusBar.getBarState()) {
             case StatusBarState.KEYGUARD:
@@ -2257,6 +2262,7 @@
         mStatusBar.clearNotificationEffects();
     }
 
+    @Override
     protected boolean isPanelVisibleBecauseOfHeadsUp() {
         return mHeadsUpManager.hasPinnedHeadsUp() || mHeadsUpAnimatingAway;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 4ac178d..2692f77 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -1235,6 +1235,7 @@
     }
 
     private View.OnClickListener mRecentsClickListener = new View.OnClickListener() {
+        @Override
         public void onClick(View v) {
             awakenDreams();
             toggleRecentApps();
@@ -1299,6 +1300,7 @@
     };
 
     private final View.OnTouchListener mHomeActionListener = new View.OnTouchListener() {
+        @Override
         public boolean onTouch(View v, MotionEvent event) {
             switch (event.getAction()) {
                 case MotionEvent.ACTION_UP:
@@ -2232,6 +2234,7 @@
     /**
      * State is one or more of the DISABLE constants from StatusBarManager.
      */
+    @Override
     public void disable(int state1, int state2, boolean animate) {
         animate &= mStatusBarWindowState != WINDOW_STATE_HIDDEN;
         mDisabledUnmodified1 = state1;
@@ -2461,6 +2464,7 @@
 
     }
 
+    @Override
     protected void updateHeadsUp(String key, Entry entry, boolean shouldPeek,
             boolean alertAgain) {
         final boolean wasHeadsUp = isHeadsUp(key);
@@ -2477,6 +2481,7 @@
         }
     }
 
+    @Override
     protected void setHeadsUpUser(int newUserId) {
         if (mHeadsUpManager != null) {
             mHeadsUpManager.setUser(newUserId);
@@ -2487,6 +2492,7 @@
         return mHeadsUpManager.isHeadsUp(key);
     }
 
+    @Override
     protected boolean isSnoozedPackage(StatusBarNotification sbn) {
         return mHeadsUpManager.isSnoozed(sbn.getPackageName());
     }
@@ -2527,6 +2533,7 @@
      * All changes to the status bar and notifications funnel through here and are batched.
      */
     private class H extends BaseStatusBar.H {
+        @Override
         public void handleMessage(Message m) {
             super.handleMessage(m);
             switch (m.what) {
@@ -2568,6 +2575,32 @@
         mHeadsUpManager.releaseAllImmediately();
     }
 
+    /**
+     * Called for system navigation gestures. First action opens the panel, second opens
+     * settings. Down action closes the entire panel.
+     */
+    @Override
+    public void handleSystemNavigationKey(int key) {
+        if (SPEW) Log.d(TAG, "handleSystemNavigationKey: " + key);
+        if (!panelsEnabled()) {
+            return;
+        }
+
+        // Panels are not available in setup
+        if (!mUserSetup) return;
+
+        if (KeyEvent.KEYCODE_SYSTEM_NAVIGATION_UP == key) {
+            mNotificationPanel.collapse(false /* delayed */, 1.0f /* speedUpFactor */);
+        } else if (KeyEvent.KEYCODE_SYSTEM_NAVIGATION_DOWN == key) {
+            if (mNotificationPanel.isFullyCollapsed()) {
+                mNotificationPanel.expand(true /* animate */);
+            } else if (!mNotificationPanel.isInSettings() && !mNotificationPanel.isExpanding()){
+                mNotificationPanel.flingSettings(0 /* velocity */, true /* expand */);
+            }
+        }
+
+    }
+
     boolean panelsEnabled() {
         return (mDisabled1 & StatusBarManager.DISABLE_EXPAND) == 0 && !ONLY_CORE_APPS;
     }
@@ -2609,15 +2642,18 @@
         mHandler.sendEmptyMessage(MSG_OPEN_SETTINGS_PANEL);
     }
 
+    @Override
     public void animateCollapsePanels(int flags) {
         animateCollapsePanels(flags, false /* force */, false /* delayed */,
                 1.0f /* speedUpFactor */);
     }
 
+    @Override
     public void animateCollapsePanels(int flags, boolean force) {
         animateCollapsePanels(flags, force, false /* delayed */, 1.0f /* speedUpFactor */);
     }
 
+    @Override
     public void animateCollapsePanels(int flags, boolean force, boolean delayed) {
         animateCollapsePanels(flags, force, delayed, 1.0f /* speedUpFactor */);
     }
@@ -3054,6 +3090,7 @@
         }
     }
 
+    @Override
     public void topAppWindowChanged(boolean showMenu) {
         if (SPEW) {
             Log.d(TAG, (showMenu?"showing":"hiding") + " the MENU button");
@@ -3090,6 +3127,7 @@
                 + ") " + v.getWidth() + "x" + v.getHeight() + "]";
     }
 
+    @Override
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         synchronized (mQueueLock) {
             pw.println("Current Status Bar state:");
@@ -3167,6 +3205,7 @@
                 pw.println("see the logcat for a dump of the views we have created.");
                 // must happen on ui thread
                 mHandler.post(new Runnable() {
+                        @Override
                         public void run() {
                             mStatusBarView.getLocationOnScreen(mAbsPos);
                             Log.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1]
@@ -3277,6 +3316,7 @@
                 mContext, intent, mCurrentUserId);
         final boolean keyguardShowing = mStatusBarKeyguardViewManager.isShowing();
         Runnable runnable = new Runnable() {
+            @Override
             public void run() {
                 mAssistManager.hideAssist();
                 intent.setFlags(
@@ -3321,6 +3361,7 @@
             @Override
             public boolean onDismiss() {
                 AsyncTask.execute(new Runnable() {
+                    @Override
                     public void run() {
                         try {
                             if (keyguardShowing && !afterKeyguardGone) {
@@ -3344,6 +3385,7 @@
     }
 
     private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+        @Override
         public void onReceive(Context context, Intent intent) {
             if (DEBUG) Log.v(TAG, "onReceive: " + intent);
             String action = intent.getAction();
@@ -3371,6 +3413,7 @@
     };
 
     private BroadcastReceiver mDemoReceiver = new BroadcastReceiver() {
+        @Override
         public void onReceive(Context context, Intent intent) {
             if (DEBUG) Log.v(TAG, "onReceive: " + intent);
             String action = intent.getAction();
@@ -3630,6 +3673,7 @@
     }
 
     Runnable mStartTracing = new Runnable() {
+        @Override
         public void run() {
             vibrate();
             SystemClock.sleep(250);
@@ -3640,6 +3684,7 @@
     };
 
     Runnable mStopTracing = new Runnable() {
+        @Override
         public void run() {
             android.os.Debug.stopMethodTracing();
             Log.d(TAG, "stopTracing");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index 27726af..2d4900b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -257,4 +257,9 @@
         } catch (RemoteException ex) {
         }
     }
+
+    @Override
+    public void handleSystemNavigationKey(int arg1) {
+        // Not implemented
+    }
 }