diff options
author | Irfan Sheriff <isheriff@google.com> | 2011-09-07 00:31:20 -0700 |
---|---|---|
committer | Irfan Sheriff <isheriff@google.com> | 2011-09-13 16:04:00 -0700 |
commit | 651cdfcbac6245f570475991588ddc2d30265e8d (patch) | |
tree | 0d7292e4a1a9a8bd12d964054200ccdac5622277 /wifi/java/android/net | |
parent | e0946eb270e669ac470467dbda033a443ee5d1cc (diff) | |
download | frameworks_base-651cdfcbac6245f570475991588ddc2d30265e8d.zip frameworks_base-651cdfcbac6245f570475991588ddc2d30265e8d.tar.gz frameworks_base-651cdfcbac6245f570475991588ddc2d30265e8d.tar.bz2 |
Unhide wifi p2p API
Bug: 5247957
Change-Id: Id93e30c0cb60f361ba13a840de8f843415777336
Diffstat (limited to 'wifi/java/android/net')
-rw-r--r-- | wifi/java/android/net/wifi/IWifiManager.aidl | 2 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiConfigStore.java | 8 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiManager.java | 4 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiNative.java | 14 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiStateMachine.java | 2 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WpsInfo.aidl (renamed from wifi/java/android/net/wifi/Wps.aidl) | 4 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WpsInfo.java (renamed from wifi/java/android/net/wifi/Wps.java) | 64 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WpsStateMachine.java | 24 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/p2p/WifiP2pConfig.java | 40 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/p2p/WifiP2pDevice.java | 35 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java | 12 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/p2p/WifiP2pGroup.java | 21 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/p2p/WifiP2pInfo.java | 13 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/p2p/WifiP2pManager.java | 562 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/p2p/WifiP2pService.java | 113 |
15 files changed, 493 insertions, 425 deletions
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 27a60cd..61dfebf 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -18,8 +18,6 @@ package android.net.wifi; import android.net.wifi.WifiInfo; import android.net.wifi.WifiConfiguration; -import android.net.wifi.Wps; -import android.net.wifi.WpsResult; import android.net.wifi.ScanResult; import android.net.DhcpInfo; diff --git a/wifi/java/android/net/wifi/WifiConfigStore.java b/wifi/java/android/net/wifi/WifiConfigStore.java index c75dec7..18d6eaa 100644 --- a/wifi/java/android/net/wifi/WifiConfigStore.java +++ b/wifi/java/android/net/wifi/WifiConfigStore.java @@ -397,7 +397,7 @@ class WifiConfigStore { * Start WPS pin method configuration with pin obtained * from the access point */ - static WpsResult startWpsWithPinFromAccessPoint(Wps config) { + static WpsResult startWpsWithPinFromAccessPoint(WpsInfo config) { WpsResult result = new WpsResult(); if (WifiNative.startWpsWithPinFromAccessPointCommand(config.BSSID, config.pin)) { /* WPS leaves all networks disabled */ @@ -415,7 +415,7 @@ class WifiConfigStore { * from the device * @return WpsResult indicating status and pin */ - static WpsResult startWpsWithPinFromDevice(Wps config) { + static WpsResult startWpsWithPinFromDevice(WpsInfo config) { WpsResult result = new WpsResult(); result.pin = WifiNative.startWpsWithPinFromDeviceCommand(config.BSSID); /* WPS leaves all networks disabled */ @@ -432,7 +432,7 @@ class WifiConfigStore { /** * Start WPS push button configuration */ - static WpsResult startWpsPbc(Wps config) { + static WpsResult startWpsPbc(WpsInfo config) { WpsResult result = new WpsResult(); if (WifiNative.startWpsPbcCommand(config.BSSID)) { /* WPS leaves all networks disabled */ @@ -594,7 +594,7 @@ class WifiConfigStore { sendConfiguredNetworksChangedBroadcast(); } - static void updateIpAndProxyFromWpsConfig(int netId, Wps wpsConfig) { + static void updateIpAndProxyFromWpsConfig(int netId, WpsInfo wpsConfig) { synchronized (sConfiguredNetworks) { WifiConfiguration config = sConfiguredNetworks.get(netId); if (config != null) { diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 0fce8e8..40ac2a0 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -1175,7 +1175,7 @@ public class WifiManager { * @param config WPS configuration * @hide */ - public void startWps(Wps config) { + public void startWps(WpsInfo config) { if (config == null) { return; } @@ -1630,4 +1630,4 @@ public class WifiManager { return false; } } -}
\ No newline at end of file +} diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java index 6cc09e9..a6ea6d4 100644 --- a/wifi/java/android/net/wifi/WifiNative.java +++ b/wifi/java/android/net/wifi/WifiNative.java @@ -261,23 +261,23 @@ public class WifiNative { public static String p2pConnect(WifiP2pConfig config, boolean joinExistingGroup) { if (config == null) return null; List<String> args = new ArrayList<String>(); - Wps wps = config.wps; + WpsInfo wps = config.wps; args.add(config.deviceAddress); switch (wps.setup) { - case PBC: + case WpsInfo.PBC: args.add("pbc"); break; - case DISPLAY: + case WpsInfo.DISPLAY: //TODO: pass the pin back for display args.add("pin"); args.add("display"); break; - case KEYPAD: + case WpsInfo.KEYPAD: args.add(wps.pin); args.add("keypad"); break; - case LABEL: + case WpsInfo.LABEL: args.add(wps.pin); args.add("label"); default: @@ -303,6 +303,10 @@ public class WifiNative { return doStringCommand(command); } + public static boolean p2pCancelConnect() { + return doBooleanCommand("P2P_CANCEL"); + } + public static boolean p2pGroupAdd() { return doBooleanCommand("P2P_GROUP_ADD"); } diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index 175a9ce..3b29d40 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -880,7 +880,7 @@ public class WifiStateMachine extends StateMachine { sendMessage(message); } - public void startWps(Messenger replyTo, Wps config) { + public void startWps(Messenger replyTo, WpsInfo config) { Message msg = obtainMessage(CMD_START_WPS, config); msg.replyTo = replyTo; sendMessage(msg); diff --git a/wifi/java/android/net/wifi/Wps.aidl b/wifi/java/android/net/wifi/WpsInfo.aidl index ba82a9a..f5e4ebe 100644 --- a/wifi/java/android/net/wifi/Wps.aidl +++ b/wifi/java/android/net/wifi/WpsInfo.aidl @@ -1,5 +1,5 @@ /** - * Copyright (c) 2010, The Android Open Source Project + * Copyright (c) 2011, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,4 +16,4 @@ package android.net.wifi; -parcelable Wps; +parcelable WpsInfo; diff --git a/wifi/java/android/net/wifi/Wps.java b/wifi/java/android/net/wifi/WpsInfo.java index 6d00696..f70e5af 100644 --- a/wifi/java/android/net/wifi/Wps.java +++ b/wifi/java/android/net/wifi/WpsInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 The Android Open Source Project + * Copyright (C) 2011 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,27 +26,24 @@ import java.util.BitSet; /** * A class representing Wi-Fi Protected Setup - * @hide * * {@see WifiP2pConfig} */ -public class Wps implements Parcelable { +public class WpsInfo implements Parcelable { + + /** Push button configuration */ + public static final int PBC = 0; + /** Display pin method configuration - pin is generated and displayed on device */ + public static final int DISPLAY = 1; + /** Keypad pin method configuration - pin is entered on device */ + public static final int KEYPAD = 2; + /** Label pin method configuration - pin is labelled on device */ + public static final int LABEL = 3; + /** Invalid configuration */ + public static final int INVALID = 4; /** Wi-Fi Protected Setup. www.wi-fi.org/wifi-protected-setup has details */ - public enum Setup { - /* Push button configuration */ - PBC, - /* Display pin method configuration - pin is generated and displayed on device */ - DISPLAY, - /* Keypad pin method configuration - pin is entered on device */ - KEYPAD, - /* Label pin method configuration - pin is obtained from a printed label */ - LABEL, - /* Invalid config */ - INVALID - } - - public Setup setup; + public int setup; /** @hide */ public String BSSID; @@ -63,8 +60,8 @@ public class Wps implements Parcelable { /** @hide */ public LinkProperties linkProperties; - public Wps() { - setup = Setup.INVALID; + public WpsInfo() { + setup = INVALID; BSSID = null; pin = null; ipAssignment = IpAssignment.UNASSIGNED; @@ -72,10 +69,9 @@ public class Wps implements Parcelable { linkProperties = new LinkProperties(); } - /** @hide */ public String toString() { StringBuffer sbuf = new StringBuffer(); - sbuf.append(" setup: ").append(setup.toString()); + sbuf.append(" setup: ").append(setup); sbuf.append('\n'); sbuf.append(" BSSID: ").append(BSSID); sbuf.append('\n'); @@ -90,13 +86,13 @@ public class Wps implements Parcelable { return sbuf.toString(); } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public int describeContents() { return 0; } - /** copy constructor {@hide} */ - public Wps(Wps source) { + /* Copy constructor */ + public WpsInfo(WpsInfo source) { if (source != null) { setup = source.setup; BSSID = source.BSSID; @@ -107,9 +103,9 @@ public class Wps implements Parcelable { } } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public void writeToParcel(Parcel dest, int flags) { - dest.writeString(setup.name()); + dest.writeInt(setup); dest.writeString(BSSID); dest.writeString(pin); dest.writeString(ipAssignment.name()); @@ -117,12 +113,12 @@ public class Wps implements Parcelable { dest.writeParcelable(linkProperties, flags); } - /** Implement the Parcelable interface {@hide} */ - public static final Creator<Wps> CREATOR = - new Creator<Wps>() { - public Wps createFromParcel(Parcel in) { - Wps config = new Wps(); - config.setup = Setup.valueOf(in.readString()); + /** Implement the Parcelable interface */ + public static final Creator<WpsInfo> CREATOR = + new Creator<WpsInfo>() { + public WpsInfo createFromParcel(Parcel in) { + WpsInfo config = new WpsInfo(); + config.setup = in.readInt(); config.BSSID = in.readString(); config.pin = in.readString(); config.ipAssignment = IpAssignment.valueOf(in.readString()); @@ -131,8 +127,8 @@ public class Wps implements Parcelable { return config; } - public Wps[] newArray(int size) { - return new Wps[size]; + public WpsInfo[] newArray(int size) { + return new WpsInfo[size]; } }; } diff --git a/wifi/java/android/net/wifi/WpsStateMachine.java b/wifi/java/android/net/wifi/WpsStateMachine.java index f9e903a..c14a8db 100644 --- a/wifi/java/android/net/wifi/WpsStateMachine.java +++ b/wifi/java/android/net/wifi/WpsStateMachine.java @@ -53,7 +53,7 @@ class WpsStateMachine extends StateMachine { private WifiStateMachine mWifiStateMachine; - private Wps mWpsConfig; + private WpsInfo mWpsInfo; private Context mContext; AsyncChannel mReplyChannel = new AsyncChannel(); @@ -90,20 +90,20 @@ class WpsStateMachine extends StateMachine { @Override public boolean processMessage(Message message) { if (DBG) Log.d(TAG, getName() + message.toString() + "\n"); - Wps wpsConfig; + WpsInfo wpsConfig; switch (message.what) { case WifiStateMachine.CMD_START_WPS: - mWpsConfig = (Wps) message.obj; + mWpsInfo = (WpsInfo) message.obj; WpsResult result; - switch (mWpsConfig.setup) { - case PBC: - result = WifiConfigStore.startWpsPbc(mWpsConfig); + switch (mWpsInfo.setup) { + case WpsInfo.PBC: + result = WifiConfigStore.startWpsPbc(mWpsInfo); break; - case KEYPAD: - result = WifiConfigStore.startWpsWithPinFromAccessPoint(mWpsConfig); + case WpsInfo.KEYPAD: + result = WifiConfigStore.startWpsWithPinFromAccessPoint(mWpsInfo); break; - case DISPLAY: - result = WifiConfigStore.startWpsWithPinFromDevice(mWpsConfig); + case WpsInfo.DISPLAY: + result = WifiConfigStore.startWpsWithPinFromDevice(mWpsInfo); break; default: result = new WpsResult(Status.FAILURE); @@ -114,7 +114,7 @@ class WpsStateMachine extends StateMachine { if (result.status == Status.SUCCESS) { transitionTo(mActiveState); } else { - Log.e(TAG, "Failed to start WPS with config " + mWpsConfig.toString()); + Log.e(TAG, "Failed to start WPS with config " + mWpsInfo.toString()); } break; case WifiStateMachine.CMD_RESET_WPS_STATE: @@ -154,7 +154,7 @@ class WpsStateMachine extends StateMachine { WifiConfigStore.enableAllNetworks(); WifiConfigStore.loadConfiguredNetworks(); WifiConfigStore.updateIpAndProxyFromWpsConfig( - stateChangeResult.networkId, mWpsConfig); + stateChangeResult.networkId, mWpsInfo); mWifiStateMachine.sendMessage(WifiStateMachine.WPS_COMPLETED_EVENT); transitionTo(mInactiveState); break; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java index e359ce5..e0c1b13 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java @@ -16,14 +16,12 @@ package android.net.wifi.p2p; -import android.net.wifi.Wps; -import android.net.wifi.Wps.Setup; +import android.net.wifi.WpsInfo; import android.os.Parcelable; import android.os.Parcel; /** * A class representing a Wi-Fi P2p configuration for setting up a connection - * @hide * * {@see WifiP2pManager} */ @@ -37,7 +35,7 @@ public class WifiP2pConfig implements Parcelable { /** * Wi-Fi Protected Setup information */ - public Wps wps; + public WpsInfo wps; /** * This is an integer value between 0 and 15 where 0 indicates the least @@ -63,8 +61,8 @@ public class WifiP2pConfig implements Parcelable { public WifiP2pConfig() { //set defaults - wps = new Wps(); - wps.setup = Setup.PBC; + wps = new WpsInfo(); + wps.setup = WpsInfo.PBC; } /** P2P-GO-NEG-REQUEST 42:fc:89:a8:96:09 dev_passwd_id=4 {@hide}*/ @@ -76,7 +74,7 @@ public class WifiP2pConfig implements Parcelable { } deviceAddress = tokens[1]; - wps = new Wps(); + wps = new WpsInfo(); if (tokens.length > 2) { String[] nameVal = tokens[2].split("="); @@ -89,25 +87,24 @@ public class WifiP2pConfig implements Parcelable { //As defined in wps/wps_defs.h switch (devPasswdId) { case 0x00: - wps.setup = Setup.LABEL; + wps.setup = WpsInfo.LABEL; break; case 0x01: - wps.setup = Setup.KEYPAD; + wps.setup = WpsInfo.KEYPAD; break; case 0x04: - wps.setup = Setup.PBC; + wps.setup = WpsInfo.PBC; break; case 0x05: - wps.setup = Setup.DISPLAY; + wps.setup = WpsInfo.DISPLAY; break; default: - wps.setup = Setup.PBC; + wps.setup = WpsInfo.PBC; break; } } } - /** @hide */ public String toString() { StringBuffer sbuf = new StringBuffer(); sbuf.append("\n address: ").append(deviceAddress); @@ -117,19 +114,22 @@ public class WifiP2pConfig implements Parcelable { return sbuf.toString(); } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public int describeContents() { return 0; } - /** copy constructor {@hide} */ + /** copy constructor */ public WifiP2pConfig(WifiP2pConfig source) { if (source != null) { - //TODO: implement - } + deviceAddress = source.deviceAddress; + wps = new WpsInfo(source.wps); + groupOwnerIntent = source.groupOwnerIntent; + persist = source.persist; + } } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public void writeToParcel(Parcel dest, int flags) { dest.writeString(deviceAddress); dest.writeParcelable(wps, flags); @@ -137,13 +137,13 @@ public class WifiP2pConfig implements Parcelable { dest.writeString(persist.name()); } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public static final Creator<WifiP2pConfig> CREATOR = new Creator<WifiP2pConfig>() { public WifiP2pConfig createFromParcel(Parcel in) { WifiP2pConfig config = new WifiP2pConfig(); config.deviceAddress = in.readString(); - config.wps = (Wps) in.readParcelable(null); + config.wps = (WpsInfo) in.readParcelable(null); config.groupOwnerIntent = in.readInt(); config.persist = Persist.valueOf(in.readString()); return config; diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java index 99c585f..1b0c301 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java @@ -24,7 +24,6 @@ import java.util.regex.Pattern; /** * A class representing a Wi-Fi p2p device - * @hide * * {@see WifiP2pManager} */ @@ -109,18 +108,16 @@ public class WifiP2pDevice implements Parcelable { */ public int groupCapability; - /** Device connection status */ - public enum Status { - CONNECTED, - INVITED, - FAILED, - AVAILABLE, - UNAVAILABLE, - } + public static final int CONNECTED = 0; + public static final int INVITED = 1; + public static final int FAILED = 2; + public static final int AVAILABLE = 3; + public static final int UNAVAILABLE = 4; - public Status status = Status.UNAVAILABLE; + /** Device connection status */ + public int status = UNAVAILABLE; - WifiP2pDevice() { + public WifiP2pDevice() { } /** @@ -197,7 +194,7 @@ public class WifiP2pDevice implements Parcelable { } if (tokens[0].startsWith("P2P-DEVICE-FOUND")) { - status = Status.AVAILABLE; + status = AVAILABLE; } } @@ -227,7 +224,6 @@ public class WifiP2pDevice implements Parcelable { } @Override - /** @hide */ public boolean equals(Object obj) { if (this == obj) return true; if (!(obj instanceof WifiP2pDevice)) return false; @@ -239,7 +235,6 @@ public class WifiP2pDevice implements Parcelable { return other.deviceAddress.equals(deviceAddress); } - /** @hide */ public String toString() { StringBuffer sbuf = new StringBuffer(); sbuf.append("Device: ").append(deviceName); @@ -254,12 +249,12 @@ public class WifiP2pDevice implements Parcelable { return sbuf.toString(); } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public int describeContents() { return 0; } - /** copy constructor {@hide} */ + /** copy constructor */ public WifiP2pDevice(WifiP2pDevice source) { if (source != null) { deviceName = source.deviceName; @@ -274,7 +269,7 @@ public class WifiP2pDevice implements Parcelable { } } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public void writeToParcel(Parcel dest, int flags) { dest.writeString(deviceName); dest.writeString(deviceAddress); @@ -284,10 +279,10 @@ public class WifiP2pDevice implements Parcelable { dest.writeInt(wpsConfigMethodsSupported); dest.writeInt(deviceCapability); dest.writeInt(groupCapability); - dest.writeString(status.name()); + dest.writeInt(status); } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public static final Creator<WifiP2pDevice> CREATOR = new Creator<WifiP2pDevice>() { public WifiP2pDevice createFromParcel(Parcel in) { @@ -300,7 +295,7 @@ public class WifiP2pDevice implements Parcelable { device.wpsConfigMethodsSupported = in.readInt(); device.deviceCapability = in.readInt(); device.groupCapability = in.readInt(); - device.status = Status.valueOf(in.readString()); + device.status = in.readInt(); return device; } diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java index 242bce0..9ce2545 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pDeviceList.java @@ -27,7 +27,6 @@ import java.util.Collections; /** * A class representing a Wi-Fi P2p device list - * @hide * * {@see WifiP2pManager} */ @@ -35,11 +34,11 @@ public class WifiP2pDeviceList implements Parcelable { private Collection<WifiP2pDevice> mDevices; - WifiP2pDeviceList() { + public WifiP2pDeviceList() { mDevices = new ArrayList<WifiP2pDevice>(); } - /** copy constructor {@hide} */ + /** copy constructor */ public WifiP2pDeviceList(WifiP2pDeviceList source) { if (source != null) { mDevices = source.getDeviceList(); @@ -91,7 +90,6 @@ public class WifiP2pDeviceList implements Parcelable { return Collections.unmodifiableCollection(mDevices); } - /** @hide */ public String toString() { StringBuffer sbuf = new StringBuffer(); for (WifiP2pDevice device : mDevices) { @@ -100,12 +98,12 @@ public class WifiP2pDeviceList implements Parcelable { return sbuf.toString(); } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public int describeContents() { return 0; } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public void writeToParcel(Parcel dest, int flags) { dest.writeInt(mDevices.size()); for(WifiP2pDevice device : mDevices) { @@ -113,7 +111,7 @@ public class WifiP2pDeviceList implements Parcelable { } } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public static final Creator<WifiP2pDeviceList> CREATOR = new Creator<WifiP2pDeviceList>() { public WifiP2pDeviceList createFromParcel(Parcel in) { diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java index 48f210b..9473993 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pGroup.java @@ -26,7 +26,6 @@ import java.util.Collections; /** * A class representing a Wi-Fi P2p group - * @hide * * {@see WifiP2pManager} */ @@ -49,7 +48,7 @@ public class WifiP2pGroup implements Parcelable { private String mInterface; - WifiP2pGroup() { + public WifiP2pGroup() { } /** @@ -202,7 +201,6 @@ public class WifiP2pGroup implements Parcelable { return mInterface; } - /** @hide */ public String toString() { StringBuffer sbuf = new StringBuffer(); sbuf.append("network: ").append(mNetworkName); @@ -215,19 +213,24 @@ public class WifiP2pGroup implements Parcelable { return sbuf.toString(); } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public int describeContents() { return 0; } - /** copy constructor {@hide} */ - // TODO: implement + /** copy constructor */ public WifiP2pGroup(WifiP2pGroup source) { if (source != null) { - } + mNetworkName = source.getNetworkName(); + mOwner = new WifiP2pDevice(source.getOwner()); + mIsGroupOwner = source.mIsGroupOwner; + for (WifiP2pDevice d : source.getClientList()) mClients.add(d); + mPassphrase = source.getPassphrase(); + mInterface = source.getInterface(); + } } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public void writeToParcel(Parcel dest, int flags) { dest.writeString(mNetworkName); dest.writeParcelable(mOwner, flags); @@ -240,7 +243,7 @@ public class WifiP2pGroup implements Parcelable { dest.writeString(mInterface); } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public static final Creator<WifiP2pGroup> CREATOR = new Creator<WifiP2pGroup>() { public WifiP2pGroup createFromParcel(Parcel in) { diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java b/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java index 81b7708..dce315a 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pInfo.java @@ -24,7 +24,6 @@ import java.net.UnknownHostException; /** * A class representing connection information about a Wi-Fi p2p group - * @hide * * {@see WifiP2pManager} */ @@ -39,11 +38,9 @@ public class WifiP2pInfo implements Parcelable { /** Group owner address */ public InetAddress groupOwnerAddress; - /** @hide */ - WifiP2pInfo() { + public WifiP2pInfo() { } - /** @hide */ public String toString() { StringBuffer sbuf = new StringBuffer(); sbuf.append("groupFormed: ").append(groupFormed) @@ -52,12 +49,12 @@ public class WifiP2pInfo implements Parcelable { return sbuf.toString(); } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public int describeContents() { return 0; } - /** copy constructor {@hide} */ + /** copy constructor */ public WifiP2pInfo(WifiP2pInfo source) { if (source != null) { groupFormed = source.groupFormed; @@ -66,7 +63,7 @@ public class WifiP2pInfo implements Parcelable { } } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public void writeToParcel(Parcel dest, int flags) { dest.writeByte(groupFormed ? (byte)1 : (byte)0); dest.writeByte(isGroupOwner ? (byte)1 : (byte)0); @@ -79,7 +76,7 @@ public class WifiP2pInfo implements Parcelable { } } - /** Implement the Parcelable interface {@hide} */ + /** Implement the Parcelable interface */ public static final Creator<WifiP2pInfo> CREATOR = new Creator<WifiP2pInfo>() { public WifiP2pInfo createFromParcel(Parcel in) { diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java index 5715186..9205300 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java @@ -24,6 +24,7 @@ import android.net.IConnectivityManager; import android.os.Binder; import android.os.IBinder; import android.os.Handler; +import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.ServiceManager; @@ -34,36 +35,44 @@ import android.util.Log; import com.android.internal.util.AsyncChannel; import com.android.internal.util.Protocol; +import java.util.HashMap; + /** * This class provides the API for managing Wi-Fi peer-to-peer connectivity. This lets an * application discover available peers, setup connection to peers and query for the list of peers. * When a p2p connection is formed over wifi, the device continues to maintain the uplink * connection over mobile or any other available network for internet connectivity on the device. * - * <p> The API is asynchronous and response to a request from an application is sent in the form - * of a {@link android.os.Message} on a {@link android.os.Handler} that needs to be initialized - * by the application right at the beginning before any p2p operations are performed via - * {@link #initialize}. + * <p> The API is asynchronous and responses to requests from an application are on listener + * callbacks provided by the application. The application needs to do an initialization with + * {@link #initialize} before doing any p2p operation. + * + * <p> Application actions {@link #discoverPeers}, {@link #connect}, {@link #cancelConnect}, + * {@link #createGroup} and {@link #removeGroup} need a {@link ActionListener} instance for + * receiving callbacks {@link ActionListener#onSuccess} or {@link ActionListener#onFailure}. + * Action callbacks indicate whether the initiation of the action was a success or a failure. + * Upon failure, the reason of failure can be one of {@link #ERROR}, {@link #P2P_UNSUPPORTED} + * or {@link #BUSY}. * - * <p> An application can request for the current list of peers using {@link #requestPeers}. The - * {@link #RESPONSE_PEERS} message on the handler indicates that the peer list is available. - * Use {@link #peersInResponse} to extract the peer device list upon the receiving the - * {@link #RESPONSE_PEERS} message. + * <p> An application can initiate discovery of peers with {@link #discoverPeers}. An initiated + * discovery request from an application stays active until the device starts connecting to a peer + * or forms a p2p group. The {@link ActionListener} callbacks provide feedback on whether the + * discovery initiation was successful or failure. Additionally, applications can listen + * to {@link #WIFI_P2P_PEERS_CHANGED_ACTION} intent action to know when the peer list changes. * - * <p> If an application needs to initiate a discovery, use {@link #discoverPeers} and listen - * to {@link #WIFI_P2P_PEERS_CHANGED_ACTION} intent action to initiate a request to fetch - * list of peers with {@link #requestPeers}. An initiated discovery request from an application - * stays active until the device starts connecting to a peer or forms a p2p group. + * <p> When the peer list change intent {@link #WIFI_P2P_PEERS_CHANGED_ACTION} is received + * or when an application needs to fetch the current list of peers, it can request the list + * of peers with {@link #requestPeers}. When the peer list is available + * {@link PeerListListener#onPeersAvailable} is called with the device list. * * <p> An application can initiate a connection request to a peer through {@link #connect}. See * {@link WifiP2pConfig} for details on setting up the configuration. For communication with legacy * Wi-Fi devices that do not support p2p, an app can create a group using {@link #createGroup} * which creates an access point whose details can be fetched with {@link #requestGroupInfo}. - * +* * <p> After a successful group formation through {@link #createGroup} or through {@link #connect}, - * use {@link #requestConnectionInfo} to fetch the connection details. Connection information - * can be obtained with {@link #connectionInfoInResponse} on a {@link #RESPONSE_CONNECTION_INFO} - * message. The connection info {@link WifiP2pInfo} contains the address of the group owner + * use {@link #requestConnectionInfo} to fetch the connection details. The connection info + * {@link WifiP2pInfo} contains the address of the group owner * {@link WifiP2pInfo#groupOwnerAddress} and a flag {@link WifiP2pInfo#isGroupOwner} to indicate * if the current device is a p2p group owner. A p2p client can thus communicate with * the p2p group owner through a socket connection. @@ -85,10 +94,10 @@ import com.android.internal.util.Protocol; * {@see WifiP2pGroup} * {@see WifiP2pDevice} * {@see WifiP2pDeviceList} - * {@see android.net.wifi.Wps} - * @hide + * {@see android.net.wifi.WpsInfo} */ public class WifiP2pManager { + private static final String TAG = "WifiP2pManager"; /** * Broadcast intent action to indicate whether Wi-Fi p2p is enabled or disabled. An * extra {@link #EXTRA_WIFI_STATE} provides the state information as int. @@ -97,7 +106,7 @@ public class WifiP2pManager { */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String WIFI_P2P_STATE_CHANGED_ACTION = - "android.net.wifi.P2P_STATE_CHANGED"; + "android.net.wifi.p2p.STATE_CHANGED"; /** * The lookup key for an int that indicates whether Wi-Fi p2p is enabled or disabled. @@ -133,7 +142,7 @@ public class WifiP2pManager { */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String WIFI_P2P_CONNECTION_CHANGED_ACTION = - "android.net.wifi.CONNECTION_STATE_CHANGE"; + "android.net.wifi.p2p.CONNECTION_STATE_CHANGE"; /** * The lookup key for a {@link android.net.wifi.p2p.WifiP2pInfo} object @@ -170,26 +179,22 @@ public class WifiP2pManager { */ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) public static final String WIFI_P2P_PEERS_CHANGED_ACTION = - "android.net.wifi.PEERS_CHANGED"; + "android.net.wifi.p2p.PEERS_CHANGED"; /** - * Activity Action: Pick a Wi-Fi p2p network to connect to. - * <p>Input: Nothing. - * <p>Output: Nothing. - * @hide + * Broadcast intent action indicating that this device details have changed. */ - @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) - public static final String ACTION_PICK_WIFI_P2P_NETWORK = - "android.net.wifi.PICK_WIFI_P2P_NETWORK"; - - IWifiP2pManager mService; + @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) + public static final String WIFI_P2P_THIS_DEVICE_CHANGED_ACTION = + "android.net.wifi.p2p.THIS_DEVICE_CHANGED"; /** - * Message {@link android.os.Message#what} sent on the application handler specified - * at {@link #initialize} indicating the asynchronous channel has disconnected. An - * application could choose to reconnect with {@link #initialize} + * The lookup key for a {@link android.net.wifi.p2p.WifiP2pDevice} object + * Retrieve with {@link android.content.Intent#getParcelableExtra(String)}. */ - public static final int HANDLER_DISCONNECTION = AsyncChannel.CMD_CHANNEL_DISCONNECTED; + public static final String EXTRA_WIFI_P2P_DEVICE = "wifiP2pDevice"; + + IWifiP2pManager mService; private static final int BASE = Protocol.BASE_WIFI_P2P_MANAGER; @@ -209,190 +214,243 @@ public class WifiP2pManager { /** @hide */ public static final int DISCOVER_PEERS = BASE + 7; - - /** - * 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 #ERROR} - * or {@link #BUSY} - */ + /** @hide */ public static final int DISCOVER_PEERS_FAILED = BASE + 8; - /** - * Message {@link android.os.Message#what} value indicating that the {@link #discoverPeers} - * operation succeeded. - * <p> The application can register for {@link #WIFI_P2P_PEERS_CHANGED_ACTION} intent - * to listen for changes in the peer list as a result of the discovery process. - */ + /** @hide */ public static final int DISCOVER_PEERS_SUCCEEDED = BASE + 9; /** @hide */ public static final int CONNECT = BASE + 10; - - /** - * 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 #ERROR} - * or {@link #BUSY} - */ + /** @hide */ public static final int CONNECT_FAILED = BASE + 11; - /** - * Message {@link android.os.Message#what} value indicating that the {@link #connect} - * operation succeeded. - * <p> The application can register for {@link #WIFI_P2P_CONNECTION_CHANGED_ACTION} intent - * to listen for connectivity change as a result of the connect operation - */ + /** @hide */ public static final int CONNECT_SUCCEEDED = BASE + 12; /** @hide */ - public static final int CREATE_GROUP = BASE + 13; + public static final int CANCEL_CONNECT = BASE + 13; + /** @hide */ + public static final int CANCEL_CONNECT_FAILED = BASE + 14; + /** @hide */ + public static final int CANCEL_CONNECT_SUCCEEDED = BASE + 15; - /** - * 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 #ERROR} - * or {@link #BUSY} - */ - public static final int CREATE_GROUP_FAILED = BASE + 14; - /** - * Message {@link android.os.Message#what} value indicating that the {@link #createGroup} - * operation succeeded. - * <p> The application can request the group details with {@link #requestGroupInfo} - */ - public static final int CREATE_GROUP_SUCCEEDED = BASE + 15; + /** @hide */ + public static final int CREATE_GROUP = BASE + 16; + /** @hide */ + public static final int CREATE_GROUP_FAILED = BASE + 17; + /** @hide */ + public static final int CREATE_GROUP_SUCCEEDED = BASE + 18; /** @hide */ - public static final int REMOVE_GROUP = BASE + 16; - /** - * 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 #ERROR} - * or {@link #BUSY} - */ - public static final int REMOVE_GROUP_FAILED = BASE + 17; + public static final int REMOVE_GROUP = BASE + 19; + /** @hide */ + public static final int REMOVE_GROUP_FAILED = BASE + 20; + /** @hide */ + public static final int REMOVE_GROUP_SUCCEEDED = BASE + 21; + + /** @hide */ + public static final int REQUEST_PEERS = BASE + 22; + /** @hide */ + public static final int RESPONSE_PEERS = BASE + 23; + + /** @hide */ + public static final int REQUEST_CONNECTION_INFO = BASE + 24; + /** @hide */ + public static final int RESPONSE_CONNECTION_INFO = BASE + 25; + + /** @hide */ + public static final int REQUEST_GROUP_INFO = BASE + 26; + /** @hide */ + public static final int RESPONSE_GROUP_INFO = BASE + 27; + /** - * Message {@link android.os.Message#what} value indicating that the {@link #removeGroup} - * operation succeeded. + * Create a new WifiP2pManager instance. Applications use + * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve + * the standard {@link android.content.Context#WIFI_P2P_SERVICE Context.WIFI_P2P_SERVICE}. + * @param service the Binder interface + * @hide - hide this because it takes in a parameter of type IWifiP2pManager, which + * is a system private class. */ - public static final int REMOVE_GROUP_SUCCEEDED = BASE + 18; + public WifiP2pManager(IWifiP2pManager service) { + mService = service; + } /** - * 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 operation failed due to an internal error + * Passed with {@link ActionListener#onFailure}. + * Indicates that the operation failed due to an internal error. */ 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 operation failed because p2p is unsupported on the - * device + * Passed with {@link ActionListener#onFailure}. + * Indicates that the operation failed because p2p is unsupported on the device. */ 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 operation failed because the framework is busy and + * Passed with {@link ActionListener#onFailure}. + * Indicates that the operation failed because the framework is busy and * unable to service the request */ public static final int BUSY = 2; - /** @hide */ - public static final int REQUEST_PEERS = BASE + 19; - /** - * Message {@link android.os.Message#what} delivered on the application hander - * in response to a {@link #requestPeers} call from the application. - * - * <p> Extract a {@link WifiP2pDeviceList} object by calling {@link #peersInResponse} - * on the message object - */ - public static final int RESPONSE_PEERS = BASE + 20; - - /** @hide */ - public static final int REQUEST_CONNECTION_INFO = BASE + 21; - - /** - * Message {@link android.os.Message#what} delivered on the application hander - * in response to a {@link #requestConnectionInfo} call from the application. - * - * <p> Extract a {@link WifiP2pInfo} object by calling {@link #connectionInfoInResponse} - * on the message object - */ - public static final int RESPONSE_CONNECTION_INFO = BASE + 22; - - /** @hide */ - public static final int REQUEST_GROUP_INFO = BASE + 23; + /** Interface for callback invocation when framework channel is lost */ + public interface ChannelListener { + /** + * The channel to the framework has been disconnected. + * Application could try re-initializing using {@link #initialize} + */ + public void onChannelDisconnected(); + } - /** - * Message {@link android.os.Message#what} delivered on the application hander - * in response to a {@link #requestGroupInfo} call from the application. - * - * <p> Extract a {@link WifiP2pGroup} object by calling {@link #groupInfoInResponse} - * on the message object - */ + /** Interface for callback invocation on an application action */ + public interface ActionListener { + /** The operation succeeded */ + public void onSuccess(); + /** + * The operation failed + * @param reason The reason for failure could be one of {@link #P2P_UNSUPPORTED}, + * {@link #ERROR} or {@link #BUSY} + */ + public void onFailure(int reason); + } - public static final int RESPONSE_GROUP_INFO = BASE + 24; + /** Interface for callback invocation when peer list is available */ + public interface PeerListListener { + /** + * The requested peer list is available + * @param peers List of available peers + */ + public void onPeersAvailable(WifiP2pDeviceList peers); + } - /** @hide */ - public static final int WPS_PBC = BASE + 25; - /** @hide */ - public static final int WPS_PIN = BASE + 26; - /** @hide */ - public static final int WPS_PIN_AVAILABLE = BASE + 27; + /** Interface for callback invocation when connection info is available */ + public interface ConnectionInfoListener { + /** + * The requested connection info is available + * @param info Wi-Fi p2p connection info + */ + public void onConnectionInfoAvailable(WifiP2pInfo info); + } - /** - * Create a new WifiP2pManager instance. Applications use - * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve - * the standard {@link android.content.Context#WIFI_P2P_SERVICE Context.WIFI_P2P_SERVICE}. - * @param service the Binder interface - * @param handler target for messages - * @hide - hide this because it takes in a parameter of type IWifiP2pManager, which - * is a system private class. - */ - public WifiP2pManager(IWifiP2pManager service) { - mService = service; + /** Interface for callback invocation when group info is available */ + public interface GroupInfoListener { + /** + * The requested p2p group info is available + * @param group Wi-Fi p2p group info + */ + public void onGroupInfoAvailable(WifiP2pGroup group); } /** - * A channel that connects the application handler to the Wifi framework. + * A channel that connects the application to the Wifi p2p framework. * Most p2p operations require a Channel as an argument. An instance of Channel is obtained * by doing a call on {@link #initialize} */ - public class Channel { - Channel(AsyncChannel c) { - mAsyncChannel = c; + public static class Channel { + Channel(Looper looper, ChannelListener l) { + mAsyncChannel = new AsyncChannel(); + mHandler = new P2pHandler(looper); + mChannelListener = l; } + private ChannelListener mChannelListener; + private HashMap<Integer, Object> mListenerMap = new HashMap<Integer, Object>(); + private Object mListenerMapLock = new Object(); + private int mListenerKey = 0; + AsyncChannel mAsyncChannel; + P2pHandler mHandler; + class P2pHandler extends Handler { + P2pHandler(Looper looper) { + super(looper); + } + + @Override + public void handleMessage(Message message) { + Object listener = getListener(message.arg2); + switch (message.what) { + case AsyncChannel.CMD_CHANNEL_DISCONNECTED: + if (mChannelListener != null) { + mChannelListener.onChannelDisconnected(); + mChannelListener = null; + } + break; + /* ActionListeners grouped together */ + case WifiP2pManager.DISCOVER_PEERS_FAILED: + case WifiP2pManager.CONNECT_FAILED: + case WifiP2pManager.CANCEL_CONNECT_FAILED: + case WifiP2pManager.CREATE_GROUP_FAILED: + case WifiP2pManager.REMOVE_GROUP_FAILED: + if (listener != null) { + ((ActionListener) listener).onFailure(message.arg1); + } + break; + /* ActionListeners grouped together */ + case WifiP2pManager.DISCOVER_PEERS_SUCCEEDED: + case WifiP2pManager.CONNECT_SUCCEEDED: + case WifiP2pManager.CANCEL_CONNECT_SUCCEEDED: + case WifiP2pManager.CREATE_GROUP_SUCCEEDED: + case WifiP2pManager.REMOVE_GROUP_SUCCEEDED: + if (listener != null) { + ((ActionListener) listener).onSuccess(); + } + break; + case WifiP2pManager.RESPONSE_PEERS: + WifiP2pDeviceList peers = (WifiP2pDeviceList) message.obj; + if (listener != null) { + ((PeerListListener) listener).onPeersAvailable(peers); + } + break; + case WifiP2pManager.RESPONSE_CONNECTION_INFO: + WifiP2pInfo wifiP2pInfo = (WifiP2pInfo) message.obj; + if (listener != null) { + ((ConnectionInfoListener) listener).onConnectionInfoAvailable(wifiP2pInfo); + } + break; + case WifiP2pManager.RESPONSE_GROUP_INFO: + WifiP2pGroup group = (WifiP2pGroup) message.obj; + if (listener != null) { + ((GroupInfoListener) listener).onGroupInfoAvailable(group); + } + break; + default: + Log.d(TAG, "Ignored " + message); + break; + } + } + } + + int putListener(Object listener) { + if (listener == null) return 0; + int key; + synchronized (mListenerMapLock) { + key = mListenerKey++; + mListenerMap.put(key, listener); + } + return key; + } + + Object getListener(int key) { + synchronized (mListenerMapLock) { + return mListenerMap.remove(key); + } + } } /** - * Registers the application handler with the Wi-Fi framework. This function + * Registers the application with the Wi-Fi framework. This function * must be the first to be called before any p2p operations are performed. * - * <p class="note"><strong>Note:</strong> - * The handler registered with the framework should only handle messages - * with {@link android.os.Message#what} values defined in this file. Adding application - * specific private {@link android.os.Message#what} types should be done on a seperate handler - * * @param srcContext is the context of the source - * @param srcHandler is the handler on which the source will receive message responses - * asynchronously + * @param srcLooper is the Looper on which the callbacks are receivied + * @param listener for callback at loss of framework communication. Can be null. * @return Channel instance that is necessary for performing any further p2p operations */ - public Channel initialize(Context srcContext, Handler srcHandler) { + public Channel initialize(Context srcContext, Looper srcLooper, ChannelListener listener) { Messenger messenger = getMessenger(); if (messenger == null) return null; - AsyncChannel asyncChannel = new AsyncChannel(); - Channel c = new Channel(asyncChannel); - if (asyncChannel.connectSync(srcContext, srcHandler, messenger) + Channel c = new Channel(srcLooper, listener); + if (c.mAsyncChannel.connectSync(srcContext, c.mHandler, messenger) == AsyncChannel.STATUS_SUCCESSFUL) { return c; } else { @@ -425,30 +483,32 @@ public class WifiP2pManager { * for the purpose of establishing a connection. * * <p> The function call immediately returns after sending a discovery request - * to the framework. The application handler is notified of a success or failure to initiate - * discovery with {@link #DISCOVER_PEERS_SUCCEEDED} or {@link #DISCOVER_PEERS_FAILED}. + * to the framework. The application is notified of a success or failure to initiate + * discovery through listener callbacks {@link ActionListener#onSuccess} or + * {@link ActionListener#onFailure}. * * <p> The discovery remains active until a connection is initiated or * a p2p group is formed. Register for {@link #WIFI_P2P_PEERS_CHANGED_ACTION} intent to * determine when the framework notifies of a change as peers are discovered. * * <p> Upon receiving a {@link #WIFI_P2P_PEERS_CHANGED_ACTION} intent, an application - * can request for the list of peers using {@link #requestPeers} which will deliver a - * {@link #RESPONSE_PEERS} message on the application handler. The application can then - * extract a {@link WifiP2pDeviceList} object by calling {@link #peersInResponse} - * on the message. + * can request for the list of peers using {@link #requestPeers}. + * + * @param c is the channel created at {@link #initialize} + * @param listener for callbacks on success or failure. Can be null. */ - public void discoverPeers(Channel c) { + public void discoverPeers(Channel c, ActionListener listener) { if (c == null) return; - c.mAsyncChannel.sendMessage(DISCOVER_PEERS); + c.mAsyncChannel.sendMessage(DISCOVER_PEERS, 0, c.putListener(listener)); } /** * Start a p2p connection to a device with the specified configuration. * * <p> The function call immediately returns after sending a connection request - * to the framework. The application handler is notified of a success or failure to initiate - * connectivity with {@link #CONNECT_SUCCEEDED} or {@link #CONNECT_FAILED}. + * to the framework. The application is notified of a success or failure to initiate + * connect through listener callbacks {@link ActionListener#onSuccess} or + * {@link ActionListener#onFailure}. * * <p> Register for {@link #WIFI_P2P_CONNECTION_CHANGED_ACTION} intent to * determine when the framework notifies of a change in connectivity. @@ -460,100 +520,102 @@ public class WifiP2pManager { * a p2p group with {@link #createGroup}, an invitation to join the group is sent to * the peer device. * - * @param config options as described in {@link WifiP2pConfig} class. + * @param c is the channel created at {@link #initialize} + * @param config options as described in {@link WifiP2pConfig} class + * @param listener for callbacks on success or failure. Can be null. */ - public void connect(Channel c, WifiP2pConfig config) { + public void connect(Channel c, WifiP2pConfig config, ActionListener listener) { if (c == null) return; - c.mAsyncChannel.sendMessage(CONNECT, config); + c.mAsyncChannel.sendMessage(CONNECT, 0, c.putListener(listener), config); + } + + /** + * Cancel any ongoing p2p group negotiation + * + * <p> The function call immediately returns after sending a connection cancellation request + * to the framework. The application is notified of a success or failure to initiate + * cancellation through listener callbacks {@link ActionListener#onSuccess} or + * {@link ActionListener#onFailure}. + * + * @param c is the channel created at {@link #initialize} + * @param listener for callbacks on success or failure. Can be null. + */ + public void cancelConnect(Channel c, ActionListener listener) { + if (c == null) return; + c.mAsyncChannel.sendMessage(CANCEL_CONNECT, 0, c.putListener(listener)); } /** * Create a p2p group with the current device as the group owner. This essentially creates * an access point that can accept connections from legacy clients as well as other p2p * devices. - * <p> For p2p operation, this would normally not be used unless the current device needs + * + * <p class="note"><strong>Note:</strong> + * This function would normally not be used unless the current device needs * to form a p2p connection with a legacy client * * <p> The function call immediately returns after sending a group creation request - * to the framework. The application handler is notified of a success or failure to create - * group with {@link #CREATE_GROUP_SUCCEEDED} or {@link #CREATE_GROUP_FAILED}. + * to the framework. The application is notified of a success or failure to initiate + * group creation through listener callbacks {@link ActionListener#onSuccess} or + * {@link ActionListener#onFailure}. + * + * <p> Application can request for the group details with {@link #requestGroupInfo}. * - * <p> Application can request for the group details with {@link #requestGroupInfo} which will - * deliver a {@link #RESPONSE_GROUP_INFO} message on the application handler. The application - * can then extract a {@link WifiP2pGroup} object by calling {@link #groupInfoInResponse} - * on the message. + * @param c is the channel created at {@link #initialize} + * @param listener for callbacks on success or failure. Can be null. */ - public void createGroup(Channel c) { + public void createGroup(Channel c, ActionListener listener) { if (c == null) return; - c.mAsyncChannel.sendMessage(CREATE_GROUP); + c.mAsyncChannel.sendMessage(CREATE_GROUP, 0, c.putListener(listener)); } /** * Remove the current p2p group. * * <p> The function call immediately returns after sending a group removal request - * to the framework. The application handler is notified of a success or failure to remove - * a group with {@link #REMOVE_GROUP_SUCCEEDED} or {@link #REMOVE_GROUP_FAILED}. + * to the framework. The application is notified of a success or failure to initiate + * group removal through listener callbacks {@link ActionListener#onSuccess} or + * {@link ActionListener#onFailure}. + * + * @param c is the channel created at {@link #initialize} + * @param listener for callbacks on success or failure. Can be null. */ - public void removeGroup(Channel c) { + public void removeGroup(Channel c, ActionListener listener) { if (c == null) return; - c.mAsyncChannel.sendMessage(REMOVE_GROUP); + c.mAsyncChannel.sendMessage(REMOVE_GROUP, 0, c.putListener(listener)); } /** - * Request the current list of peers. This returns a {@link #RESPONSE_PEERS} on the application - * handler. The {@link #RESPONSE_PEERS} message on the handler indicates that the peer list is - * available. Use {@link #peersInResponse} to extract {@link WifiP2pDeviceList} from the message + * Request the current list of peers. + * + * @param c is the channel created at {@link #initialize} + * @param listener for callback when peer list is available. Can be null. */ - public void requestPeers(Channel c) { + public void requestPeers(Channel c, PeerListListener listener) { if (c == null) return; - c.mAsyncChannel.sendMessage(REQUEST_PEERS); + c.mAsyncChannel.sendMessage(REQUEST_PEERS, 0, c.putListener(listener)); } /** - * Upon receiving a {@link #RESPONSE_PEERS} on the application handler, an application - * can extract the peer device list using this function. - */ - public WifiP2pDeviceList peersInResponse(Message msg) { - return (WifiP2pDeviceList) msg.obj; - } - - /** - * Request device connection info. This returns a {@link #RESPONSE_CONNECTION_INFO} on - * the application handler. The {@link #RESPONSE_CONNECTION_INFO} message on the handler - * indicates that connection info is available. Use {@link #connectionInfoInResponse} to - * extract {@link WifiP2pInfo} from the message. + * Request device connection info. + * + * @param c is the channel created at {@link #initialize} + * @param listener for callback when connection info is available. Can be null. */ - public void requestConnectionInfo(Channel c) { + public void requestConnectionInfo(Channel c, ConnectionInfoListener listener) { if (c == null) return; - c.mAsyncChannel.sendMessage(REQUEST_CONNECTION_INFO); + c.mAsyncChannel.sendMessage(REQUEST_CONNECTION_INFO, 0, c.putListener(listener)); } /** - * Upon receiving a {@link #RESPONSE_CONNECTION_INFO} on the application handler, an application - * can extract the connection info using this function. - */ - public WifiP2pInfo connectionInfoInResponse(Message msg) { - return (WifiP2pInfo) msg.obj; - } - - /** - * Request p2p group info. This returns a {@link #RESPONSE_GROUP_INFO} on - * the application handler. The {@link #RESPONSE_GROUP_INFO} message on the handler - * indicates that group info is available. Use {@link #groupInfoInResponse} to - * extract {@link WifiP2pGroup} from the message. + * Request p2p group info. + * + * @param c is the channel created at {@link #initialize} + * @param listener for callback when group info is available. Can be null. */ - public void requestGroupInfo(Channel c) { + public void requestGroupInfo(Channel c, GroupInfoListener listener) { if (c == null) return; - c.mAsyncChannel.sendMessage(REQUEST_GROUP_INFO); - } - - /** - * Upon receiving a {@link #RESPONSE_GROUP_INFO} on the application handler, an application - * can extract the group info using this function. - */ - public WifiP2pGroup groupInfoInResponse(Message msg) { - return (WifiP2pGroup) msg.obj; + c.mAsyncChannel.sendMessage(REQUEST_GROUP_INFO, 0, c.putListener(listener)); } /** @@ -571,36 +633,4 @@ public class WifiP2pManager { } } - /** - * Setup DNS connectivity on the current process to the connected Wi-Fi p2p peers - * - * @return -1 on failure - * @hide - */ - public int startPeerCommunication() { - IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); - IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b); - try { - return cm.startUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, "p2p", new Binder()); - } catch (RemoteException e) { - return -1; - } - } - - /** - * Tear down connectivity to the connected Wi-Fi p2p peers - * - * @return -1 on failure - * @hide - */ - public int stopPeerCommunication() { - IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE); - IConnectivityManager cm = IConnectivityManager.Stub.asInterface(b); - try { - return cm.stopUsingNetworkFeature(ConnectivityManager.TYPE_WIFI, "p2p"); - } catch (RemoteException e) { - return -1; - } - } - } diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java index fb2c134..1b02774 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java @@ -41,9 +41,7 @@ import android.net.wifi.WifiManager; import android.net.wifi.WifiMonitor; import android.net.wifi.WifiNative; import android.net.wifi.WifiStateMachine; -import android.net.wifi.Wps; -import android.net.wifi.Wps.Setup; -import android.net.wifi.p2p.WifiP2pDevice.Status; +import android.net.wifi.WpsInfo; import android.os.Binder; import android.os.IBinder; import android.os.INetworkManagementService; @@ -137,11 +135,12 @@ public class WifiP2pService extends IWifiP2pManager.Stub { private static final int AIRPLANE_MODE_CHANGED = BASE + 6; /* Emergency callback mode */ private static final int EMERGENCY_CALLBACK_MODE = BASE + 7; + private static final int WPS_PBC = BASE + 8; + private static final int WPS_PIN = BASE + 9; private final boolean mP2pSupported; - private final String mDeviceType; - private String mDeviceName; - private String mDeviceAddress; + + private WifiP2pDevice mThisDevice = new WifiP2pDevice(); /* 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 @@ -164,9 +163,9 @@ public class WifiP2pService extends IWifiP2pManager.Stub { mP2pSupported = mContext.getPackageManager().hasSystemFeature( PackageManager.FEATURE_WIFI_DIRECT); - mDeviceType = mContext.getResources().getString( + mThisDevice.primaryDeviceType = mContext.getResources().getString( com.android.internal.R.string.config_wifi_p2p_device_type); - mDeviceName = getDefaultDeviceName(); + mThisDevice.deviceName = getDefaultDeviceName(); mP2pStateMachine = new P2pStateMachine(TAG, mP2pSupported); mP2pStateMachine.start(); @@ -350,6 +349,10 @@ public class WifiP2pService extends IWifiP2pManager.Stub { replyToMessage(message, WifiP2pManager.CONNECT_FAILED, WifiP2pManager.BUSY); break; + case WifiP2pManager.CANCEL_CONNECT: + replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED, + WifiP2pManager.BUSY); + break; case WifiP2pManager.CREATE_GROUP: replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED, WifiP2pManager.BUSY); @@ -410,6 +413,10 @@ public class WifiP2pService extends IWifiP2pManager.Stub { replyToMessage(message, WifiP2pManager.CONNECT_FAILED, WifiP2pManager.P2P_UNSUPPORTED); break; + case WifiP2pManager.CANCEL_CONNECT: + replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED, + WifiP2pManager.P2P_UNSUPPORTED); + break; case WifiP2pManager.CREATE_GROUP: replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED, WifiP2pManager.P2P_UNSUPPORTED); @@ -656,7 +663,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { break; case WifiMonitor.P2P_DEVICE_FOUND_EVENT: WifiP2pDevice device = (WifiP2pDevice) message.obj; - if (mDeviceAddress.equals(device.deviceAddress)) break; + if (mThisDevice.deviceAddress.equals(device.deviceAddress)) break; mPeers.update(device); sendP2pPeersChangedBroadcast(); break; @@ -683,7 +690,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { // do nothing if p2pConnect did not return a pin } } - updateDeviceStatus(mSavedConnectConfig.deviceAddress, Status.INVITED); + updateDeviceStatus(mSavedConnectConfig.deviceAddress, WifiP2pDevice.INVITED); sendP2pPeersChangedBroadcast(); replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED); transitionTo(mGroupNegotiationState); @@ -706,7 +713,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { P2pStateMachine.this, mGroup.getInterface()); mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP); WifiP2pDevice groupOwner = mGroup.getOwner(); - updateDeviceStatus(groupOwner.deviceAddress, Status.CONNECTED); + updateDeviceStatus(groupOwner.deviceAddress, WifiP2pDevice.CONNECTED); sendP2pPeersChangedBroadcast(); } transitionTo(mGroupCreatedState); @@ -783,7 +790,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { case WifiMonitor.P2P_GO_NEGOTIATION_FAILURE_EVENT: case WifiMonitor.P2P_GROUP_FORMATION_FAILURE_EVENT: if (DBG) logd(getName() + " go failure"); - updateDeviceStatus(mSavedConnectConfig.deviceAddress, Status.FAILED); + updateDeviceStatus(mSavedConnectConfig.deviceAddress, WifiP2pDevice.FAILED); mSavedConnectConfig = null; sendP2pPeersChangedBroadcast(); transitionTo(mInactiveState); @@ -791,7 +798,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { case GROUP_NEGOTIATION_TIMED_OUT: if (mGroupNegotiationTimeoutIndex == message.arg1) { if (DBG) logd("Group negotiation timed out"); - updateDeviceStatus(mSavedConnectConfig.deviceAddress, Status.FAILED); + updateDeviceStatus(mSavedConnectConfig.deviceAddress, WifiP2pDevice.FAILED); mSavedConnectConfig = null; sendP2pPeersChangedBroadcast(); transitionTo(mInactiveState); @@ -802,6 +809,14 @@ public class WifiP2pService extends IWifiP2pManager.Stub { replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED, WifiP2pManager.BUSY); break; + case WifiP2pManager.CANCEL_CONNECT: + if (WifiNative.p2pCancelConnect()) { + replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_SUCCEEDED); + } else { + replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED, + WifiP2pManager.ERROR); + } + break; default: return NOT_HANDLED; } @@ -815,6 +830,8 @@ public class WifiP2pService extends IWifiP2pManager.Stub { if (DBG) logd(getName()); mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null); + updateThisDevice(WifiP2pDevice.CONNECTED); + //DHCP server has already been started if I am a group owner if (mGroup.isGroupOwner()) { setWifiP2pInfoOnGroupFormation(SERVER_ADDRESS); @@ -832,7 +849,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { String deviceAddress = getDeviceAddress(interfaceAddress); if (deviceAddress != null) { mGroup.addClient(deviceAddress); - updateDeviceStatus(deviceAddress, Status.CONNECTED); + updateDeviceStatus(deviceAddress, WifiP2pDevice.CONNECTED); if (DBG) logd(getName() + " ap sta connected"); sendP2pPeersChangedBroadcast(); } else { @@ -843,7 +860,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { interfaceAddress = (String) message.obj; deviceAddress = getDeviceAddress(interfaceAddress); if (deviceAddress != null) { - updateDeviceStatus(deviceAddress, Status.AVAILABLE); + updateDeviceStatus(deviceAddress, WifiP2pDevice.AVAILABLE); if (mGroup.removeClient(deviceAddress)) { if (DBG) logd("Removed client " + deviceAddress); if (!mPersistGroup && mGroup.isClientListEmpty()) { @@ -888,7 +905,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { boolean changed = false; for (WifiP2pDevice d : mPeers.getDeviceList()) { if (devices.contains(d) || mGroup.getOwner().equals(d)) { - d.status = Status.AVAILABLE; + d.status = WifiP2pDevice.AVAILABLE; changed = true; } } @@ -926,7 +943,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { WifiP2pConfig config = (WifiP2pConfig) message.obj; logd("Inviting device : " + config.deviceAddress); if (WifiNative.p2pInvite(mGroup, config.deviceAddress)) { - updateDeviceStatus(config.deviceAddress, Status.INVITED); + updateDeviceStatus(config.deviceAddress, WifiP2pDevice.INVITED); sendP2pPeersChangedBroadcast(); replyToMessage(message, WifiP2pManager.CONNECT_SUCCEEDED); } else { @@ -947,10 +964,10 @@ public class WifiP2pService extends IWifiP2pManager.Stub { case WifiMonitor.P2P_GROUP_STARTED_EVENT: Slog.e(TAG, "Duplicate group creation event notice, ignore"); break; - case WifiP2pManager.WPS_PBC: + case WPS_PBC: WifiNative.wpsPbc(); break; - case WifiP2pManager.WPS_PIN: + case WPS_PIN: WifiNative.wpsPin((String) message.obj); break; default: @@ -960,6 +977,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { } public void exit() { + updateThisDevice(WifiP2pDevice.AVAILABLE); setWifiP2pInfoOnGroupTermination(); mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null); sendP2pConnectionChangedBroadcast(); @@ -979,6 +997,13 @@ public class WifiP2pService extends IWifiP2pManager.Stub { mContext.sendStickyBroadcast(intent); } + private void sendThisDeviceChangedBroadcast() { + final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION); + intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); + intent.putExtra(WifiP2pManager.EXTRA_WIFI_P2P_DEVICE, new WifiP2pDevice(mThisDevice)); + mContext.sendStickyBroadcast(intent); + } + private void sendP2pPeersChangedBroadcast() { final Intent intent = new Intent(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); @@ -1048,7 +1073,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { private void notifyP2pGoNegotationRequest(WifiP2pConfig config) { Resources r = Resources.getSystem(); - Wps wps = config.wps; + WpsInfo wps = config.wps; final View textEntryView = LayoutInflater.from(mContext) .inflate(R.layout.wifi_p2p_go_negotiation_request_alert, null); final EditText pin = (EditText) textEntryView .findViewById(R.id.wifi_p2p_wps_pin); @@ -1061,9 +1086,9 @@ public class WifiP2pService extends IWifiP2pManager.Stub { if (DBG) logd(getName() + " connect " + pin.getText()); if (pin.getVisibility() == View.GONE) { - mSavedGoNegotiationConfig.wps.setup = Setup.PBC; + mSavedGoNegotiationConfig.wps.setup = WpsInfo.PBC; } else { - mSavedGoNegotiationConfig.wps.setup = Setup.KEYPAD; + mSavedGoNegotiationConfig.wps.setup = WpsInfo.KEYPAD; mSavedGoNegotiationConfig.wps.pin = pin.getText().toString(); } sendMessage(WifiP2pManager.CONNECT, mSavedGoNegotiationConfig); @@ -1079,7 +1104,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { }) .create(); - if (wps.setup == Setup.PBC) { + if (wps.setup == WpsInfo.PBC) { pin.setVisibility(View.GONE); dialog.setMessage(r.getString(R.string.wifi_p2p_pbc_go_negotiation_request_message, config.deviceAddress)); @@ -1104,7 +1129,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { .setPositiveButton(r.getString(R.string.ok), new OnClickListener() { public void onClick(DialogInterface dialog, int which) { if (DBG) logd(getName() + " wps_pbc"); - sendMessage(WifiP2pManager.WPS_PBC); + sendMessage(WPS_PBC); } }) .setNegativeButton(r.getString(R.string.cancel), null) @@ -1130,7 +1155,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { .setPositiveButton(r.getString(R.string.ok), new OnClickListener() { public void onClick(DialogInterface dialog, int which) { if (DBG) logd(getName() + " wps_pin"); - sendMessage(WifiP2pManager.WPS_PIN, pin.getText().toString()); + sendMessage(WPS_PIN, pin.getText().toString()); } }) .setNegativeButton(r.getString(R.string.cancel), null) @@ -1173,7 +1198,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { dialog.show(); } - private void updateDeviceStatus(String deviceAddress, Status status) { + private void updateDeviceStatus(String deviceAddress, int status) { for (WifiP2pDevice d : mPeers.getDeviceList()) { if (d.deviceAddress.equals(deviceAddress)) { d.status = status; @@ -1218,28 +1243,50 @@ public class WifiP2pService extends IWifiP2pManager.Stub { private void initializeP2pSettings() { WifiNative.setPersistentReconnect(true); - WifiNative.setDeviceName(mDeviceName); - WifiNative.setDeviceType(mDeviceType); + WifiNative.setDeviceName(mThisDevice.deviceName); + WifiNative.setDeviceType(mThisDevice.primaryDeviceType); - mDeviceAddress = WifiNative.p2pGetDeviceAddress(); - if (DBG) Slog.d(TAG, "DeviceAddress: " + mDeviceAddress); + mThisDevice.deviceAddress = WifiNative.p2pGetDeviceAddress(); + updateThisDevice(WifiP2pDevice.AVAILABLE); + if (DBG) Slog.d(TAG, "DeviceAddress: " + mThisDevice.deviceAddress); + } + + private void updateThisDevice(int status) { + mThisDevice.status = status; + sendThisDeviceChangedBroadcast(); } //State machine initiated requests can have replyTo set to null indicating //there are no recepients, we ignore those reply actions private void replyToMessage(Message msg, int what) { if (msg.replyTo == null) return; - mReplyChannel.replyToMessage(msg, what); + Message dstMsg = obtainMessage(msg); + dstMsg.what = what; + mReplyChannel.replyToMessage(msg, dstMsg); } private void replyToMessage(Message msg, int what, int arg1) { if (msg.replyTo == null) return; - mReplyChannel.replyToMessage(msg, what, arg1); + Message dstMsg = obtainMessage(msg); + dstMsg.what = what; + dstMsg.arg1 = arg1; + mReplyChannel.replyToMessage(msg, dstMsg); } private void replyToMessage(Message msg, int what, Object obj) { if (msg.replyTo == null) return; - mReplyChannel.replyToMessage(msg, what, obj); + Message dstMsg = obtainMessage(msg); + dstMsg.what = what; + dstMsg.obj = obj; + mReplyChannel.replyToMessage(msg, dstMsg); + } + + /* arg2 on the source message has a hash code that needs to be retained in replies + * see WifiP2pManager for details */ + private Message obtainMessage(Message srcMsg) { + Message msg = Message.obtain(); + msg.arg2 = srcMsg.arg2; + return msg; } private void logd(String s) { |