Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit feef9887 authored by Jeff Brown's avatar Jeff Brown Committed by The Android Automerger
Browse files

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
parent bf2ed3fc
Loading
Loading
Loading
Loading
+18 −3
Original line number Diff line number Diff line
@@ -297,16 +297,31 @@ public final class DisplayManager {
    }

    /**
     * Initiates a fresh scan of availble Wifi displays.
     * Starts scanning for available Wifi displays.
     * The results are sent as a {@link #ACTION_WIFI_DISPLAY_STATUS_CHANGED} broadcast.
     * <p>
     * Calls to this method nest and must be matched by an equal number of calls to
     * {@link #stopWifiDisplayScan()}.
     * </p><p>
     * Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY}.
     * </p>
     *
     * @hide
     */
    public void startWifiDisplayScan() {
        mGlobal.startWifiDisplayScan();
    }

    /**
     * Stops scanning for available Wifi displays.
     * <p>
     * Requires {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY}.
     * </p>
     *
     * @hide
     */
    public void scanWifiDisplays() {
        mGlobal.scanWifiDisplays();
    public void stopWifiDisplayScan() {
        mGlobal.stopWifiDisplayScan();
    }

    /**
+28 −5
Original line number Diff line number Diff line
@@ -72,6 +72,8 @@ public final class DisplayManagerGlobal {
    private final SparseArray<DisplayInfo> mDisplayInfoCache = new SparseArray<DisplayInfo>();
    private int[] mDisplayIdCache;

    private int mWifiDisplayScanNestCount;

    private DisplayManagerGlobal(IDisplayManager dm) {
        mDm = dm;
    }
@@ -267,12 +269,33 @@ public final class DisplayManagerGlobal {
        }
    }

    public void scanWifiDisplays() {
    public void startWifiDisplayScan() {
        synchronized (mLock) {
            if (mWifiDisplayScanNestCount++ == 0) {
                registerCallbackIfNeededLocked();
                try {
                    mDm.startWifiDisplayScan();
                } catch (RemoteException ex) {
                    Log.e(TAG, "Failed to scan for Wifi displays.", ex);
                }
            }
        }
    }

    public void stopWifiDisplayScan() {
        synchronized (mLock) {
            if (--mWifiDisplayScanNestCount == 0) {
                try {
            mDm.scanWifiDisplays();
                    mDm.stopWifiDisplayScan();
                } catch (RemoteException ex) {
                    Log.e(TAG, "Failed to scan for Wifi displays.", ex);
                }
            } else if (mWifiDisplayScanNestCount < 0) {
                Log.wtf(TAG, "Wifi display scan nest count became negative: "
                        + mWifiDisplayScanNestCount);
                mWifiDisplayScanNestCount = 0;
            }
        }
    }

    public void connectWifiDisplay(String deviceAddress) {
+13 −10
Original line number Diff line number Diff line
@@ -29,11 +29,14 @@ interface IDisplayManager {

    void registerCallback(in IDisplayManagerCallback callback);

    // No permissions required.
    void scanWifiDisplays();
    // Requires CONFIGURE_WIFI_DISPLAY permission.
    // The process must have previously registered a callback.
    void startWifiDisplayScan();

    // Requires CONFIGURE_WIFI_DISPLAY permission to connect to an unknown device.
    // No permissions required to connect to a known device.
    // Requires CONFIGURE_WIFI_DISPLAY permission.
    void stopWifiDisplayScan();

    // Requires CONFIGURE_WIFI_DISPLAY permission.
    void connectWifiDisplay(String address);

    // No permissions required.
@@ -45,6 +48,12 @@ interface IDisplayManager {
    // Requires CONFIGURE_WIFI_DISPLAY permission.
    void forgetWifiDisplay(String address);

    // Requires CONFIGURE_WIFI_DISPLAY permission.
    void pauseWifiDisplay();

    // Requires CONFIGURE_WIFI_DISPLAY permission.
    void resumeWifiDisplay();

    // No permissions required.
    WifiDisplayStatus getWifiDisplayStatus();

@@ -55,10 +64,4 @@ interface IDisplayManager {

    // No permissions required but must be same Uid as the creator.
    void releaseVirtualDisplay(in IBinder token);

    // Requires CONFIGURE_WIFI_DISPLAY permission.
    void pauseWifiDisplay();

    // Requires CONFIGURE_WIFI_DISPLAY permission.
    void resumeWifiDisplay();
}
+34 −27
Original line number Diff line number Diff line
@@ -61,9 +61,6 @@ public class MediaRouter {
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    static class Static implements DisplayManager.DisplayListener {
        // Time between wifi display scans when actively scanning in milliseconds.
        private static final int WIFI_DISPLAY_SCAN_INTERVAL = 10000;

        final Context mAppContext;
        final Resources mResources;
        final IAudioService mAudioService;
@@ -87,6 +84,7 @@ public class MediaRouter {

        final boolean mCanConfigureWifiDisplays;
        boolean mActivelyScanningWifiDisplays;
        String mPreviousActiveWifiDisplayAddress;

        int mDiscoveryRequestRouteTypes;
        boolean mDiscoverRequestActiveScan;
@@ -106,16 +104,6 @@ public class MediaRouter {
            }
        };

        final Runnable mScanWifiDisplays = new Runnable() {
            @Override
            public void run() {
                if (mActivelyScanningWifiDisplays) {
                    mDisplayService.scanWifiDisplays();
                    mHandler.postDelayed(this, WIFI_DISPLAY_SCAN_INTERVAL);
                }
            }
        };

        Static(Context appContext) {
            mAppContext = appContext;
            mResources = Resources.getSystem();
@@ -279,15 +267,24 @@ public class MediaRouter {
            }

            // Update wifi display scanning.
            if (activeScanWifiDisplay && mCanConfigureWifiDisplays) {
            // TODO: All of this should be managed by the media router service.
            if (mCanConfigureWifiDisplays) {
                if (mSelectedRoute != null
                        && mSelectedRoute.matchesTypes(ROUTE_TYPE_REMOTE_DISPLAY)) {
                    // Don't scan while already connected to a remote display since
                    // it may interfere with the ongoing transmission.
                    activeScanWifiDisplay = false;
                }
                if (activeScanWifiDisplay) {
                    if (!mActivelyScanningWifiDisplays) {
                        mActivelyScanningWifiDisplays = true;
                    mHandler.post(mScanWifiDisplays);
                        mDisplayService.startWifiDisplayScan();
                    }
                } else {
                    if (mActivelyScanningWifiDisplays) {
                        mActivelyScanningWifiDisplays = false;
                    mHandler.removeCallbacks(mScanWifiDisplays);
                        mDisplayService.stopWifiDisplayScan();
                    }
                }
            }

@@ -945,6 +942,9 @@ public class MediaRouter {
            }
            dispatchRouteSelected(types & route.getSupportedTypes(), route);
        }

        // The behavior of active scans may depend on the currently selected route.
        sStatic.updateDiscoveryRequest();
    }

    static void selectDefaultRouteStatic() {
@@ -1291,10 +1291,8 @@ public class MediaRouter {
    }

    static void updateWifiDisplayStatus(WifiDisplayStatus status) {
        boolean wantScan = false;
        WifiDisplay[] displays;
        WifiDisplay activeDisplay;

        if (status.getFeatureState() == WifiDisplayStatus.FEATURE_STATE_ON) {
            displays = status.getDisplays();
            activeDisplay = status.getActiveDisplay();
@@ -1314,6 +1312,8 @@ public class MediaRouter {
            displays = WifiDisplay.EMPTY_ARRAY;
            activeDisplay = null;
        }
        String activeDisplayAddress = activeDisplay != null ?
                activeDisplay.getDeviceAddress() : null;

        // Add or update routes.
        for (int i = 0; i < displays.length; i++) {
@@ -1323,9 +1323,11 @@ public class MediaRouter {
                if (route == null) {
                    route = makeWifiDisplayRoute(d, status);
                    addRouteStatic(route);
                    wantScan = true;
                } else {
                    updateWifiDisplayRoute(route, d, status);
                    String address = d.getDeviceAddress();
                    boolean disconnected = !address.equals(activeDisplayAddress)
                            && address.equals(sStatic.mPreviousActiveWifiDisplayAddress);
                    updateWifiDisplayRoute(route, d, status, disconnected);
                }
                if (d.equals(activeDisplay)) {
                    selectRouteStatic(route.getSupportedTypes(), route, false);
@@ -1343,6 +1345,10 @@ public class MediaRouter {
                }
            }
        }

        // Remember the current active wifi display address so that we can infer disconnections.
        // TODO: This hack will go away once all of this is moved into the media router service.
        sStatic.mPreviousActiveWifiDisplayAddress = activeDisplayAddress;
    }

    private static boolean shouldShowWifiDisplay(WifiDisplay d, WifiDisplay activeDisplay) {
@@ -1400,7 +1406,8 @@ public class MediaRouter {
    }

    private static void updateWifiDisplayRoute(
            RouteInfo route, WifiDisplay display, WifiDisplayStatus wfdStatus) {
            RouteInfo route, WifiDisplay display, WifiDisplayStatus wfdStatus,
            boolean disconnected) {
        boolean changed = false;
        final String newName = display.getFriendlyDisplayName();
        if (!route.getName().equals(newName)) {
@@ -1418,7 +1425,7 @@ public class MediaRouter {
            dispatchRouteChanged(route);
        }

        if (!enabled && route.isSelected()) {
        if ((!enabled || disconnected) && route.isSelected()) {
            // Oops, no longer available. Reselect the default.
            selectDefaultRouteStatic();
        }
+2 −8
Original line number Diff line number Diff line
@@ -692,14 +692,8 @@ class QuickSettingsModel implements BluetoothStateChangeCallback,
        } else {
            connectedRoute = null;
            connecting = false;
            final int count = mMediaRouter.getRouteCount();
            for (int i = 0; i < count; i++) {
                MediaRouter.RouteInfo route = mMediaRouter.getRouteAt(i);
                if (route.matchesTypes(MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY)) {
                    enabled = true;
                    break;
                }
            }
            enabled = mMediaRouter.isRouteAvailable(MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY,
                    MediaRouter.AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE);
        }

        mRemoteDisplayState.enabled = enabled;
Loading