Bug 16147163: Secure camera can now be launched with FUL running

This change introduces a class that handles launching the secure camera even
when other apps may be using the camera hardware.  It does this by sending out
a broadcast telling apps to stop using the camera as soon as the user begins to
swipe to use the secure camera.  It then waits until either the camera is
available or a timeout period has expired before it fires off the intent to
start the secure camera.

Secure camera apps can indicate (via their meta-data) that they will instead
handle the responsibility of waiting for the camera to be available.  In this
case, the new class still handles sending out the broadcast telling other apps
to close the camera, but it fires off the intent to start the secure camera
before the camera hardware is available.  This is optimal because some of the
time spent closing the camera can happen in parallel with the time spent
starting the secure camera app.  Since we can't depend on third-party apps to
wait for camera availability, the default is for us to wait for the camera to
be available before firing off the intent.  However, our first party app is
able to take the optimized approach.

Change-Id: I1eaed94875e8f50018cffab25aa1e9b21d85f25b
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 4f9d4a3..d237be6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -78,6 +78,12 @@
     private boolean mQsTracking;
 
     /**
+     * Handles launching the secure camera properly even when other applications may be using the
+     * camera hardware.
+     */
+    private SecureCameraLaunchManager mSecureCameraLaunchManager;
+
+    /**
      * If set, the ongoing touch gesture might both trigger the expansion in {@link PanelView} and
      * the expansion for quick settings.
      */
@@ -174,6 +180,8 @@
                 android.R.interpolator.fast_out_linear_in);
         mKeyguardBottomArea = (KeyguardBottomAreaView) findViewById(R.id.keyguard_bottom_area);
         mAfforanceHelper = new KeyguardAffordanceHelper(this, getContext());
+        mSecureCameraLaunchManager =
+                new SecureCameraLaunchManager(getContext(), mKeyguardBottomArea);
     }
 
     @Override
@@ -218,6 +226,16 @@
         }
     }
 
+    @Override
+    public void onAttachedToWindow() {
+        mSecureCameraLaunchManager.create();
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        mSecureCameraLaunchManager.destroy();
+    }
+
     /**
      * Positions the clock and notifications dynamically depending on how many notifications are
      * showing.
@@ -1271,7 +1289,7 @@
         if (start) {
             mKeyguardBottomArea.launchPhone();
         } else {
-            mKeyguardBottomArea.launchCamera();
+            mSecureCameraLaunchManager.startSecureCameraLaunch();
         }
         mBlockTouches = true;
     }
@@ -1336,6 +1354,7 @@
 
     @Override
     public void onSwipingStarted() {
+        mSecureCameraLaunchManager.onSwipingStarted();
         requestDisallowInterceptTouchEvent(true);
         mOnlyAffordanceInThisMotion = true;
     }