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

Commit 289c2b25 authored by Irfan Sheriff's avatar Irfan Sheriff Committed by Android (Google) Code Review
Browse files

Merge "Fix p2p API interface to framework"

parents 8160270c 4be4d31f
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -356,6 +356,21 @@ public class WifiNative {
        return null;
    }

    public static String p2pGetDeviceAddress() {
        String status = statusCommand();
        if (status == null) return "";

        String[] tokens = status.split("\n");
        for (String token : tokens) {
            if (token.startsWith("p2p_device_address=")) {
                String[] nameValue = token.split("=");
                if (nameValue.length != 2) break;
                return nameValue[1];
            }
        }
        return "";
    }

    public static String p2pPeer(String deviceAddress) {
        return doStringCommand("P2P_PEER " + deviceAddress);
    }
+15 −3
Original line number Diff line number Diff line
@@ -57,9 +57,21 @@ public class WifiP2pDeviceList implements Parcelable {
        return true;
    }

    public void add(WifiP2pDevice device) {
    public void update(WifiP2pDevice device) {
        if (device == null) return;
        if (mDevices.contains(device)) return;
        for (WifiP2pDevice d : mDevices) {
            //Found, update fields that can change
            if (d.equals(device)) {
                d.deviceName = device.deviceName;
                d.primaryDeviceType = device.primaryDeviceType;
                d.secondaryDeviceType = device.secondaryDeviceType;
                d.wpsConfigMethodsSupported = device.wpsConfigMethodsSupported;
                d.deviceCapability = device.deviceCapability;
                d.groupCapability = device.groupCapability;
                return;
            }
        }
        //Not found, add a new one
        mDevices.add(device);
    }

@@ -101,7 +113,7 @@ public class WifiP2pDeviceList implements Parcelable {

                int deviceCount = in.readInt();
                for (int i = 0; i < deviceCount; i++) {
                    deviceList.add((WifiP2pDevice)in.readParcelable(null));
                    deviceList.update((WifiP2pDevice)in.readParcelable(null));
                }
                return deviceList;
            }
+80 −42
Original line number Diff line number Diff line
@@ -33,9 +33,6 @@ public class WifiP2pGroup implements Parcelable {
    /** The network name */
    private String mNetworkName;

    /** The network bssid */
    private String mNetworkBssid;

    /** Group owner */
    private WifiP2pDevice mOwner;

@@ -45,27 +42,12 @@ public class WifiP2pGroup implements Parcelable {
    /** Group clients */
    private List<WifiP2pDevice> mClients = new ArrayList<WifiP2pDevice>();

    private int mChannel;

    /**
     * The network passphrase
     * <p/>
     * The passphrase used for WPA2-PSK
     */
    /** The passphrase used for WPA2-PSK */
    private String mPassphrase;

    /**
     * TODO: fix
     * Sometimes supplicant sends a psk
     */
    private String mPsk;

    /** Indicates that the group is persistent */
    private boolean mIsPersistent;

    private String mInterface;

    public WifiP2pGroup() {
    WifiP2pGroup() {
    }

    /**
@@ -81,6 +63,7 @@ public class WifiP2pGroup implements Parcelable {
     *  bssid=fa:7b:7a:42:82:13 unknown-network
     *
     *  Note: The events formats can be looked up in the wpa_supplicant code
     *  @hide
     */
    public WifiP2pGroup(String supplicantEvent) throws IllegalArgumentException {

@@ -103,20 +86,6 @@ public class WifiP2pGroup implements Parcelable {
                    continue;
                }

                if (nameValue[0].equals("freq")) {
                    try {
                        mChannel = Integer.parseInt(nameValue[1]);
                    } catch (NumberFormatException e) {
                        mChannel = 0; //invalid
                    }
                    continue;
                }

                if (nameValue[0].equals("psk")) {
                    mPsk = nameValue[1];
                    continue;
                }

                if (nameValue[0].equals("passphrase")) {
                    mPassphrase = nameValue[1];
                    continue;
@@ -135,28 +104,51 @@ public class WifiP2pGroup implements Parcelable {
                    mOwner = new WifiP2pDevice(nameValue[1]);
                    continue;
                }

                if (nameValue[0].equals("bssid")) {
                    mNetworkBssid = nameValue[1];
                }
            }
        } else {
            throw new IllegalArgumentException("Malformed supplicant event");
        }
    }

    /** @hide */
    public void setNetworkName(String networkName) {
        mNetworkName = networkName;
    }

    /**
     * Get the network name (SSID) of the group. Legacy Wi-Fi clients will discover
     * the p2p group using the network name.
     */
    public String getNetworkName() {
        return mNetworkName;
    }

    /** @hide */
    public void setIsGroupOwner(boolean isGo) {
        mIsGroupOwner = isGo;
    }

    /** Check whether this device is the group owner of the created p2p group */
    public boolean isGroupOwner() {
        return mIsGroupOwner;
    }

    /** @hide */
    public void setOwner(WifiP2pDevice device) {
        mOwner = device;
    }

    /** Get the details of the group owner as a {@link WifiP2pDevice} object */
    public WifiP2pDevice getOwner() {
        return mOwner;
    }

    /** @hide */
    public void addClient(String address) {
        addClient(new WifiP2pDevice(address));
    }

    /** @hide */
    public void addClient(WifiP2pDevice device) {
        for (WifiP2pDevice client : mClients) {
            if (client.equals(device)) return;
@@ -164,31 +156,60 @@ public class WifiP2pGroup implements Parcelable {
        mClients.add(device);
    }

    /** @hide */
    public boolean removeClient(String address) {
        return mClients.remove(new WifiP2pDevice(address));
    }

    /** @hide */
    public boolean removeClient(WifiP2pDevice device) {
        return mClients.remove(device);
    }

    /** @hide */
    public boolean isClientListEmpty() {
        return mClients.size() == 0;
    }

    /** Get the list of clients currently part of the p2p group */
    public Collection<WifiP2pDevice> getClientList() {
        return Collections.unmodifiableCollection(mClients);
    }

    /** @hide */
    public void setPassphrase(String passphrase) {
        mPassphrase = passphrase;
    }

    /**
     * Get the passphrase of the group. This function will return a valid passphrase only
     * at the group owner. Legacy Wi-Fi clients will need this passphrase alongside
     * network name obtained from {@link #getNetworkName()} to join the group
     */
    public String getPassphrase() {
        return mPassphrase;
    }

    /** @hide */
    public void setInterface(String intf) {
        mInterface = intf;
    }

    /** Get the interface name on which the group is created */
    public String getInterface() {
        return mInterface;
    }

    // TODO: implement
    /** @hide */
    public String toString() {
        StringBuffer sbuf = new StringBuffer();
        //sbuf.append("SSID: ").append(SSID);
        //sbuf.append("\n passphrase: ").append(passphrase);
        sbuf.append("network: ").append(mNetworkName);
        sbuf.append("\n isGO: ").append(mIsGroupOwner);
        sbuf.append("\n GO: ").append(mOwner);
        for (WifiP2pDevice client : mClients) {
            sbuf.append("\n Client: ").append(client);
        }
        sbuf.append("\n interface: ").append(mInterface);
        return sbuf.toString();
    }

@@ -205,8 +226,16 @@ public class WifiP2pGroup implements Parcelable {
    }

    /** Implement the Parcelable interface {@hide} */
    // STOPSHIP: implement
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(mNetworkName);
        dest.writeParcelable(mOwner, flags);
        dest.writeByte(mIsGroupOwner ? (byte) 1: (byte) 0);
        dest.writeInt(mClients.size());
        for (WifiP2pDevice client : mClients) {
            dest.writeParcelable(client, flags);
        }
        dest.writeString(mPassphrase);
        dest.writeString(mInterface);
    }

    /** Implement the Parcelable interface {@hide} */
@@ -214,6 +243,15 @@ public class WifiP2pGroup implements Parcelable {
        new Creator<WifiP2pGroup>() {
            public WifiP2pGroup createFromParcel(Parcel in) {
                WifiP2pGroup group = new WifiP2pGroup();
                group.setNetworkName(in.readString());
                group.setOwner((WifiP2pDevice)in.readParcelable(null));
                group.setIsGroupOwner(in.readByte() == (byte)1);
                int clientCount = in.readInt();
                for (int i=0; i<clientCount; i++) {
                    group.addClient((WifiP2pDevice) in.readParcelable(null));
                }
                group.setPassphrase(in.readString());
                group.setInterface(in.readString());
                return group;
            }

+19 −21
Original line number Diff line number Diff line
@@ -212,8 +212,8 @@ public class WifiP2pManager {
    /**
     * Message {@link android.os.Message#what} value indicating that the {@link #discoverPeers}
     * operation failed.
     * <p> The reason for failure could be one of {@link #P2P_UNSUPPORTED}, {@link #P2P_DISABLED}
     * or {@link #ALREADY_IN_EFFECT}
     * <p> The reason for failure could be one of {@link #P2P_UNSUPPORTED}, {@link #ERROR}
     * or {@link #BUSY}
     */
    public static final int DISCOVER_PEERS_FAILED                   = BASE + 8;
    /**
@@ -230,8 +230,8 @@ public class WifiP2pManager {
    /**
     * Message {@link android.os.Message#what} value indicating that the {@link #connect}
     * operation failed.
     * <p> The reason for failure could be one of {@link #P2P_UNSUPPORTED}, {@link #P2P_DISABLED}
     * or {@link #ALREADY_IN_EFFECT}
     * <p> The reason for failure could be one of {@link #P2P_UNSUPPORTED}, {@link #ERROR}
     * or {@link #BUSY}
     */
    public static final int CONNECT_FAILED                          = BASE + 11;
    /**
@@ -248,8 +248,8 @@ public class WifiP2pManager {
    /**
     * Message {@link android.os.Message#what} value indicating that the {@link #createGroup}
     * operation failed.
     * <p> The reason for failure could be one of {@link #P2P_UNSUPPORTED}, {@link #P2P_DISABLED}
     * or {@link #ALREADY_IN_EFFECT}
     * <p> The reason for failure could be one of {@link #P2P_UNSUPPORTED}, {@link #ERROR}
     * or {@link #BUSY}
     */
    public static final int CREATE_GROUP_FAILED                     = BASE + 14;
    /**
@@ -264,8 +264,8 @@ public class WifiP2pManager {
    /**
     * Message {@link android.os.Message#what} value indicating that the {@link #removeGroup}
     * operation failed.
     * <p> The reason for failure could be one of {@link #P2P_UNSUPPORTED}, {@link #P2P_DISABLED}
     * or {@link #ALREADY_IN_EFFECT}
     * <p> The reason for failure could be one of {@link #P2P_UNSUPPORTED}, {@link #ERROR}
     * or {@link #BUSY}
     */
    public static final int REMOVE_GROUP_FAILED                     = BASE + 17;
    /**
@@ -279,31 +279,29 @@ public class WifiP2pManager {
     * {@link #DISCOVER_PEERS_FAILED}, {@link #CONNECT_FAILED}, {@link #CREATE_GROUP_FAILED}
     * and {@link #REMOVE_GROUP_FAILED}
     *
     * <p> This indicates that the reason for failure is because p2p is unsupported on the
     * device
     * <p> This indicates that the operation failed due to an internal error
     */
    public static final int P2P_UNSUPPORTED     = 1;
    public static final int ERROR               = 0;

    /**
     * Supported {@link android.os.Message#arg1} value on the following response messages:
     * {@link #DISCOVER_PEERS_FAILED}, {@link #CONNECT_FAILED}, {@link #CREATE_GROUP_FAILED}
     * and {@link #REMOVE_GROUP_FAILED}
     *
     * <p> This indicates that the reason for failure is because p2p is currently disabled
     * by the user
     * <p> This indicates that the operation failed because p2p is unsupported on the
     * device
     */
    public static final int P2P_DISABLED        = 2;
    public static final int P2P_UNSUPPORTED     = 1;

    /**
     * Supported {@link android.os.Message#arg1} value on the following response messages:
     * {@link #DISCOVER_PEERS_FAILED}, {@link #CONNECT_FAILED}, {@link #CREATE_GROUP_FAILED}
     * and {@link #REMOVE_GROUP_FAILED}
     *
     * <p> This indicates that the reason for failure is because the operation is already in
     * effect
     * <p> This indicates that the operation failed because the framework is busy and
     * unable to service the request
     */
    public static final int ALREADY_IN_EFFECT   = 3;

    public static final int BUSY                = 2;

    /** @hide */
    public static final int REQUEST_PEERS                           = BASE + 19;
@@ -342,11 +340,11 @@ public class WifiP2pManager {
    public static final int RESPONSE_GROUP_INFO                     = BASE + 24;

    /** @hide */
    public static final int WPS_PBC                                 = BASE + 23;
    public static final int WPS_PBC                                 = BASE + 25;
    /** @hide */
    public static final int WPS_PIN                                 = BASE + 24;
    public static final int WPS_PIN                                 = BASE + 26;
    /** @hide */
    public static final int WPS_PIN_AVAILABLE                       = BASE + 25;
    public static final int WPS_PIN_AVAILABLE                       = BASE + 27;

    /**
     * Create a new WifiP2pManager instance. Applications use
+67 −19
Original line number Diff line number Diff line
@@ -129,6 +129,12 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
    private final boolean mP2pSupported;
    private final String mDeviceType;
    private String mDeviceName;
    private String mDeviceAddress;

    /* When a group has been explicitly created by an app, we persist the group
     * even after all clients have been disconnected until an explicit remove
     * is invoked */
    private boolean mPersistGroup;

    private NetworkInfo mNetworkInfo;

@@ -315,22 +321,28 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
                    deferMessage(message);
                    break;
                case WifiP2pManager.ENABLE_P2P:
                    replyToMessage(message, WifiP2pManager.ENABLE_P2P_FAILED);
                    replyToMessage(message, WifiP2pManager.ENABLE_P2P_FAILED,
                            WifiP2pManager.BUSY);
                    break;
                case WifiP2pManager.DISABLE_P2P:
                    replyToMessage(message, WifiP2pManager.DISABLE_P2P_FAILED);
                    replyToMessage(message, WifiP2pManager.DISABLE_P2P_FAILED,
                            WifiP2pManager.BUSY);
                    break;
                case WifiP2pManager.DISCOVER_PEERS:
                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED);
                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
                            WifiP2pManager.BUSY);
                    break;
                case WifiP2pManager.CONNECT:
                    replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
                    replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
                            WifiP2pManager.BUSY);
                    break;
                case WifiP2pManager.CREATE_GROUP:
                    replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED);
                    replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
                            WifiP2pManager.BUSY);
                    break;
                case WifiP2pManager.REMOVE_GROUP:
                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED);
                    replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
                            WifiP2pManager.BUSY);
                    break;
                case WifiP2pManager.REQUEST_PEERS:
                    replyToMessage(message, WifiP2pManager.RESPONSE_PEERS, mPeers);
@@ -338,6 +350,9 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
                case WifiP2pManager.REQUEST_CONNECTION_INFO:
                    replyToMessage(message, WifiP2pManager.RESPONSE_CONNECTION_INFO, mWifiP2pInfo);
                    break;
                case WifiP2pManager.REQUEST_GROUP_INFO:
                    replyToMessage(message, WifiP2pManager.RESPONSE_GROUP_INFO, mGroup);
                    break;
                // Ignore
                case WIFI_DISABLE_USER_ACCEPT:
                case GROUP_NEGOTIATION_TIMED_OUT:
@@ -589,8 +604,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
            if (DBG) logd(getName());
            sendP2pStateChangedBroadcast(true);
            mNetworkInfo.setIsAvailable(true);
            //Start listening for new connections
            WifiNative.p2pListen();
            initializeP2pSettings();
        }

