@@ -64,6 +64,12 @@ final class WifiDisplayController implements DumpUtils.Dump {
6464 private static final int MAX_THROUGHPUT = 50 ;
6565 private static final int CONNECTION_TIMEOUT_SECONDS = 30 ;
6666
67+ private static final int DISCOVER_PEERS_MAX_RETRIES = 10 ;
68+ private static final int DISCOVER_PEERS_RETRY_DELAY_MILLIS = 500 ;
69+
70+ private static final int CONNECT_MAX_RETRIES = 3 ;
71+ private static final int CONNECT_RETRY_DELAY_MILLIS = 500 ;
72+
6773 private final Context mContext ;
6874 private final Handler mHandler ;
6975 private final Listener mListener ;
@@ -78,6 +84,12 @@ final class WifiDisplayController implements DumpUtils.Dump {
7884 private final ArrayList <WifiP2pDevice > mKnownWifiDisplayPeers =
7985 new ArrayList <WifiP2pDevice >();
8086
87+ // True if there is a call to discoverPeers in progress.
88+ private boolean mDiscoverPeersInProgress ;
89+
90+ // Number of discover peers retries remaining.
91+ private int mDiscoverPeersRetriesLeft ;
92+
8193 // The device to which we want to connect, or null if we want to be disconnected.
8294 private WifiP2pDevice mDesiredDevice ;
8395
@@ -94,6 +106,9 @@ final class WifiDisplayController implements DumpUtils.Dump {
94106 // The device that we announced to the rest of the system.
95107 private WifiP2pDevice mPublishedDevice ;
96108
109+ // Number of connection retries remaining.
110+ private int mConnectionRetriesLeft ;
111+
97112 public WifiDisplayController (Context context , Handler handler , Listener listener ) {
98113 mContext = context ;
99114 mHandler = handler ;
@@ -114,10 +129,13 @@ public void dump(PrintWriter pw) {
114129 pw .println ("mWfdEnabled=" + mWfdEnabled );
115130 pw .println ("mWfdEnabling=" + mWfdEnabling );
116131 pw .println ("mNetworkInfo=" + mNetworkInfo );
132+ pw .println ("mDiscoverPeersInProgress=" + mDiscoverPeersInProgress );
133+ pw .println ("mDiscoverPeersRetriesLeft=" + mDiscoverPeersRetriesLeft );
117134 pw .println ("mDesiredDevice=" + describeWifiP2pDevice (mDesiredDevice ));
118135 pw .println ("mConnectingDisplay=" + describeWifiP2pDevice (mConnectingDevice ));
119136 pw .println ("mConnectedDevice=" + describeWifiP2pDevice (mConnectedDevice ));
120137 pw .println ("mPublishedDevice=" + describeWifiP2pDevice (mPublishedDevice ));
138+ pw .println ("mConnectionRetriesLeft=" + mConnectionRetriesLeft );
121139
122140 pw .println ("mKnownWifiDisplayPeers: size=" + mKnownWifiDisplayPeers .size ());
123141 for (WifiP2pDevice device : mKnownWifiDisplayPeers ) {
@@ -160,13 +178,22 @@ public void onFailure(int reason) {
160178 }
161179
162180 private void discoverPeers () {
181+ if (!mDiscoverPeersInProgress ) {
182+ mDiscoverPeersInProgress = true ;
183+ mDiscoverPeersRetriesLeft = DISCOVER_PEERS_MAX_RETRIES ;
184+ tryDiscoverPeers ();
185+ }
186+ }
187+
188+ private void tryDiscoverPeers () {
163189 mWifiP2pManager .discoverPeers (mWifiP2pChannel , new ActionListener () {
164190 @ Override
165191 public void onSuccess () {
166192 if (DEBUG ) {
167193 Slog .d (TAG , "Discover peers succeeded. Requesting peers now." );
168194 }
169195
196+ mDiscoverPeersInProgress = false ;
170197 requestPeers ();
171198 }
172199
@@ -175,6 +202,30 @@ public void onFailure(int reason) {
175202 if (DEBUG ) {
176203 Slog .d (TAG , "Discover peers failed with reason " + reason + "." );
177204 }
205+
206+ if (mDiscoverPeersInProgress ) {
207+ if (reason == 0 && mDiscoverPeersRetriesLeft > 0 && mWfdEnabled ) {
208+ mHandler .postDelayed (new Runnable () {
209+ @ Override
210+ public void run () {
211+ if (mDiscoverPeersInProgress ) {
212+ if (mDiscoverPeersRetriesLeft > 0 && mWfdEnabled ) {
213+ mDiscoverPeersRetriesLeft -= 1 ;
214+ if (DEBUG ) {
215+ Slog .d (TAG , "Retrying discovery. Retries left: "
216+ + mDiscoverPeersRetriesLeft );
217+ }
218+ tryDiscoverPeers ();
219+ } else {
220+ mDiscoverPeersInProgress = false ;
221+ }
222+ }
223+ }
224+ }, DISCOVER_PEERS_RETRY_DELAY_MILLIS );
225+ } else {
226+ mDiscoverPeersInProgress = false ;
227+ }
228+ }
178229 }
179230 });
180231 }
@@ -230,9 +281,11 @@ private void connect(final WifiP2pDevice device) {
230281 + describeWifiP2pDevice (device ) + " and not part way through "
231282 + "connecting to a different device." );
232283 }
284+ return ;
233285 }
234286
235287 mDesiredDevice = device ;
288+ mConnectionRetriesLeft = CONNECT_MAX_RETRIES ;
236289 updateConnection ();
237290 }
238291
@@ -241,6 +294,21 @@ private void disconnect() {
241294 updateConnection ();
242295 }
243296
297+ private void retryConnection () {
298+ if (mDesiredDevice != null && mPublishedDevice != mDesiredDevice
299+ && mConnectionRetriesLeft > 0 ) {
300+ mConnectionRetriesLeft -= 1 ;
301+ Slog .i (TAG , "Retrying Wifi display connection. Retries left: "
302+ + mConnectionRetriesLeft );
303+
304+ // Cheap hack. Make a new instance of the device object so that we
305+ // can distinguish it from the previous connection attempt.
306+ // This will cause us to tear everything down before we try again.
307+ mDesiredDevice = new WifiP2pDevice (mDesiredDevice );
308+ updateConnection ();
309+ }
310+ }
311+
244312 /**
245313 * This function is called repeatedly after each asynchronous operation
246314 * until all preconditions for the connection have been satisfied and the
@@ -353,7 +421,7 @@ public void onFailure(int reason) {
353421 + newDevice .deviceName + ", reason=" + reason );
354422 if (mConnectingDevice == newDevice ) {
355423 mConnectingDevice = null ;
356- handleConnectionFailure ();
424+ handleConnectionFailure (false );
357425 }
358426 }
359427 });
@@ -366,7 +434,7 @@ public void onFailure(int reason) {
366434 if (addr == null ) {
367435 Slog .i (TAG , "Failed to get local interface address for communicating "
368436 + "with Wifi display: " + mConnectedDevice .deviceName );
369- handleConnectionFailure ();
437+ handleConnectionFailure (false );
370438 return ; // done
371439 }
372440
@@ -426,7 +494,7 @@ public void onGroupInfoAvailable(WifiP2pGroup info) {
426494 Slog .i (TAG , "Aborting connection to Wifi display because "
427495 + "the current P2P group does not contain the device "
428496 + "we expected to find: " + mConnectingDevice .deviceName );
429- handleConnectionFailure ();
497+ handleConnectionFailure (false );
430498 return ;
431499 }
432500
@@ -436,7 +504,8 @@ public void onGroupInfoAvailable(WifiP2pGroup info) {
436504 }
437505
438506 if (mConnectingDevice != null && mConnectingDevice == mDesiredDevice ) {
439- Slog .i (TAG , "Connected to Wifi display: " + mConnectingDevice .deviceName );
507+ Slog .i (TAG , "Connected to Wifi display: "
508+ + mConnectingDevice .deviceName );
440509
441510 mHandler .removeCallbacks (mConnectionTimeout );
442511 mConnectedDeviceGroupInfo = info ;
@@ -459,15 +528,25 @@ public void run() {
459528 Slog .i (TAG , "Timed out waiting for Wifi display connection after "
460529 + CONNECTION_TIMEOUT_SECONDS + " seconds: "
461530 + mConnectingDevice .deviceName );
462- handleConnectionFailure ();
531+ handleConnectionFailure (true );
463532 }
464533 }
465534 };
466535
467- private void handleConnectionFailure () {
536+ private void handleConnectionFailure (boolean timeoutOccurred ) {
468537 if (mDesiredDevice != null ) {
469538 Slog .i (TAG , "Wifi display connection failed!" );
470- disconnect ();
539+
540+ if (mConnectionRetriesLeft > 0 ) {
541+ mHandler .postDelayed (new Runnable () {
542+ @ Override
543+ public void run () {
544+ retryConnection ();
545+ }
546+ }, timeoutOccurred ? 0 : CONNECT_RETRY_DELAY_MILLIS );
547+ } else {
548+ disconnect ();
549+ }
471550 }
472551 }
473552
0 commit comments