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

Commit bcca5ebf authored by Weng Su's avatar Weng Su
Browse files

Add "Speed & compatibility" preference to Wi-Fi hotspot Settings

- Show 4 speed types in summary
  - 2.4 Ghz
  - 5 Ghz
  - 2.4 and 5 GHz
  - 6 GHz

Bug: 245258763
Test: manual test
atest -c WifiTetherViewModelTest
atest -c WifiHotspotRepositoryTest
make RunSettingsRoboTests ROBOTEST_FILTER=WifiTetherSettingsTest

Change-Id: I6deb41cb355b0ceb1f1fd2d84408a83b90433e7d
parent ebf06975
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -363,6 +363,9 @@
    <!-- Whether Wi-Fi hotspot settings should be shown or not. -->
    <bool name="config_show_wifi_hotspot_settings">true</bool>

    <!-- Whether Wi-Fi hotspot speed should be shown or not. -->
    <bool name="config_show_wifi_hotspot_speed">false</bool>

    <!-- Whether toggle_airplane is available or not. -->
    <bool name="config_show_toggle_airplane">true</bool>

+10 −0
Original line number Diff line number Diff line
@@ -2015,6 +2015,16 @@
    <string name="wifi_hotspot_maximize_compatibility_single_ap_summary">Helps other devices find this hotspot. Reduces hotspot connection speed.</string>
    <!-- Summary for the toggle to show the maximize compatibility warning message in dual AP device [CHAR LIMIT=NONE]-->
    <string name="wifi_hotspot_maximize_compatibility_dual_ap_summary">Helps other devices find this hotspot. Increases battery usage.</string>
    <!-- Title for Wifi hotspot speed [CHAR LIMIT=NONE]-->
    <string name="wifi_hotspot_speed_title">Speed &amp; compatibility</string>
    <!-- Summary for Wifi hotspot speed to 2.4 GHz band [CHAR LIMIT=NONE]-->
    <string name="wifi_hotspot_speed_2g_summary">2.4 GHz / Any device can connect</string>
    <!-- Summary for Wifi hotspot speed to 5 GHz band [CHAR LIMIT=NONE]-->
    <string name="wifi_hotspot_speed_5g_summary">5 GHz / Most devices can connect</string>
    <!-- Summary for Wifi hotspot speed to 6 GHz band [CHAR LIMIT=NONE]-->
    <string name="wifi_hotspot_speed_6g_summary">6 GHz / Few devices can connect</string>
    <!-- Summary for Wifi hotspot speed to 6 GHz band [CHAR LIMIT=NONE]-->
    <string name="wifi_hotspot_speed_2g_and_5g_summary">2.4 and 5 GHz / Any device can connect</string>
    <!-- Summary text when turning hotspot on -->
    <string name="wifi_tether_starting">Turning hotspot on\u2026</string>
+6 −0
Original line number Diff line number Diff line
@@ -45,4 +45,10 @@
    <SwitchPreference
        android:key="wifi_tether_maximize_compatibility"
        android:title="@string/wifi_hotspot_maximize_compatibility"/>

    <Preference
        android:key="wifi_hotspot_speed"
        android:title="@string/wifi_hotspot_speed_title"
        android:summary="@string/summary_placeholder"
        settings:isPreferenceVisible="@bool/config_show_wifi_hotspot_speed"/>
</PreferenceScreen>
+13 −0
Original line number Diff line number Diff line
@@ -20,8 +20,13 @@ import android.content.Context;
import android.net.wifi.WifiManager;

import androidx.annotation.NonNull;
import androidx.lifecycle.ViewModelProvider;
import androidx.lifecycle.ViewModelStoreOwner;

import com.android.settings.wifi.repository.WifiHotspotRepository;
import com.android.settings.wifi.tether.WifiTetherViewModel;

import org.jetbrains.annotations.NotNull;

/**
 * Wi-Fi Feature Provider
@@ -55,5 +60,13 @@ public class WifiFeatureProvider {
        }
        return mWifiHotspotRepository;
    }

    /**
     * Get WifiTetherViewModel
     */
    public WifiTetherViewModel getWifiTetherViewModel(@NotNull ViewModelStoreOwner owner) {
        return new ViewModelProvider(owner).get(WifiTetherViewModel.class);
    }

}
+215 −0
Original line number Diff line number Diff line
@@ -16,13 +16,27 @@

package com.android.settings.wifi.repository;

