diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-01-09 17:51:23 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-01-09 17:51:23 -0800 |
commit | b798689749c64baba81f02e10cf2157c747d6b46 (patch) | |
tree | da394a395ddb1a6cf69193314846b03fe47a397e /wifi/java | |
parent | f013e1afd1e68af5e3b868c26a653bbfb39538f8 (diff) | |
download | frameworks_base-b798689749c64baba81f02e10cf2157c747d6b46.zip frameworks_base-b798689749c64baba81f02e10cf2157c747d6b46.tar.gz frameworks_base-b798689749c64baba81f02e10cf2157c747d6b46.tar.bz2 |
auto import from //branches/cupcake/...@125939
Diffstat (limited to 'wifi/java')
-rw-r--r-- | wifi/java/android/net/wifi/IWifiManager.aidl | 2 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiManager.java | 81 | ||||
-rw-r--r-- | wifi/java/android/net/wifi/WifiStateTracker.java | 176 |
3 files changed, 171 insertions, 88 deletions
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 64be50e..e454cae 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -66,7 +66,7 @@ interface IWifiManager DhcpInfo getDhcpInfo(); - boolean acquireWifiLock(IBinder lock, String tag); + boolean acquireWifiLock(IBinder lock, int lockType, String tag); boolean releaseWifiLock(IBinder lock); } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 18645b5..db989d0 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -24,8 +24,6 @@ import android.os.IBinder; import android.os.Handler; import android.os.RemoteException; -import com.android.internal.os.RuntimeInit; - import java.util.List; /** @@ -227,6 +225,27 @@ public class WifiManager { @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION) public static final String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK"; + /** + * In this mode, Wi-Fi will be kept active, + * and will behave normally, i.e., it will attempt to automatically + * establish a connection to a remembered access point that is + * within range, and will do periodic scans if there are remembered + * access points but none are in range. + * @hide pending API council review + */ + public static final int WIFI_MODE_FULL = 1; + /** + * In this mode, Wi-Fi will be kept active, + * but the only operation that will be supported is initiation of + * scans, and the subsequent reporting of scan results. No attempts + * will be made to automatically connect to remembered access points, + * nor will periodic scans be automatically performed looking for + * remembered access points. Scans must be explicitly requested by + * an application in this mode. + * @hide pending API council review + */ + public static final int WIFI_MODE_SCAN_ONLY = 2; + /** Anything worse than or equal to this will show 0 bars. */ private static final int MIN_RSSI = -100; @@ -236,10 +255,6 @@ public class WifiManager { IWifiManager mService; Handler mHandler; - /** Don't allow use of default constructor */ - private WifiManager() { - } - /** * Create a new WifiManager instance. * Applications will almost always want to use @@ -247,7 +262,7 @@ public class WifiManager { * the standard {@link android.content.Context#WIFI_SERVICE Context.WIFI_SERVICE}. * @param service the Binder interface * @param handler target for messages - * {@hide} - hide this because it takes in a parameter of type IWifiManager, which + * @hide - hide this because it takes in a parameter of type IWifiManager, which * is a system private class. */ public WifiManager(IWifiManager service, Handler handler) { @@ -658,13 +673,15 @@ public class WifiManager { */ public class WifiLock { private String mTag; - private IBinder mBinder; + private final IBinder mBinder; private int mRefCount; + int mLockType; private boolean mRefCounted; private boolean mHeld; - private WifiLock(String tag) { + private WifiLock(int lockType, String tag) { mTag = tag; + mLockType = lockType; mBinder = new Binder(); mRefCount = 0; mRefCounted = true; @@ -674,20 +691,20 @@ public class WifiManager { /** * Locks the Wi-Fi radio on until {@link #release} is called. * - * If this WifiLock is reference-counted, each call to {@link #acquire} will increment the + * If this WifiLock is reference-counted, each call to {@code acquire} will increment the * reference count, and the radio will remain locked as long as the reference count is * above zero. * - * If this WifiLock is not reference-counted, the first call to {@link #acquire} will lock + * If this WifiLock is not reference-counted, the first call to {@code acquire} will lock * the radio, but subsequent calls will be ignored. Only one call to {@link #release} - * will be required, regardless of the number of times that {@link #acquire} is called. + * will be required, regardless of the number of times that {@code acquire} is called. */ public void acquire() { synchronized (mBinder) { if (mRefCounted ? (++mRefCount > 0) : (!mHeld)) { try { - mService.acquireWifiLock(mBinder, mTag); - } catch (RemoteException e) { + mService.acquireWifiLock(mBinder, mLockType, mTag); + } catch (RemoteException ignore) { } mHeld = true; } @@ -697,12 +714,12 @@ public class WifiManager { /** * Unlocks the Wi-Fi radio, allowing it to turn off when the device is idle. * - * If this WifiLock is reference-counted, each call to {@link #release} will decrement the + * If this WifiLock is reference-counted, each call to {@code release} will decrement the * reference count, and the radio will be unlocked only when the reference count reaches - * zero. If the reference count goes below zero (that is, if {@link #release} is called + * zero. If the reference count goes below zero (that is, if {@code release} is called * a greater number of times than {@link #acquire}), an exception is thrown. * - * If this WifiLock is not reference-counted, the first call to {@link #release} (after + * If this WifiLock is not reference-counted, the first call to {@code release} (after * the radio was locked using {@link #acquire}) will unlock the radio, and subsequent * calls will be ignored. */ @@ -711,7 +728,7 @@ public class WifiManager { if (mRefCounted ? (--mRefCount == 0) : (mHeld)) { try { mService.releaseWifiLock(mBinder); - } catch (RemoteException e) { + } catch (RemoteException ignore) { } mHeld = false; } @@ -763,14 +780,13 @@ public class WifiManager { @Override protected void finalize() throws Throwable { + super.finalize(); synchronized (mBinder) { if (mHeld) { try { mService.releaseWifiLock(mBinder); - } catch (RemoteException e) { + } catch (RemoteException ignore) { } - RuntimeInit.crash("WifiLock", new Exception( - "WifiLock finalized while still held: " + mTag)); } } } @@ -779,6 +795,8 @@ public class WifiManager { /** * Creates a new WifiLock. * + * @param lockType the type of lock to create. See {@link #WIFI_MODE_FULL} and + * {@link #WIFI_MODE_SCAN_ONLY} for descriptions of the types of Wi-Fi locks. * @param tag a tag for the WifiLock to identify it in debugging messages. This string is * never shown to the user under normal conditions, but should be descriptive * enough to identify your application and the specific WifiLock within it, if it @@ -787,9 +805,26 @@ public class WifiManager { * @return a new, unacquired WifiLock with the given tag. * * @see WifiLock + * + * @hide pending API council review */ - public WifiLock createWifiLock(String tag) { - return new WifiLock(tag); + public WifiLock createWifiLock(int lockType, String tag) { + return new WifiLock(lockType, tag); } + /** + * Creates a new WifiLock. + * + * @param tag a tag for the WifiLock to identify it in debugging messages. This string is + * never shown to the user under normal conditions, but should be descriptive + * enough to identify your application and the specific WifiLock within it, if it + * holds multiple WifiLocks. + * + * @return a new, unacquired WifiLock with the given tag. + * + * @see WifiLock + */ + public WifiLock createWifiLock(String tag) { + return new WifiLock(WIFI_MODE_FULL, tag); + } } diff --git a/wifi/java/android/net/wifi/WifiStateTracker.java b/wifi/java/android/net/wifi/WifiStateTracker.java index 87a0e95..9b96da0 100644 --- a/wifi/java/android/net/wifi/WifiStateTracker.java +++ b/wifi/java/android/net/wifi/WifiStateTracker.java @@ -50,7 +50,7 @@ import java.net.UnknownHostException; * Track the state of Wifi connectivity. All event handling is done here, * and all changes in connectivity state are initiated here. * - * {@hide} + * @hide */ public class WifiStateTracker extends NetworkStateTracker { @@ -225,7 +225,16 @@ public class WifiStateTracker extends NetworkStateTracker { private boolean mIsScanModeActive; private boolean mIsScanModeSetDueToAHiddenNetwork; - private boolean mDriverIsStopped; + + // Wi-Fi run states: + private static final int RUN_STATE_STARTING = 1; + private static final int RUN_STATE_RUNNING = 2; + private static final int RUN_STATE_STOPPING = 3; + private static final int RUN_STATE_STOPPED = 4; + private int mRunState; + + private boolean mIsScanOnly; + private String mInterfaceName; private static String LS = System.getProperty("line.separator"); @@ -277,6 +286,7 @@ public class WifiStateTracker extends NetworkStateTracker { // Allocate DHCP info object once, and fill it in on each request mDhcpInfo = new DhcpInfo(); mIsScanModeSetDueToAHiddenNetwork = false; + mRunState = RUN_STATE_STARTING; // Setting is in seconds NOTIFICATION_REPEAT_DELAY_MS = Settings.Secure.getInt(context.getContentResolver(), @@ -367,7 +377,7 @@ public class WifiStateTracker extends NetworkStateTracker { * unavailable. * @return {@code true} if Wi-Fi connections are possible */ - public boolean isAvailable() { + public synchronized boolean isAvailable() { /* * TODO: Should we also look at scan results to see whether we're * in range of any access points? @@ -375,7 +385,7 @@ public class WifiStateTracker extends NetworkStateTracker { SupplicantState suppState = mWifiInfo.getSupplicantState(); return suppState != SupplicantState.UNINITIALIZED && suppState != SupplicantState.INACTIVE && - (mTornDownByConnMgr || !mDriverIsStopped); + (mTornDownByConnMgr || !isDriverStopped()); } /** @@ -471,15 +481,10 @@ public class WifiStateTracker extends NetworkStateTracker { /** * Send the tracker a notification that the Wi-Fi driver has been stopped. - * The notification is in the form of a synthesized DISCONNECTED event. */ void notifyDriverStopped() { - setDriverStopped(true); - Message msg = Message.obtain( - this, EVENT_SUPPLICANT_STATE_CHANGED, - new SupplicantStateChangeResult(-1, SupplicantState.DISCONNECTED)); - msg.sendToTarget(); - + mRunState = RUN_STATE_STOPPED; + // Send a driver stopped message to our handler Message.obtain(this, EVENT_DRIVER_STATE_CHANGED, 0, 0).sendToTarget(); } @@ -489,8 +494,6 @@ public class WifiStateTracker extends NetworkStateTracker { * having been stopped. */ void notifyDriverStarted() { - setDriverStopped(false); - // Send a driver started message to our handler Message.obtain(this, EVENT_DRIVER_STATE_CHANGED, 1, 0).sendToTarget(); } @@ -505,12 +508,8 @@ public class WifiStateTracker extends NetworkStateTracker { } } - private synchronized void setDriverStopped(boolean isStopped) { - mDriverIsStopped = isStopped; - } - private synchronized boolean isDriverStopped() { - return mDriverIsStopped; + return mRunState == RUN_STATE_STOPPED || mRunState == RUN_STATE_STOPPING; } /** @@ -543,23 +542,25 @@ public class WifiStateTracker extends NetworkStateTracker { } /** - * Start the Wi-Fi driver, if it is in the stopped state. If - * the driver has been stopped as a result of a teardown request - * by the connectivity manager, then only the connectivity - * manager can restart it. + * Set the run state to either "normal" or "scan-only". + * @param scanOnlyMode true if the new mode should be scan-only. */ - public synchronized void startDriver() { - if (mDriverIsStopped && !mTornDownByConnMgr) { - WifiNative.startDriverCommand(); - } - } - - /** - * Stop the Wi-Fi driver, if it is not already in the stopped state. - */ - public synchronized void stopDriver() { - if (!mDriverIsStopped) { - WifiNative.stopDriverCommand(); + public synchronized void setScanOnlyMode(boolean scanOnlyMode) { + // do nothing unless scan-only mode is changing + if (mIsScanOnly != scanOnlyMode) { + int scanType = (scanOnlyMode ? + SUPPL_SCAN_HANDLING_LIST_ONLY : SUPPL_SCAN_HANDLING_NORMAL); + if (LOCAL_LOGD) Log.v(TAG, "Scan-only mode changing to " + scanOnlyMode + " scanType=" + scanType); + if (WifiNative.setScanResultHandlingCommand(scanType)) { + mIsScanOnly = scanOnlyMode; + if (!isDriverStopped()) { + if (scanOnlyMode) { + WifiNative.disconnectCommand(); + } else { + WifiNative.reconnectCommand(); + } + } + } } } @@ -610,6 +611,7 @@ public class WifiStateTracker extends NetworkStateTracker { switch (msg.what) { case EVENT_SUPPLICANT_CONNECTION: + mRunState = RUN_STATE_RUNNING; checkUseStaticIp(); /* * DHCP requests are blocking, so run them in a separate thread. @@ -618,6 +620,7 @@ public class WifiStateTracker extends NetworkStateTracker { dhcpThread.start(); mDhcpTarget = new DhcpHandler(dhcpThread.getLooper(), this); mIsScanModeActive = true; + mTornDownByConnMgr = false; mLastBssid = null; mLastSsid = null; requestConnectionInfo(); @@ -745,9 +748,25 @@ public class WifiStateTracker extends NetworkStateTracker { (newState == SupplicantState.DISCONNECTED && isDriverStopped())) { setSupplicantState(newState); if (newState == SupplicantState.DORMANT) { - handleDisconnectedState(DetailedState.FAILED); + DetailedState newDetailedState; + if (!mIsScanOnly) { + newDetailedState = DetailedState.FAILED; + } else { + newDetailedState = DetailedState.IDLE; + } + handleDisconnectedState(newDetailedState); sendNetworkStateChangeBroadcast(); - sendEmptyMessageDelayed(EVENT_DEFERRED_RECONNECT, RECONNECT_DELAY_MSECS); + if (mRunState == RUN_STATE_RUNNING && !mIsScanOnly) { + sendEmptyMessageDelayed(EVENT_DEFERRED_RECONNECT, RECONNECT_DELAY_MSECS); + } else if (mRunState == RUN_STATE_STOPPING) { + synchronized (this) { + WifiNative.stopDriverCommand(); + } + } else if (mRunState == RUN_STATE_STARTING && !mIsScanOnly) { + synchronized (this) { + WifiNative.reconnectCommand(); + } + } } else if (newState == SupplicantState.DISCONNECTED) { if (isDriverStopped()) { handleDisconnectedState(DetailedState.DISCONNECTED); @@ -804,6 +823,14 @@ public class WifiStateTracker extends NetworkStateTracker { EventLog.writeEvent(EVENTLOG_NETWORK_STATE_CHANGED, eventLogParam); if (LOCAL_LOGD) Log.v(TAG, "New network state is " + result.state); + /* + * If we're in scan-only mode, don't advance the state machine, and + * don't report the state change to clients. + */ + if (mIsScanOnly) { + if (LOCAL_LOGD) Log.v(TAG, "Dropping event in scan-only mode"); + break; + } if (result.state != DetailedState.SCANNING) { /* * Reset the scan count since there was a network state @@ -867,7 +894,6 @@ public class WifiStateTracker extends NetworkStateTracker { break; case EVENT_SCAN_RESULTS_AVAILABLE: - mContext.sendBroadcast(new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)); sendScanResultsAvailable(); /** @@ -908,7 +934,9 @@ public class WifiStateTracker extends NetworkStateTracker { if (++mReconnectCount > getMaxDhcpRetries()) { mWM.disableNetwork(mLastNetworkId); } - WifiNative.reconnectCommand(); + synchronized(this) { + WifiNative.reconnectCommand(); + } } break; @@ -952,7 +980,9 @@ public class WifiStateTracker extends NetworkStateTracker { mHaveIPAddress = false; mWifiInfo.setIpAddress(0); mObtainingIPAddress = false; - WifiNative.disconnectCommand(); + synchronized(this) { + WifiNative.disconnectCommand(); + } } break; @@ -973,9 +1003,16 @@ public class WifiStateTracker extends NetworkStateTracker { */ setNumAllowedChannels(); synchronized (this) { - // In some situations, supplicant needs to be kickstarted to - // start the background scanning - WifiNative.scanCommand(); + if (mRunState == RUN_STATE_STARTING) { + mRunState = RUN_STATE_RUNNING; + if (!mIsScanOnly) { + WifiNative.reconnectCommand(); + } else { + // In some situations, supplicant needs to be kickstarted to + // start the background scanning + WifiNative.scanCommand(); + } + } } } break; @@ -1122,16 +1159,6 @@ public class WifiStateTracker extends NetworkStateTracker { public WifiInfo requestConnectionInfo() { requestConnectionStatus(mWifiInfo); requestPolledInfo(mWifiInfo); -/* - WifiInfo info = mWifiInfo; - - Log.v(TAG, "Status from supplicant: NID=" + info.getNetworkId() + - " SSID=" + (info.getSSID() == null ? "<none>" : info.getSSID()) + - " BSSID=" + (info.getBSSID() == null ? "<none>" : info.getBSSID()) + - " WPA_STATE=" + (info.getSupplicantState() == null ? "<none>" : info.getSupplicantState()) + - " RSSI=" + info.getRssi()); -*/ - return mWifiInfo; } @@ -1201,7 +1228,7 @@ public class WifiStateTracker extends NetworkStateTracker { * interested in RSSI of all the changes in signal * level. */ - // TODO: The "3" below needs to be a symbol somewhere, but + // TODO: The second arg to the call below needs to be a symbol somewhere, but // it's actually the size of an array of icons that's private // to StatusBar Policy. int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, 4); @@ -1235,14 +1262,14 @@ public class WifiStateTracker extends NetworkStateTracker { /** * Disable Wi-Fi connectivity by stopping the driver. */ - public synchronized boolean teardown() { - // Take down any open network notifications - setNotificationVisible(false, 0, false, 0); - + public boolean teardown() { if (!mTornDownByConnMgr) { - boolean result = WifiNative.stopDriverCommand(); - setTornDownByConnMgr(result); - return result; + if (disconnectAndStop()) { + setTornDownByConnMgr(true); + return true; + } else { + return false; + } } else { return true; } @@ -1251,16 +1278,37 @@ public class WifiStateTracker extends NetworkStateTracker { /** * Reenable Wi-Fi connectivity by restarting the driver. */ - public synchronized boolean reconnect() { + public boolean reconnect() { if (mTornDownByConnMgr) { - boolean result = WifiNative.startDriverCommand(); - setTornDownByConnMgr(!result); - return result; + if (restart()) { + setTornDownByConnMgr(false); + return true; + } else { + return false; + } } else { return true; } } + public synchronized boolean disconnectAndStop() { + // Take down any open network notifications + setNotificationVisible(false, 0, false, 0); + + mRunState = RUN_STATE_STOPPING; + return WifiNative.disconnectCommand(); + } + + public synchronized boolean restart() { + if (mRunState == RUN_STATE_STOPPED) { + mRunState = RUN_STATE_STARTING; + return WifiNative.startDriverCommand(); + } else if (mRunState == RUN_STATE_STOPPING) { + mRunState = RUN_STATE_STARTING; + } + return true; + } + public boolean setRadio(boolean turnOn) { return mWM.setWifiEnabled(turnOn); } |