Improve Wifi display discovery API.

Change-Id: I4d46503e5413f52da16f79bbc9c631cc5ae9c178
diff --git a/core/java/android/hardware/display/WifiDisplayStatus.java b/core/java/android/hardware/display/WifiDisplayStatus.java
index 542d1b3..d5fe45d 100644
--- a/core/java/android/hardware/display/WifiDisplayStatus.java
+++ b/core/java/android/hardware/display/WifiDisplayStatus.java
@@ -32,18 +32,27 @@
  */
 public final class WifiDisplayStatus implements Parcelable {
     private final boolean mEnabled;
-    private final WifiDisplay mConnectedDisplay;
+    private final int mScanState;
+    private final int mActiveDisplayState;
+    private final WifiDisplay mActiveDisplay;
     private final WifiDisplay[] mKnownDisplays;
-    private final boolean mScanInProgress;
-    private final boolean mConnectionInProgress;
+
+    public static final int SCAN_STATE_NOT_SCANNING = 0;
+    public static final int SCAN_STATE_SCANNING = 1;
+
+    public static final int DISPLAY_STATE_NOT_CONNECTED = 0;
+    public static final int DISPLAY_STATE_CONNECTING = 1;
+    public static final int DISPLAY_STATE_CONNECTED = 2;
 
     public static final Creator<WifiDisplayStatus> CREATOR = new Creator<WifiDisplayStatus>() {
         public WifiDisplayStatus createFromParcel(Parcel in) {
             boolean enabled = (in.readInt() != 0);
+            int scanState = in.readInt();
+            int activeDisplayState= in.readInt();
 
-            WifiDisplay connectedDisplay = null;
+            WifiDisplay activeDisplay = null;
             if (in.readInt() != 0) {
-                connectedDisplay = WifiDisplay.CREATOR.createFromParcel(in);
+                activeDisplay = WifiDisplay.CREATOR.createFromParcel(in);
             }
 
             WifiDisplay[] knownDisplays = WifiDisplay.CREATOR.newArray(in.readInt());
@@ -51,11 +60,8 @@
                 knownDisplays[i] = WifiDisplay.CREATOR.createFromParcel(in);
             }
 
-            boolean scanInProgress = (in.readInt() != 0);
-            boolean connectionInProgress = (in.readInt() != 0);
-
-            return new WifiDisplayStatus(enabled, connectedDisplay, knownDisplays,
-                    scanInProgress, connectionInProgress);
+            return new WifiDisplayStatus(enabled, scanState, activeDisplayState,
+                    activeDisplay, knownDisplays);
         }
 
         public WifiDisplayStatus[] newArray(int size) {
@@ -64,21 +70,21 @@
     };
 
     public WifiDisplayStatus() {
-        this(false, null, WifiDisplay.EMPTY_ARRAY, false, false);
+        this(false, SCAN_STATE_NOT_SCANNING, DISPLAY_STATE_NOT_CONNECTED,
+                null, WifiDisplay.EMPTY_ARRAY);
     }
 
-    public WifiDisplayStatus(boolean enabled,
-            WifiDisplay connectedDisplay, WifiDisplay[] knownDisplays,
-            boolean scanInProgress, boolean connectionInProgress) {
+    public WifiDisplayStatus(boolean enabled, int scanState, int activeDisplayState,
+            WifiDisplay activeDisplay, WifiDisplay[] knownDisplays) {
         if (knownDisplays == null) {
             throw new IllegalArgumentException("knownDisplays must not be null");
         }
 
         mEnabled = enabled;
-        mConnectedDisplay = connectedDisplay;
+        mScanState = scanState;
+        mActiveDisplayState = activeDisplayState;
+        mActiveDisplay = activeDisplay;
         mKnownDisplays = knownDisplays;
-        mScanInProgress = scanInProgress;
-        mConnectionInProgress = connectionInProgress;
     }
 
     /**
@@ -94,10 +100,30 @@
     }
 
     /**
-     * Gets the currently connected Wifi display or null if none.
+     * Returns the current state of the Wifi display scan.
+     *
+     * @return One of: {@link #SCAN_STATE_NOT_SCANNING} or {@link #SCAN_STATE_SCANNING}.
      */
-    public WifiDisplay getConnectedDisplay() {
-        return mConnectedDisplay;
+    public int getScanState() {
+        return mScanState;
+    }
+
+    /**
+     * Get the state of the currently active display.
+     *
+     * @return One of: {@link #DISPLAY_STATE_NOT_CONNECTED}, {@link #DISPLAY_STATE_CONNECTING},
+     * or {@link #DISPLAY_STATE_CONNECTED}.
+     */
+    public int getActiveDisplayState() {
+        return mActiveDisplayState;
+    }
+
+    /**
+     * Gets the Wifi display that is currently active.  It may be connecting or
+     * connected.
+     */
+    public WifiDisplay getActiveDisplay() {
+        return mActiveDisplay;
     }
 
     /**
@@ -107,27 +133,15 @@
         return mKnownDisplays;
     }
 
-    /**
-     * Returns true if there is currently a Wifi display scan in progress.
-     */
-    public boolean isScanInProgress() {
-        return mScanInProgress;
-    }
-
-    /**
-     * Returns true if there is currently a Wifi display connection in progress.
-     */
-    public boolean isConnectionInProgress() {
-        return mConnectionInProgress;
-    }
-
     @Override
     public void writeToParcel(Parcel dest, int flags) {
         dest.writeInt(mEnabled ? 1 : 0);
+        dest.writeInt(mScanState);
+        dest.writeInt(mActiveDisplayState);
 
-        if (mConnectedDisplay != null) {
+        if (mActiveDisplay != null) {
             dest.writeInt(1);
-            mConnectedDisplay.writeToParcel(dest, flags);
+            mActiveDisplay.writeToParcel(dest, flags);
         } else {
             dest.writeInt(0);
         }
@@ -136,9 +150,6 @@
         for (WifiDisplay display : mKnownDisplays) {
             display.writeToParcel(dest, flags);
         }
-
-        dest.writeInt(mScanInProgress ? 1 : 0);
-        dest.writeInt(mConnectionInProgress ? 1 : 0);
     }
 
     @Override
@@ -150,10 +161,10 @@
     @Override
     public String toString() {
         return "WifiDisplayStatus{enabled=" + mEnabled
-                + ", connectedDisplay=" + mConnectedDisplay
+                + ", scanState=" + mScanState
+                + ", activeDisplayState=" + mActiveDisplayState
+                + ", activeDisplay=" + mActiveDisplay
                 + ", knownDisplays=" + Arrays.toString(mKnownDisplays)
-                + ", scanInProgress=" + mScanInProgress
-                + ", connectionInProgress=" + mConnectionInProgress
                 + "}";
     }
 }
diff --git a/services/java/com/android/server/display/WifiDisplayAdapter.java b/services/java/com/android/server/display/WifiDisplayAdapter.java
index ca500c0..ee82050 100644
--- a/services/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/java/com/android/server/display/WifiDisplayAdapter.java
@@ -55,10 +55,10 @@
 
     private WifiDisplayStatus mCurrentStatus;
     private boolean mEnabled;
-    private WifiDisplay mConnectedDisplay;
+    private int mScanState;
+    private int mActiveDisplayState;
+    private WifiDisplay mActiveDisplay;
     private WifiDisplay[] mKnownDisplays = WifiDisplay.EMPTY_ARRAY;
-    private boolean mScanInProgress;
-    private boolean mConnectionInProgress;
 
     private boolean mPendingStatusChangeBroadcast;
 
@@ -80,10 +80,10 @@
 
         pw.println("mCurrentStatus=" + getWifiDisplayStatusLocked());
         pw.println("mEnabled=" + mEnabled);
-        pw.println("mConnectedDisplay=" + mConnectedDisplay);
+        pw.println("mScanState=" + mScanState);
+        pw.println("mActiveDisplayState=" + mActiveDisplayState);
+        pw.println("mActiveDisplay=" + mActiveDisplay);
         pw.println("mKnownDisplays=" + Arrays.toString(mKnownDisplays));
-        pw.println("mScanInProgress=" + mScanInProgress);
-        pw.println("mConnectionInProgress=" + mConnectionInProgress);
         pw.println("mPendingStatusChangeBroadcast=" + mPendingStatusChangeBroadcast);
 
         // Try to dump the controller state.
@@ -145,9 +145,8 @@
 
     public WifiDisplayStatus getWifiDisplayStatusLocked() {
         if (mCurrentStatus == null) {
-            mCurrentStatus = new WifiDisplayStatus(mEnabled,
-                    mConnectedDisplay, mKnownDisplays,
-                    mScanInProgress, mConnectionInProgress);
+            mCurrentStatus = new WifiDisplayStatus(mEnabled, mScanState, mActiveDisplayState,
+                    mActiveDisplay, mKnownDisplays);
         }
         return mCurrentStatus;
     }
@@ -211,9 +210,9 @@
         @Override
         public void onScanStarted() {
             synchronized (getSyncRoot()) {
-                if (!mScanInProgress) {
+                if (mScanState != WifiDisplayStatus.SCAN_STATE_SCANNING) {
                     mCurrentStatus = null;
-                    mScanInProgress = true;
+                    mScanState = WifiDisplayStatus.SCAN_STATE_SCANNING;
                     scheduleStatusChangedBroadcastLocked();
                 }
             }
@@ -221,10 +220,11 @@
 
         public void onScanFinished(WifiDisplay[] knownDisplays) {
             synchronized (getSyncRoot()) {
-                if (!Arrays.equals(mKnownDisplays, knownDisplays) || mScanInProgress) {
+                if (mScanState != WifiDisplayStatus.SCAN_STATE_NOT_SCANNING
+                        || !Arrays.equals(mKnownDisplays, knownDisplays)) {
                     mCurrentStatus = null;
+                    mScanState = WifiDisplayStatus.SCAN_STATE_NOT_SCANNING;
                     mKnownDisplays = knownDisplays;
-                    mScanInProgress = false;
                     scheduleStatusChangedBroadcastLocked();
                 }
             }
@@ -233,9 +233,12 @@
         @Override
         public void onDisplayConnecting(WifiDisplay display) {
             synchronized (getSyncRoot()) {
-                if (!mConnectionInProgress) {
+                if (mActiveDisplayState != WifiDisplayStatus.DISPLAY_STATE_CONNECTING
+                        || mActiveDisplay == null
+                        || !mActiveDisplay.equals(display)) {
                     mCurrentStatus = null;
-                    mConnectionInProgress = true;
+                    mActiveDisplayState = WifiDisplayStatus.DISPLAY_STATE_CONNECTING;
+                    mActiveDisplay = display;
                     scheduleStatusChangedBroadcastLocked();
                 }
             }
@@ -244,9 +247,11 @@
         @Override
         public void onDisplayConnectionFailed() {
             synchronized (getSyncRoot()) {
-                if (mConnectionInProgress) {
+                if (mActiveDisplayState != WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED
+                        || mActiveDisplay != null) {
                     mCurrentStatus = null;
-                    mConnectionInProgress = false;
+                    mActiveDisplayState = WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED;
+                    mActiveDisplay = null;
                     scheduleStatusChangedBroadcastLocked();
                 }
             }
@@ -257,11 +262,12 @@
             synchronized (getSyncRoot()) {
                 handleConnectLocked(display, iface);
 
-                if (mConnectedDisplay == null || !mConnectedDisplay.equals(display)
-                        || mConnectionInProgress) {
+                if (mActiveDisplayState != WifiDisplayStatus.DISPLAY_STATE_CONNECTED
+                        || mActiveDisplay == null
+                        || !mActiveDisplay.equals(display)) {
                     mCurrentStatus = null;
-                    mConnectedDisplay = display;
-                    mConnectionInProgress = false;
+                    mActiveDisplayState = WifiDisplayStatus.DISPLAY_STATE_CONNECTED;
+                    mActiveDisplay = display;
                     scheduleStatusChangedBroadcastLocked();
                 }
             }
@@ -273,10 +279,11 @@
             synchronized (getSyncRoot()) {
                 handleDisconnectLocked();
 
-                if (mConnectedDisplay != null || mConnectionInProgress) {
+                if (mActiveDisplayState != WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED
+                        || mActiveDisplay != null) {
                     mCurrentStatus = null;
-                    mConnectedDisplay = null;
-                    mConnectionInProgress = false;
+                    mActiveDisplayState = WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED;
+                    mActiveDisplay = null;
                     scheduleStatusChangedBroadcastLocked();
                 }
             }
diff --git a/services/java/com/android/server/display/WifiDisplayController.java b/services/java/com/android/server/display/WifiDisplayController.java
index 131502f..b617d00 100644
--- a/services/java/com/android/server/display/WifiDisplayController.java
+++ b/services/java/com/android/server/display/WifiDisplayController.java
@@ -536,7 +536,7 @@
 
     private void handleConnectionChanged(NetworkInfo networkInfo) {
         mNetworkInfo = networkInfo;
-        if (mWifiP2pEnabled && mWfdEnabled && networkInfo.isConnected()) {
+        if (mWfdEnabled && networkInfo.isConnected()) {
             if (mDesiredDevice != null) {
                 mWifiP2pManager.requestGroupInfo(mWifiP2pChannel, new GroupInfoListener() {
                     @Override
@@ -573,6 +573,13 @@
             }
         } else {
             disconnect();
+
+            // After disconnection for a group, for some reason we have a tendency
+            // to get a peer change notification with an empty list of peers.
+            // Perform a fresh scan.
+            if (mWfdEnabled) {
+                requestPeers();
+            }
         }
     }