import static android.net.wifi.SoftApConfiguration.BAND_2GHZ;
import static android.net.wifi.SoftApConfiguration.BAND_5GHZ;
import static android.net.wifi.SoftApConfiguration.BAND_6GHZ;
import static android.net.wifi.WifiAvailableChannel.OP_MODE_SAP;

import android.content.Context;
import android.net.wifi.SoftApConfiguration;
import android.net.wifi.WifiAvailableChannel;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiScanner;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Transformations;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.function.Consumer;

@@ -30,6 +44,36 @@ import java.util.function.Consumer;
 * Wi-Fi Hotspot Repository
 */
public class WifiHotspotRepository {
    private static final String TAG = "WifiHotspotRepository";
    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    /** Wi-Fi hotspot band unknown. */
    public static final int BAND_UNKNOWN = 0;
    /** Wi-Fi hotspot band 2.4GHz and 5GHz. */
    public static final int BAND_2GHZ_5GHZ = BAND_2GHZ | BAND_5GHZ;
    /** Wi-Fi hotspot band 2.4GHz and 5GHz and 6GHz. */
    public static final int BAND_2GHZ_5GHZ_6GHZ = BAND_2GHZ | BAND_5GHZ | BAND_6GHZ;

    /** Wi-Fi hotspot speed unknown. */
    public static final int SPEED_UNKNOWN = 0;
    /** Wi-Fi hotspot speed 2.4GHz. */
    public static final int SPEED_2GHZ = 1;
    /** Wi-Fi hotspot speed 5GHz. */
    public static final int SPEED_5GHZ = 2;
    /** Wi-Fi hotspot speed 2.4GHz and 5GHz. */
    public static final int SPEED_2GHZ_5GHZ = 3;
    /** Wi-Fi hotspot speed 6GHz. */
    public static final int SPEED_6GHZ = 4;

    protected static Map<Integer, Integer> sSpeedMap = new HashMap<>();

    static {
        sSpeedMap.put(BAND_UNKNOWN, SPEED_UNKNOWN);
        sSpeedMap.put(BAND_2GHZ, SPEED_2GHZ);
        sSpeedMap.put(BAND_5GHZ, SPEED_5GHZ);
        sSpeedMap.put(BAND_6GHZ, SPEED_6GHZ);
        sSpeedMap.put(BAND_2GHZ_5GHZ, SPEED_2GHZ_5GHZ);
    }

