diff options
author | Irfan Sheriff <isheriff@google.com> | 2012-07-02 15:58:28 -0700 |
---|---|---|
committer | Irfan Sheriff <isheriff@google.com> | 2012-07-24 13:34:36 -0700 |
commit | 88759bbd31e05a4163e1f8e72804ca83000afd53 (patch) | |
tree | f795fd767a7e3466624a6108fc308cc96d88f528 | |
parent | b10f455e4494de687634aed1e24fc8f7edff427a (diff) | |
download | frameworks_base-88759bbd31e05a4163e1f8e72804ca83000afd53.zip frameworks_base-88759bbd31e05a4163e1f8e72804ca83000afd53.tar.gz frameworks_base-88759bbd31e05a4163e1f8e72804ca83000afd53.tar.bz2 |
Update WifiManager API
Use feedback based on NSD to update WifiManager API
Change-Id: I0c1dc74f7e2fa7cd697a995b7194e3e0366d7981
5 files changed, 166 insertions, 198 deletions
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 4a75c05..0f1c36c 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -477,7 +477,7 @@ class ContextImpl extends Context { public Object createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(WIFI_SERVICE); IWifiManager service = IWifiManager.Stub.asInterface(b); - return new WifiManager(service, ctx.mMainThread.getHandler()); + return new WifiManager(ctx.getOuterContext(), service); }}); registerService(WIFI_P2P_SERVICE, new ServiceFetcher() { diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java index f01562c..6630601 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestActivity.java @@ -94,7 +94,6 @@ public class ConnectivityManagerTestActivity extends Activity { * Control Wifi States */ public WifiManager mWifiManager; - public WifiManager.Channel mChannel; /* * Verify connectivity state @@ -242,7 +241,6 @@ public class ConnectivityManagerTestActivity extends Activity { // Get an instance of WifiManager mWifiManager =(WifiManager)getSystemService(Context.WIFI_SERVICE); mContext = this; - mChannel = mWifiManager.initialize(mContext, mContext.getMainLooper(), null); if (mWifiManager.isWifiApEnabled()) { // if soft AP is enabled, disable it @@ -599,7 +597,7 @@ public class ConnectivityManagerTestActivity extends Activity { log("found " + ssid + " in the scan result list"); log("retry: " + retry); foundApInScanResults = true; - mWifiManager.connect(mChannel, config, + mWifiManager.connect(config, new WifiManager.ActionListener() { public void onSuccess() { } @@ -658,7 +656,7 @@ public class ConnectivityManagerTestActivity extends Activity { for (WifiConfiguration wifiConfig: wifiConfigList) { log("remove wifi configuration: " + wifiConfig.networkId); int netId = wifiConfig.networkId; - mWifiManager.forget(mChannel, netId, new WifiManager.ActionListener() { + mWifiManager.forget(netId, new WifiManager.ActionListener() { public void onSuccess() { } public void onFailure(int reason) { diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java index 8d73bc0..81075ef 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/WifiConnectionTest.java @@ -63,7 +63,6 @@ public class WifiConnectionTest private ConnectivityManagerTestActivity mAct; private ConnectivityManagerTestRunner mRunner; private WifiManager mWifiManager = null; - private WifiManager.Channel mChannel; private Set<WifiConfiguration> enabledNetworks = null; public WifiConnectionTest() { @@ -77,7 +76,6 @@ public class WifiConnectionTest mWifiManager = (WifiManager) mRunner.getContext().getSystemService(Context.WIFI_SERVICE); mAct = getActivity(); - mChannel = mWifiManager.initialize(mAct, mAct.getMainLooper(), null); networks = mAct.loadNetworkConfigurations(); if (DEBUG) { @@ -93,24 +91,6 @@ public class WifiConnectionTest assertTrue("wpa_supplicant is not started ", mAct.mWifiManager.pingSupplicant()); } - private class WifiServiceHandler extends Handler { - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: - if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { - //AsyncChannel in msg.obj - } else { - log("Failed to establish AsyncChannel connection"); - } - break; - default: - //Ignore - break; - } - } - } - private void printNetworkConfigurations() { log("==== print network configurations parsed from XML file ===="); log("number of access points: " + networks.size()); diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java index c3cc7c5..d5fcc1c 100644 --- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java +++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/util/ConnectionUtil.java @@ -74,7 +74,6 @@ public class ConnectionUtil { private int mWifiState; private NetworkInfo mWifiNetworkInfo; private WifiManager mWifiManager; - private WifiManager.Channel mChannel; private Context mContext; // Verify connectivity state private static final int NUM_NETWORK_TYPES = ConnectivityManager.MAX_NETWORK_TYPE + 1; @@ -115,7 +114,6 @@ public class ConnectionUtil { // Get an instance of WifiManager mWifiManager =(WifiManager)mContext.getSystemService(Context.WIFI_SERVICE); - mChannel = mWifiManager.initialize(mContext, mContext.getMainLooper(), null); mDownloadManager = (DownloadManager)mContext.getSystemService(Context.DOWNLOAD_SERVICE); @@ -574,7 +572,7 @@ public class ConnectionUtil { Log.v(LOG_TAG, "Found " + ssid + " in the scan result list."); Log.v(LOG_TAG, "Retry: " + retry); foundApInScanResults = true; - mWifiManager.connect(mChannel, config, new WifiManager.ActionListener() { + mWifiManager.connect(config, new WifiManager.ActionListener() { public void onSuccess() { } public void onFailure(int reason) { @@ -628,7 +626,7 @@ public class ConnectionUtil { for (WifiConfiguration wifiConfig: wifiConfigList) { Log.v(LOG_TAG, "Remove wifi configuration: " + wifiConfig.networkId); int netId = wifiConfig.networkId; - mWifiManager.forget(mChannel, netId, new WifiManager.ActionListener() { + mWifiManager.forget(netId, new WifiManager.ActionListener() { public void onSuccess() { } public void onFailure(int reason) { diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 36f38f9..6e58a2d 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -23,13 +23,17 @@ import android.net.DhcpInfo; import android.os.Binder; import android.os.IBinder; import android.os.Handler; +import android.os.HandlerThread; import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.WorkSource; import android.os.Messenger; +import android.util.Log; import android.util.SparseArray; +import java.util.concurrent.CountDownLatch; + import com.android.internal.util.AsyncChannel; import com.android.internal.util.Protocol; @@ -58,6 +62,7 @@ import java.util.List; */ public class WifiManager { + private static final String TAG = "WifiManager"; // Supplicant error codes: /** * The error code if there was a problem authenticating. @@ -481,9 +486,6 @@ public class WifiManager { /** @hide */ public static final int DATA_ACTIVITY_INOUT = 0x03; - IWifiManager mService; - Handler mHandler; - /* Maximum number of active locks we allow. * This limit was added to prevent apps from creating a ridiculous number * of locks and crashing the system by overflowing the global ref table. @@ -493,19 +495,33 @@ public class WifiManager { /* Number of currently active WifiLocks and MulticastLocks */ private int mActiveLockCount; + private Context mContext; + IWifiManager mService; + + private static final int INVALID_KEY = 0; + private int mListenerKey = 1; + private final SparseArray mListenerMap = new SparseArray(); + private final Object mListenerMapLock = new Object(); + + private AsyncChannel mAsyncChannel = new AsyncChannel(); + private ServiceHandler mHandler; + private Messenger mWifiServiceMessenger; + private final CountDownLatch mConnected = new CountDownLatch(1); + /** * Create a new WifiManager instance. * Applications will almost always want to use * {@link android.content.Context#getSystemService Context.getSystemService()} to retrieve * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}. + * @param context the application context * @param service the Binder interface - * @param handler target for messages * @hide - hide this because it takes in a parameter of type IWifiManager, which * is a system private class. */ - public WifiManager(IWifiManager service, Handler handler) { + public WifiManager(Context context, IWifiManager service) { + mContext = context; mService = service; - mHandler = handler; + init(); } /** @@ -1168,15 +1184,6 @@ public class WifiManager { /** WPS timed out {@hide} */ public static final int WPS_TIMED_OUT = 7; - /** Interface for callback invocation when framework channel is lost {@hide} */ - public interface ChannelListener { - /** - * The channel to the framework has been disconnected. - * Application could try re-initializing using {@link #initialize} - */ - public void onChannelDisconnected(); - } - /** Interface for callback invocation on an application action {@hide} */ public interface ActionListener { /** The operation succeeded */ @@ -1205,134 +1212,122 @@ public class WifiManager { public void onFailure(int reason); } - /** - * A channel that connects the application to the Wifi framework. - * Most operations require a Channel as an argument. An instance of Channel is obtained - * by doing a call on {@link #initialize} - * @hide - */ - public static class Channel { - Channel(Looper looper, ChannelListener l) { - mAsyncChannel = new AsyncChannel(); - mHandler = new WifiHandler(looper); - mChannelListener = l; + private class ServiceHandler extends Handler { + ServiceHandler(Looper looper) { + super(looper); } - private ChannelListener mChannelListener; - private SparseArray<Object> mListenerMap = new SparseArray<Object>(); - private Object mListenerMapLock = new Object(); - private int mListenerKey = 0; - private static final int INVALID_KEY = -1; - - AsyncChannel mAsyncChannel; - WifiHandler mHandler; - class WifiHandler extends Handler { - WifiHandler(Looper looper) { - super(looper); - } - @Override - public void handleMessage(Message message) { - Object listener = removeListener(message.arg2); - switch (message.what) { - case AsyncChannel.CMD_CHANNEL_DISCONNECTED: - if (mChannelListener != null) { - mChannelListener.onChannelDisconnected(); - mChannelListener = null; - } - break; - /* ActionListeners grouped together */ - case WifiManager.CONNECT_NETWORK_FAILED: - case WifiManager.FORGET_NETWORK_FAILED: - case WifiManager.SAVE_NETWORK_FAILED: - case WifiManager.CANCEL_WPS_FAILED: - case WifiManager.DISABLE_NETWORK_FAILED: - if (listener != null) { - ((ActionListener) listener).onFailure(message.arg1); - } - break; - /* ActionListeners grouped together */ - case WifiManager.CONNECT_NETWORK_SUCCEEDED: - case WifiManager.FORGET_NETWORK_SUCCEEDED: - case WifiManager.SAVE_NETWORK_SUCCEEDED: - case WifiManager.CANCEL_WPS_SUCCEDED: - case WifiManager.DISABLE_NETWORK_SUCCEEDED: - if (listener != null) { - ((ActionListener) listener).onSuccess(); - } - break; - case WifiManager.START_WPS_SUCCEEDED: - if (listener != null) { - WpsResult result = (WpsResult) message.obj; - ((WpsListener) listener).onStartSuccess(result.pin); - //Listener needs to stay until completion or failure - synchronized(mListenerMapLock) { - mListenerMap.put(message.arg2, listener); - } - } - break; - case WifiManager.WPS_COMPLETED: - if (listener != null) { - ((WpsListener) listener).onCompletion(); - } - break; - case WifiManager.WPS_FAILED: - if (listener != null) { - ((WpsListener) listener).onFailure(message.arg1); + @Override + public void handleMessage(Message message) { + Object listener = removeListener(message.arg2); + switch (message.what) { + case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: + if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { + mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); + } else { + Log.e(TAG, "Failed to set up channel connection"); + // This will cause all further async API calls on the WifiManager + // to fail and throw an exception + mAsyncChannel = null; + } + mConnected.countDown(); + break; + case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED: + // Ignore + break; + case AsyncChannel.CMD_CHANNEL_DISCONNECTED: + Log.e(TAG, "Channel connection lost"); + // This will cause all further async API calls on the WifiManager + // to fail and throw an exception + mAsyncChannel = null; + break; + /* ActionListeners grouped together */ + case WifiManager.CONNECT_NETWORK_FAILED: + case WifiManager.FORGET_NETWORK_FAILED: + case WifiManager.SAVE_NETWORK_FAILED: + case WifiManager.CANCEL_WPS_FAILED: + case WifiManager.DISABLE_NETWORK_FAILED: + if (listener != null) { + ((ActionListener) listener).onFailure(message.arg1); + } + break; + /* ActionListeners grouped together */ + case WifiManager.CONNECT_NETWORK_SUCCEEDED: + case WifiManager.FORGET_NETWORK_SUCCEEDED: + case WifiManager.SAVE_NETWORK_SUCCEEDED: + case WifiManager.CANCEL_WPS_SUCCEDED: + case WifiManager.DISABLE_NETWORK_SUCCEEDED: + if (listener != null) { + ((ActionListener) listener).onSuccess(); + } + break; + case WifiManager.START_WPS_SUCCEEDED: + if (listener != null) { + WpsResult result = (WpsResult) message.obj; + ((WpsListener) listener).onStartSuccess(result.pin); + //Listener needs to stay until completion or failure + synchronized(mListenerMapLock) { + mListenerMap.put(message.arg2, listener); } - break; - default: - //ignore - break; - } + } + break; + case WifiManager.WPS_COMPLETED: + if (listener != null) { + ((WpsListener) listener).onCompletion(); + } + break; + case WifiManager.WPS_FAILED: + if (listener != null) { + ((WpsListener) listener).onFailure(message.arg1); + } + break; + default: + //ignore + break; } } + } - int putListener(Object listener) { - if (listener == null) return INVALID_KEY; - int key; - synchronized (mListenerMapLock) { - do { - key = mListenerKey++; - } while (key == INVALID_KEY); - mListenerMap.put(key, listener); - } - return key; + private int putListener(Object listener) { + if (listener == null) return INVALID_KEY; + int key; + synchronized (mListenerMapLock) { + do { + key = mListenerKey++; + } while (key == INVALID_KEY); + mListenerMap.put(key, listener); } + return key; + } - Object removeListener(int key) { - if (key == INVALID_KEY) return null; - synchronized (mListenerMapLock) { - Object listener = mListenerMap.get(key); - mListenerMap.remove(key); - return listener; - } + private Object removeListener(int key) { + if (key == INVALID_KEY) return null; + synchronized (mListenerMapLock) { + Object listener = mListenerMap.get(key); + mListenerMap.remove(key); + return listener; } } - /** - * Registers the application with the Wi-Fi framework. This function - * must be the first to be called before any Wi-Fi operations are performed. - * - * @param srcContext is the context of the source - * @param srcLooper is the Looper on which the callbacks are receivied - * @param listener for callback at loss of framework communication. Can be null. - * @return Channel instance that is necessary for performing any further Wi-Fi operations. - * A null is returned upon failure to initialize. - * @hide - */ - public Channel initialize(Context srcContext, Looper srcLooper, ChannelListener listener) { - Messenger messenger = getWifiServiceMessenger(); - if (messenger == null) return null; - - Channel c = new Channel(srcLooper, listener); - if (c.mAsyncChannel.connectSync(srcContext, c.mHandler, messenger) - == AsyncChannel.STATUS_SUCCESSFUL) { - return c; - } else { - return null; + private void init() { + mWifiServiceMessenger = getWifiServiceMessenger(); + if (mWifiServiceMessenger == null) throw new RuntimeException("Failed to initialize"); + HandlerThread t = new HandlerThread("WifiManager"); + t.start(); + mHandler = new ServiceHandler(t.getLooper()); + mAsyncChannel.connect(mContext, mHandler, mWifiServiceMessenger); + try { + mConnected.await(); + } catch (InterruptedException e) { + Log.e(TAG, "interrupted wait at init"); } } + private void validateChannel() { + if (mAsyncChannel == null) throw new IllegalStateException( + "Bad WifiManager instance state, re-initialize"); + } + /** * Connect to a network with the given configuration. The network also * gets added to the supplicant configuration. @@ -1341,20 +1336,21 @@ public class WifiManager { * sequence of addNetwork(), enableNetwork(), saveConfiguration() and * reconnect() * - * @param c is the channel created at {@link #initialize} * @param config the set of variables that describe the configuration, * contained in a {@link WifiConfiguration} object. * @param listener for callbacks on success or failure. Can be null. + * @throws IllegalStateException if the WifiManager instance needs to be + * initialized again + * * @hide */ - public void connect(Channel c, WifiConfiguration config, ActionListener listener) { - if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); + public void connect(WifiConfiguration config, ActionListener listener) { if (config == null) throw new IllegalArgumentException("config cannot be null"); - + validateChannel(); // Use INVALID_NETWORK_ID for arg1 when passing a config object // arg1 is used to pass network id when the network already exists - c.mAsyncChannel.sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID, - c.putListener(listener), config); + mAsyncChannel.sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID, + putListener(listener), config); } /** @@ -1363,17 +1359,17 @@ public class WifiManager { * This function is used instead of a enableNetwork(), saveConfiguration() and * reconnect() * - * @param c is the channel created at {@link #initialize} * @param networkId the network id identifiying the network in the * supplicant configuration list * @param listener for callbacks on success or failure. Can be null. + * @throws IllegalStateException if the WifiManager instance needs to be + * initialized again * @hide */ - public void connect(Channel c, int networkId, ActionListener listener) { - if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); + public void connect(int networkId, ActionListener listener) { if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative"); - - c.mAsyncChannel.sendMessage(CONNECT_NETWORK, networkId, c.putListener(listener)); + validateChannel(); + mAsyncChannel.sendMessage(CONNECT_NETWORK, networkId, putListener(listener)); } /** @@ -1387,17 +1383,17 @@ public class WifiManager { * For an existing network, it accomplishes the task of updateNetwork() * and saveConfiguration() * - * @param c is the channel created at {@link #initialize} * @param config the set of variables that describe the configuration, * contained in a {@link WifiConfiguration} object. * @param listener for callbacks on success or failure. Can be null. + * @throws IllegalStateException if the WifiManager instance needs to be + * initialized again * @hide */ - public void save(Channel c, WifiConfiguration config, ActionListener listener) { - if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); + public void save(WifiConfiguration config, ActionListener listener) { if (config == null) throw new IllegalArgumentException("config cannot be null"); - - c.mAsyncChannel.sendMessage(SAVE_NETWORK, 0, c.putListener(listener), config); + validateChannel(); + mAsyncChannel.sendMessage(SAVE_NETWORK, 0, putListener(listener), config); } /** @@ -1406,64 +1402,62 @@ public class WifiManager { * This function is used instead of a sequence of removeNetwork() * and saveConfiguration(). * - * @param c is the channel created at {@link #initialize} * @param config the set of variables that describe the configuration, * contained in a {@link WifiConfiguration} object. * @param listener for callbacks on success or failure. Can be null. + * @throws IllegalStateException if the WifiManager instance needs to be + * initialized again * @hide */ - public void forget(Channel c, int netId, ActionListener listener) { - if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); + public void forget(int netId, ActionListener listener) { if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative"); - - c.mAsyncChannel.sendMessage(FORGET_NETWORK, netId, c.putListener(listener)); + validateChannel(); + mAsyncChannel.sendMessage(FORGET_NETWORK, netId, putListener(listener)); } /** * Disable network * - * @param c is the channel created at {@link #initialize} * @param netId is the network Id * @param listener for callbacks on success or failure. Can be null. + * @throws IllegalStateException if the WifiManager instance needs to be + * initialized again * @hide */ - public void disable(Channel c, int netId, ActionListener listener) { - if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); + public void disable(int netId, ActionListener listener) { if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative"); - - c.mAsyncChannel.sendMessage(DISABLE_NETWORK, netId, c.putListener(listener)); + validateChannel(); + mAsyncChannel.sendMessage(DISABLE_NETWORK, netId, putListener(listener)); } /** * Start Wi-fi Protected Setup * - * @param c is the channel created at {@link #initialize} * @param config WPS configuration * @param listener for callbacks on success or failure. Can be null. + * @throws IllegalStateException if the WifiManager instance needs to be + * initialized again * @hide */ - public void startWps(Channel c, WpsInfo config, WpsListener listener) { - if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); + public void startWps(WpsInfo config, WpsListener listener) { if (config == null) throw new IllegalArgumentException("config cannot be null"); - - c.mAsyncChannel.sendMessage(START_WPS, 0, c.putListener(listener), config); + validateChannel(); + mAsyncChannel.sendMessage(START_WPS, 0, putListener(listener), config); } /** * Cancel any ongoing Wi-fi Protected Setup * - * @param c is the channel created at {@link #initialize} * @param listener for callbacks on success or failure. Can be null. + * @throws IllegalStateException if the WifiManager instance needs to be + * initialized again * @hide */ - public void cancelWps(Channel c, ActionListener listener) { - if (c == null) throw new IllegalArgumentException("Channel needs to be initialized"); - - c.mAsyncChannel.sendMessage(CANCEL_WPS, 0, c.putListener(listener)); + public void cancelWps(ActionListener listener) { + validateChannel(); + mAsyncChannel.sendMessage(CANCEL_WPS, 0, putListener(listener)); } - - /** * Get a reference to WifiService handler. This is used by a client to establish * an AsyncChannel communication with WifiService @@ -1492,8 +1486,6 @@ public class WifiManager { } } - - /** * Returns the file in which IP and proxy configuration data is stored * @hide |