Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit be9ee6a4 authored by Irfan Sheriff's avatar Irfan Sheriff
Browse files

Fix configuration change handling

When IP or proxy config changes, we now reconfigure
the network and inform connectivityservice.

Also, fixed the naming for changes on configured
networks.

Bug: 3237735
Change-Id: I2a94b3158b6b0e0d27442d7fd525a8a23f0497f8
parent 88bf6084
Loading
Loading
Loading
Loading
+61 −0
Original line number Diff line number Diff line
/*
 * 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;
    }
}
+32 −26
Original line number Diff line number Diff line
@@ -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,
+6 −8
Original line number Diff line number Diff line
@@ -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
+42 −30
Original line number Diff line number Diff line
@@ -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);
                  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:
+2 −2
Original line number Diff line number Diff line
@@ -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);