@@ -611,12 +624,14 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
                    if (WifiNative.p2pFind(timeout)) {
                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_SUCCEEDED);
                    } else {
                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED);
                        replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
                                WifiP2pManager.ERROR);
                    }
                    break;
                case WifiMonitor.P2P_DEVICE_FOUND_EVENT:
                    WifiP2pDevice device = (WifiP2pDevice) message.obj;
                    mPeers.add(device);
                    if (mDeviceAddress.equals(device.deviceAddress)) break;
                    mPeers.update(device);
                    sendP2pPeersChangedBroadcast();
                    break;
                case WifiMonitor.P2P_DEVICE_LOST_EVENT:
@@ -626,13 +641,15 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
                case WifiP2pManager.CONNECT:
                    if (DBG) logd(getName() + " sending connect");
                    mSavedConnectConfig = (WifiP2pConfig) message.obj;
                    mPersistGroup = false;
                    int netId = configuredNetworkId(mSavedConnectConfig.deviceAddress);
                    if (netId >= 0) {
                        //TODO: if failure, remove config and do a regular p2pConnect()
                        WifiNative.p2pReinvoke(netId, mSavedConnectConfig.deviceAddress);
                    } else {
                        //TODO: Check if device is a GO and "join"
                        String pin = WifiNative.p2pConnect(mSavedConnectConfig, false);
                        boolean join = false;
                        if (isGroupOwner(mSavedConnectConfig.deviceAddress)) join = true;
                        String pin = WifiNative.p2pConnect(mSavedConnectConfig, join);
                        try {
                            Integer.parseInt(pin);
                            notifyWpsPin(pin, mSavedConnectConfig.deviceAddress);
@@ -682,8 +699,11 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
    }

    class InactiveState extends State {
        @Override public void enter() {
        @Override
        public void enter() {
            if (DBG) logd(getName());
            //Start listening every time we get inactive
            WifiNative.p2pListen();
        }

        @Override
@@ -695,10 +715,12 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
                    notifyP2pGoNegotationRequest(mSavedGoNegotiationConfig);
                    break;
                case WifiP2pManager.CREATE_GROUP:
                    mPersistGroup = true;
                    if (WifiNative.p2pGroupAdd()) {
                        replyToMessage(message, WifiP2pManager.CREATE_GROUP_SUCCEEDED);
                    } else {
                        replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED);
                        replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED,
                                WifiP2pManager.ERROR);
                    }
                    transitionTo(mGroupNegotiationState);
                    break;
@@ -748,6 +770,11 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
                        transitionTo(mInactiveState);
                    }
                    break;
                case WifiP2pManager.DISCOVER_PEERS:
                    /* Discovery will break negotiation */
                    replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED,
                            WifiP2pManager.BUSY);
                    break;
                default:
                    return NOT_HANDLED;
            }
