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

Commit 52e4b23e authored by d34d's avatar d34d Committed by Gerrit Code Review
Browse files

Tethering: Turn off Wi-Fi Hotspot after inactivity (1/3)

Turn off the Wi-Fi hotspot after a specified time of inactivity.
The hotspot is considered to be inactive when no clients are
connected to it.

Change-Id: Ife48d5254b06b4e80841d5970984ab9979574e07
parent 19960ebe
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
@@ -36,8 +36,11 @@ import android.net.Network;
import android.net.NetworkInfo;
import android.net.NetworkUtils;
import android.net.RouteInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiDevice;
import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.Handler;
import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.Message;
@@ -164,12 +167,16 @@ public class Tethering extends BaseNetworkObserver {
    private static final int DNSMASQ_POLLING_INTERVAL = 1000;
    private static final int DNSMASQ_POLLING_MAX_TIMES = 10;

    private long mWiFiApInactivityTimeout;
    private final Handler mHandler;

    public Tethering(Context context, INetworkManagementService nmService,
            INetworkStatsService statsService, Looper looper) {
        mContext = context;
        mNMService = nmService;
        mStatsService = statsService;
        mLooper = looper;
        mHandler = new Handler(mLooper);

        mPublicSync = new Object();

@@ -269,6 +276,18 @@ public class Tethering extends BaseNetworkObserver {
                    sm = new TetherInterfaceSM(iface, mLooper, usb);
                    mIfaces.put(iface, sm);
                    sm.start();
                    if (isWifi(iface)) {
                        // check if the user has specified an inactivity timeout for wifi AP and
                        // if so schedule the timeout
                        final WifiManager wm =
                                (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
                        final WifiConfiguration apConfig = wm.getWifiApConfiguration();
                        mWiFiApInactivityTimeout =
                                apConfig != null ? apConfig.wifiApInactivityTimeout : 0;
                        if (mWiFiApInactivityTimeout > 0 && mL2ConnectedDeviceMap.size() == 0) {
                            scheduleInactivityTimeout();
                        }
                    }
                }
            } else {
                if (isUsb(iface)) {
@@ -278,6 +297,9 @@ public class Tethering extends BaseNetworkObserver {
                } else if (sm != null) {
                    sm.sendMessage(TetherInterfaceSM.CMD_INTERFACE_DOWN);
                    mIfaces.remove(iface);
                    if (isWifi(iface)) {
                        cancelInactivityTimeout();
                    }
                }
            }
        }
@@ -428,6 +450,29 @@ public class Tethering extends BaseNetworkObserver {
        return result;
    }

    private final Runnable mDisableWifiApRunnable = new Runnable() {
        @Override
        public void run() {
            if (VDBG) Log.d(TAG, "Turning off hotpost due to inactivity");
            final WifiManager wifiManager =
                    (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
            wifiManager.setWifiApEnabled(null, false);
        }
    };

    private void scheduleInactivityTimeout() {
        if (mWiFiApInactivityTimeout > 0) {
            if (VDBG) Log.d(TAG, "scheduleInactivityTimeout: " + mWiFiApInactivityTimeout);
            mHandler.removeCallbacks(mDisableWifiApRunnable);
            mHandler.postDelayed(mDisableWifiApRunnable, mWiFiApInactivityTimeout);
        }
    }

    private void cancelInactivityTimeout() {
        if (VDBG) Log.d(TAG, "cancelInactivityTimeout");
        mHandler.removeCallbacks(mDisableWifiApRunnable);
    }

    /*
     * DnsmasqThread is used to read the Device info from dnsmasq.
     */
@@ -511,10 +556,15 @@ public class Tethering extends BaseNetworkObserver {
                    new DnsmasqThread(this, device,
                        DNSMASQ_POLLING_INTERVAL, DNSMASQ_POLLING_MAX_TIMES).start();
                }
                cancelInactivityTimeout();
            } else if (device.deviceState == WifiDevice.DISCONNECTED) {
                mL2ConnectedDeviceMap.remove(device.deviceAddress);
                mConnectedDeviceMap.remove(device.deviceAddress);
                sendTetherConnectStateChangedBroadcast();
                // schedule inactivity timeout if non-zero and no more devices are connected
                if (mWiFiApInactivityTimeout > 0 && mL2ConnectedDeviceMap.size() == 0) {
                    scheduleInactivityTimeout();
                }
            }
        } catch (IllegalArgumentException ex) {
            Log.e(TAG, "WifiDevice IllegalArgument: " + ex);
+10 −0
Original line number Diff line number Diff line
@@ -456,6 +456,13 @@ public class WifiConfiguration implements Parcelable {
     */
    public int userApproved = USER_UNSPECIFIED;

    /**
     * @hide
     * Inactivity time before wifi tethering is disabled.  Here inactivity means no clients
     * connected.  A value of 0 means the AP will not be disabled when there is no activity
     */
    public long wifiApInactivityTimeout;

    /** The Below RSSI thresholds are used to configure AutoJoin
     *  - GOOD/LOW/BAD thresholds are used so as to calculate link score
     *  - UNWANTED_SOFT are used by the blacklisting logic so as to handle
@@ -1556,6 +1563,7 @@ public class WifiConfiguration implements Parcelable {
            creationTime = source.creationTime;
            updateTime = source.updateTime;
            SIMNum = source.SIMNum;
            wifiApInactivityTimeout = source.wifiApInactivityTimeout;
        }
    }

@@ -1638,6 +1646,7 @@ public class WifiConfiguration implements Parcelable {
        dest.writeInt(numNoInternetAccessReports);
        dest.writeInt(noInternetAccessExpected ? 1 : 0);
        dest.writeInt(SIMNum);
        dest.writeLong(wifiApInactivityTimeout);
    }

    /** Implement the Parcelable interface {@hide} */
@@ -1717,6 +1726,7 @@ public class WifiConfiguration implements Parcelable {
                config.numNoInternetAccessReports = in.readInt();
                config.noInternetAccessExpected = in.readInt() != 0;
                config.SIMNum = in.readInt();
                config.wifiApInactivityTimeout = in.readLong();
                return config;
            }