From 7d6d9c005e5cfad787bb62b7fee6be2d75b13ca3 Mon Sep 17 00:00:00 2001 From: Irfan Sheriff Date: Tue, 10 Jan 2012 15:50:45 -0800 Subject: [PATCH] Initial support for concurrency Use of multiple socket connections over wlan0 and p2p and p2p state machine is now controlled entirely from wifi state machine Add discovery stop to allow STA scans to proceed after p2p is used Change-Id: I790c9112d3f475f638f06fc3ae9e191f6d90ef35 --- core/jni/android_net_wifi_Wifi.cpp | 12 +- core/res/res/values/strings.xml | 8 - wifi/java/android/net/wifi/WifiMonitor.java | 11 - wifi/java/android/net/wifi/WifiNative.java | 14 +- .../android/net/wifi/WifiStateMachine.java | 87 +---- .../android/net/wifi/p2p/WifiP2pDevice.java | 3 +- .../android/net/wifi/p2p/WifiP2pManager.java | 87 ++--- .../android/net/wifi/p2p/WifiP2pService.java | 357 +++--------------- 8 files changed, 129 insertions(+), 450 deletions(-) diff --git a/core/jni/android_net_wifi_Wifi.cpp b/core/jni/android_net_wifi_Wifi.cpp index 2ac3ca8d8da42..c5ff16e4baa65 100644 --- a/core/jni/android_net_wifi_Wifi.cpp +++ b/core/jni/android_net_wifi_Wifi.cpp @@ -116,14 +116,9 @@ static jboolean android_net_wifi_unloadDriver(JNIEnv* env, jobject) return (jboolean)(::wifi_unload_driver() == 0); } -static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject) +static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject, jboolean p2pSupported) { - return (jboolean)(::wifi_start_supplicant() == 0); -} - -static jboolean android_net_wifi_startP2pSupplicant(JNIEnv* env, jobject) -{ - return (jboolean)(::wifi_start_p2p_supplicant() == 0); + return (jboolean)(::wifi_start_supplicant(p2pSupported) == 0); } static jboolean android_net_wifi_killSupplicant(JNIEnv* env, jobject) @@ -207,8 +202,7 @@ static JNINativeMethod gWifiMethods[] = { { "loadDriver", "()Z", (void *)android_net_wifi_loadDriver }, { "isDriverLoaded", "()Z", (void *)android_net_wifi_isDriverLoaded }, { "unloadDriver", "()Z", (void *)android_net_wifi_unloadDriver }, - { "startSupplicant", "()Z", (void *)android_net_wifi_startSupplicant }, - { "startP2pSupplicant", "()Z", (void *)android_net_wifi_startP2pSupplicant }, + { "startSupplicant", "(Z)Z", (void *)android_net_wifi_startSupplicant }, { "killSupplicant", "()Z", (void *)android_net_wifi_killSupplicant }, { "connectToSupplicant", "(Ljava/lang/String;)Z", (void *)android_net_wifi_connectToSupplicant }, diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index dc45c4087533e..40748bde5bc13 100755 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -2696,11 +2696,6 @@ AndroidAP - - Wi-Fi Direct - Start Wi-Fi Direct. This will turn off Wi-Fi client/hotspot. - Couldn\'t start Wi-Fi Direct. - Accept Decline Invitation sent @@ -2711,9 +2706,6 @@ Type the required PIN: PIN: - Wi-Fi Direct is on - Touch for settings - Insert character diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java index bbb74d1a8090f..d05e0b8ace892 100644 --- a/wifi/java/android/net/wifi/WifiMonitor.java +++ b/wifi/java/android/net/wifi/WifiMonitor.java @@ -365,17 +365,6 @@ public class WifiMonitor { } else if (event == DRIVER_STATE) { handleDriverEvent(eventData); } else if (event == TERMINATING) { - /** - * If monitor socket is closed, we have already - * stopped the supplicant, simply exit the monitor thread - */ - if (eventData.startsWith(MONITOR_SOCKET_CLOSED_STR)) { - if (false) { - Log.d(TAG, "Monitor socket is closed, exiting thread"); - } - break; - } - /** * Close the supplicant connection if we see * too many recv errors diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java index 48a785c98b282..e3dd3a621faed 100644 --- a/wifi/java/android/net/wifi/WifiNative.java +++ b/wifi/java/android/net/wifi/WifiNative.java @@ -39,6 +39,8 @@ import java.util.List; */ public class WifiNative { + private static final boolean DBG = false; + private final String mTAG; private static final int DEFAULT_GROUP_OWNER_INTENT = 7; static final int BLUETOOTH_COEXISTENCE_MODE_ENABLED = 0; @@ -53,9 +55,7 @@ public class WifiNative { public native static boolean unloadDriver(); - public native static boolean startSupplicant(); - - public native static boolean startP2pSupplicant(); + public native static boolean startSupplicant(boolean p2pSupported); /* Sends a kill signal to supplicant. To be used when we have lost connection or when the supplicant is hung */ @@ -79,6 +79,7 @@ public class WifiNative { public WifiNative(String iface) { mInterface = iface; + mTAG = "WifiNative-" + iface; } public boolean connectToSupplicant() { @@ -94,14 +95,17 @@ public class WifiNative { } private boolean doBooleanCommand(String command) { + if (DBG) Log.d(mTAG, "doBoolean: " + command); return doBooleanCommand(mInterface, command); } private int doIntCommand(String command) { + if (DBG) Log.d(mTAG, "doInt: " + command); return doIntCommand(mInterface, command); } private String doStringCommand(String command) { + if (DBG) Log.d(mTAG, "doString: " + command); return doStringCommand(mInterface, command); } @@ -437,6 +441,10 @@ public class WifiNative { return doBooleanCommand("P2P_FIND " + timeout); } + public boolean p2pStopFind() { + return doBooleanCommand("P2P_STOP_FIND"); + } + public boolean p2pListen() { return doBooleanCommand("P2P_LISTEN"); } diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index 8c9e472f74b59..0877e62326fb9 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -45,6 +45,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageManager; import android.net.ConnectivityManager; import android.net.DhcpInfo; import android.net.DhcpInfoInternal; @@ -118,6 +119,8 @@ public class WifiStateMachine extends StateMachine { private INetworkManagementService mNwService; private ConnectivityManager mCm; + private final boolean mP2pSupported; + /* Scan results handling */ private List mScanResults; private static final Pattern scanResultPattern = Pattern.compile("\t+"); @@ -361,9 +364,9 @@ public class WifiStateMachine extends StateMachine { /* Reset the WPS state machine */ static final int CMD_RESET_WPS_STATE = BASE + 122; - /* Interaction with WifiP2pService */ - public static final int WIFI_ENABLE_PENDING = BASE + 131; - public static final int P2P_ENABLE_PROCEED = BASE + 132; + /* P2p commands */ + public static final int CMD_ENABLE_P2P = BASE + 131; + public static final int CMD_DISABLE_P2P = BASE + 132; private static final int CONNECT_MODE = 1; private static final int SCAN_ONLY_MODE = 2; @@ -482,9 +485,6 @@ public class WifiStateMachine extends StateMachine { /* Waiting for untether confirmation to stop soft Ap */ private State mSoftApStoppingState = new SoftApStoppingState(); - /* Wait till p2p is disabled */ - private State mWaitForP2pDisableState = new WaitForP2pDisableState(); - private class TetherStateChange { ArrayList available; ArrayList active; @@ -556,6 +556,9 @@ public class WifiStateMachine extends StateMachine { IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); mNwService = INetworkManagementService.Stub.asInterface(b); + mP2pSupported = mContext.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_WIFI_DIRECT); + mWifiNative = new WifiNative(mInterfaceName); mWifiConfigStore = new WifiConfigStore(context, mWifiNative); mWifiMonitor = new WifiMonitor(this, mWifiNative); @@ -639,7 +642,6 @@ public class WifiStateMachine extends StateMachine { addState(mTetheringState, mSoftApStartedState); addState(mTetheredState, mSoftApStartedState); addState(mSoftApStoppingState, mDefaultState); - addState(mWaitForP2pDisableState, mDefaultState); setInitialState(mInitialState); @@ -1892,11 +1894,6 @@ public class WifiStateMachine extends StateMachine { mReplyChannel.replyToMessage(message, WifiManager.CMD_WPS_COMPLETED, new WpsResult(Status.FAILURE)); break; - case WifiP2pService.P2P_ENABLE_PENDING: - // turn off wifi and defer to be handled in DriverUnloadedState - setWifiEnabled(false); - deferMessage(message); - break; default: loge("Error! unhandled message" + message); break; @@ -2056,7 +2053,7 @@ public class WifiStateMachine extends StateMachine { loge("Unable to change interface settings: " + ie); } - if(mWifiNative.startSupplicant()) { + if(mWifiNative.startSupplicant(mP2pSupported)) { if (DBG) log("Supplicant start successful"); mWifiMonitor.startMonitoring(); transitionTo(mSupplicantStartingState); @@ -2168,11 +2165,7 @@ public class WifiStateMachine extends StateMachine { if (DBG) log(getName() + message.toString() + "\n"); switch (message.what) { case CMD_LOAD_DRIVER: - mWifiP2pChannel.sendMessage(WIFI_ENABLE_PENDING); - transitionTo(mWaitForP2pDisableState); - break; - case WifiP2pService.P2P_ENABLE_PENDING: - mReplyChannel.replyToMessage(message, P2P_ENABLE_PROCEED); + transitionTo(mDriverLoadingState); break; default: return NOT_HANDLED; @@ -2549,13 +2542,15 @@ public class WifiStateMachine extends StateMachine { mWifiNative.status(); transitionTo(mDisconnectedState); } + + if (mP2pSupported) mWifiP2pChannel.sendMessage(WifiStateMachine.CMD_ENABLE_P2P); } @Override public boolean processMessage(Message message) { if (DBG) log(getName() + message.toString() + "\n"); boolean eventLoggingEnabled = true; switch(message.what) { - case CMD_SET_SCAN_TYPE: + case CMD_SET_SCAN_TYPE: mSetScanActive = (message.arg1 == SCAN_ACTIVE); mWifiNative.setScanMode(mSetScanActive); break; @@ -2668,6 +2663,8 @@ public class WifiStateMachine extends StateMachine { mIsRunning = false; updateBatteryWorkSource(null); mScanResults = null; + + if (mP2pSupported) mWifiP2pChannel.sendMessage(WifiStateMachine.CMD_DISABLE_P2P); } } @@ -3341,7 +3338,6 @@ public class WifiStateMachine extends StateMachine { case CMD_START_PACKET_FILTERING: case CMD_STOP_PACKET_FILTERING: case CMD_TETHER_STATE_CHANGE: - case WifiP2pService.P2P_ENABLE_PENDING: deferMessage(message); break; case WifiStateMachine.CMD_RESPONSE_AP_CONFIG: @@ -3405,55 +3401,6 @@ public class WifiStateMachine extends StateMachine { transitionTo(mTetheringState); } break; - case WifiP2pService.P2P_ENABLE_PENDING: - // turn of soft Ap and defer to be handled in DriverUnloadedState - setWifiApEnabled(null, false); - deferMessage(message); - break; - default: - return NOT_HANDLED; - } - EventLog.writeEvent(EVENTLOG_WIFI_EVENT_HANDLED, message.what); - return HANDLED; - } - } - - class WaitForP2pDisableState extends State { - private int mSavedArg; - @Override - public void enter() { - if (DBG) log(getName() + "\n"); - EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName()); - - //Preserve the argument arg1 that has information used in DriverLoadingState - mSavedArg = getCurrentMessage().arg1; - } - @Override - public boolean processMessage(Message message) { - if (DBG) log(getName() + message.toString() + "\n"); - switch(message.what) { - case WifiP2pService.WIFI_ENABLE_PROCEED: - //restore argument from original message (CMD_LOAD_DRIVER) - message.arg1 = mSavedArg; - transitionTo(mDriverLoadingState); - break; - case CMD_LOAD_DRIVER: - case CMD_UNLOAD_DRIVER: - case CMD_START_SUPPLICANT: - case CMD_STOP_SUPPLICANT: - case CMD_START_AP: - case CMD_STOP_AP: - case CMD_START_DRIVER: - case CMD_STOP_DRIVER: - case CMD_SET_SCAN_MODE: - case CMD_SET_SCAN_TYPE: - case CMD_SET_HIGH_PERF_MODE: - case CMD_SET_COUNTRY_CODE: - case CMD_SET_FREQUENCY_BAND: - case CMD_START_PACKET_FILTERING: - case CMD_STOP_PACKET_FILTERING: - deferMessage(message); - break; default: return NOT_HANDLED; } @@ -3503,7 +3450,6 @@ public class WifiStateMachine extends StateMachine { case CMD_SET_FREQUENCY_BAND: case CMD_START_PACKET_FILTERING: case CMD_STOP_PACKET_FILTERING: - case WifiP2pService.P2P_ENABLE_PENDING: deferMessage(message); break; default: @@ -3599,7 +3545,6 @@ public class WifiStateMachine extends StateMachine { case CMD_SET_FREQUENCY_BAND: case CMD_START_PACKET_FILTERING: case CMD_STOP_PACKET_FILTERING: - case WifiP2pService.P2P_ENABLE_PENDING: deferMessage(message); break; default: diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java index 7471a2d0a28fc..b0cde6439e599 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pDevice.java @@ -301,7 +301,8 @@ public class WifiP2pDevice implements Parcelable { private String trimQuotes(String str) { str = str.trim(); if (str.startsWith("'") && str.endsWith("'")) { - return str.substring(1, str.length()-1); + if (str.length() <= 2) return ""; + else return str.substring(1, str.length()-1); } return str; } diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java index 9205300a5d2e7..4fd0a575b701c 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java @@ -199,68 +199,61 @@ public class WifiP2pManager { private static final int BASE = Protocol.BASE_WIFI_P2P_MANAGER; /** @hide */ - public static final int ENABLE_P2P = BASE + 1; + public static final int DISCOVER_PEERS = BASE + 1; /** @hide */ - public static final int ENABLE_P2P_FAILED = BASE + 2; + public static final int DISCOVER_PEERS_FAILED = BASE + 2; /** @hide */ - public static final int ENABLE_P2P_SUCCEEDED = BASE + 3; + public static final int DISCOVER_PEERS_SUCCEEDED = BASE + 3; /** @hide */ - public static final int DISABLE_P2P = BASE + 4; + public static final int STOP_DISCOVERY = BASE + 4; /** @hide */ - public static final int DISABLE_P2P_FAILED = BASE + 5; + public static final int STOP_DISCOVERY_FAILED = BASE + 5; /** @hide */ - public static final int DISABLE_P2P_SUCCEEDED = BASE + 6; + public static final int STOP_DISCOVERY_SUCCEEDED = BASE + 6; /** @hide */ - public static final int DISCOVER_PEERS = BASE + 7; + public static final int CONNECT = BASE + 7; /** @hide */ - public static final int DISCOVER_PEERS_FAILED = BASE + 8; + public static final int CONNECT_FAILED = BASE + 8; /** @hide */ - public static final int DISCOVER_PEERS_SUCCEEDED = BASE + 9; + public static final int CONNECT_SUCCEEDED = BASE + 9; /** @hide */ - public static final int CONNECT = BASE + 10; + public static final int CANCEL_CONNECT = BASE + 10; /** @hide */ - public static final int CONNECT_FAILED = BASE + 11; + public static final int CANCEL_CONNECT_FAILED = BASE + 11; /** @hide */ - public static final int CONNECT_SUCCEEDED = BASE + 12; + public static final int CANCEL_CONNECT_SUCCEEDED = BASE + 12; /** @hide */ - public static final int CANCEL_CONNECT = BASE + 13; + public static final int CREATE_GROUP = BASE + 13; /** @hide */ - public static final int CANCEL_CONNECT_FAILED = BASE + 14; + public static final int CREATE_GROUP_FAILED = BASE + 14; /** @hide */ - public static final int CANCEL_CONNECT_SUCCEEDED = BASE + 15; + public static final int CREATE_GROUP_SUCCEEDED = BASE + 15; /** @hide */ - public static final int CREATE_GROUP = BASE + 16; + public static final int REMOVE_GROUP = BASE + 16; /** @hide */ - public static final int CREATE_GROUP_FAILED = BASE + 17; + public static final int REMOVE_GROUP_FAILED = BASE + 17; /** @hide */ - public static final int CREATE_GROUP_SUCCEEDED = BASE + 18; + public static final int REMOVE_GROUP_SUCCEEDED = BASE + 18; /** @hide */ - public static final int REMOVE_GROUP = BASE + 19; + public static final int REQUEST_PEERS = BASE + 19; /** @hide */ - public static final int REMOVE_GROUP_FAILED = BASE + 20; - /** @hide */ - public static final int REMOVE_GROUP_SUCCEEDED = BASE + 21; + public static final int RESPONSE_PEERS = BASE + 20; /** @hide */ - public static final int REQUEST_PEERS = BASE + 22; + public static final int REQUEST_CONNECTION_INFO = BASE + 21; /** @hide */ - public static final int RESPONSE_PEERS = BASE + 23; + public static final int RESPONSE_CONNECTION_INFO = BASE + 22; /** @hide */ - public static final int REQUEST_CONNECTION_INFO = BASE + 24; + public static final int REQUEST_GROUP_INFO = BASE + 23; /** @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; + public static final int RESPONSE_GROUP_INFO = BASE + 24; /** * Create a new WifiP2pManager instance. Applications use @@ -376,6 +369,7 @@ public class WifiP2pManager { break; /* ActionListeners grouped together */ case WifiP2pManager.DISCOVER_PEERS_FAILED: + case WifiP2pManager.STOP_DISCOVERY_FAILED: case WifiP2pManager.CONNECT_FAILED: case WifiP2pManager.CANCEL_CONNECT_FAILED: case WifiP2pManager.CREATE_GROUP_FAILED: @@ -386,6 +380,7 @@ public class WifiP2pManager { break; /* ActionListeners grouped together */ case WifiP2pManager.DISCOVER_PEERS_SUCCEEDED: + case WifiP2pManager.STOP_DISCOVERY_SUCCEEDED: case WifiP2pManager.CONNECT_SUCCEEDED: case WifiP2pManager.CANCEL_CONNECT_SUCCEEDED: case WifiP2pManager.CREATE_GROUP_SUCCEEDED: @@ -458,26 +453,6 @@ public class WifiP2pManager { } } - /** - * Sends in a request to the system to enable p2p. This will pop up a dialog - * to the user and upon authorization will enable p2p. - * @hide - */ - public void enableP2p(Channel c) { - if (c == null) return; - c.mAsyncChannel.sendMessage(ENABLE_P2P); - } - - /** - * Sends in a request to the system to disable p2p. This will pop up a dialog - * to the user and upon authorization will enable p2p. - * @hide - */ - public void disableP2p(Channel c) { - if (c == null) return; - c.mAsyncChannel.sendMessage(DISABLE_P2P); - } - /** * Initiate peer discovery. A discovery process involves scanning for available Wi-Fi peers * for the purpose of establishing a connection. @@ -502,6 +477,16 @@ public class WifiP2pManager { c.mAsyncChannel.sendMessage(DISCOVER_PEERS, 0, c.putListener(listener)); } + /** + * TODO: Add more documentation before opening up + * Cancel peer discovery + * @hide + */ + public void stopPeerDiscovery(Channel c, ActionListener listener) { + if (c == null) return; + c.mAsyncChannel.sendMessage(STOP_DISCOVERY, 0, c.putListener(listener)); + } + /** * Start a p2p connection to a device with the specified configuration. * diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java index 69cbb5c35938d..5b0e424894902 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java @@ -49,6 +49,7 @@ import android.os.Handler; import android.os.HandlerThread; import android.os.Message; import android.os.Messenger; +import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; import android.provider.Settings; @@ -84,7 +85,7 @@ import java.util.Collection; */ public class WifiP2pService extends IWifiP2pManager.Stub { private static final String TAG = "WifiP2pService"; - private static final boolean DBG = true; + private static final boolean DBG = false; private static final String NETWORKTYPE = "WIFI_P2P"; private Context mContext; @@ -94,11 +95,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub { INetworkManagementService mNwService; private DhcpStateMachine mDhcpStateMachine; - //Tracked to notify the user about wifi client/hotspot being shut down - //during p2p bring up - private int mWifiState = WifiManager.WIFI_STATE_DISABLED; - private int mWifiApState = WifiManager.WIFI_AP_STATE_DISABLED; - private P2pStateMachine mP2pStateMachine; private AsyncChannel mReplyChannel = new AsyncChannel(); private AsyncChannel mWifiChannel; @@ -110,6 +106,9 @@ public class WifiP2pService extends IWifiP2pManager.Stub { private static final int GROUP_CREATING_WAIT_TIME_MS = 120 * 1000; private static int mGroupCreatingTimeoutIndex = 0; + /* Set a two minute discover timeout to avoid STA scans from being blocked */ + private static final int DISCOVER_TIMEOUT_S = 120; + /** * Delay between restarts upon failure to setup connection with supplicant */ @@ -124,28 +123,13 @@ public class WifiP2pService extends IWifiP2pManager.Stub { private static final int BASE = Protocol.BASE_WIFI_P2P_SERVICE; - /* Message sent to WifiStateMachine to indicate p2p enable is pending */ - public static final int P2P_ENABLE_PENDING = BASE + 1; - /* Message sent to WifiStateMachine to indicate Wi-Fi client/hotspot operation can proceed */ - public static final int WIFI_ENABLE_PROCEED = BASE + 2; - /* Delayed message to timeout group creation */ - public static final int GROUP_CREATING_TIMED_OUT = BASE + 3; - - /* User accepted to disable Wi-Fi in order to enable p2p */ - private static final int WIFI_DISABLE_USER_ACCEPT = BASE + 4; - /* User rejected to disable Wi-Fi in order to enable p2p */ - private static final int WIFI_DISABLE_USER_REJECT = BASE + 5; + public static final int GROUP_CREATING_TIMED_OUT = BASE + 1; /* User accepted a peer request */ - private static final int PEER_CONNECTION_USER_ACCEPT = BASE + 6; + private static final int PEER_CONNECTION_USER_ACCEPT = BASE + 2; /* User rejected a peer request */ - private static final int PEER_CONNECTION_USER_REJECT = BASE + 7; - - /* Airplane mode changed */ - private static final int AIRPLANE_MODE_CHANGED = BASE + 8; - /* Emergency callback mode */ - private static final int EMERGENCY_CALLBACK_MODE = BASE + 9; + private static final int PEER_CONNECTION_USER_REJECT = BASE + 3; private final boolean mP2pSupported; @@ -166,7 +150,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { public WifiP2pService(Context context) { mContext = context; - //STOPSHIP: fix this + //STOPSHIP: get this from native side mInterface = "p2p0"; mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI_P2P, 0, NETWORKTYPE, ""); @@ -179,15 +163,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub { mP2pStateMachine = new P2pStateMachine(TAG, mP2pSupported); mP2pStateMachine.start(); - - // broadcasts - IntentFilter filter = new IntentFilter(); - filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); - filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED); - filter.addAction(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED); - filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); - mContext.registerReceiver(new WifiStateReceiver(), filter); - } public void connectivityServiceReady() { @@ -195,26 +170,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub { mNwService = INetworkManagementService.Stub.asInterface(b); } - private class WifiStateReceiver extends BroadcastReceiver { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { - mWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, - WifiManager.WIFI_STATE_DISABLED); - } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) { - mWifiApState = intent.getIntExtra(WifiManager.EXTRA_WIFI_AP_STATE, - WifiManager.WIFI_AP_STATE_DISABLED); - } else if (action.equals(Intent.ACTION_AIRPLANE_MODE_CHANGED)) { - mP2pStateMachine.sendMessage(AIRPLANE_MODE_CHANGED); - } else if (action.equals(TelephonyIntents.ACTION_EMERGENCY_CALLBACK_MODE_CHANGED)) { - if (intent.getBooleanExtra("phoneinECMState", false) == true) { - mP2pStateMachine.sendMessage(EMERGENCY_CALLBACK_MODE); - } - } - } - } - private void enforceAccessPermission() { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_WIFI_STATE, "WifiP2pService"); @@ -264,8 +219,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub { private P2pNotSupportedState mP2pNotSupportedState = new P2pNotSupportedState(); private P2pDisablingState mP2pDisablingState = new P2pDisablingState(); private P2pDisabledState mP2pDisabledState = new P2pDisabledState(); - private WaitForUserActionState mWaitForUserActionState = new WaitForUserActionState(); - private WaitForWifiDisableState mWaitForWifiDisableState = new WaitForWifiDisableState(); private P2pEnablingState mP2pEnablingState = new P2pEnablingState(); private P2pEnabledState mP2pEnabledState = new P2pEnabledState(); // Inactive is when p2p is enabled with no connectivity @@ -299,8 +252,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub { addState(mP2pNotSupportedState, mDefaultState); addState(mP2pDisablingState, mDefaultState); addState(mP2pDisabledState, mDefaultState); - addState(mWaitForUserActionState, mP2pDisabledState); - addState(mWaitForWifiDisableState, mP2pDisabledState); addState(mP2pEnablingState, mDefaultState); addState(mP2pEnabledState, mDefaultState); addState(mInactiveState, mP2pEnabledState); @@ -346,23 +297,14 @@ public class WifiP2pService extends IWifiP2pManager.Stub { AsyncChannel ac = new AsyncChannel(); ac.connect(mContext, getHandler(), message.replyTo); break; - case WifiStateMachine.WIFI_ENABLE_PENDING: - // Disable p2p operation before we can respond - sendMessage(WifiP2pManager.DISABLE_P2P); - deferMessage(message); - break; - case WifiP2pManager.ENABLE_P2P: - replyToMessage(message, WifiP2pManager.ENABLE_P2P_FAILED, - WifiP2pManager.BUSY); - break; - case WifiP2pManager.DISABLE_P2P: - replyToMessage(message, WifiP2pManager.DISABLE_P2P_FAILED, - WifiP2pManager.BUSY); - break; case WifiP2pManager.DISCOVER_PEERS: replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED, WifiP2pManager.BUSY); break; + case WifiP2pManager.STOP_DISCOVERY: + replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED, + WifiP2pManager.BUSY); + break; case WifiP2pManager.CONNECT: replyToMessage(message, WifiP2pManager.CONNECT_FAILED, WifiP2pManager.BUSY); @@ -388,16 +330,14 @@ public class WifiP2pService extends IWifiP2pManager.Stub { case WifiP2pManager.REQUEST_GROUP_INFO: replyToMessage(message, WifiP2pManager.RESPONSE_GROUP_INFO, mGroup); break; - case AIRPLANE_MODE_CHANGED: - if (isAirplaneModeOn()) sendMessage(WifiP2pManager.DISABLE_P2P); - break; - case EMERGENCY_CALLBACK_MODE: - sendMessage(WifiP2pManager.DISABLE_P2P); - break; // Ignore case WifiMonitor.P2P_INVITATION_RESULT_EVENT: - case WIFI_DISABLE_USER_ACCEPT: - case WIFI_DISABLE_USER_REJECT: + case WifiMonitor.SCAN_RESULTS_EVENT: + case WifiMonitor.SUP_CONNECTION_EVENT: + case WifiMonitor.SUP_DISCONNECTION_EVENT: + case WifiMonitor.NETWORK_CONNECTION_EVENT: + case WifiMonitor.NETWORK_DISCONNECTION_EVENT: + case WifiMonitor.SUPPLICANT_STATE_CHANGE_EVENT: case PEER_CONNECTION_USER_ACCEPT: case PEER_CONNECTION_USER_REJECT: case GROUP_CREATING_TIMED_OUT: @@ -414,22 +354,14 @@ public class WifiP2pService extends IWifiP2pManager.Stub { @Override public boolean processMessage(Message message) { switch (message.what) { - // Allow Wi-Fi to proceed - case WifiStateMachine.WIFI_ENABLE_PENDING: - replyToMessage(message, WIFI_ENABLE_PROCEED); - break; - case WifiP2pManager.ENABLE_P2P: - replyToMessage(message, WifiP2pManager.ENABLE_P2P_FAILED, - WifiP2pManager.P2P_UNSUPPORTED); - break; - case WifiP2pManager.DISABLE_P2P: - replyToMessage(message, WifiP2pManager.DISABLE_P2P_FAILED, - WifiP2pManager.P2P_UNSUPPORTED); - break; - case WifiP2pManager.DISCOVER_PEERS: + case WifiP2pManager.DISCOVER_PEERS: replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED, WifiP2pManager.P2P_UNSUPPORTED); break; + case WifiP2pManager.STOP_DISCOVERY: + replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED, + WifiP2pManager.P2P_UNSUPPORTED); + break; case WifiP2pManager.CONNECT: replyToMessage(message, WifiP2pManager.CONNECT_FAILED, WifiP2pManager.P2P_UNSUPPORTED); @@ -438,7 +370,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { replyToMessage(message, WifiP2pManager.CANCEL_CONNECT_FAILED, WifiP2pManager.P2P_UNSUPPORTED); break; - case WifiP2pManager.CREATE_GROUP: + case WifiP2pManager.CREATE_GROUP: replyToMessage(message, WifiP2pManager.CREATE_GROUP_FAILED, WifiP2pManager.P2P_UNSUPPORTED); break; @@ -454,27 +386,16 @@ public class WifiP2pService extends IWifiP2pManager.Stub { } class P2pDisablingState extends State { - @Override - public void enter() { - if (DBG) logd(getName()); - logd("stopping supplicant"); - if (!mWifiNative.stopSupplicant()) { - loge("Failed to stop supplicant, issue kill"); - mWifiNative.killSupplicant(); - } - } - @Override public boolean processMessage(Message message) { if (DBG) logd(getName() + message.toString()); switch (message.what) { case WifiMonitor.SUP_DISCONNECTION_EVENT: - logd("Supplicant connection lost"); - mWifiNative.closeSupplicantConnection(); + if (DBG) logd("p2p socket connection lost"); transitionTo(mP2pDisabledState); break; - case WifiP2pManager.ENABLE_P2P: - case WifiP2pManager.DISABLE_P2P: + case WifiStateMachine.CMD_ENABLE_P2P: + case WifiStateMachine.CMD_DISABLE_P2P: deferMessage(message); break; default: @@ -484,7 +405,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub { } } - class P2pDisabledState extends State { @Override public void enter() { @@ -495,118 +415,19 @@ public class WifiP2pService extends IWifiP2pManager.Stub { public boolean processMessage(Message message) { if (DBG) logd(getName() + message.toString()); switch (message.what) { - case WifiP2pManager.ENABLE_P2P: - OnClickListener listener = new OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - if (which == DialogInterface.BUTTON_POSITIVE) { - sendMessage(WIFI_DISABLE_USER_ACCEPT); - } else { - sendMessage(WIFI_DISABLE_USER_REJECT); - } - } - }; - - // Show a user request dialog if we know Wi-Fi client/hotspot is in operation - if (mWifiState != WifiManager.WIFI_STATE_DISABLED || - mWifiApState != WifiManager.WIFI_AP_STATE_DISABLED) { - Resources r = Resources.getSystem(); - AlertDialog dialog = new AlertDialog.Builder(mContext) - .setTitle(r.getString(R.string.wifi_p2p_dialog_title)) - .setMessage(r.getString(R.string.wifi_p2p_turnon_message)) - .setPositiveButton(r.getString(R.string.ok), listener) - .setNegativeButton(r.getString(R.string.cancel), listener) - .create(); - dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); - dialog.show(); - transitionTo(mWaitForUserActionState); - } else { - mWifiChannel.sendMessage(P2P_ENABLE_PENDING); - transitionTo(mWaitForWifiDisableState); - } - replyToMessage(message, WifiP2pManager.ENABLE_P2P_SUCCEEDED); - break; - case WifiP2pManager.DISABLE_P2P: - replyToMessage(message, WifiP2pManager.DISABLE_P2P_SUCCEEDED); - break; - case WifiStateMachine.WIFI_ENABLE_PENDING: - replyToMessage(message, WIFI_ENABLE_PROCEED); - break; - default: - return NOT_HANDLED; - } - return HANDLED; - } - } - - class WaitForUserActionState extends State { - @Override - public void enter() { - if (DBG) logd(getName()); - } - - @Override - public boolean processMessage(Message message) { - if (DBG) logd(getName() + message.toString()); - switch (message.what) { - case WIFI_DISABLE_USER_ACCEPT: - mWifiChannel.sendMessage(P2P_ENABLE_PENDING); - transitionTo(mWaitForWifiDisableState); - break; - case WIFI_DISABLE_USER_REJECT: - logd("User rejected enabling p2p"); - sendP2pStateChangedBroadcast(false); - transitionTo(mP2pDisabledState); - break; - case WifiP2pManager.ENABLE_P2P: - case WifiP2pManager.DISABLE_P2P: - deferMessage(message); - break; - default: - return NOT_HANDLED; - } - return HANDLED; - } - } - - class WaitForWifiDisableState extends State { - @Override - public void enter() { - if (DBG) logd(getName()); - } - - @Override - public boolean processMessage(Message message) { - if (DBG) logd(getName() + message.toString()); - switch (message.what) { - case WifiStateMachine.P2P_ENABLE_PROCEED: + case WifiStateMachine.CMD_ENABLE_P2P: try { - mNwService.wifiFirmwareReload(mInterface, "P2P"); - } catch (Exception e) { - loge("Failed to reload p2p firmware " + e); - // continue - } - - //A runtime crash can leave the interface up and - //this affects p2p when supplicant starts up. - //Ensure interface is down before a supplicant start. - try { - mNwService.setInterfaceDown(mInterface); - } catch (Exception e) { - if (DBG) Slog.w(TAG, "Unable to bring down wlan interface: " + e); - } - - if (mWifiNative.startP2pSupplicant()) { - mWifiMonitor.startMonitoring(); - transitionTo(mP2pEnablingState); - } else { - notifyP2pEnableFailure(); - transitionTo(mP2pDisabledState); + mNwService.setInterfaceUp(mInterface); + } catch (RemoteException re) { + loge("Unable to change interface settings: " + re); + } catch (IllegalStateException ie) { + loge("Unable to change interface settings: " + ie); } + mWifiMonitor.startMonitoring(); + transitionTo(mP2pEnablingState); break; - case WifiP2pManager.ENABLE_P2P: - case WifiP2pManager.DISABLE_P2P: - deferMessage(message); + case WifiStateMachine.CMD_DISABLE_P2P: + //Nothing to do break; default: return NOT_HANDLED; @@ -626,22 +447,15 @@ public class WifiP2pService extends IWifiP2pManager.Stub { if (DBG) logd(getName() + message.toString()); switch (message.what) { case WifiMonitor.SUP_CONNECTION_EVENT: - logd("P2p start successful"); + if (DBG) logd("P2p socket connection successful"); transitionTo(mInactiveState); break; case WifiMonitor.SUP_DISCONNECTION_EVENT: - if (++mP2pRestartCount <= P2P_RESTART_TRIES) { - loge("Failed to start p2p, retry"); - mWifiNative.killSupplicant(); - sendMessageDelayed(WifiP2pManager.ENABLE_P2P, P2P_RESTART_INTERVAL_MSECS); - } else { - loge("Failed " + mP2pRestartCount + " times to start p2p, quit "); - mP2pRestartCount = 0; - } + loge("P2p socket connection failed"); transitionTo(mP2pDisabledState); break; - case WifiP2pManager.ENABLE_P2P: - case WifiP2pManager.DISABLE_P2P: + case WifiStateMachine.CMD_ENABLE_P2P: + case WifiStateMachine.CMD_DISABLE_P2P: deferMessage(message); break; default: @@ -658,30 +472,36 @@ public class WifiP2pService extends IWifiP2pManager.Stub { sendP2pStateChangedBroadcast(true); mNetworkInfo.setIsAvailable(true); initializeP2pSettings(); - showNotification(); } @Override public boolean processMessage(Message message) { if (DBG) logd(getName() + message.toString()); switch (message.what) { - case WifiP2pManager.ENABLE_P2P: - replyToMessage(message, WifiP2pManager.ENABLE_P2P_SUCCEEDED); + case WifiStateMachine.CMD_ENABLE_P2P: + //Nothing to do break; - case WifiP2pManager.DISABLE_P2P: + case WifiStateMachine.CMD_DISABLE_P2P: if (mPeers.clear()) sendP2pPeersChangedBroadcast(); - replyToMessage(message, WifiP2pManager.DISABLE_P2P_SUCCEEDED); + mWifiNative.closeSupplicantConnection(); transitionTo(mP2pDisablingState); break; case WifiP2pManager.DISCOVER_PEERS: - int timeout = message.arg1; - if (mWifiNative.p2pFind(timeout)) { + if (mWifiNative.p2pFind(DISCOVER_TIMEOUT_S)) { replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_SUCCEEDED); } else { replyToMessage(message, WifiP2pManager.DISCOVER_PEERS_FAILED, WifiP2pManager.ERROR); } break; + case WifiP2pManager.STOP_DISCOVERY: + if (mWifiNative.p2pStopFind()) { + replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_SUCCEEDED); + } else { + replyToMessage(message, WifiP2pManager.STOP_DISCOVERY_FAILED, + WifiP2pManager.ERROR); + } + break; case WifiMonitor.P2P_DEVICE_FOUND_EVENT: WifiP2pDevice device = (WifiP2pDevice) message.obj; if (mThisDevice.deviceAddress.equals(device.deviceAddress)) break; @@ -692,15 +512,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { device = (WifiP2pDevice) message.obj; if (mPeers.remove(device)) sendP2pPeersChangedBroadcast(); break; - case WifiMonitor.SUP_DISCONNECTION_EVENT: /* Supplicant died */ - loge("Connection lost, restart p2p"); - mWifiNative.killSupplicant(); - mWifiNative.closeSupplicantConnection(); - if (mPeers.clear()) sendP2pPeersChangedBroadcast(); - transitionTo(mP2pDisabledState); - sendMessageDelayed(WifiP2pManager.ENABLE_P2P, P2P_RESTART_INTERVAL_MSECS); - break; - default: + default: return NOT_HANDLED; } return HANDLED; @@ -710,7 +522,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub { public void exit() { sendP2pStateChangedBroadcast(false); mNetworkInfo.setIsAvailable(false); - clearNotification(); } } @@ -719,7 +530,8 @@ public class WifiP2pService extends IWifiP2pManager.Stub { public void enter() { if (DBG) logd(getName()); //Start listening every time we get inactive - mWifiNative.p2pListen(); + //TODO: Fix listen after driver behavior is fixed + //mWifiNative.p2pListen(); } @Override @@ -737,6 +549,8 @@ public class WifiP2pService extends IWifiP2pManager.Stub { //TODO: if failure, remove config and do a regular p2pConnect() mWifiNative.p2pReinvoke(netId, mSavedPeerConfig.deviceAddress); } else { + //Stop discovery before issuing connect + mWifiNative.p2pStopFind(); //If peer is a GO, we do not need to send provisional discovery, //the supplicant takes care of it. if (isGroupOwner(mSavedPeerConfig.deviceAddress)) { @@ -1114,7 +928,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub { } // Do the regular device lost handling return NOT_HANDLED; - case WifiP2pManager.DISABLE_P2P: + case WifiStateMachine.CMD_DISABLE_P2P: sendMessage(WifiP2pManager.REMOVE_GROUP); deferMessage(message); break; @@ -1494,54 +1308,5 @@ public class WifiP2pService extends IWifiP2pManager.Stub { Slog.e(TAG, s); } - private void showNotification() { - NotificationManager notificationManager = - (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE); - if (notificationManager == null || mNotification != null) { - return; - } - - Intent intent = new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS); - intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY); - - PendingIntent pi = PendingIntent.getActivity(mContext, 0, intent, 0); - - Resources r = Resources.getSystem(); - CharSequence title = r.getText(R.string.wifi_p2p_enabled_notification_title); - CharSequence message = r.getText(R.string.wifi_p2p_enabled_notification_message); - - mNotification = new Notification(); - mNotification.when = 0; - //TODO: might change to be a seperate icon - mNotification.icon = R.drawable.stat_sys_tether_wifi; - mNotification.defaults &= ~Notification.DEFAULT_SOUND; - mNotification.flags = Notification.FLAG_ONGOING_EVENT; - mNotification.tickerText = title; - mNotification.setLatestEventInfo(mContext, title, message, pi); - - notificationManager.notify(mNotification.icon, mNotification); - } - - private void clearNotification() { - NotificationManager notificationManager = - (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE); - if (notificationManager != null && mNotification != null) { - notificationManager.cancel(mNotification.icon); - mNotification = null; - } - } - - private boolean isAirplaneSensitive() { - String airplaneModeRadios = Settings.System.getString(mContext.getContentResolver(), - Settings.System.AIRPLANE_MODE_RADIOS); - return airplaneModeRadios == null - || airplaneModeRadios.contains(Settings.System.RADIO_WIFI); - } - - private boolean isAirplaneModeOn() { - return isAirplaneSensitive() && Settings.System.getInt(mContext.getContentResolver(), - Settings.System.AIRPLANE_MODE_ON, 0) == 1; - } - } }