Merge "Initial support for concurrency"

This commit is contained in:
Irfan Sheriff
2012-02-14 15:37:07 -08:00
committed by Android (Google) Code Review
8 changed files with 129 additions and 450 deletions

View File

@@ -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 },

View File

@@ -2708,11 +2708,6 @@
<!-- Do not translate. Default access point SSID used for tethering -->
<string name="wifi_tether_configure_ssid_default" translatable="false">AndroidAP</string>
<!-- Wi-Fi p2p dialog title-->
<string name="wifi_p2p_dialog_title">Wi-Fi Direct</string>
<string name="wifi_p2p_turnon_message">Start Wi-Fi Direct. This will turn off Wi-Fi client/hotspot.</string>
<string name="wifi_p2p_failed_message">Couldn\'t start Wi-Fi Direct.</string>
<string name="accept">Accept</string>
<string name="decline">Decline</string>
<string name="wifi_p2p_invitation_sent_title">Invitation sent</string>
@@ -2723,9 +2718,6 @@
<string name="wifi_p2p_enter_pin_message">Type the required PIN: </string>
<string name="wifi_p2p_show_pin_message">PIN: </string>
<string name="wifi_p2p_enabled_notification_title">Wi-Fi Direct is on</string>
<string name="wifi_p2p_enabled_notification_message">Touch for settings</string>
<!-- Name of the dialog that lets the user choose an accented character to insert -->
<string name="select_character">Insert character</string>

View File

@@ -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

View File

@@ -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");
}

View File

@@ -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<ScanResult> 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<String> available;
ArrayList<String> 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);
@@ -1896,11 +1898,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;
@@ -2060,7 +2057,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);
@@ -2172,11 +2169,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;
@@ -2556,13 +2549,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;
@@ -2675,6 +2670,8 @@ public class WifiStateMachine extends StateMachine {
mIsRunning = false;
updateBatteryWorkSource(null);
mScanResults = null;
if (mP2pSupported) mWifiP2pChannel.sendMessage(WifiStateMachine.CMD_DISABLE_P2P);
}
}
@@ -3348,7 +3345,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:
@@ -3412,55 +3408,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;
}
@@ -3510,7 +3457,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:
@@ -3606,7 +3552,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:

View File

@@ -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;
}

View File

@@ -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.
*

View File

@@ -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;
}
}
}