Merge "Fix configuration change handling"

This commit is contained in:
Irfan Sheriff
2010-12-03 14:29:08 -08:00
committed by Android (Google) Code Review
5 changed files with 143 additions and 66 deletions

View File

@@ -0,0 +1,61 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net.wifi;
import static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID;
class NetworkUpdateResult {
int netId;
boolean ipChanged;
boolean proxyChanged;
public NetworkUpdateResult(int id) {
netId = id;
ipChanged = false;
proxyChanged = false;
}
public NetworkUpdateResult(boolean ip, boolean proxy) {
netId = INVALID_NETWORK_ID;
ipChanged = ip;
proxyChanged = proxy;
}
public void setNetworkId(int id) {
netId = id;
}
public int getNetworkId() {
return netId;
}
public void setIpChanged(boolean ip) {
ipChanged = ip;
}
public boolean hasIpChanged() {
return ipChanged;
}
public void setProxyChanged(boolean proxy) {
proxyChanged = proxy;
}
public boolean hasProxyChanged() {
return proxyChanged;
}
}

View File

@@ -16,7 +16,6 @@
package android.net.wifi;
import android.app.ActivityManagerNative;
import android.content.Context;
import android.content.Intent;
import android.net.DhcpInfo;
@@ -28,6 +27,7 @@ import android.net.wifi.WifiConfiguration.IpAssignment;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.wifi.WifiConfiguration.ProxySettings;
import android.net.wifi.WifiConfiguration.Status;
import android.net.wifi.NetworkUpdateResult;
import static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID;
import android.os.Environment;
import android.text.TextUtils;
@@ -42,7 +42,6 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.BitSet;
@@ -178,7 +177,7 @@ class WifiConfigStore {
}
WifiNative.saveConfigCommand();
sendConfigChangeBroadcast();
sendConfiguredNetworksChangedBroadcast();
}
/**
@@ -194,7 +193,8 @@ class WifiConfigStore {
*/
static void selectNetwork(WifiConfiguration config) {
if (config != null) {
int netId = addOrUpdateNetworkNative(config);
NetworkUpdateResult result = addOrUpdateNetworkNative(config);
int netId = result.getNetworkId();
if (netId != INVALID_NETWORK_ID) {
selectNetwork(netId);
} else {
@@ -248,9 +248,10 @@ class WifiConfigStore {
*
* @param config WifiConfiguration to be saved
*/
static void saveNetwork(WifiConfiguration config) {
static NetworkUpdateResult saveNetwork(WifiConfiguration config) {
boolean newNetwork = (config.networkId == INVALID_NETWORK_ID);
int netId = addOrUpdateNetworkNative(config);
NetworkUpdateResult result = addOrUpdateNetworkNative(config);
int netId = result.getNetworkId();
/* enable a new network */
if (newNetwork && netId != INVALID_NETWORK_ID) {
WifiNative.enableNetworkCommand(netId, false);
@@ -259,7 +260,8 @@ class WifiConfigStore {
}
}
WifiNative.saveConfigCommand();
sendConfigChangeBroadcast();
sendConfiguredNetworksChangedBroadcast();
return result;
}
/**
@@ -274,7 +276,7 @@ class WifiConfigStore {
sConfiguredNetworks.remove(netId);
}
writeIpAndProxyConfigurations();
sendConfigChangeBroadcast();
sendConfiguredNetworksChangedBroadcast();
} else {
Log.e(TAG, "Failed to remove network " + netId);
}
@@ -289,9 +291,9 @@ class WifiConfigStore {
* @param config wifi configuration to add/update
*/
static int addOrUpdateNetwork(WifiConfiguration config) {
int ret = addOrUpdateNetworkNative(config);
sendConfigChangeBroadcast();
return ret;
NetworkUpdateResult result = addOrUpdateNetworkNative(config);
sendConfiguredNetworksChangedBroadcast();
return result.getNetworkId();
}
/**
@@ -307,7 +309,7 @@ class WifiConfigStore {
synchronized (sConfiguredNetworks) {
if (ret) sConfiguredNetworks.remove(netId);
}
sendConfigChangeBroadcast();
sendConfiguredNetworksChangedBroadcast();
return ret;
}
@@ -321,7 +323,7 @@ class WifiConfigStore {
*/
static boolean enableNetwork(int netId, boolean disableOthers) {
boolean ret = enableNetworkWithoutBroadcast(netId, disableOthers);
sendConfigChangeBroadcast();
sendConfiguredNetworksChangedBroadcast();
return ret;
}
@@ -349,7 +351,7 @@ class WifiConfigStore {
WifiConfiguration config = sConfiguredNetworks.get(netId);
if (config != null) config.status = Status.DISABLED;
}
sendConfigChangeBroadcast();
sendConfiguredNetworksChangedBroadcast();
return ret;
}
@@ -475,9 +477,9 @@ class WifiConfigStore {
return false;
}
private static void sendConfigChangeBroadcast() {
if (!ActivityManagerNative.isSystemReady()) return;
Intent intent = new Intent(WifiManager.SUPPLICANT_CONFIG_CHANGED_ACTION);
private static void sendConfiguredNetworksChangedBroadcast() {
Intent intent = new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
sContext.sendBroadcast(intent);
}
@@ -522,7 +524,7 @@ class WifiConfigStore {
}
}
readIpAndProxyConfigurations();
sendConfigChangeBroadcast();
sendConfiguredNetworksChangedBroadcast();
}
/* Mark all networks except specified netId as disabled */
@@ -748,7 +750,7 @@ class WifiConfigStore {
}
}
private static int addOrUpdateNetworkNative(WifiConfiguration config) {
private static NetworkUpdateResult addOrUpdateNetworkNative(WifiConfiguration config) {
/*
* If the supplied networkId is INVALID_NETWORK_ID, we create a new empty
* network configuration. Otherwise, the networkId should
@@ -756,14 +758,14 @@ class WifiConfigStore {
*/
int netId = config.networkId;
boolean updateFailed = true;
boolean newNetwork = (netId == INVALID_NETWORK_ID);
// networkId of INVALID_NETWORK_ID means we want to create a new network
boolean newNetwork = (netId == INVALID_NETWORK_ID);
if (newNetwork) {
netId = WifiNative.addNetworkCommand();
if (netId < 0) {
Log.e(TAG, "Failed to add a network!");
return INVALID_NETWORK_ID;
return new NetworkUpdateResult(INVALID_NETWORK_ID);
}
}
@@ -937,7 +939,7 @@ class WifiConfigStore {
"Failed to set a network variable, removed network: "
+ netId);
}
return INVALID_NETWORK_ID;
return new NetworkUpdateResult(INVALID_NETWORK_ID);
}
/* An update of the network variables requires reading them
@@ -959,12 +961,15 @@ class WifiConfigStore {
}
}
readNetworkVariables(sConfig);
writeIpAndProxyConfigurationsOnChange(sConfig, config);
return netId;
NetworkUpdateResult result = writeIpAndProxyConfigurationsOnChange(sConfig, config);
result.setNetworkId(netId);
return result;
}
/* Compare current and new configuration and write to file on change */
private static void writeIpAndProxyConfigurationsOnChange(WifiConfiguration currentConfig,
private static NetworkUpdateResult writeIpAndProxyConfigurationsOnChange(
WifiConfiguration currentConfig,
WifiConfiguration newConfig) {
boolean ipChanged = false;
boolean proxyChanged = false;
@@ -1056,8 +1061,9 @@ class WifiConfigStore {
if (ipChanged || proxyChanged) {
currentConfig.linkProperties = linkProperties;
writeIpAndProxyConfigurations();
sendConfigChangeBroadcast();
sendConfiguredNetworksChangedBroadcast();
}
return new NetworkUpdateResult(ipChanged, proxyChanged);
}
private static void addIpSettingsFromConfig(LinkProperties linkProperties,

View File

@@ -131,7 +131,6 @@ public class WifiManager {
*
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String WIFI_AP_STATE_CHANGED_ACTION =
"android.net.wifi.WIFI_AP_STATE_CHANGED";
@@ -276,13 +275,12 @@ public class WifiManager {
*/
public static final String EXTRA_SUPPLICANT_ERROR = "supplicantError";
/**
* Broadcast intent action indicating that the supplicant configuration changed.
* Broadcast intent action indicating that the configured networks changed.
* This can be as a result of adding/updating/deleting a network
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String SUPPLICANT_CONFIG_CHANGED_ACTION =
"android.net.wifi.supplicant.CONFIG_CHANGE";
public static final String CONFIGURED_NETWORKS_CHANGED_ACTION =
"android.net.wifi.CONFIGURED_NETWORKS_CHANGE";
/**
* An access point scan has completed, and results are available from the supplicant.
* Call {@link #getScanResults()} to obtain the results.
@@ -301,12 +299,12 @@ public class WifiManager {
public static final String EXTRA_NEW_RSSI = "newRssi";
/**
* Broadcast intent action indicating that the IP configuration
* Broadcast intent action indicating that the link configuration
* changed on wifi.
* @hide
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
public static final String CONFIG_CHANGED_ACTION = "android.net.wifi.CONFIG_CHANGED";
public static final String LINK_CONFIGURATION_CHANGED_ACTION =
"android.net.wifi.LINK_CONFIGURATION_CHANGED";
/**
* The lookup key for a {@link android.net.LinkProperties} object associated with the

View File

@@ -37,7 +37,6 @@ import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLED;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_ENABLING;
import static android.net.wifi.WifiManager.WIFI_AP_STATE_FAILED;
import android.app.ActivityManagerNative;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.net.LinkAddress;
@@ -47,6 +46,7 @@ import android.net.NetworkUtils;
import android.net.ConnectivityManager;
import android.net.NetworkInfo.DetailedState;
import android.net.LinkProperties;
import android.net.wifi.NetworkUpdateResult;
import android.os.Binder;
import android.os.Message;
import android.os.IBinder;
@@ -193,9 +193,6 @@ public class WifiStateMachine extends HierarchicalStateMachine {
static final int CMD_IP_CONFIG_SUCCESS = 15;
/* Indicates DHCP failed */
static final int CMD_IP_CONFIG_FAILURE = 16;
/* Re-configure interface */
static final int CMD_RECONFIGURE_IP = 17;
/* Start the soft access point */
static final int CMD_START_AP = 21;
@@ -1336,15 +1333,14 @@ public class WifiStateMachine extends HierarchicalStateMachine {
};
private void sendScanResultsAvailableBroadcast() {
if (!ActivityManagerNative.isSystemReady()) return;
mContext.sendBroadcast(new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
Intent intent = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mContext.sendBroadcast(intent);
}
private void sendRssiChangeBroadcast(final int newRssi) {
if (!ActivityManagerNative.isSystemReady()) return;
Intent intent = new Intent(WifiManager.RSSI_CHANGED_ACTION);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
intent.putExtra(WifiManager.EXTRA_NEW_RSSI, newRssi);
mContext.sendBroadcast(intent);
}
@@ -1360,18 +1356,16 @@ public class WifiStateMachine extends HierarchicalStateMachine {
mContext.sendStickyBroadcast(intent);
}
/* TODO: Unused for now, will be used when ip change on connected network is handled */
private void sendConfigChangeBroadcast() {
if (!ActivityManagerNative.isSystemReady()) return;
Intent intent = new Intent(WifiManager.CONFIG_CHANGED_ACTION);
private void sendLinkConfigurationChangedBroadcast() {
Intent intent = new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties);
mContext.sendBroadcast(intent);
}
private void sendSupplicantConnectionChangedBroadcast(boolean connected) {
if (!ActivityManagerNative.isSystemReady()) return;
Intent intent = new Intent(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
intent.putExtra(WifiManager.EXTRA_SUPPLICANT_CONNECTED, connected);
mContext.sendBroadcast(intent);
}
@@ -1380,7 +1374,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
* Record the detailed state of a network.
* @param state the new @{code DetailedState}
*/
private void setDetailedState(NetworkInfo.DetailedState state) {
private void setNetworkDetailedState(NetworkInfo.DetailedState state) {
Log.d(TAG, "setDetailed state, old ="
+ mNetworkInfo.getDetailedState() + " and new state=" + state);
if (state != mNetworkInfo.getDetailedState()) {
@@ -1388,6 +1382,10 @@ public class WifiStateMachine extends HierarchicalStateMachine {
}
}
private DetailedState getNetworkDetailedState() {
return mNetworkInfo.getDetailedState();
}
/**
* Resets the Wi-Fi Connections by clearing any state, resetting any sockets
* using the interface, stopping DHCP & disabling interface
@@ -1408,7 +1406,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
NetworkUtils.disableInterface(mInterfaceName);
/* send event to CM & network change broadcast */
setDetailedState(DetailedState.DISCONNECTED);
setNetworkDetailedState(DetailedState.DISCONNECTED);
sendNetworkStateChangeBroadcast(mLastBssid);
/* Reset data structures */
@@ -1576,7 +1574,6 @@ public class WifiStateMachine extends HierarchicalStateMachine {
case CMD_DISCONNECT:
case CMD_RECONNECT:
case CMD_REASSOCIATE:
case CMD_RECONFIGURE_IP:
case SUP_CONNECTION_EVENT:
case SUP_DISCONNECTION_EVENT:
case DRIVER_START_EVENT:
@@ -2415,7 +2412,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
mWifiInfo.setNetworkId(stateChangeResult.networkId);
mLastNetworkId = stateChangeResult.networkId;
/* send event to CM & network change broadcast */
setDetailedState(DetailedState.OBTAINING_IPADDR);
setNetworkDetailedState(DetailedState.OBTAINING_IPADDR);
sendNetworkStateChangeBroadcast(mLastBssid);
transitionTo(mConnectingState);
break;
@@ -2526,8 +2523,12 @@ public class WifiStateMachine extends HierarchicalStateMachine {
mWifiInfo.setIpAddress(mDhcpInfo.ipAddress);
}
configureLinkProperties();
setDetailedState(DetailedState.CONNECTED);
sendNetworkStateChangeBroadcast(mLastBssid);
if (getNetworkDetailedState() == DetailedState.CONNECTED) {
sendLinkConfigurationChangedBroadcast();
} else {
setNetworkDetailedState(DetailedState.CONNECTED);
sendNetworkStateChangeBroadcast(mLastBssid);
}
//TODO: The framework is not detecting a DHCP renewal and a possible
//IP change. we should detect this and send out a config change broadcast
transitionTo(mConnectedState);
@@ -2565,6 +2566,9 @@ public class WifiStateMachine extends HierarchicalStateMachine {
break;
}
return NOT_HANDLED;
case CMD_SAVE_NETWORK:
deferMessage(message);
break;
/* Ignore */
case NETWORK_CONNECTION_EVENT:
break;
@@ -2582,9 +2586,6 @@ public class WifiStateMachine extends HierarchicalStateMachine {
case CMD_START_SCAN:
deferMessage(message);
break;
case CMD_RECONFIGURE_IP:
deferMessage(message);
break;
/* Defer any power mode changes since we must keep active power mode at DHCP */
case CMD_SET_HIGH_PERF_MODE:
deferMessage(message);
@@ -2632,11 +2633,6 @@ public class WifiStateMachine extends HierarchicalStateMachine {
WifiNative.disconnectCommand();
transitionTo(mDisconnectingState);
break;
case CMD_RECONFIGURE_IP:
Log.d(TAG,"Reconfiguring IP on connection");
NetworkUtils.resetConnections(mInterfaceName);
transitionTo(mConnectingState);
break;
case CMD_STOP_DRIVER:
sendMessage(CMD_DISCONNECT);
deferMessage(message);
@@ -2663,6 +2659,22 @@ public class WifiStateMachine extends HierarchicalStateMachine {
break;
}
return NOT_HANDLED;
case CMD_SAVE_NETWORK:
WifiConfiguration config = (WifiConfiguration) message.obj;
NetworkUpdateResult result = WifiConfigStore.saveNetwork(config);
if (mWifiInfo.getNetworkId() == result.getNetworkId()) {
if (result.hasIpChanged()) {
Log.d(TAG,"Reconfiguring IP on connection");
NetworkUtils.resetConnections(mInterfaceName);
transitionTo(mConnectingState);
}
if (result.hasProxyChanged()) {
Log.d(TAG,"Reconfiguring proxy on connection");
configureLinkProperties();
sendLinkConfigurationChangedBroadcast();
}
}
break;
/* Ignore */
case NETWORK_CONNECTION_EVENT:
break;
@@ -2767,7 +2779,7 @@ public class WifiStateMachine extends HierarchicalStateMachine {
case SUPPLICANT_STATE_CHANGE_EVENT:
StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
SupplicantState state = (SupplicantState) stateChangeResult.state;
setDetailedState(WifiInfo.getDetailedStateOf(state));
setNetworkDetailedState(WifiInfo.getDetailedStateOf(state));
/* DriverStartedState does the rest of the handling */
return NOT_HANDLED;
default:

View File

@@ -86,7 +86,7 @@ public class WifiStateTracker implements NetworkStateTracker {
mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.CONFIG_CHANGED_ACTION);
filter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);
mWifiStateReceiver = new WifiStateReceiver();
mContext.registerReceiver(mWifiStateReceiver, filter);
@@ -254,7 +254,7 @@ public class WifiStateTracker implements NetworkStateTracker {
}
Message msg = mCsHandler.obtainMessage(EVENT_STATE_CHANGED, mNetworkInfo);
msg.sendToTarget();
} else if (intent.getAction().equals(WifiManager.CONFIG_CHANGED_ACTION)) {
} else if (intent.getAction().equals(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION)) {
mLinkProperties = (LinkProperties) intent.getParcelableExtra(
WifiManager.EXTRA_LINK_PROPERTIES);
Message msg = mCsHandler.obtainMessage(EVENT_CONFIGURATION_CHANGED, mNetworkInfo);