@@ -792,13 +819,17 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
                        updateDeviceStatus(deviceAddress, Status.AVAILABLE);
                        if (mGroup.removeClient(deviceAddress)) {
                            if (DBG) logd("Removed client " + deviceAddress);
                            sendP2pPeersChangedBroadcast();
                            if (!mPersistGroup && mGroup.isClientListEmpty()) {
                                Slog.d(TAG, "Client list empty, remove non-persistent p2p group");
                                WifiNative.p2pGroupRemove(mGroup.getInterface());
                            }
                        } else {
                            if (DBG) logd("Failed to remove client " + deviceAddress);
                            for (WifiP2pDevice c : mGroup.getClientList()) {
                                if (DBG) logd("client " + c.deviceAddress);
                            }
                        }
                        sendP2pPeersChangedBroadcast();
                        if (DBG) loge(getName() + " ap sta disconnected");
                    } else {
                        loge("Disconnect on unknown device address : " + interfaceAddress);
@@ -820,7 +851,8 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
                    if (WifiNative.p2pGroupRemove(mGroup.getInterface())) {
                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_SUCCEEDED);
                    } else {
                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED);
                        replyToMessage(message, WifiP2pManager.REMOVE_GROUP_FAILED,
                                WifiP2pManager.ERROR);
                    }
                    break;
                case WifiMonitor.P2P_GROUP_REMOVED_EVENT:
