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

Commit 115873a1 authored by lesl's avatar lesl
Browse files

softap: Update LOHS API usage

Use SoftApConfiguration to replace WifiConfiguration
1. Deprecate public old getWifiConfiguration API.
2. Add new API getSoftApConfiguration in LocalOnlyHotspotReservation

The new security type SAE and SAE Transition mode support in Soft Ap,
Return null config when LOHS enable and security type is SAE or SAE Transition mode.

Bug: 138801922
Bug: 142752869
Test: atest frameworks/base/wifi/tests/
Test: atest android.net.wifi.cts.WifiManagerTest#testStartLocalOnlyHotspotSingleRequestByApps
Test: atest android.net.wifi.cts.WifiManagerTest#testStartLocalOnlyHotspotSuccess
Test: atest android.net.wifi.cts.WifiManagerTest#testStartLocalOnlyHotspotWithConfig
Change-Id: I32fbceff03b3821dde4f05356abb7f1645b90127
parent 64232b75
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -30756,7 +30756,8 @@ package android.net.wifi {
  public class WifiManager.LocalOnlyHotspotReservation implements java.lang.AutoCloseable {
    method public void close();
    method public android.net.wifi.WifiConfiguration getWifiConfiguration();
    method @NonNull public android.net.wifi.SoftApConfiguration getSoftApConfiguration();
    method @Deprecated @Nullable public android.net.wifi.WifiConfiguration getWifiConfiguration();
  }
  public class WifiManager.MulticastLock {
+2 −2
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

package android.net.wifi;

import android.net.wifi.WifiConfiguration;
import android.net.wifi.SoftApConfiguration;

/**
 * Communicates LOHS status back to the application process.
@@ -24,7 +24,7 @@ import android.net.wifi.WifiConfiguration;
 * @hide
 */
oneway interface ILocalOnlyHotspotCallback {
    void onHotspotStarted(in WifiConfiguration config);
    void onHotspotStarted(in SoftApConfiguration config);
    void onHotspotStopped();
    void onHotspotFailed(int reason);
}
+59 −9
Original line number Diff line number Diff line
@@ -2971,7 +2971,7 @@ public class WifiManager {
     * Each application can make a single active call to this method. The {@link
     * LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} callback supplies the
     * requestor with a {@link LocalOnlyHotspotReservation} that contains a
     * {@link WifiConfiguration} with the SSID, security type and credentials needed to connect
     * {@link SoftApConfiguration} with the SSID, security type and credentials needed to connect
     * to the hotspot.  Communicating this information is up to the application.
     * <p>
     * If the LocalOnlyHotspot cannot be created, the {@link LocalOnlyHotspotCallback#onFailed(int)}
@@ -3136,7 +3136,7 @@ public class WifiManager {
     * Allow callers (Settings UI) to watch LocalOnlyHotspot state changes.  Callers will
     * receive a {@link LocalOnlyHotspotSubscription} object as a parameter of the
     * {@link LocalOnlyHotspotObserver#onRegistered(LocalOnlyHotspotSubscription)}. The registered
     * callers will receive the {@link LocalOnlyHotspotObserver#onStarted(WifiConfiguration)} and
     * callers will receive the {@link LocalOnlyHotspotObserver#onStarted(SoftApConfiguration)} and
     * {@link LocalOnlyHotspotObserver#onStopped()} callbacks.
     * <p>
     * Applications should have the
@@ -3711,13 +3711,13 @@ public class WifiManager {
    }

    /**
     * LocalOnlyHotspotReservation that contains the {@link WifiConfiguration} for the active
     * LocalOnlyHotspotReservation that contains the {@link SoftApConfiguration} for the active
     * LocalOnlyHotspot request.
     * <p>
     * Applications requesting LocalOnlyHotspot for sharing will receive an instance of the
     * LocalOnlyHotspotReservation in the
     * {@link LocalOnlyHotspotCallback#onStarted(LocalOnlyHotspotReservation)} call.  This
     * reservation contains the relevant {@link WifiConfiguration}.
     * reservation contains the relevant {@link SoftApConfiguration}.
     * When an application is done with the LocalOnlyHotspot, they should call {@link
     * LocalOnlyHotspotReservation#close()}.  Once this happens, the application will not receive
     * any further callbacks. If the LocalOnlyHotspot is stopped due to a
@@ -3727,20 +3727,70 @@ public class WifiManager {
    public class LocalOnlyHotspotReservation implements AutoCloseable {

        private final CloseGuard mCloseGuard = new CloseGuard();
        private final WifiConfiguration mConfig;
        private final SoftApConfiguration mConfig;
        private boolean mClosed = false;

        /** @hide */
        @VisibleForTesting
        public LocalOnlyHotspotReservation(WifiConfiguration config) {
        public LocalOnlyHotspotReservation(SoftApConfiguration config) {
            mConfig = config;
            mCloseGuard.open("close");
        }

        /**
         * Returns the {@link WifiConfiguration} of the current Local Only Hotspot (LOHS).
         * May be null if hotspot enabled and security type is not
         * {@link WifiConfiguration.KeyMgmt.None} or {@link WifiConfiguration.KeyMgmt.WPA2_PSK}.
         *
         * @deprecated Use {@link getSoftApConfiguration()} to get the LOHS configuration.
         */
        @Deprecated
        @Nullable
        public WifiConfiguration getWifiConfiguration() {
            return convertToWifiConfiguration(mConfig);
        }

        /**
         * Returns the {@link SoftapConfiguration} of the current Local Only Hotspot (LOHS).
         */
        @NonNull
        public SoftApConfiguration getSoftApConfiguration() {
            return mConfig;
        }

        /**
         * Convert to WifiConfiguration from SoftApConfuration.
         *
         * Copy to the filed which is public and used by SoftAp.
         */
        private WifiConfiguration convertToWifiConfiguration(SoftApConfiguration softApConfig) {
            if (softApConfig == null) return null;

            WifiConfiguration wifiConfig = new WifiConfiguration();
            wifiConfig.networkId = WifiConfiguration.LOCAL_ONLY_NETWORK_ID;
            wifiConfig.SSID = softApConfig.getSsid();
            if (softApConfig.getBssid() != null) {
                wifiConfig.BSSID = softApConfig.getBssid().toString();
            }
            wifiConfig.preSharedKey = softApConfig.getPassphrase();
            wifiConfig.hiddenSSID = softApConfig.isHiddenSsid();
            int authType = softApConfig.getSecurityType();
            switch (authType) {
                case SoftApConfiguration.SECURITY_TYPE_OPEN:
                    authType = WifiConfiguration.KeyMgmt.NONE;
                    wifiConfig.allowedKeyManagement.set(authType);
                    break;
                case SoftApConfiguration.SECURITY_TYPE_WPA2_PSK:
                    authType = WifiConfiguration.KeyMgmt.WPA2_PSK;
                    wifiConfig.allowedKeyManagement.set(authType);
                    break;
                default:
                    wifiConfig = null;
                    break;
            }
            return wifiConfig;
        }

        @Override
        public void close() {
            try {
@@ -3835,7 +3885,7 @@ public class WifiManager {
        }

        @Override
        public void onHotspotStarted(WifiConfiguration config) {
        public void onHotspotStarted(SoftApConfiguration config) {
            WifiManager manager = mWifiManager.get();
            if (manager == null) return;

@@ -3927,7 +3977,7 @@ public class WifiManager {
        /**
         * LocalOnlyHotspot started with the supplied config.
         */
        public void onStarted(WifiConfiguration config) {};
        public void onStarted(SoftApConfiguration config) {};

        /**
         * LocalOnlyHotspot stopped.
@@ -3967,7 +4017,7 @@ public class WifiManager {
        }

        @Override
        public void onHotspotStarted(WifiConfiguration config) {
        public void onHotspotStarted(SoftApConfiguration config) {
            WifiManager manager = mWifiManager.get();
            if (manager == null) return;

+111 −22
Original line number Diff line number Diff line
@@ -105,6 +105,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Executor;

/**
@@ -146,6 +147,50 @@ public class WifiManagerTest {
    private ScanResultsCallback mScanResultsCallback;
    private WifiActivityEnergyInfo mWifiActivityEnergyInfo;

    /**
     * Util function to check public field which used for softap  in WifiConfiguration
     * same as the value in SoftApConfiguration.
     *
     */
    private boolean compareWifiAndSoftApConfiguration(
            SoftApConfiguration softApConfig, WifiConfiguration wifiConfig) {
        if (!Objects.equals(wifiConfig.SSID, softApConfig.getSsid())) {
            return false;
        }
        if (!Objects.equals(wifiConfig.BSSID, softApConfig.getBssid())) {
            return false;
        }
        if (!Objects.equals(wifiConfig.preSharedKey, softApConfig.getPassphrase())) {
            return false;
        }

        if (wifiConfig.hiddenSSID != softApConfig.isHiddenSsid()) {
            return false;
        }
        switch (softApConfig.getSecurityType()) {
            case SoftApConfiguration.SECURITY_TYPE_OPEN:
                if (wifiConfig.getAuthType() != WifiConfiguration.KeyMgmt.NONE) {
                    return false;
                }
                break;
            case SoftApConfiguration.SECURITY_TYPE_WPA2_PSK:
                if (wifiConfig.getAuthType() != WifiConfiguration.KeyMgmt.WPA2_PSK) {
                    return false;
                }
                break;
            default:
                return false;
        }
        return true;
    }

    private SoftApConfiguration generatorTestSoftApConfig() {
        return new SoftApConfiguration.Builder()
                .setSsid("TestSSID")
                .setPassphrase("TestPassphrase", SoftApConfiguration.SECURITY_TYPE_WPA2_PSK)
                .build();
    }

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
@@ -210,12 +255,12 @@ public class WifiManagerTest {
     */
    @Test
    public void testStartTetheredHotspotCallsServiceWithSoftApConfig() throws Exception {
        SoftApConfiguration mSoftApConfig = new SoftApConfiguration.Builder().build();
        when(mWifiService.startTetheredHotspot(eq(mSoftApConfig))).thenReturn(true);
        assertTrue(mWifiManager.startTetheredHotspot(mSoftApConfig));
        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
        when(mWifiService.startTetheredHotspot(eq(softApConfig))).thenReturn(true);
        assertTrue(mWifiManager.startTetheredHotspot(softApConfig));

        when(mWifiService.startTetheredHotspot(eq(mSoftApConfig))).thenReturn(false);
        assertFalse(mWifiManager.startTetheredHotspot(mSoftApConfig));
        when(mWifiService.startTetheredHotspot(eq(softApConfig))).thenReturn(false);
        assertFalse(mWifiManager.startTetheredHotspot(softApConfig));
    }

    /**
@@ -237,14 +282,18 @@ public class WifiManagerTest {
     */
    @Test
    public void testCreationAndCloseOfLocalOnlyHotspotReservation() throws Exception {
        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
        mWifiManager.startLocalOnlyHotspot(callback, mHandler);

        callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig));
        callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(softApConfig));

        assertEquals(softApConfig, callback.mRes.getSoftApConfiguration());
        WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration();
        assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig));

        assertEquals(mApConfig, callback.mRes.getWifiConfiguration());
        callback.mRes.close();
        verify(mWifiService).stopLocalOnlyHotspot();
    }
@@ -255,15 +304,18 @@ public class WifiManagerTest {
    @Test
    public void testLocalOnlyHotspotReservationCallsStopProperlyInTryWithResources()
            throws Exception {
        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
        when(mWifiService.startLocalOnlyHotspot(any(ILocalOnlyHotspotCallback.class), anyString(),
                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
        mWifiManager.startLocalOnlyHotspot(callback, mHandler);

        callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(mApConfig));
        callback.onStarted(mWifiManager.new LocalOnlyHotspotReservation(softApConfig));

        try (WifiManager.LocalOnlyHotspotReservation res = callback.mRes) {
            assertEquals(mApConfig, res.getWifiConfiguration());
            assertEquals(softApConfig, res.getSoftApConfiguration());
            WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration();
            assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig));
        }

        verify(mWifiService).stopLocalOnlyHotspot();
@@ -313,6 +365,7 @@ public class WifiManagerTest {
     */
    @Test
    public void testLocalOnlyHotspotCallback() {
        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
        assertFalse(callback.mOnStartedCalled);
        assertFalse(callback.mOnStoppedCalled);
@@ -321,7 +374,7 @@ public class WifiManagerTest {

        // test onStarted
        WifiManager.LocalOnlyHotspotReservation res =
                mWifiManager.new LocalOnlyHotspotReservation(mApConfig);
                mWifiManager.new LocalOnlyHotspotReservation(softApConfig);
        callback.onStarted(res);
        assertEquals(res, callback.mRes);
        assertTrue(callback.mOnStartedCalled);
@@ -347,7 +400,7 @@ public class WifiManagerTest {
        public boolean mOnRegistered = false;
        public boolean mOnStartedCalled = false;
        public boolean mOnStoppedCalled = false;
        public WifiConfiguration mConfig = null;
        public SoftApConfiguration mConfig = null;
        public LocalOnlyHotspotSubscription mSub = null;
        public long mCallingThreadId = -1;

@@ -359,7 +412,7 @@ public class WifiManagerTest {
        }

        @Override
        public void onStarted(WifiConfiguration config) {
        public void onStarted(SoftApConfiguration config) {
            mOnStartedCalled = true;
            mConfig = config;
            mCallingThreadId = Thread.currentThread().getId();
@@ -378,6 +431,7 @@ public class WifiManagerTest {
    @Test
    public void testLocalOnlyHotspotObserver() {
        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
        assertFalse(observer.mOnRegistered);
        assertFalse(observer.mOnStartedCalled);
        assertFalse(observer.mOnStoppedCalled);
@@ -393,18 +447,18 @@ public class WifiManagerTest {
        assertEquals(null, observer.mConfig);
        assertEquals(sub, observer.mSub);

        observer.onStarted(mApConfig);
        observer.onStarted(softApConfig);
        assertTrue(observer.mOnRegistered);
        assertTrue(observer.mOnStartedCalled);
        assertFalse(observer.mOnStoppedCalled);
        assertEquals(mApConfig, observer.mConfig);
        assertEquals(softApConfig, observer.mConfig);
        assertEquals(sub, observer.mSub);

        observer.onStopped();
        assertTrue(observer.mOnRegistered);
        assertTrue(observer.mOnStartedCalled);
        assertTrue(observer.mOnStoppedCalled);
        assertEquals(mApConfig, observer.mConfig);
        assertEquals(softApConfig, observer.mConfig);
        assertEquals(sub, observer.mSub);
    }

@@ -486,6 +540,39 @@ public class WifiManagerTest {
     */
    @Test
    public void testOnStartedIsCalledWithReservation() throws Exception {
        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
        TestLooper callbackLooper = new TestLooper();
        Handler callbackHandler = new Handler(callbackLooper.getLooper());
        ArgumentCaptor<ILocalOnlyHotspotCallback> internalCallback =
                ArgumentCaptor.forClass(ILocalOnlyHotspotCallback.class);
        when(mWifiService.startLocalOnlyHotspot(internalCallback.capture(), anyString(),
                nullable(String.class), eq(null))).thenReturn(REQUEST_REGISTERED);
        mWifiManager.startLocalOnlyHotspot(callback, callbackHandler);
        callbackLooper.dispatchAll();
        mLooper.dispatchAll();
        assertFalse(callback.mOnStartedCalled);
        assertEquals(null, callback.mRes);
        // now trigger the callback
        internalCallback.getValue().onHotspotStarted(softApConfig);
        mLooper.dispatchAll();
        callbackLooper.dispatchAll();
        assertTrue(callback.mOnStartedCalled);
        assertEquals(softApConfig, callback.mRes.getSoftApConfiguration());
        WifiConfiguration wifiConfig = callback.mRes.getWifiConfiguration();
        assertTrue(compareWifiAndSoftApConfiguration(softApConfig, wifiConfig));
    }

    /**
     * Verify the LOHS onStarted callback is triggered when WifiManager receives a HOTSPOT_STARTED
     * message from WifiServiceImpl when softap enabled with SAE security type.
     */
    @Test
    public void testOnStartedIsCalledWithReservationAndSaeSoftApConfig() throws Exception {
        SoftApConfiguration softApConfig = new SoftApConfiguration.Builder()
                .setSsid("TestSSID")
                .setPassphrase("TestPassphrase", SoftApConfiguration.SECURITY_TYPE_WPA3_SAE)
                .build();
        TestLocalOnlyHotspotCallback callback = new TestLocalOnlyHotspotCallback();
        TestLooper callbackLooper = new TestLooper();
        Handler callbackHandler = new Handler(callbackLooper.getLooper());
@@ -499,11 +586,12 @@ public class WifiManagerTest {
        assertFalse(callback.mOnStartedCalled);
        assertEquals(null, callback.mRes);
        // now trigger the callback
        internalCallback.getValue().onHotspotStarted(mApConfig);
        internalCallback.getValue().onHotspotStarted(softApConfig);
        mLooper.dispatchAll();
        callbackLooper.dispatchAll();
        assertTrue(callback.mOnStartedCalled);
        assertEquals(mApConfig, callback.mRes.getWifiConfiguration());
        assertEquals(softApConfig, callback.mRes.getSoftApConfiguration());
        assertEquals(null, callback.mRes.getWifiConfiguration());
    }

    /**
@@ -1035,6 +1123,7 @@ public class WifiManagerTest {
     */
    @Test
    public void testObserverOnStartedIsCalledWithWifiConfig() throws Exception {
        SoftApConfiguration softApConfig = generatorTestSoftApConfig();
        TestLocalOnlyHotspotObserver observer = new TestLocalOnlyHotspotObserver();
        TestLooper observerLooper = new TestLooper();
        Handler observerHandler = new Handler(observerLooper.getLooper());
@@ -1046,11 +1135,11 @@ public class WifiManagerTest {
        mLooper.dispatchAll();
        assertFalse(observer.mOnStartedCalled);
        // now trigger the callback
        internalCallback.getValue().onHotspotStarted(mApConfig);
        internalCallback.getValue().onHotspotStarted(softApConfig);
        mLooper.dispatchAll();
        observerLooper.dispatchAll();
        assertTrue(observer.mOnStartedCalled);
        assertEquals(mApConfig, observer.mConfig);
        assertEquals(softApConfig, observer.mConfig);
    }

    /**
@@ -1246,7 +1335,7 @@ public class WifiManagerTest {
     */
    @Test
    public void testSetSoftApConfigurationSuccessReturnsTrue() throws Exception {
        SoftApConfiguration apConfig = new SoftApConfiguration.Builder().build();
        SoftApConfiguration apConfig = generatorTestSoftApConfig();

        when(mWifiService.setSoftApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
                .thenReturn(true);
@@ -1258,7 +1347,7 @@ public class WifiManagerTest {
     */
    @Test
    public void testSetSoftApConfigurationFailureReturnsFalse() throws Exception {
        SoftApConfiguration apConfig = new SoftApConfiguration.Builder().build();
        SoftApConfiguration apConfig = generatorTestSoftApConfig();

        when(mWifiService.setSoftApConfiguration(eq(apConfig), eq(TEST_PACKAGE_NAME)))
                .thenReturn(false);
@@ -1273,7 +1362,7 @@ public class WifiManagerTest {
        doThrow(new SecurityException()).when(mWifiService).setSoftApConfiguration(any(), any());

        try {
            mWifiManager.setSoftApConfiguration(new SoftApConfiguration.Builder().build());
            mWifiManager.setSoftApConfiguration(generatorTestSoftApConfig());
            fail("setWifiApConfiguration should rethrow Exceptions from WifiService");
        } catch (SecurityException e) { }
    }