diff options
author | Jeff Brown <jeffbrown@google.com> | 2013-11-21 16:42:03 -0800 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2013-11-21 19:32:59 -0800 |
commit | ce468a35b388ca46578934706b38dbae94941643 (patch) | |
tree | 0e403cf705d7b938c0f0f77d09052486b7e14fb3 /services/java/com/android/server/display/WifiDisplayController.java | |
parent | 90e9b1d3dc15e97bb7ecb88289c3707fe03fb1a6 (diff) |
Stop wifi display discovery when no longer needed.
Keep track of how many clients are requesting scans and scan
continuously until all of them are gone then explicitly terminate the
scan instead of letting it time out as before.
Suspend wifi display scans while connecting or connected to a remote
display. This is handled by both the display manager and media router
since neither has complete information about what is happening.
Much of this code will no longer be needed once wifi display support
is integrated directly into the media router service.
Ensure that we don't attempt to scan or connect to wifi displays
while the wifi display feature is off.
Infer when a connection attempt fails and unselect the wifi display
route automatically so it doesn't appear to be connecting forever.
Fix issues around correctly canceling and retrying connection attempts.
Often we would cancel but not retry.
Improved connection reliability somewhat. It seems that discovery must
already be in progress in order for a connection attempt to succeed.
Ensure QuickSettings uses exactly the same logic as the MediaRouteButton
to determine when the remote display tile should be made visible.
Bug: 11717053
Change-Id: I18afc977b0e8c26204b8c96adaa79f05225f7b6e
Diffstat (limited to 'services/java/com/android/server/display/WifiDisplayController.java')
-rw-r--r-- | services/java/com/android/server/display/WifiDisplayController.java | 163 |
1 files changed, 115 insertions, 48 deletions
diff --git a/services/java/com/android/server/display/WifiDisplayController.java b/services/java/com/android/server/display/WifiDisplayController.java index b2939fe7e4d4..dbb59b269bf5 100644 --- a/services/java/com/android/server/display/WifiDisplayController.java +++ b/services/java/com/android/server/display/WifiDisplayController.java @@ -27,7 +27,6 @@ import android.database.ContentObserver; import android.hardware.display.WifiDisplay; import android.hardware.display.WifiDisplaySessionInfo; import android.hardware.display.WifiDisplayStatus; -import android.media.AudioManager; import android.media.RemoteDisplay; import android.net.NetworkInfo; import android.net.Uri; @@ -75,12 +74,19 @@ final class WifiDisplayController implements DumpUtils.Dump { private static final int DEFAULT_CONTROL_PORT = 7236; private static final int MAX_THROUGHPUT = 50; - private static final int CONNECTION_TIMEOUT_SECONDS = 60; + private static final int CONNECTION_TIMEOUT_SECONDS = 30; private static final int RTSP_TIMEOUT_SECONDS = 30; private static final int RTSP_TIMEOUT_SECONDS_CERT_MODE = 120; - private static final int DISCOVER_PEERS_MAX_RETRIES = 10; - private static final int DISCOVER_PEERS_RETRY_DELAY_MILLIS = 500; + // We repeatedly issue calls to discover peers every so often for a few reasons. + // 1. The initial request may fail and need to retried. + // 2. Discovery will self-abort after any group is initiated, which may not necessarily + // be what we want to have happen. + // 3. Discovery will self-timeout after 2 minutes, whereas we want discovery to + // be occur for as long as a client is requesting it be. + // 4. We don't seem to get updated results for displays we've already found until + // we ask to discover again, particularly for the isSessionAvailable() property. + private static final int DISCOVER_PEERS_INTERVAL_MILLIS = 10000; private static final int CONNECT_MAX_RETRIES = 3; private static final int CONNECT_RETRY_DELAY_MILLIS = 500; @@ -103,12 +109,12 @@ final class WifiDisplayController implements DumpUtils.Dump { // True if Wifi display is enabled by the user. private boolean mWifiDisplayOnSetting; + // True if a scan was requested independent of whether one is actually in progress. + private boolean mScanRequested; + // True if there is a call to discoverPeers in progress. private boolean mDiscoverPeersInProgress; - // Number of discover peers retries remaining. - private int mDiscoverPeersRetriesLeft; - // The device to which we want to connect, or null if we want to be disconnected. private WifiP2pDevice mDesiredDevice; @@ -209,8 +215,8 @@ final class WifiDisplayController implements DumpUtils.Dump { pw.println("mWfdEnabled=" + mWfdEnabled); pw.println("mWfdEnabling=" + mWfdEnabling); pw.println("mNetworkInfo=" + mNetworkInfo); + pw.println("mScanRequested=" + mScanRequested); pw.println("mDiscoverPeersInProgress=" + mDiscoverPeersInProgress); - pw.println("mDiscoverPeersRetriesLeft=" + mDiscoverPeersRetriesLeft); pw.println("mDesiredDevice=" + describeWifiP2pDevice(mDesiredDevice)); pw.println("mConnectingDisplay=" + describeWifiP2pDevice(mConnectingDevice)); pw.println("mDisconnectingDisplay=" + describeWifiP2pDevice(mDisconnectingDevice)); @@ -232,8 +238,18 @@ final class WifiDisplayController implements DumpUtils.Dump { } } - public void requestScan() { - discoverPeers(); + public void requestStartScan() { + if (!mScanRequested) { + mScanRequested = true; + updateScanState(); + } + } + + public void requestStopScan() { + if (mScanRequested) { + mScanRequested = false; + updateScanState(); + } } public void requestConnect(String address) { @@ -282,6 +298,7 @@ final class WifiDisplayController implements DumpUtils.Dump { mWfdEnabling = false; mWfdEnabled = true; reportFeatureState(); + updateScanState(); } } @@ -318,6 +335,7 @@ final class WifiDisplayController implements DumpUtils.Dump { mWfdEnabling = false; mWfdEnabled = false; reportFeatureState(); + updateScanState(); disconnect(); } } @@ -340,12 +358,29 @@ final class WifiDisplayController implements DumpUtils.Dump { WifiDisplayStatus.FEATURE_STATE_OFF; } - private void discoverPeers() { - if (!mDiscoverPeersInProgress) { - mDiscoverPeersInProgress = true; - mDiscoverPeersRetriesLeft = DISCOVER_PEERS_MAX_RETRIES; - handleScanStarted(); - tryDiscoverPeers(); + private void updateScanState() { + if (mScanRequested && mWfdEnabled && mDesiredDevice == null) { + if (!mDiscoverPeersInProgress) { + Slog.i(TAG, "Starting Wifi display scan."); + mDiscoverPeersInProgress = true; + handleScanStarted(); + tryDiscoverPeers(); + } + } else { + if (mDiscoverPeersInProgress) { + // Cancel automatic retry right away. + mHandler.removeCallbacks(mDiscoverPeers); + + // Defer actually stopping discovery if we have a connection attempt in progress. + // The wifi display connection attempt often fails if we are not in discovery + // mode. So we allow discovery to continue until we give up trying to connect. + if (mDesiredDevice == null || mDesiredDevice == mConnectedDevice) { + Slog.i(TAG, "Stopping Wifi display scan."); + mDiscoverPeersInProgress = false; + stopPeerDiscovery(); + handleScanFinished(); + } + } } } @@ -357,8 +392,9 @@ final class WifiDisplayController implements DumpUtils.Dump { Slog.d(TAG, "Discover peers succeeded. Requesting peers now."); } - mDiscoverPeersInProgress = false; - requestPeers(); + if (mDiscoverPeersInProgress) { + requestPeers(); + } } @Override @@ -367,30 +403,28 @@ final class WifiDisplayController implements DumpUtils.Dump { Slog.d(TAG, "Discover peers failed with reason " + reason + "."); } - if (mDiscoverPeersInProgress) { - if (reason == 0 && mDiscoverPeersRetriesLeft > 0 && mWfdEnabled) { - mHandler.postDelayed(new Runnable() { - @Override - public void run() { - if (mDiscoverPeersInProgress) { - if (mDiscoverPeersRetriesLeft > 0 && mWfdEnabled) { - mDiscoverPeersRetriesLeft -= 1; - if (DEBUG) { - Slog.d(TAG, "Retrying discovery. Retries left: " - + mDiscoverPeersRetriesLeft); - } - tryDiscoverPeers(); - } else { - handleScanFinished(); - mDiscoverPeersInProgress = false; - } - } - } - }, DISCOVER_PEERS_RETRY_DELAY_MILLIS); - } else { - handleScanFinished(); - mDiscoverPeersInProgress = false; - } + // Ignore the error. + // We will retry automatically in a little bit. + } + }); + + // Retry discover peers periodically until stopped. + mHandler.postDelayed(mDiscoverPeers, DISCOVER_PEERS_INTERVAL_MILLIS); + } + + private void stopPeerDiscovery() { + mWifiP2pManager.stopPeerDiscovery(mWifiP2pChannel, new ActionListener() { + @Override + public void onSuccess() { + if (DEBUG) { + Slog.d(TAG, "Stop peer discovery succeeded."); + } + } + + @Override + public void onFailure(int reason) { + if (DEBUG) { + Slog.d(TAG, "Stop peer discovery failed with reason " + reason + "."); } } }); @@ -415,7 +449,9 @@ final class WifiDisplayController implements DumpUtils.Dump { } } - handleScanFinished(); + if (mDiscoverPeersInProgress) { + handleScanResults(); + } } }); } @@ -429,7 +465,7 @@ final class WifiDisplayController implements DumpUtils.Dump { }); } - private void handleScanFinished() { + private void handleScanResults() { final int count = mAvailableWifiDisplayPeers.size(); final WifiDisplay[] displays = WifiDisplay.CREATOR.newArray(count); for (int i = 0; i < count; i++) { @@ -441,7 +477,16 @@ final class WifiDisplayController implements DumpUtils.Dump { mHandler.post(new Runnable() { @Override public void run() { - mListener.onScanFinished(displays); + mListener.onScanResults(displays); + } + }); + } + + private void handleScanFinished() { + mHandler.post(new Runnable() { + @Override + public void run() { + mListener.onScanFinished(); } }); } @@ -484,6 +529,12 @@ final class WifiDisplayController implements DumpUtils.Dump { return; } + if (!mWfdEnabled) { + Slog.i(TAG, "Ignoring request to connect to Wifi display because the " + +" feature is currently disabled: " + device.deviceName); + return; + } + mDesiredDevice = device; mConnectionRetriesLeft = CONNECT_MAX_RETRIES; updateConnection(); @@ -508,6 +559,10 @@ final class WifiDisplayController implements DumpUtils.Dump { * connection is established (or not). */ private void updateConnection() { + // Step 0. Stop scans if necessary to prevent interference while connected. + // Resume scans later when no longer attempting to connect. + updateScanState(); + // Step 1. Before we try to connect to a new device, tell the system we // have disconnected from the old one. if (mRemoteDisplay != null && mConnectedDevice != mDesiredDevice) { @@ -661,7 +716,7 @@ final class WifiDisplayController implements DumpUtils.Dump { return; // wait for asynchronous callback } - // Step 6. Listen for incoming connections. + // Step 6. Listen for incoming RTSP connection. if (mConnectedDevice != null && mRemoteDisplay == null) { Inet4Address addr = getInterfaceAddress(mConnectedDeviceGroupInfo); if (addr == null) { @@ -817,7 +872,11 @@ final class WifiDisplayController implements DumpUtils.Dump { } } else { mConnectedDeviceGroupInfo = null; - disconnect(); + + // Disconnect if we lost the network while connecting or connected to a display. + if (mConnectingDevice != null || mConnectedDevice != null) { + 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. @@ -828,6 +887,13 @@ final class WifiDisplayController implements DumpUtils.Dump { } } + private final Runnable mDiscoverPeers = new Runnable() { + @Override + public void run() { + tryDiscoverPeers(); + } + }; + private final Runnable mConnectionTimeout = new Runnable() { @Override public void run() { @@ -1033,7 +1099,8 @@ final class WifiDisplayController implements DumpUtils.Dump { void onFeatureStateChanged(int featureState); void onScanStarted(); - void onScanFinished(WifiDisplay[] availableDisplays); + void onScanResults(WifiDisplay[] availableDisplays); + void onScanFinished(); void onDisplayConnecting(WifiDisplay display); void onDisplayConnectionFailed(); |