Merge "P2p enhancements"
This commit is contained in:
@@ -260,11 +260,18 @@ public class ConnectivityManager {
|
||||
*/
|
||||
public static final int TYPE_MOBILE_CBS = 12;
|
||||
|
||||
/** {@hide} */
|
||||
public static final int MAX_RADIO_TYPE = TYPE_MOBILE_CBS;
|
||||
/**
|
||||
* A Wi-Fi p2p connection. Only requesting processes will have access to
|
||||
* the peers connected.
|
||||
* {@hide}
|
||||
*/
|
||||
public static final int TYPE_WIFI_P2P = 13;
|
||||
|
||||
/** {@hide} */
|
||||
public static final int MAX_NETWORK_TYPE = TYPE_MOBILE_CBS;
|
||||
public static final int MAX_RADIO_TYPE = TYPE_WIFI_P2P;
|
||||
|
||||
/** {@hide} */
|
||||
public static final int MAX_NETWORK_TYPE = TYPE_WIFI_P2P;
|
||||
|
||||
public static final int DEFAULT_NETWORK_PREFERENCE = TYPE_WIFI;
|
||||
|
||||
@@ -303,6 +310,8 @@ public class ConnectivityManager {
|
||||
return "MOBILE_IMS";
|
||||
case TYPE_MOBILE_CBS:
|
||||
return "MOBILE_CBS";
|
||||
case TYPE_WIFI_P2P:
|
||||
return "WIFI_P2P";
|
||||
default:
|
||||
return Integer.toString(type);
|
||||
}
|
||||
|
||||
@@ -100,7 +100,8 @@ public class DhcpInfoInternal {
|
||||
if (TextUtils.isEmpty(dns1) == false) {
|
||||
p.addDns(NetworkUtils.numericToInetAddress(dns1));
|
||||
} else {
|
||||
Log.d(TAG, "makeLinkProperties with empty dns1!");
|
||||
p.addDns(NetworkUtils.numericToInetAddress(serverAddress));
|
||||
Log.d(TAG, "empty dns1, use dhcp server as dns1!");
|
||||
}
|
||||
if (TextUtils.isEmpty(dns2) == false) {
|
||||
p.addDns(NetworkUtils.numericToInetAddress(dns2));
|
||||
|
||||
@@ -116,6 +116,7 @@
|
||||
<item>"mobile_fota,10,0,2,60000,true"</item>
|
||||
<item>"mobile_ims,11,0,2,60000,true"</item>
|
||||
<item>"mobile_cbs,12,0,2,60000,true"</item>
|
||||
<item>"wifi_p2p,13,1,0,-1,true"</item>
|
||||
</string-array>
|
||||
|
||||
<!-- Array of ConnectivityManager.TYPE_xxxx constants for networks that may only
|
||||
|
||||
@@ -468,14 +468,10 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
for (int netType : mPriorityList) {
|
||||
switch (mNetConfigs[netType].radio) {
|
||||
case ConnectivityManager.TYPE_WIFI:
|
||||
if (DBG) log("Starting Wifi Service.");
|
||||
WifiStateTracker wst = new WifiStateTracker();
|
||||
WifiService wifiService = new WifiService(context);
|
||||
ServiceManager.addService(Context.WIFI_SERVICE, wifiService);
|
||||
wifiService.checkAndStartWifi();
|
||||
mNetTrackers[ConnectivityManager.TYPE_WIFI] = wst;
|
||||
wst.startMonitoring(context, mHandler);
|
||||
break;
|
||||
mNetTrackers[netType] = new WifiStateTracker(netType,
|
||||
mNetConfigs[netType].name);
|
||||
mNetTrackers[netType].startMonitoring(context, mHandler);
|
||||
break;
|
||||
case ConnectivityManager.TYPE_MOBILE:
|
||||
mNetTrackers[netType] = new MobileDataStateTracker(netType,
|
||||
mNetConfigs[netType].name);
|
||||
@@ -882,15 +878,8 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
|
||||
FeatureUser f = new FeatureUser(networkType, feature, binder);
|
||||
|
||||
// TODO - move this into the MobileDataStateTracker
|
||||
int usedNetworkType = networkType;
|
||||
if(networkType == ConnectivityManager.TYPE_MOBILE) {
|
||||
usedNetworkType = convertFeatureToNetworkType(feature);
|
||||
if (usedNetworkType < 0) {
|
||||
loge("Can't match any netTracker!");
|
||||
usedNetworkType = networkType;
|
||||
}
|
||||
}
|
||||
// TODO - move this into individual networktrackers
|
||||
int usedNetworkType = convertFeatureToNetworkType(networkType, feature);
|
||||
|
||||
if (mProtectedNetworks.contains(usedNetworkType)) {
|
||||
enforceConnectivityInternalPermission();
|
||||
@@ -900,7 +889,6 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
if (network != null) {
|
||||
Integer currentPid = new Integer(getCallingPid());
|
||||
if (usedNetworkType != networkType) {
|
||||
NetworkStateTracker radio = mNetTrackers[networkType];
|
||||
NetworkInfo ni = network.getNetworkInfo();
|
||||
|
||||
if (ni.isAvailable() == false) {
|
||||
@@ -1046,14 +1034,9 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO - move to MobileDataStateTracker
|
||||
int usedNetworkType = networkType;
|
||||
if (networkType == ConnectivityManager.TYPE_MOBILE) {
|
||||
usedNetworkType = convertFeatureToNetworkType(feature);
|
||||
if (usedNetworkType < 0) {
|
||||
usedNetworkType = networkType;
|
||||
}
|
||||
}
|
||||
// TODO - move to individual network trackers
|
||||
int usedNetworkType = convertFeatureToNetworkType(networkType, feature);
|
||||
|
||||
tracker = mNetTrackers[usedNetworkType];
|
||||
if (tracker == null) {
|
||||
if (DBG) log("ignoring - no known tracker for net type " + usedNetworkType);
|
||||
@@ -2672,25 +2655,38 @@ public class ConnectivityService extends IConnectivityManager.Stub {
|
||||
Slog.e(TAG, s);
|
||||
}
|
||||
|
||||
int convertFeatureToNetworkType(String feature){
|
||||
int networkType = -1;
|
||||
if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) {
|
||||
networkType = ConnectivityManager.TYPE_MOBILE_MMS;
|
||||
} else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) {
|
||||
networkType = ConnectivityManager.TYPE_MOBILE_SUPL;
|
||||
} else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN) ||
|
||||
TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN_ALWAYS)) {
|
||||
networkType = ConnectivityManager.TYPE_MOBILE_DUN;
|
||||
} else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_HIPRI)) {
|
||||
networkType = ConnectivityManager.TYPE_MOBILE_HIPRI;
|
||||
} else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_FOTA)) {
|
||||
networkType = ConnectivityManager.TYPE_MOBILE_FOTA;
|
||||
} else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_IMS)) {
|
||||
networkType = ConnectivityManager.TYPE_MOBILE_IMS;
|
||||
} else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_CBS)) {
|
||||
networkType = ConnectivityManager.TYPE_MOBILE_CBS;
|
||||
int convertFeatureToNetworkType(int networkType, String feature) {
|
||||
int usedNetworkType = networkType;
|
||||
|
||||
if(networkType == ConnectivityManager.TYPE_MOBILE) {
|
||||
if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_MMS)) {
|
||||
usedNetworkType = ConnectivityManager.TYPE_MOBILE_MMS;
|
||||
} else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_SUPL)) {
|
||||
usedNetworkType = ConnectivityManager.TYPE_MOBILE_SUPL;
|
||||
} else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN) ||
|
||||
TextUtils.equals(feature, Phone.FEATURE_ENABLE_DUN_ALWAYS)) {
|
||||
usedNetworkType = ConnectivityManager.TYPE_MOBILE_DUN;
|
||||
} else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_HIPRI)) {
|
||||
usedNetworkType = ConnectivityManager.TYPE_MOBILE_HIPRI;
|
||||
} else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_FOTA)) {
|
||||
usedNetworkType = ConnectivityManager.TYPE_MOBILE_FOTA;
|
||||
} else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_IMS)) {
|
||||
usedNetworkType = ConnectivityManager.TYPE_MOBILE_IMS;
|
||||
} else if (TextUtils.equals(feature, Phone.FEATURE_ENABLE_CBS)) {
|
||||
usedNetworkType = ConnectivityManager.TYPE_MOBILE_CBS;
|
||||
} else {
|
||||
Slog.e(TAG, "Can't match any mobile netTracker!");
|
||||
}
|
||||
} else if (networkType == ConnectivityManager.TYPE_WIFI) {
|
||||
if (TextUtils.equals(feature, "p2p")) {
|
||||
usedNetworkType = ConnectivityManager.TYPE_WIFI_P2P;
|
||||
} else {
|
||||
Slog.e(TAG, "Can't match any wifi netTracker!");
|
||||
}
|
||||
} else {
|
||||
Slog.e(TAG, "Unexpected network type");
|
||||
}
|
||||
return networkType;
|
||||
return usedNetworkType;
|
||||
}
|
||||
|
||||
private static <T> T checkNotNull(T value, String message) {
|
||||
|
||||
@@ -110,6 +110,7 @@ class ServerThread extends Thread {
|
||||
NetworkPolicyManagerService networkPolicy = null;
|
||||
ConnectivityService connectivity = null;
|
||||
WifiP2pService wifiP2p = null;
|
||||
WifiService wifi = null;
|
||||
IPackageManager pm = null;
|
||||
Context context = null;
|
||||
WindowManagerService wm = null;
|
||||
@@ -309,6 +310,15 @@ class ServerThread extends Thread {
|
||||
Slog.e(TAG, "Failure starting Wi-Fi P2pService", e);
|
||||
}
|
||||
|
||||
try {
|
||||
Slog.i(TAG, "Wi-Fi Service");
|
||||
wifi = new WifiService(context);
|
||||
ServiceManager.addService(Context.WIFI_SERVICE, wifi);
|
||||
wifi.checkAndStartWifi();
|
||||
} catch (Throwable e) {
|
||||
Slog.e(TAG, "Failure starting Wi-Fi Service", e);
|
||||
}
|
||||
|
||||
try {
|
||||
Slog.i(TAG, "Connectivity Service");
|
||||
connectivity = new ConnectivityService(context, networkManagement, networkPolicy);
|
||||
|
||||
@@ -27,6 +27,7 @@ import android.net.LinkCapabilities;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.NetworkStateTracker;
|
||||
import android.net.wifi.p2p.WifiP2pManager;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
|
||||
@@ -58,8 +59,8 @@ public class WifiStateTracker implements NetworkStateTracker {
|
||||
private BroadcastReceiver mWifiStateReceiver;
|
||||
private WifiManager mWifiManager;
|
||||
|
||||
public WifiStateTracker() {
|
||||
mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI, 0, NETWORKTYPE, "");
|
||||
public WifiStateTracker(int netType, String networkName) {
|
||||
mNetworkInfo = new NetworkInfo(netType, 0, networkName, "");
|
||||
mLinkProperties = new LinkProperties();
|
||||
mLinkCapabilities = new LinkCapabilities();
|
||||
|
||||
@@ -87,6 +88,7 @@ public class WifiStateTracker implements NetworkStateTracker {
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
|
||||
filter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);
|
||||
filter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
|
||||
|
||||
mWifiStateReceiver = new WifiStateReceiver();
|
||||
mContext.registerReceiver(mWifiStateReceiver, filter);
|
||||
@@ -104,7 +106,6 @@ public class WifiStateTracker implements NetworkStateTracker {
|
||||
|
||||
/**
|
||||
* Re-enable connectivity to a network after a {@link #teardown()}.
|
||||
* TODO: do away with return value after making MobileDataStateTracker async
|
||||
*/
|
||||
public boolean reconnect() {
|
||||
mTeardownRequested.set(false);
|
||||
@@ -115,7 +116,6 @@ public class WifiStateTracker implements NetworkStateTracker {
|
||||
/**
|
||||
* Turn the wireless radio off for a network.
|
||||
* @param turnOn {@code true} to turn the radio on, {@code false}
|
||||
* TODO: do away with return value after making MobileDataStateTracker async
|
||||
*/
|
||||
public boolean setRadio(boolean turnOn) {
|
||||
mWifiManager.setWifiEnabled(turnOn);
|
||||
@@ -205,7 +205,21 @@ public class WifiStateTracker implements NetworkStateTracker {
|
||||
private class WifiStateReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
|
||||
|
||||
if (intent.getAction().equals(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION)) {
|
||||
mNetworkInfo = (NetworkInfo) intent.getParcelableExtra(
|
||||
WifiP2pManager.EXTRA_NETWORK_INFO);
|
||||
mLinkProperties = intent.getParcelableExtra(
|
||||
WifiP2pManager.EXTRA_LINK_PROPERTIES);
|
||||
if (mLinkProperties == null) {
|
||||
mLinkProperties = new LinkProperties();
|
||||
}
|
||||
mLinkCapabilities = intent.getParcelableExtra(
|
||||
WifiP2pManager.EXTRA_LINK_CAPABILITIES);
|
||||
if (mLinkCapabilities == null) {
|
||||
mLinkCapabilities = new LinkCapabilities();
|
||||
}
|
||||
} else if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
|
||||
mNetworkInfo = (NetworkInfo) intent.getParcelableExtra(
|
||||
WifiManager.EXTRA_NETWORK_INFO);
|
||||
mLinkProperties = intent.getParcelableExtra(
|
||||
|
||||
@@ -19,13 +19,17 @@ package android.net.wifi.p2p;
|
||||
import android.annotation.SdkConstant;
|
||||
import android.annotation.SdkConstant.SdkConstantType;
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.IConnectivityManager;
|
||||
import android.os.Binder;
|
||||
import android.os.IBinder;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.WorkSource;
|
||||
import android.os.Messenger;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.util.AsyncChannel;
|
||||
import com.android.internal.util.Protocol;
|
||||
@@ -97,6 +101,22 @@ public class WifiP2pManager {
|
||||
*/
|
||||
public static final String EXTRA_NETWORK_INFO = "networkInfo";
|
||||
|
||||
/**
|
||||
* The lookup key for a {@link android.net.LinkProperties} object associated with the
|
||||
* network. Retrieve with
|
||||
* {@link android.content.Intent#getParcelableExtra(String)}.
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_LINK_PROPERTIES = "linkProperties";
|
||||
|
||||
/**
|
||||
* The lookup key for a {@link android.net.LinkCapabilities} object associated with the
|
||||
* network. Retrieve with
|
||||
* {@link android.content.Intent#getParcelableExtra(String)}.
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_LINK_CAPABILITIES = "linkCapabilities";
|
||||
|
||||
/**
|
||||
* Broadcast intent action indicating that the available peer list has changed
|
||||
*/
|
||||
@@ -115,9 +135,6 @@ public class WifiP2pManager {
|
||||
|
||||
IWifiP2pManager mService;
|
||||
|
||||
/* For communication with WifiP2pService */
|
||||
private AsyncChannel mAsyncChannel = new AsyncChannel();
|
||||
|
||||
/* AsyncChannel notifications to apps */
|
||||
public static final int HANDLER_CONNECTION = AsyncChannel.CMD_CHANNEL_HALF_CONNECTED;
|
||||
public static final int HANDLER_DISCONNECTION = AsyncChannel.CMD_CHANNEL_DISCONNECTED;
|
||||
@@ -194,18 +211,35 @@ public class WifiP2pManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the application handler with the Wi-Fi framework.
|
||||
* This function must be the first to be called before any p2p control
|
||||
* or query operations can be performed.
|
||||
* A channel that connects the application handler to the Wifi framework.
|
||||
* All p2p operations are performed on a channel.
|
||||
*/
|
||||
public class Channel {
|
||||
Channel(AsyncChannel c) {
|
||||
mAsyncChannel = c;
|
||||
}
|
||||
AsyncChannel mAsyncChannel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the application handler with the Wi-Fi framework. This function
|
||||
* must be the first to be called before any p2p control or query operations can be performed.
|
||||
* @param srcContext is the context of the source
|
||||
* @param srcHandler is the handler on which the source receives messages
|
||||
* @return {@code true} if the operation succeeded
|
||||
* @return Channel instance that is necessary for performing p2p operations
|
||||
*/
|
||||
public boolean connectHandler(Context srcContext, Handler srcHandler) {
|
||||
public Channel initialize(Context srcContext, Handler srcHandler) {
|
||||
Messenger messenger = getMessenger();
|
||||
if (messenger == null) return false;
|
||||
return mAsyncChannel.connectSync(srcContext, srcHandler, messenger)
|
||||
== AsyncChannel.STATUS_SUCCESSFUL;
|
||||
if (messenger == null) return null;
|
||||
|
||||
AsyncChannel asyncChannel = new AsyncChannel();
|
||||
Channel c = new Channel(asyncChannel);
|
||||
if (asyncChannel.connectSync(srcContext, srcHandler, messenger)
|
||||
== AsyncChannel.STATUS_SUCCESSFUL) {
|
||||
return c;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isP2pSupported() {
|
||||
@@ -220,16 +254,18 @@ 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.
|
||||
*/
|
||||
public void enableP2p() {
|
||||
mAsyncChannel.sendMessage(ENABLE_P2P);
|
||||
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.
|
||||
*/
|
||||
public void disableP2p() {
|
||||
mAsyncChannel.sendMessage(DISABLE_P2P);
|
||||
public void disableP2p(Channel c) {
|
||||
if (c == null) return;
|
||||
c.mAsyncChannel.sendMessage(DISABLE_P2P);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -238,29 +274,33 @@ public class WifiP2pManager {
|
||||
* A dialog to the user is thrown to request his permission since it can
|
||||
* have a significant impact on power consumption
|
||||
*/
|
||||
public void setListenState(int timeout) {
|
||||
mAsyncChannel.sendMessage(START_LISTEN_MODE, timeout);
|
||||
public void setListenState(Channel c, int timeout) {
|
||||
if (c == null) return;
|
||||
c.mAsyncChannel.sendMessage(START_LISTEN_MODE, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiates peer discovery
|
||||
*/
|
||||
public void discoverPeers() {
|
||||
mAsyncChannel.sendMessage(DISCOVER_PEERS);
|
||||
public void discoverPeers(Channel c) {
|
||||
if (c == null) return;
|
||||
c.mAsyncChannel.sendMessage(DISCOVER_PEERS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiates peer discovery with a timeout
|
||||
*/
|
||||
public void discoverPeers(int timeout) {
|
||||
mAsyncChannel.sendMessage(DISCOVER_PEERS, timeout);
|
||||
public void discoverPeers(Channel c, int timeout) {
|
||||
if (c == null) return;
|
||||
c.mAsyncChannel.sendMessage(DISCOVER_PEERS, timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel any existing peer discovery operation
|
||||
*/
|
||||
public void cancelPeerDiscovery() {
|
||||
mAsyncChannel.sendMessage(CANCEL_DISCOVER_PEERS);
|
||||
public void cancelPeerDiscovery(Channel c) {
|
||||
if (c == null) return;
|
||||
c.mAsyncChannel.sendMessage(CANCEL_DISCOVER_PEERS);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -268,47 +308,53 @@ public class WifiP2pManager {
|
||||
*
|
||||
* @param peer Configuration described in a {@link WifiP2pConfig} object.
|
||||
*/
|
||||
public void connect(WifiP2pConfig config) {
|
||||
mAsyncChannel.sendMessage(CONNECT, config);
|
||||
public void connect(Channel c, WifiP2pConfig config) {
|
||||
if (c == null) return;
|
||||
c.mAsyncChannel.sendMessage(CONNECT, config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel any ongoing negotiation or disconnect from an existing group
|
||||
*/
|
||||
public void disconnect() {
|
||||
mAsyncChannel.sendMessage(CANCEL_CONNECT);
|
||||
public void disconnect(Channel c) {
|
||||
if (c == null) return;
|
||||
c.mAsyncChannel.sendMessage(CANCEL_CONNECT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a p2p group. This is essentially an access point that can accept
|
||||
* client connections.
|
||||
*/
|
||||
public void createGroup() {
|
||||
mAsyncChannel.sendMessage(CREATE_GROUP);
|
||||
public void createGroup(Channel c) {
|
||||
if (c == null) return;
|
||||
c.mAsyncChannel.sendMessage(CREATE_GROUP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the current group. This also removes the p2p interface created
|
||||
* during group formation.
|
||||
*/
|
||||
public void removeGroup() {
|
||||
mAsyncChannel.sendMessage(REMOVE_GROUP);
|
||||
public void removeGroup(Channel c) {
|
||||
if (c == null) return;
|
||||
c.mAsyncChannel.sendMessage(REMOVE_GROUP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request current p2p settings. This returns a RESPONSE_SETTINGS on the source
|
||||
* handler.
|
||||
*/
|
||||
public void requestP2pSettings() {
|
||||
mAsyncChannel.sendMessage(REQUEST_SETTINGS);
|
||||
public void requestP2pSettings(Channel c) {
|
||||
if (c == null) return;
|
||||
c.mAsyncChannel.sendMessage(REQUEST_SETTINGS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the list of peers. This returns a RESPONSE_PEERS on the source
|
||||
* handler.
|
||||
*/
|
||||
public void requestPeers() {
|
||||
mAsyncChannel.sendMessage(REQUEST_PEERS);
|
||||
public void requestPeers(Channel c) {
|
||||
if (c == null) return;
|
||||
c.mAsyncChannel.sendMessage(REQUEST_PEERS);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -322,8 +368,9 @@ public class WifiP2pManager {
|
||||
* Request device connection status. This returns a RESPONSE_CONNECTION_STATUS on
|
||||
* the source handler.
|
||||
*/
|
||||
public void requestConnectionStatus() {
|
||||
mAsyncChannel.sendMessage(REQUEST_CONNECTION_STATUS);
|
||||
public void requestConnectionStatus(Channel c) {
|
||||
if (c == null) return;
|
||||
c.mAsyncChannel.sendMessage(REQUEST_CONNECTION_STATUS);
|
||||
}
|
||||
|
||||
|
||||
@@ -341,4 +388,38 @@ public class WifiP2pManager {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,6 +25,15 @@ import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Resources;
|
||||
import android.net.IConnectivityManager;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.DhcpInfoInternal;
|
||||
import android.net.DhcpStateMachine;
|
||||
import android.net.InterfaceConfiguration;
|
||||
import android.net.LinkAddress;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.NetworkInfo;
|
||||
import android.net.NetworkUtils;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.net.wifi.WifiMonitor;
|
||||
import android.net.wifi.WifiNative;
|
||||
@@ -47,16 +56,16 @@ import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.EditText;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Collection;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.util.AsyncChannel;
|
||||
import com.android.internal.util.Protocol;
|
||||
import com.android.internal.util.State;
|
||||
import com.android.internal.util.StateMachine;
|
||||
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* WifiP2pService inclues a state machine to perform Wi-Fi p2p operations. Applications
|
||||
* communicate with this service to issue device discovery and connectivity requests
|
||||
@@ -70,14 +79,16 @@ import com.android.internal.util.StateMachine;
|
||||
public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
private static final String TAG = "WifiP2pService";
|
||||
private static final boolean DBG = true;
|
||||
private static final String NETWORKTYPE = "WIFI_P2P";
|
||||
|
||||
private Context mContext;
|
||||
private String mInterface;
|
||||
|
||||
INetworkManagementService mNwService;
|
||||
private DhcpStateMachine mDhcpStateMachine;
|
||||
|
||||
// Tracked to notify the user about wifi client/hotspot being shut down
|
||||
// during p2p bring up
|
||||
//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;
|
||||
|
||||
@@ -85,6 +96,9 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
private AsyncChannel mReplyChannel = new AsyncChannel();;
|
||||
private AsyncChannel mWifiChannel;
|
||||
|
||||
private static final int GROUP_NEGOTIATION_WAIT_TIME_MS = 60 * 1000;
|
||||
private static int mGroupNegotiationTimeoutIndex = 0;
|
||||
|
||||
private static final int BASE = Protocol.BASE_WIFI_P2P_SERVICE;
|
||||
|
||||
/* Message sent to WifiStateMachine to indicate p2p enable is pending */
|
||||
@@ -92,15 +106,24 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
/* 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 of group negotiation */
|
||||
public static final int GROUP_NEGOTIATION_TIMED_OUT = BASE + 3;
|
||||
|
||||
/* User accepted to disable Wi-Fi in order to enable p2p */
|
||||
private static final int WIFI_DISABLE_USER_ACCEPT = BASE + 11;
|
||||
|
||||
private final boolean mP2pSupported;
|
||||
|
||||
private NetworkInfo mNetworkInfo;
|
||||
private LinkProperties mLinkProperties;
|
||||
|
||||
public WifiP2pService(Context context) {
|
||||
mContext = context;
|
||||
|
||||
mInterface = SystemProperties.get("wifi.interface", "wlan0");
|
||||
mNetworkInfo = new NetworkInfo(ConnectivityManager.TYPE_WIFI_P2P, 0, NETWORKTYPE, "");
|
||||
mLinkProperties = new LinkProperties();
|
||||
|
||||
mP2pSupported = mContext.getResources().getBoolean(
|
||||
com.android.internal.R.bool.config_wifi_p2p_support);
|
||||
|
||||
@@ -113,7 +136,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
filter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
|
||||
mContext.registerReceiver(new WifiStateReceiver(), filter);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void connectivityServiceReady() {
|
||||
IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
|
||||
@@ -300,6 +323,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
break;
|
||||
// Ignore
|
||||
case WIFI_DISABLE_USER_ACCEPT:
|
||||
case GROUP_NEGOTIATION_TIMED_OUT:
|
||||
break;
|
||||
default:
|
||||
Slog.e(TAG, "Unhandled message " + message);
|
||||
@@ -459,6 +483,10 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
WifiP2pManager.ENABLE_P2P_SUCCEEDED);
|
||||
transitionTo(mInactiveState);
|
||||
break;
|
||||
case WifiP2pManager.DISABLE_P2P:
|
||||
//TODO: fix
|
||||
WifiNative.killSupplicant();
|
||||
transitionTo(mP2pDisabledState);
|
||||
default:
|
||||
return NOT_HANDLED;
|
||||
}
|
||||
@@ -471,6 +499,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
public void enter() {
|
||||
if (DBG) Slog.d(TAG, getName());
|
||||
sendP2pStateChangedBroadcast(true);
|
||||
mNetworkInfo.setIsAvailable(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -526,6 +555,7 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
@Override
|
||||
public void exit() {
|
||||
sendP2pStateChangedBroadcast(false);
|
||||
mNetworkInfo.setIsAvailable(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -550,6 +580,8 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
WifiP2pGroup group = (WifiP2pGroup) message.obj;
|
||||
notifyP2pInvitationReceived(group);
|
||||
break;
|
||||
case WifiP2pManager.REQUEST_PEERS:
|
||||
return NOT_HANDLED;
|
||||
default:
|
||||
return NOT_HANDLED;
|
||||
}
|
||||
@@ -558,8 +590,11 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
}
|
||||
|
||||
class GroupNegotiationState extends State {
|
||||
@Override public void enter() {
|
||||
@Override
|
||||
public void enter() {
|
||||
if (DBG) Slog.d(TAG, getName());
|
||||
sendMessageDelayed(obtainMessage(GROUP_NEGOTIATION_TIMED_OUT,
|
||||
++mGroupNegotiationTimeoutIndex, 0), GROUP_NEGOTIATION_WAIT_TIME_MS);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -582,18 +617,29 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
case WifiMonitor.P2P_GROUP_STARTED_EVENT:
|
||||
mGroup = (WifiP2pGroup) message.obj;
|
||||
if (DBG) Slog.d(TAG, getName() + " group started");
|
||||
// If this device is GO, do nothing since there is a follow up
|
||||
// AP_STA_CONNECTED event
|
||||
if (!mGroup.isGroupOwner()) {
|
||||
if (mGroup.isGroupOwner()) {
|
||||
startDhcpServer(mGroup.getInterface());
|
||||
} else {
|
||||
mDhcpStateMachine = DhcpStateMachine.makeDhcpStateMachine(mContext,
|
||||
P2pStateMachine.this, mGroup.getInterface());
|
||||
mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_START_DHCP);
|
||||
WifiP2pDevice groupOwner = mGroup.getOwner();
|
||||
updateDeviceStatus(groupOwner.deviceAddress, Status.CONNECTED);
|
||||
sendP2pPeersChangedBroadcast();
|
||||
}
|
||||
transitionTo(mGroupCreatedState);
|
||||
break;
|
||||
case WifiP2pManager.CANCEL_CONNECT:
|
||||
case WifiP2pManager.CANCEL_CONNECT:
|
||||
// TODO: fix
|
||||
break;
|
||||
case GROUP_NEGOTIATION_TIMED_OUT:
|
||||
if (mGroupNegotiationTimeoutIndex == message.arg1) {
|
||||
if (DBG) Slog.d(TAG, "Group negotiation timed out");
|
||||
updateDeviceStatus(mSavedConnectConfig.deviceAddress, Status.FAILED);
|
||||
mSavedConnectConfig = null;
|
||||
transitionTo(mInactiveState);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return NOT_HANDLED;
|
||||
}
|
||||
@@ -605,6 +651,11 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
@Override
|
||||
public void enter() {
|
||||
if (DBG) Slog.d(TAG, getName());
|
||||
mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, null, null);
|
||||
|
||||
if (mGroup.isGroupOwner()) {
|
||||
sendP2pConnectionChangedBroadcast();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -638,7 +689,16 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
}
|
||||
if (DBG) Slog.e(TAG, getName() + " ap sta disconnected");
|
||||
break;
|
||||
// Disconnect & remove group have same effect when connected
|
||||
case DhcpStateMachine.CMD_POST_DHCP_ACTION:
|
||||
DhcpInfoInternal dhcpInfo = (DhcpInfoInternal) message.obj;
|
||||
if (DBG) Slog.d(TAG, "DhcpInfo: " + dhcpInfo);
|
||||
if (dhcpInfo != null) {
|
||||
mLinkProperties = dhcpInfo.makeLinkProperties();
|
||||
mLinkProperties.setInterfaceName(mGroup.getInterface());
|
||||
sendP2pConnectionChangedBroadcast();
|
||||
}
|
||||
break;
|
||||
//disconnect & remove group have same effect when connected
|
||||
case WifiP2pManager.CANCEL_CONNECT:
|
||||
case WifiP2pManager.REMOVE_GROUP:
|
||||
if (DBG) Slog.e(TAG, getName() + " remove group");
|
||||
@@ -655,6 +715,16 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (mGroup.isGroupOwner()) {
|
||||
stopDhcpServer();
|
||||
} else {
|
||||
if (DBG) Slog.d(TAG, "stop DHCP client");
|
||||
mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
|
||||
mDhcpStateMachine.quit();
|
||||
mDhcpStateMachine = null;
|
||||
}
|
||||
|
||||
mGroup = null;
|
||||
if (changed) sendP2pPeersChangedBroadcast();
|
||||
transitionTo(mInactiveState);
|
||||
@@ -663,10 +733,12 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
WifiP2pDevice device = (WifiP2pDevice) message.obj;
|
||||
if (device.equals(mGroup.getOwner())) {
|
||||
Slog.d(TAG, "Lost the group owner, killing p2p connection");
|
||||
sendMessage(WifiP2pManager.REMOVE_GROUP);
|
||||
WifiNative.p2pFlush();
|
||||
WifiNative.p2pGroupRemove(mGroup.getInterface());
|
||||
} else if (mGroup.removeClient(device) && mGroup.isClientListEmpty()) {
|
||||
Slog.d(TAG, "Client list empty, killing p2p connection");
|
||||
sendMessage(WifiP2pManager.REMOVE_GROUP);
|
||||
WifiNative.p2pFlush();
|
||||
WifiNative.p2pGroupRemove(mGroup.getInterface());
|
||||
}
|
||||
return NOT_HANDLED; // Do the regular device lost handling
|
||||
case WifiP2pManager.DISABLE_P2P:
|
||||
@@ -705,6 +777,10 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
}
|
||||
return HANDLED;
|
||||
}
|
||||
|
||||
public void exit() {
|
||||
mNetworkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendP2pStateChangedBroadcast(boolean enabled) {
|
||||
@@ -726,6 +802,55 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
mContext.sendBroadcast(intent);
|
||||
}
|
||||
|
||||
private void sendP2pConnectionChangedBroadcast() {
|
||||
if (DBG) Slog.d(TAG, "sending p2p connection changed broadcast");
|
||||
Intent intent = new Intent(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
|
||||
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
|
||||
| Intent.FLAG_RECEIVER_REPLACE_PENDING);
|
||||
intent.putExtra(WifiP2pManager.EXTRA_NETWORK_INFO, new NetworkInfo(mNetworkInfo));
|
||||
intent.putExtra(WifiP2pManager.EXTRA_LINK_PROPERTIES,
|
||||
new LinkProperties (mLinkProperties));
|
||||
mContext.sendStickyBroadcast(intent);
|
||||
}
|
||||
|
||||
private void startDhcpServer(String intf) {
|
||||
/* Is chosen as a unique range to avoid conflict with
|
||||
the range defined in Tethering.java */
|
||||
String[] dhcp_range = {"192.168.49.2", "192.168.49.254"};
|
||||
String serverAddress = "192.168.49.1";
|
||||
|
||||
mLinkProperties.clear();
|
||||
mLinkProperties.setInterfaceName(mGroup.getInterface());
|
||||
|
||||
InterfaceConfiguration ifcg = null;
|
||||
try {
|
||||
ifcg = mNwService.getInterfaceConfig(intf);
|
||||
ifcg.addr = new LinkAddress(NetworkUtils.numericToInetAddress(
|
||||
serverAddress), 24);
|
||||
ifcg.interfaceFlags = "[up]";
|
||||
mNwService.setInterfaceConfig(intf, ifcg);
|
||||
/* This starts the dnsmasq server */
|
||||
mNwService.startTethering(dhcp_range);
|
||||
} catch (Exception e) {
|
||||
Slog.e(TAG, "Error configuring interface " + intf + ", :" + e);
|
||||
return;
|
||||
}
|
||||
|
||||
mLinkProperties.addDns(NetworkUtils.numericToInetAddress(serverAddress));
|
||||
Slog.d(TAG, "Started Dhcp server on " + intf);
|
||||
}
|
||||
|
||||
private void stopDhcpServer() {
|
||||
try {
|
||||
mNwService.stopTethering();
|
||||
} catch (Exception e) {
|
||||
Slog.e(TAG, "Error stopping Dhcp server" + e);
|
||||
return;
|
||||
}
|
||||
|
||||
Slog.d(TAG, "Stopped Dhcp server");
|
||||
}
|
||||
|
||||
private void notifyP2pEnableFailure() {
|
||||
Resources r = Resources.getSystem();
|
||||
AlertDialog dialog = new AlertDialog.Builder(mContext)
|
||||
@@ -760,11 +885,16 @@ public class WifiP2pService extends IWifiP2pManager.Stub {
|
||||
.setView(textEntryView)
|
||||
.setPositiveButton(r.getString(R.string.ok), new OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (DBG) Slog.d(TAG, getName() + " connect " + pin.getText());
|
||||
if (DBG) Slog.d(TAG, getName() + " connect " + pin.getText());
|
||||
|
||||
if (pin.getVisibility() == View.GONE) {
|
||||
mSavedGoNegotiationConfig.wpsConfig.setup = Setup.PBC;
|
||||
} else {
|
||||
mSavedGoNegotiationConfig.wpsConfig.setup = Setup.KEYPAD;
|
||||
mSavedGoNegotiationConfig.wpsConfig.pin = pin.getText().toString();
|
||||
sendMessage(WifiP2pManager.CONNECT, mSavedGoNegotiationConfig);
|
||||
mSavedGoNegotiationConfig = null;
|
||||
}
|
||||
sendMessage(WifiP2pManager.CONNECT, mSavedGoNegotiationConfig);
|
||||
mSavedGoNegotiationConfig = null;
|
||||
}
|
||||
})
|
||||
.setNegativeButton(r.getString(R.string.cancel), new OnClickListener() {
|
||||
|
||||
Reference in New Issue
Block a user