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

Commit 50acd731 authored by Craig Mautner's avatar Craig Mautner Committed by Android Git Automerger
Browse files

am 67a3fb6f: am c10914ca: Merge "Support Wifi display devices that rename...

am 67a3fb6f: am c10914ca: Merge "Support Wifi display devices that rename themselves." into jb-mr1.1-dev

* commit '67a3fb6f':
  Support Wifi display devices that rename themselves.
parents 8a96ab8f 67a3fb6f
Loading
Loading
Loading
Loading
+9 −0
Original line number Original line Diff line number Diff line
@@ -107,6 +107,15 @@ public final class WifiDisplay implements Parcelable {
                && Objects.equal(mDeviceAlias, other.mDeviceAlias);
                && Objects.equal(mDeviceAlias, other.mDeviceAlias);
    }
    }


    /**
     * Returns true if the other display is not null and has the same address as this one.
     * Can be used to perform identity comparisons on displays ignoring properties
     * that might change during a connection such as the name or alias.
     */
    public boolean hasSameAddress(WifiDisplay other) {
        return other != null && mDeviceAddress.equals(other.mDeviceAddress);
    }

    @Override
    @Override
    public int hashCode() {
    public int hashCode() {
        // The address on its own should be sufficiently unique for hashing purposes.
        // The address on its own should be sufficiently unique for hashing purposes.
+1 −1
Original line number Original line Diff line number Diff line
@@ -862,7 +862,7 @@ public class MediaRouter {
    private static WifiDisplay findMatchingDisplay(WifiDisplay d, WifiDisplay[] displays) {
    private static WifiDisplay findMatchingDisplay(WifiDisplay d, WifiDisplay[] displays) {
        for (int i = 0; i < displays.length; i++) {
        for (int i = 0; i < displays.length; i++) {
            final WifiDisplay other = displays[i];
            final WifiDisplay other = displays[i];
            if (d.getDeviceAddress().equals(other.getDeviceAddress())) {
            if (d.hasSameAddress(other)) {
                return other;
                return other;
            }
            }
        }
        }
+9 −16
Original line number Original line Diff line number Diff line
@@ -81,6 +81,15 @@ final class PersistentDataStore {
        }
        }
    }
    }


    public WifiDisplay getRememberedWifiDisplay(String deviceAddress) {
        loadIfNeeded();
        int index = findRememberedWifiDisplay(deviceAddress);
        if (index >= 0) {
            return mRememberedWifiDisplays.get(index);
        }
        return null;
    }

    public WifiDisplay[] getRememberedWifiDisplays() {
    public WifiDisplay[] getRememberedWifiDisplays() {
        loadIfNeeded();
        loadIfNeeded();
        return mRememberedWifiDisplays.toArray(new WifiDisplay[mRememberedWifiDisplays.size()]);
        return mRememberedWifiDisplays.toArray(new WifiDisplay[mRememberedWifiDisplays.size()]);
@@ -137,22 +146,6 @@ final class PersistentDataStore {
        return true;
        return true;
    }
    }


    public boolean renameWifiDisplay(String deviceAddress, String alias) {
        int index = findRememberedWifiDisplay(deviceAddress);
        if (index >= 0) {
            WifiDisplay display = mRememberedWifiDisplays.get(index);
            if (Objects.equal(display.getDeviceAlias(), alias)) {
                return false; // already has this alias
            }
            WifiDisplay renamedDisplay = new WifiDisplay(deviceAddress,
                    display.getDeviceName(), alias);
            mRememberedWifiDisplays.set(index, renamedDisplay);
            setDirty();
            return true;
        }
        return false;
    }

    public boolean forgetWifiDisplay(String deviceAddress) {
    public boolean forgetWifiDisplay(String deviceAddress) {
        int index = findRememberedWifiDisplay(deviceAddress);
        int index = findRememberedWifiDisplay(deviceAddress);
        if (index >= 0) {
        if (index >= 0) {
+72 −13
Original line number Original line Diff line number Diff line
@@ -45,6 +45,8 @@ import android.view.Surface;
import java.io.PrintWriter;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Arrays;


import libcore.util.Objects;

/**
/**
 * Connects to Wifi displays that implement the Miracast protocol.
 * Connects to Wifi displays that implement the Miracast protocol.
 * <p>
 * <p>
@@ -224,16 +226,18 @@ final class WifiDisplayAdapter extends DisplayAdapter {
            }
            }
        }
        }


        if (mPersistentDataStore.renameWifiDisplay(address, alias)) {
        WifiDisplay display = mPersistentDataStore.getRememberedWifiDisplay(address);
        if (display != null && !Objects.equal(display.getDeviceAlias(), alias)) {
            display = new WifiDisplay(address, display.getDeviceName(), alias);
            if (mPersistentDataStore.rememberWifiDisplay(display)) {
                mPersistentDataStore.saveIfNeeded();
                mPersistentDataStore.saveIfNeeded();
                updateRememberedDisplaysLocked();
                updateRememberedDisplaysLocked();
                scheduleStatusChangedBroadcastLocked();
                scheduleStatusChangedBroadcastLocked();
            }
            }
        }


        if (mActiveDisplay != null && mActiveDisplay.getDeviceAddress().equals(address)
        if (mActiveDisplay != null && mActiveDisplay.getDeviceAddress().equals(address)) {
                && mDisplayDevice != null) {
            renameDisplayDeviceLocked(mActiveDisplay.getFriendlyDisplayName());
            mDisplayDevice.setNameLocked(mActiveDisplay.getFriendlyDisplayName());
            sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_CHANGED);
        }
        }
    }
    }


@@ -272,9 +276,42 @@ final class WifiDisplayAdapter extends DisplayAdapter {
        mAvailableDisplays = mPersistentDataStore.applyWifiDisplayAliases(mAvailableDisplays);
        mAvailableDisplays = mPersistentDataStore.applyWifiDisplayAliases(mAvailableDisplays);
    }
    }


    private void handleConnectLocked(WifiDisplay display,
    private void fixRememberedDisplayNamesFromAvailableDisplaysLocked() {
        // It may happen that a display name has changed since it was remembered.
        // Consult the list of available displays and update the name if needed.
        // We don't do anything special for the active display here.  The display
        // controller will send a separate event when it needs to be updates.
        boolean changed = false;
        for (int i = 0; i < mRememberedDisplays.length; i++) {
            WifiDisplay rememberedDisplay = mRememberedDisplays[i];
            WifiDisplay availableDisplay = findAvailableDisplayLocked(
                    rememberedDisplay.getDeviceAddress());
            if (availableDisplay != null && !rememberedDisplay.equals(availableDisplay)) {
                if (DEBUG) {
                    Slog.d(TAG, "fixRememberedDisplayNamesFromAvailableDisplaysLocked: "
                            + "updating remembered display to " + availableDisplay);
                }
                mRememberedDisplays[i] = availableDisplay;
                changed |= mPersistentDataStore.rememberWifiDisplay(availableDisplay);
            }
        }
        if (changed) {
            mPersistentDataStore.saveIfNeeded();
        }
    }

    private WifiDisplay findAvailableDisplayLocked(String address) {
        for (WifiDisplay display : mAvailableDisplays) {
            if (display.getDeviceAddress().equals(address)) {
                return display;
            }
        }
        return null;
    }

    private void addDisplayDeviceLocked(WifiDisplay display,
            Surface surface, int width, int height, int flags) {
            Surface surface, int width, int height, int flags) {
        handleDisconnectLocked();
        removeDisplayDeviceLocked();


        if (mPersistentDataStore.rememberWifiDisplay(display)) {
        if (mPersistentDataStore.rememberWifiDisplay(display)) {
            mPersistentDataStore.saveIfNeeded();
            mPersistentDataStore.saveIfNeeded();
@@ -303,7 +340,7 @@ final class WifiDisplayAdapter extends DisplayAdapter {
        scheduleUpdateNotificationLocked();
        scheduleUpdateNotificationLocked();
    }
    }


    private void handleDisconnectLocked() {
    private void removeDisplayDeviceLocked() {
        if (mDisplayDevice != null) {
        if (mDisplayDevice != null) {
            mDisplayDevice.clearSurfaceLocked();
            mDisplayDevice.clearSurfaceLocked();
            sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_REMOVED);
            sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_REMOVED);
@@ -313,6 +350,13 @@ final class WifiDisplayAdapter extends DisplayAdapter {
        }
        }
    }
    }


    private void renameDisplayDeviceLocked(String name) {
        if (mDisplayDevice != null && !mDisplayDevice.getNameLocked().equals(name)) {
            mDisplayDevice.setNameLocked(name);
            sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_CHANGED);
        }
    }

    private void scheduleStatusChangedBroadcastLocked() {
    private void scheduleStatusChangedBroadcastLocked() {
        mCurrentStatus = null;
        mCurrentStatus = null;
        if (!mPendingStatusChangeBroadcast) {
        if (!mPendingStatusChangeBroadcast) {
@@ -446,6 +490,7 @@ final class WifiDisplayAdapter extends DisplayAdapter {
                        || !Arrays.equals(mAvailableDisplays, availableDisplays)) {
                        || !Arrays.equals(mAvailableDisplays, availableDisplays)) {
                    mScanState = WifiDisplayStatus.SCAN_STATE_NOT_SCANNING;
                    mScanState = WifiDisplayStatus.SCAN_STATE_NOT_SCANNING;
                    mAvailableDisplays = availableDisplays;
                    mAvailableDisplays = availableDisplays;
                    fixRememberedDisplayNamesFromAvailableDisplaysLocked();
                    scheduleStatusChangedBroadcastLocked();
                    scheduleStatusChangedBroadcastLocked();
                }
                }
            }
            }
@@ -483,7 +528,7 @@ final class WifiDisplayAdapter extends DisplayAdapter {
                int width, int height, int flags) {
                int width, int height, int flags) {
            synchronized (getSyncRoot()) {
            synchronized (getSyncRoot()) {
                display = mPersistentDataStore.applyWifiDisplayAlias(display);
                display = mPersistentDataStore.applyWifiDisplayAlias(display);
                handleConnectLocked(display, surface, width, height, flags);
                addDisplayDeviceLocked(display, surface, width, height, flags);


                if (mActiveDisplayState != WifiDisplayStatus.DISPLAY_STATE_CONNECTED
                if (mActiveDisplayState != WifiDisplayStatus.DISPLAY_STATE_CONNECTED
                        || mActiveDisplay == null
                        || mActiveDisplay == null
@@ -495,11 +540,25 @@ final class WifiDisplayAdapter extends DisplayAdapter {
            }
            }
        }
        }


        @Override
        public void onDisplayChanged(WifiDisplay display) {
            synchronized (getSyncRoot()) {
                display = mPersistentDataStore.applyWifiDisplayAlias(display);
                if (mActiveDisplay != null
                        && mActiveDisplay.hasSameAddress(display)
                        && !mActiveDisplay.equals(display)) {
                    mActiveDisplay = display;
                    renameDisplayDeviceLocked(display.getFriendlyDisplayName());
                    scheduleStatusChangedBroadcastLocked();
                }
            }
        }

        @Override
        @Override
        public void onDisplayDisconnected() {
        public void onDisplayDisconnected() {
            // Stop listening.
            // Stop listening.
            synchronized (getSyncRoot()) {
            synchronized (getSyncRoot()) {
                handleDisconnectLocked();
                removeDisplayDeviceLocked();


                if (mActiveDisplayState != WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED
                if (mActiveDisplayState != WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED
                        || mActiveDisplay != null) {
                        || mActiveDisplay != null) {
+58 −9
Original line number Original line Diff line number Diff line
@@ -120,6 +120,12 @@ final class WifiDisplayController implements DumpUtils.Dump {
    // or are not trying to connect.
    // or are not trying to connect.
    private WifiP2pDevice mConnectingDevice;
    private WifiP2pDevice mConnectingDevice;


    // The device from which we are currently disconnecting.
    private WifiP2pDevice mDisconnectingDevice;

    // The device to which we were previously trying to connect and are now canceling.
    private WifiP2pDevice mCancelingDevice;

    // The device to which we are currently connected, which means we have an active P2P group.
    // The device to which we are currently connected, which means we have an active P2P group.
    private WifiP2pDevice mConnectedDevice;
    private WifiP2pDevice mConnectedDevice;


@@ -186,6 +192,7 @@ final class WifiDisplayController implements DumpUtils.Dump {
        updateWfdEnableState();
        updateWfdEnableState();
    }
    }


    @Override
    public void dump(PrintWriter pw) {
    public void dump(PrintWriter pw) {
        pw.println("mWifiDisplayOnSetting=" + mWifiDisplayOnSetting);
        pw.println("mWifiDisplayOnSetting=" + mWifiDisplayOnSetting);
        pw.println("mWifiP2pEnabled=" + mWifiP2pEnabled);
        pw.println("mWifiP2pEnabled=" + mWifiP2pEnabled);
@@ -196,6 +203,8 @@ final class WifiDisplayController implements DumpUtils.Dump {
        pw.println("mDiscoverPeersRetriesLeft=" + mDiscoverPeersRetriesLeft);
        pw.println("mDiscoverPeersRetriesLeft=" + mDiscoverPeersRetriesLeft);
        pw.println("mDesiredDevice=" + describeWifiP2pDevice(mDesiredDevice));
        pw.println("mDesiredDevice=" + describeWifiP2pDevice(mDesiredDevice));
        pw.println("mConnectingDisplay=" + describeWifiP2pDevice(mConnectingDevice));
        pw.println("mConnectingDisplay=" + describeWifiP2pDevice(mConnectingDevice));
        pw.println("mDisconnectingDisplay=" + describeWifiP2pDevice(mDisconnectingDevice));
        pw.println("mCancelingDisplay=" + describeWifiP2pDevice(mCancelingDevice));
        pw.println("mConnectedDevice=" + describeWifiP2pDevice(mConnectedDevice));
        pw.println("mConnectedDevice=" + describeWifiP2pDevice(mConnectedDevice));
        pw.println("mConnectionRetriesLeft=" + mConnectionRetriesLeft);
        pw.println("mConnectionRetriesLeft=" + mConnectionRetriesLeft);
        pw.println("mRemoteDisplay=" + mRemoteDisplay);
        pw.println("mRemoteDisplay=" + mRemoteDisplay);
@@ -384,7 +393,9 @@ final class WifiDisplayController implements DumpUtils.Dump {
        final int count = mAvailableWifiDisplayPeers.size();
        final int count = mAvailableWifiDisplayPeers.size();
        final WifiDisplay[] displays = WifiDisplay.CREATOR.newArray(count);
        final WifiDisplay[] displays = WifiDisplay.CREATOR.newArray(count);
        for (int i = 0; i < count; i++) {
        for (int i = 0; i < count; i++) {
            displays[i] = createWifiDisplay(mAvailableWifiDisplayPeers.get(i));
            WifiP2pDevice device = mAvailableWifiDisplayPeers.get(i);
            displays[i] = createWifiDisplay(device);
            updateDesiredDevice(device);
        }
        }


        mHandler.post(new Runnable() {
        mHandler.post(new Runnable() {
@@ -395,6 +406,23 @@ final class WifiDisplayController implements DumpUtils.Dump {
        });
        });
    }
    }


    private void updateDesiredDevice(WifiP2pDevice device) {
        // Handle the case where the device to which we are connecting or connected
        // may have been renamed or reported different properties in the latest scan.
        final String address = device.deviceAddress;
        if (mDesiredDevice != null && mDesiredDevice.deviceAddress.equals(address)) {
            if (DEBUG) {
                Slog.d(TAG, "updateDesiredDevice: new information "
                        + describeWifiP2pDevice(device));
            }
            mDesiredDevice.update(device);
            if (mAdvertisedDisplay != null
                    && mAdvertisedDisplay.getDeviceAddress().equals(address)) {
                readvertiseDisplay(createWifiDisplay(mDesiredDevice));
            }
        }
    }

    private void connect(final WifiP2pDevice device) {
    private void connect(final WifiP2pDevice device) {
        if (mDesiredDevice != null
        if (mDesiredDevice != null
                && !mDesiredDevice.deviceAddress.equals(device.deviceAddress)) {
                && !mDesiredDevice.deviceAddress.equals(device.deviceAddress)) {
@@ -459,12 +487,17 @@ final class WifiDisplayController implements DumpUtils.Dump {
        }
        }


        // Step 2. Before we try to connect to a new device, disconnect from the old one.
        // Step 2. Before we try to connect to a new device, disconnect from the old one.
        if (mDisconnectingDevice != null) {
            return; // wait for asynchronous callback
        }
        if (mConnectedDevice != null && mConnectedDevice != mDesiredDevice) {
        if (mConnectedDevice != null && mConnectedDevice != mDesiredDevice) {
            Slog.i(TAG, "Disconnecting from Wifi display: " + mConnectedDevice.deviceName);
            Slog.i(TAG, "Disconnecting from Wifi display: " + mConnectedDevice.deviceName);
            mDisconnectingDevice = mConnectedDevice;
            mConnectedDevice = null;


            unadvertiseDisplay();
            unadvertiseDisplay();


            final WifiP2pDevice oldDevice = mConnectedDevice;
            final WifiP2pDevice oldDevice = mDisconnectingDevice;
            mWifiP2pManager.removeGroup(mWifiP2pChannel, new ActionListener() {
            mWifiP2pManager.removeGroup(mWifiP2pChannel, new ActionListener() {
                @Override
                @Override
                public void onSuccess() {
                public void onSuccess() {
@@ -480,8 +513,8 @@ final class WifiDisplayController implements DumpUtils.Dump {
                }
                }


                private void next() {
                private void next() {
                    if (mConnectedDevice == oldDevice) {
                    if (mDisconnectingDevice == oldDevice) {
                        mConnectedDevice = null;
                        mDisconnectingDevice = null;
                        updateConnection();
                        updateConnection();
                    }
                    }
                }
                }
@@ -491,13 +524,18 @@ final class WifiDisplayController implements DumpUtils.Dump {


        // Step 3. Before we try to connect to a new device, stop trying to connect
        // Step 3. Before we try to connect to a new device, stop trying to connect
        // to the old one.
        // to the old one.
        if (mCancelingDevice != null) {
            return; // wait for asynchronous callback
        }
        if (mConnectingDevice != null && mConnectingDevice != mDesiredDevice) {
        if (mConnectingDevice != null && mConnectingDevice != mDesiredDevice) {
            Slog.i(TAG, "Canceling connection to Wifi display: " + mConnectingDevice.deviceName);
            Slog.i(TAG, "Canceling connection to Wifi display: " + mConnectingDevice.deviceName);
            mCancelingDevice = mConnectingDevice;
            mConnectingDevice = null;


            unadvertiseDisplay();
            unadvertiseDisplay();
            mHandler.removeCallbacks(mConnectionTimeout);
            mHandler.removeCallbacks(mConnectionTimeout);


            final WifiP2pDevice oldDevice = mConnectingDevice;
            final WifiP2pDevice oldDevice = mCancelingDevice;
            mWifiP2pManager.cancelConnect(mWifiP2pChannel, new ActionListener() {
            mWifiP2pManager.cancelConnect(mWifiP2pChannel, new ActionListener() {
                @Override
                @Override
                public void onSuccess() {
                public void onSuccess() {
@@ -513,8 +551,8 @@ final class WifiDisplayController implements DumpUtils.Dump {
                }
                }


                private void next() {
                private void next() {
                    if (mConnectingDevice == oldDevice) {
                    if (mCancelingDevice == oldDevice) {
                        mConnectingDevice = null;
                        mCancelingDevice = null;
                        updateConnection();
                        updateConnection();
                    }
                    }
                }
                }
@@ -763,13 +801,17 @@ final class WifiDisplayController implements DumpUtils.Dump {
                public void run() {
                public void run() {
                    if (oldSurface != null && surface != oldSurface) {
                    if (oldSurface != null && surface != oldSurface) {
                        mListener.onDisplayDisconnected();
                        mListener.onDisplayDisconnected();
                    } else if (oldDisplay != null && !Objects.equal(display, oldDisplay)) {
                    } else if (oldDisplay != null && !oldDisplay.hasSameAddress(display)) {
                        mListener.onDisplayConnectionFailed();
                        mListener.onDisplayConnectionFailed();
                    }
                    }


                    if (display != null) {
                    if (display != null) {
                        if (!Objects.equal(display, oldDisplay)) {
                        if (!display.hasSameAddress(oldDisplay)) {
                            mListener.onDisplayConnecting(display);
                            mListener.onDisplayConnecting(display);
                        } else if (!display.equals(oldDisplay)) {
                            // The address is the same but some other property such as the
                            // name must have changed.
                            mListener.onDisplayChanged(display);
                        }
                        }
                        if (surface != null && surface != oldSurface) {
                        if (surface != null && surface != oldSurface) {
                            mListener.onDisplayConnected(display, surface, width, height, flags);
                            mListener.onDisplayConnected(display, surface, width, height, flags);
@@ -784,6 +826,12 @@ final class WifiDisplayController implements DumpUtils.Dump {
        advertiseDisplay(null, null, 0, 0, 0);
        advertiseDisplay(null, null, 0, 0, 0);
    }
    }


    private void readvertiseDisplay(WifiDisplay display) {
        advertiseDisplay(display, mAdvertisedDisplaySurface,
                mAdvertisedDisplayWidth, mAdvertisedDisplayHeight,
                mAdvertisedDisplayFlags);
    }

    private static Inet4Address getInterfaceAddress(WifiP2pGroup info) {
    private static Inet4Address getInterfaceAddress(WifiP2pGroup info) {
        NetworkInterface iface;
        NetworkInterface iface;
        try {
        try {
@@ -885,6 +933,7 @@ final class WifiDisplayController implements DumpUtils.Dump {


        void onDisplayConnecting(WifiDisplay display);
        void onDisplayConnecting(WifiDisplay display);
        void onDisplayConnectionFailed();
        void onDisplayConnectionFailed();
        void onDisplayChanged(WifiDisplay display);
        void onDisplayConnected(WifiDisplay display,
        void onDisplayConnected(WifiDisplay display,
                Surface surface, int width, int height, int flags);
                Surface surface, int width, int height, int flags);
        void onDisplayDisconnected();
        void onDisplayDisconnected();