Merge "Improve reporting of wifi connection state." into jb-mr1-dev
This commit is contained in:
@@ -27,7 +27,6 @@ import android.hardware.display.WifiDisplayStatus;
|
||||
import android.media.RemoteDisplay;
|
||||
import android.os.Handler;
|
||||
import android.os.IBinder;
|
||||
import android.util.Slog;
|
||||
import android.view.Surface;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
@@ -50,8 +49,8 @@ import java.util.Arrays;
|
||||
final class WifiDisplayAdapter extends DisplayAdapter {
|
||||
private static final String TAG = "WifiDisplayAdapter";
|
||||
|
||||
private WifiDisplayHandle mDisplayHandle;
|
||||
private WifiDisplayController mDisplayController;
|
||||
private WifiDisplayDevice mDisplayDevice;
|
||||
|
||||
private WifiDisplayStatus mCurrentStatus;
|
||||
private boolean mEnabled;
|
||||
@@ -71,13 +70,6 @@ final class WifiDisplayAdapter extends DisplayAdapter {
|
||||
public void dumpLocked(PrintWriter pw) {
|
||||
super.dumpLocked(pw);
|
||||
|
||||
if (mDisplayHandle == null) {
|
||||
pw.println("mDisplayHandle=null");
|
||||
} else {
|
||||
pw.println("mDisplayHandle:");
|
||||
mDisplayHandle.dumpLocked(pw);
|
||||
}
|
||||
|
||||
pw.println("mCurrentStatus=" + getWifiDisplayStatusLocked());
|
||||
pw.println("mEnabled=" + mEnabled);
|
||||
pw.println("mScanState=" + mScanState);
|
||||
@@ -151,16 +143,29 @@ final class WifiDisplayAdapter extends DisplayAdapter {
|
||||
return mCurrentStatus;
|
||||
}
|
||||
|
||||
private void handleConnectLocked(WifiDisplay display, String iface) {
|
||||
private void handleConnectLocked(WifiDisplay display,
|
||||
Surface surface, int width, int height, int flags) {
|
||||
handleDisconnectLocked();
|
||||
|
||||
mDisplayHandle = new WifiDisplayHandle(display.getDeviceName(), iface);
|
||||
int deviceFlags = 0;
|
||||
if ((flags & RemoteDisplay.DISPLAY_FLAG_SECURE) != 0) {
|
||||
deviceFlags |= DisplayDeviceInfo.FLAG_SECURE;
|
||||
}
|
||||
|
||||
float refreshRate = 60.0f; // TODO: get this for real
|
||||
|
||||
String name = display.getDeviceName();
|
||||
IBinder displayToken = Surface.createDisplay(name);
|
||||
mDisplayDevice = new WifiDisplayDevice(displayToken, name, width, height,
|
||||
refreshRate, deviceFlags, surface);
|
||||
sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_ADDED);
|
||||
}
|
||||
|
||||
private void handleDisconnectLocked() {
|
||||
if (mDisplayHandle != null) {
|
||||
mDisplayHandle.disposeLocked();
|
||||
mDisplayHandle = null;
|
||||
if (mDisplayDevice != null) {
|
||||
mDisplayDevice.clearSurfaceLocked();
|
||||
sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_REMOVED);
|
||||
mDisplayDevice = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,9 +263,10 @@ final class WifiDisplayAdapter extends DisplayAdapter {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayConnected(WifiDisplay display, String iface) {
|
||||
public void onDisplayConnected(WifiDisplay display, Surface surface,
|
||||
int width, int height, int flags) {
|
||||
synchronized (getSyncRoot()) {
|
||||
handleConnectLocked(display, iface);
|
||||
handleConnectLocked(display, surface, width, height, flags);
|
||||
|
||||
if (mActiveDisplayState != WifiDisplayStatus.DISPLAY_STATE_CONNECTED
|
||||
|| mActiveDisplay == null
|
||||
@@ -337,92 +343,4 @@ final class WifiDisplayAdapter extends DisplayAdapter {
|
||||
return mInfo;
|
||||
}
|
||||
}
|
||||
|
||||
private final class WifiDisplayHandle implements RemoteDisplay.Listener {
|
||||
private final String mName;
|
||||
private final String mIface;
|
||||
private final RemoteDisplay mRemoteDisplay;
|
||||
|
||||
private WifiDisplayDevice mDevice;
|
||||
private int mLastError;
|
||||
|
||||
public WifiDisplayHandle(String name, String iface) {
|
||||
mName = name;
|
||||
mIface = iface;
|
||||
mRemoteDisplay = RemoteDisplay.listen(iface, this, getHandler());
|
||||
|
||||
Slog.i(TAG, "Listening for Wifi display connections on " + iface
|
||||
+ " from " + mName);
|
||||
}
|
||||
|
||||
public void disposeLocked() {
|
||||
Slog.i(TAG, "Stopped listening for Wifi display connections on " + mIface
|
||||
+ " from " + mName);
|
||||
|
||||
removeDisplayLocked();
|
||||
mRemoteDisplay.dispose();
|
||||
}
|
||||
|
||||
public void dumpLocked(PrintWriter pw) {
|
||||
pw.println(" " + mName + ": " + (mDevice != null ? "connected" : "disconnected"));
|
||||
pw.println(" mIface=" + mIface);
|
||||
pw.println(" mLastError=" + mLastError);
|
||||
}
|
||||
|
||||
// Called on the handler thread.
|
||||
@Override
|
||||
public void onDisplayConnected(Surface surface, int width, int height, int flags) {
|
||||
synchronized (getSyncRoot()) {
|
||||
mLastError = 0;
|
||||
removeDisplayLocked();
|
||||
addDisplayLocked(surface, width, height, flags);
|
||||
|
||||
Slog.i(TAG, "Wifi display connected: " + mName);
|
||||
}
|
||||
}
|
||||
|
||||
// Called on the handler thread.
|
||||
@Override
|
||||
public void onDisplayDisconnected() {
|
||||
synchronized (getSyncRoot()) {
|
||||
mLastError = 0;
|
||||
removeDisplayLocked();
|
||||
|
||||
Slog.i(TAG, "Wifi display disconnected: " + mName);
|
||||
}
|
||||
}
|
||||
|
||||
// Called on the handler thread.
|
||||
@Override
|
||||
public void onDisplayError(int error) {
|
||||
synchronized (getSyncRoot()) {
|
||||
mLastError = error;
|
||||
removeDisplayLocked();
|
||||
|
||||
Slog.i(TAG, "Wifi display disconnected due to error " + error + ": " + mName);
|
||||
}
|
||||
}
|
||||
|
||||
private void addDisplayLocked(Surface surface, int width, int height, int flags) {
|
||||
int deviceFlags = 0;
|
||||
if ((flags & RemoteDisplay.DISPLAY_FLAG_SECURE) != 0) {
|
||||
deviceFlags |= DisplayDeviceInfo.FLAG_SECURE;
|
||||
}
|
||||
|
||||
float refreshRate = 60.0f; // TODO: get this for real
|
||||
|
||||
IBinder displayToken = Surface.createDisplay(mName);
|
||||
mDevice = new WifiDisplayDevice(displayToken, mName, width, height,
|
||||
refreshRate, deviceFlags, surface);
|
||||
sendDisplayDeviceEventLocked(mDevice, DISPLAY_DEVICE_EVENT_ADDED);
|
||||
}
|
||||
|
||||
private void removeDisplayLocked() {
|
||||
if (mDevice != null) {
|
||||
mDevice.clearSurfaceLocked();
|
||||
sendDisplayDeviceEventLocked(mDevice, DISPLAY_DEVICE_EVENT_REMOVED);
|
||||
mDevice = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.hardware.display.WifiDisplay;
|
||||
import android.media.RemoteDisplay;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.wifi.p2p.WifiP2pConfig;
|
||||
import android.net.wifi.p2p.WifiP2pDevice;
|
||||
@@ -36,6 +37,7 @@ import android.net.wifi.p2p.WifiP2pManager.GroupInfoListener;
|
||||
import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
|
||||
import android.os.Handler;
|
||||
import android.util.Slog;
|
||||
import android.view.Surface;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.net.Inet4Address;
|
||||
@@ -64,6 +66,7 @@ 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 = 30;
|
||||
private static final int RTSP_TIMEOUT_SECONDS = 15;
|
||||
|
||||
private static final int DISCOVER_PEERS_MAX_RETRIES = 10;
|
||||
private static final int DISCOVER_PEERS_RETRY_DELAY_MILLIS = 500;
|
||||
@@ -104,12 +107,19 @@ final class WifiDisplayController implements DumpUtils.Dump {
|
||||
// The group info obtained after connecting.
|
||||
private WifiP2pGroup mConnectedDeviceGroupInfo;
|
||||
|
||||
// The device that we announced to the rest of the system.
|
||||
private WifiP2pDevice mPublishedDevice;
|
||||
|
||||
// Number of connection retries remaining.
|
||||
private int mConnectionRetriesLeft;
|
||||
|
||||
// The remote display that is listening on the connection.
|
||||
// Created after the Wifi P2P network is connected.
|
||||
private RemoteDisplay mRemoteDisplay;
|
||||
|
||||
// The remote display interface.
|
||||
private String mRemoteDisplayInterface;
|
||||
|
||||
// True if RTSP has connected.
|
||||
private boolean mRemoteDisplayConnected;
|
||||
|
||||
public WifiDisplayController(Context context, Handler handler, Listener listener) {
|
||||
mContext = context;
|
||||
mHandler = handler;
|
||||
@@ -135,8 +145,10 @@ final class WifiDisplayController implements DumpUtils.Dump {
|
||||
pw.println("mDesiredDevice=" + describeWifiP2pDevice(mDesiredDevice));
|
||||
pw.println("mConnectingDisplay=" + describeWifiP2pDevice(mConnectingDevice));
|
||||
pw.println("mConnectedDevice=" + describeWifiP2pDevice(mConnectedDevice));
|
||||
pw.println("mPublishedDevice=" + describeWifiP2pDevice(mPublishedDevice));
|
||||
pw.println("mConnectionRetriesLeft=" + mConnectionRetriesLeft);
|
||||
pw.println("mRemoteDisplay=" + mRemoteDisplay);
|
||||
pw.println("mRemoteDisplayInterface=" + mRemoteDisplayInterface);
|
||||
pw.println("mRemoteDisplayConnected=" + mRemoteDisplayConnected);
|
||||
|
||||
pw.println("mKnownWifiDisplayPeers: size=" + mKnownWifiDisplayPeers.size());
|
||||
for (WifiP2pDevice device : mKnownWifiDisplayPeers) {
|
||||
@@ -341,7 +353,7 @@ final class WifiDisplayController implements DumpUtils.Dump {
|
||||
}
|
||||
|
||||
private void retryConnection() {
|
||||
if (mDesiredDevice != null && mPublishedDevice != mDesiredDevice
|
||||
if (mDesiredDevice != null && mConnectedDevice != mDesiredDevice
|
||||
&& mConnectionRetriesLeft > 0) {
|
||||
mConnectionRetriesLeft -= 1;
|
||||
Slog.i(TAG, "Retrying Wifi display connection. Retries left: "
|
||||
@@ -363,14 +375,22 @@ final class WifiDisplayController implements DumpUtils.Dump {
|
||||
private void updateConnection() {
|
||||
// Step 1. Before we try to connect to a new device, tell the system we
|
||||
// have disconnected from the old one.
|
||||
if (mPublishedDevice != null && mPublishedDevice != mDesiredDevice) {
|
||||
if (mRemoteDisplay != null && mConnectedDevice != mDesiredDevice) {
|
||||
Slog.i(TAG, "Stopped listening for RTSP connection on " + mRemoteDisplayInterface
|
||||
+ " from Wifi display: " + mConnectedDevice.deviceName);
|
||||
|
||||
mRemoteDisplay.dispose();
|
||||
mRemoteDisplay = null;
|
||||
mRemoteDisplayInterface = null;
|
||||
mRemoteDisplayConnected = false;
|
||||
mHandler.removeCallbacks(mRtspTimeout);
|
||||
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mListener.onDisplayDisconnected();
|
||||
}
|
||||
});
|
||||
mPublishedDevice = null;
|
||||
|
||||
// continue to next step
|
||||
}
|
||||
@@ -471,9 +491,9 @@ final class WifiDisplayController implements DumpUtils.Dump {
|
||||
|
||||
@Override
|
||||
public void onFailure(int reason) {
|
||||
Slog.i(TAG, "Failed to initiate connection to Wifi display: "
|
||||
+ newDevice.deviceName + ", reason=" + reason);
|
||||
if (mConnectingDevice == newDevice) {
|
||||
Slog.i(TAG, "Failed to initiate connection to Wifi display: "
|
||||
+ newDevice.deviceName + ", reason=" + reason);
|
||||
mConnectingDevice = null;
|
||||
handleConnectionFailure(false);
|
||||
}
|
||||
@@ -482,8 +502,8 @@ final class WifiDisplayController implements DumpUtils.Dump {
|
||||
return; // wait for asynchronous callback
|
||||
}
|
||||
|
||||
// Step 6. Publish the new connection.
|
||||
if (mConnectedDevice != null && mPublishedDevice == null) {
|
||||
// Step 6. Listen for incoming connections.
|
||||
if (mConnectedDevice != null && mRemoteDisplay == null) {
|
||||
Inet4Address addr = getInterfaceAddress(mConnectedDeviceGroupInfo);
|
||||
if (addr == null) {
|
||||
Slog.i(TAG, "Failed to get local interface address for communicating "
|
||||
@@ -492,17 +512,57 @@ final class WifiDisplayController implements DumpUtils.Dump {
|
||||
return; // done
|
||||
}
|
||||
|
||||
final WifiDisplay display = createWifiDisplay(mConnectedDevice);
|
||||
final WifiP2pDevice oldDevice = mConnectedDevice;
|
||||
final int port = getPortNumber(mConnectedDevice);
|
||||
final String iface = addr.getHostAddress() + ":" + port;
|
||||
mRemoteDisplayInterface = iface;
|
||||
|
||||
mPublishedDevice = mConnectedDevice;
|
||||
mHandler.post(new Runnable() {
|
||||
Slog.i(TAG, "Listening for RTSP connection on " + iface
|
||||
+ " from Wifi display: " + mConnectedDevice.deviceName);
|
||||
|
||||
mRemoteDisplay = RemoteDisplay.listen(iface, new RemoteDisplay.Listener() {
|
||||
@Override
|
||||
public void run() {
|
||||
mListener.onDisplayConnected(display, iface);
|
||||
public void onDisplayConnected(final Surface surface,
|
||||
final int width, final int height, final int flags) {
|
||||
if (mConnectedDevice == oldDevice && !mRemoteDisplayConnected) {
|
||||
Slog.i(TAG, "Opened RTSP connection with Wifi display: "
|
||||
+ mConnectedDevice.deviceName);
|
||||
mRemoteDisplayConnected = true;
|
||||
mHandler.removeCallbacks(mRtspTimeout);
|
||||
|
||||
final WifiDisplay display = createWifiDisplay(mConnectedDevice);
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mListener.onDisplayConnected(display,
|
||||
surface, width, height, flags);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@Override
|
||||
public void onDisplayDisconnected() {
|
||||
if (mConnectedDevice == oldDevice) {
|
||||
Slog.i(TAG, "Closed RTSP connection with Wifi display: "
|
||||
+ mConnectedDevice.deviceName);
|
||||
mHandler.removeCallbacks(mRtspTimeout);
|
||||
disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisplayError(int error) {
|
||||
if (mConnectedDevice == oldDevice) {
|
||||
Slog.i(TAG, "Lost RTSP connection with Wifi display due to error "
|
||||
+ error + ": " + mConnectedDevice.deviceName);
|
||||
mHandler.removeCallbacks(mRtspTimeout);
|
||||
handleConnectionFailure(false);
|
||||
}
|
||||
}
|
||||
}, mHandler);
|
||||
|
||||
mHandler.postDelayed(mRtspTimeout, RTSP_TIMEOUT_SECONDS * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -591,17 +651,30 @@ final class WifiDisplayController implements DumpUtils.Dump {
|
||||
}
|
||||
};
|
||||
|
||||
private final Runnable mRtspTimeout = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mConnectedDevice != null
|
||||
&& mRemoteDisplay != null && !mRemoteDisplayConnected) {
|
||||
Slog.i(TAG, "Timed out waiting for Wifi display RTSP connection after "
|
||||
+ RTSP_TIMEOUT_SECONDS + " seconds: "
|
||||
+ mConnectedDevice.deviceName);
|
||||
handleConnectionFailure(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private void handleConnectionFailure(boolean timeoutOccurred) {
|
||||
Slog.i(TAG, "Wifi display connection failed!");
|
||||
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mListener.onDisplayConnectionFailed();
|
||||
}
|
||||
});
|
||||
|
||||
if (mDesiredDevice != null) {
|
||||
Slog.i(TAG, "Wifi display connection failed!");
|
||||
|
||||
mHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mListener.onDisplayConnectionFailed();
|
||||
}
|
||||
});
|
||||
|
||||
if (mConnectionRetriesLeft > 0) {
|
||||
mHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
@@ -714,7 +787,8 @@ final class WifiDisplayController implements DumpUtils.Dump {
|
||||
|
||||
void onDisplayConnecting(WifiDisplay display);
|
||||
void onDisplayConnectionFailed();
|
||||
void onDisplayConnected(WifiDisplay display, String iface);
|
||||
void onDisplayConnected(WifiDisplay display,
|
||||
Surface surface, int width, int height, int flags);
|
||||
void onDisplayDisconnected();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user