diff options
author | Irfan Sheriff <isheriff@google.com> | 2011-09-03 11:03:23 -0700 |
---|---|---|
committer | Irfan Sheriff <isheriff@google.com> | 2011-09-06 11:01:17 -0700 |
commit | 4be4d31f34a0fd0e23de1cbda311c07412f8d0b8 (patch) | |
tree | e7d1041487d52ca8475cd715481b5c2744f8eda3 /wifi/java | |
parent | 9cc2718abc0152d79e3e8bf23be94ddd3cc9db87 (diff) | |
download | frameworks_base-4be4d31f34a0fd0e23de1cbda311c07412f8d0b8.zip frameworks_base-4be4d31f34a0fd0e23de1cbda311c07412f8d0b8.tar.gz frameworks_base-4be4d31f34a0fd0e23de1cbda311c07412f8d0b8.tar.bz2 |
Fix p2p API interface to framework
- Update the WifiP2pGroup class
- Add reason code response for all failures
- Fix display of self in peer list
- Retain p2p group when explicitly created by API and fix join behavior
Bug: 5247957
Change-Id: Ibd9b163887db1c8a9dd8213253fda20c436a49e3
Diffstat (limited to 'wifi/java')
-rw-r--r-- | wifi/java/android/net/wifi/WifiNative.java | 15 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java | 18 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/p2p/WifiP2pGroup.java | 122 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/p2p/WifiP2pManager.java | 40 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/p2p/WifiP2pService.java | 86 |
5 files changed, 196 insertions, 85 deletions
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java index 450f816..cebcc47 100644 --- a/wifi/java/android/net/wifi/WifiNative.java +++ b/wifi/java/android/net/wifi/WifiNative.java @@ -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); } diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java index 50f624a..aa3554c 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java @@ -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; } diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java index 14246b4..e35d360 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java @@ -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; } diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java index 0bdd269..11de9c4 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java @@ -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 diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java index f67680d..333160f 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java @@ -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 |