@@ -852,8 +884,11 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
                    if (device.equals(mGroup.getOwner())) {
                        logd("Lost the group owner, killing p2p connection");
                        WifiNative.p2pGroupRemove(mGroup.getInterface());
                    } else {
                        mGroup.removeClient(device);
                    } else if (mGroup.removeClient(device)) {
                        if (!mPersistGroup && mGroup.isClientListEmpty()) {
                            Slog.d(TAG, "Client list empty, removing a non-persistent p2p group");
                            WifiNative.p2pGroupRemove(mGroup.getInterface());
                        }
                    }
                    return NOT_HANDLED; // Do the regular device lost handling
                case WifiP2pManager.DISABLE_P2P:
@@ -868,7 +903,8 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
                        sendP2pPeersChangedBroadcast();
                        replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED);
                    } else {
                        replyToMessage(message, WifiP2pManager.CONNECT_FAILED);
                        replyToMessage(message, WifiP2pManager.CONNECT_FAILED,
                                WifiP2pManager.ERROR);
                    }
                    // TODO: figure out updating the status to declined when invitation is rejected
                    break;
@@ -1118,6 +1154,15 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
        }
    }

    private boolean isGroupOwner(String deviceAddress) {
        for (WifiP2pDevice d : mPeers.getDeviceList()) {
            if (d.deviceAddress.equals(deviceAddress)) {
                return d.isGroupOwner();
            }
        }
        return false;
    }

    //TODO: implement when wpa_supplicant is fixed
    private int configuredNetworkId(String deviceAddress) {
        return -1;
@@ -1148,6 +1193,9 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
        WifiNative.setPersistentReconnect(true);
        WifiNative.setDeviceName(mDeviceName);
        WifiNative.setDeviceType(mDeviceType);

        mDeviceAddress = WifiNative.p2pGetDeviceAddress();
        if (DBG) Slog.d(TAG, "DeviceAddress: " + mDeviceAddress);
    }

    //State machine initiated requests can have replyTo set to null indicating