    protected final Context mAppContext;
    protected final WifiManager mWifiManager;
@@ -37,6 +81,14 @@ public class WifiHotspotRepository {
    protected String mLastPassword;
    protected LastPasswordListener mLastPasswordListener = new LastPasswordListener();

    protected MutableLiveData<Integer> mSpeedType;

    protected Boolean mIsDualBand;
    protected Boolean mIs5gAvailable;
    protected Boolean mIs6gAvailable;
    protected String mCurrentCountryCode;
    protected ActiveCountryCodeChangedCallback mActiveCountryCodeChangedCallback;

    public WifiHotspotRepository(@NonNull Context appContext, @NonNull WifiManager wifiManager) {
        mAppContext = appContext;
        mWifiManager = wifiManager;
@@ -73,4 +125,167 @@ public class WifiHotspotRepository {
        //first 12 chars from xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx
        return randomUUID.substring(0, 8) + randomUUID.substring(9, 13);
    }

    /**
     * Sets the tethered Wi-Fi AP Configuration.
     *
     * @param config A valid SoftApConfiguration specifying the configuration of the SAP.
     */
    public void setSoftApConfiguration(@NonNull SoftApConfiguration config) {
        mWifiManager.setSoftApConfiguration(config);
        refresh();
    }

    /**
     * Refresh data from the SoftApConfiguration.
     */
    public void refresh() {
        updateSpeedType();
    }

    /**
     * Set to auto refresh data.
     *
     * @param enabled whether the auto refresh should be enabled or not.
     */
    public void setAutoRefresh(boolean enabled) {
        if (enabled) {
            startAutoRefresh();
        } else {
            stopAutoRefresh();
        }
    }

    /**
     * Gets SpeedType LiveData
     */
    public LiveData<Integer> getSpeedType() {
        if (mSpeedType == null) {
            mSpeedType = new MutableLiveData<>();
            updateSpeedType();
        }
        return Transformations.distinctUntilChanged(mSpeedType);
    }

    protected void updateSpeedType() {
        if (mSpeedType == null) {
            return;
        }
        SoftApConfiguration config = mWifiManager.getSoftApConfiguration();
        if (config == null) {
            mSpeedType.setValue(SPEED_UNKNOWN);
            return;
        }
        int keyBand = config.getBand();
        logd("updateSpeedType(), getBand():" + keyBand);
        if (!is5gAvailable()) {
            keyBand &= ~BAND_5GHZ;
        }
        if (!is6gAvailable()) {
            keyBand &= ~BAND_6GHZ;
        }
        if ((keyBand & BAND_6GHZ) != 0) {
            keyBand = BAND_6GHZ;
        } else if (isDualBand() && is5gAvailable()) {
            keyBand = BAND_2GHZ_5GHZ;
        } else if ((keyBand & BAND_5GHZ) != 0) {
            keyBand = BAND_5GHZ;
        } else if ((keyBand & BAND_2GHZ) != 0) {
            keyBand = BAND_2GHZ;
        } else {
            keyBand = 0;
        }
        logd("updateSpeedType(), keyBand:" + keyBand);
        mSpeedType.setValue(sSpeedMap.get(keyBand));
    }

    protected boolean isDualBand() {
        if (mIsDualBand == null) {
            mIsDualBand = mWifiManager.isBridgedApConcurrencySupported();
            logd("isDualBand():" + mIsDualBand);
        }
        return mIsDualBand;
    }

    protected boolean is5gAvailable() {
        if (mIs5gAvailable == null) {
            // TODO(b/272450463): isBandAvailable(WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS) will
            //  cause crash in the old model device, use a simple check to workaround it first.
            mIs5gAvailable = (mWifiManager.is5GHzBandSupported() && mCurrentCountryCode != null);
            logd("is5gAvailable():" + mIs5gAvailable);
        }
        return mIs5gAvailable;
    }

    protected boolean is6gAvailable() {
        if (mIs6gAvailable == null) {
            mIs6gAvailable = mWifiManager.is6GHzBandSupported()
                    && isBandAvailable(WifiScanner.WIFI_BAND_6_GHZ);
            logd("is6gAvailable():" + mIs6gAvailable);
        }
        return mIs6gAvailable;
    }

    /**
     * Return whether the Hotspot band is available or not.
     *
     * @param band one of the following band constants defined in {@code WifiScanner#WIFI_BAND_*}
     *             constants.
     *             1. {@code WifiScanner#WIFI_BAND_5_GHZ_WITH_DFS}
     *             2. {@code WifiScanner#WIFI_BAND_6_GHZ}
     */
    protected boolean isBandAvailable(int band) {
        List<WifiAvailableChannel> channels = mWifiManager.getUsableChannels(band, OP_MODE_SAP);
        return (channels != null && channels.size() > 0);
    }

    protected void purgeRefreshData() {
        mIsDualBand = null;
        mIs5gAvailable = null;
        mIs6gAvailable = null;
    }

    protected void startAutoRefresh() {
        if (mActiveCountryCodeChangedCallback != null) {
            return;
        }
        logd("startMonitorSoftApConfiguration()");
        mActiveCountryCodeChangedCallback = new ActiveCountryCodeChangedCallback();
        mWifiManager.registerActiveCountryCodeChangedCallback(mAppContext.getMainExecutor(),
                mActiveCountryCodeChangedCallback);
    }

    protected void stopAutoRefresh() {
        if (mActiveCountryCodeChangedCallback == null) {
            return;
        }
        logd("stopMonitorSoftApConfiguration()");
        mWifiManager.unregisterActiveCountryCodeChangedCallback(mActiveCountryCodeChangedCallback);
        mActiveCountryCodeChangedCallback = null;
    }

    protected class ActiveCountryCodeChangedCallback implements
            WifiManager.ActiveCountryCodeChangedCallback {
        @Override
        public void onActiveCountryCodeChanged(String country) {
            logd("onActiveCountryCodeChanged(), country:" + country);
            mCurrentCountryCode = country;
            purgeRefreshData();
            refresh();
        }

        @Override
        public void onCountryCodeInactive() {
            logd("onCountryCodeInactive()");
            mCurrentCountryCode = null;
            purgeRefreshData();
            refresh();
        }
    }

    private static void logd(String msg) {
        if (DEBUG) {
            Log.d(TAG, msg);
        }
    }
}
Loading