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

Commit 88074f36 authored by Alex Kingsborough's avatar Alex Kingsborough
Browse files

Make instant hotspot multi user

Change-Id: If9921497d7b29955720a82f22f77b86c61857ad6
Bug: 371586248
Test: Manually connect to hotspot via Quick Settings
Test: atest passing for all affected unittest files
Flag: com.android.systemui.multiuser_wifi_picker_tracker_support
parent 66883bf0
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -15,6 +15,16 @@ flag {
    bug: "302578396"
}

flag {
   name: "multiuser_wifi_picker_tracker_support"
   namespace: "systemui"
   description: "Adds WifiPickerTracker support for multiple users to support when HSUM is enabled."
   bug: "371586248"
   metadata {
        purpose: PURPOSE_BUGFIX
   }
}

flag {
   name: "udfps_view_performance"
   namespace: "systemui"
+50 −35
Original line number Diff line number Diff line
@@ -16,18 +16,22 @@

package com.android.systemui.statusbar.connectivity

import android.content.Context
import android.os.UserHandle
import android.os.UserManager
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import android.platform.test.annotations.EnableFlags
import android.testing.TestableLooper.RunWithLooper
import androidx.lifecycle.Lifecycle
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.Flags.FLAG_MULTIUSER_WIFI_PICKER_TRACKER_SUPPORT
import com.android.systemui.SysuiTestCase
import com.android.systemui.settings.UserTracker
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.capture
import com.android.wifitrackerlib.WifiEntry
import com.android.wifitrackerlib.WifiPickerTracker
import com.google.common.truth.Truth.assertThat
import java.util.concurrent.Executor
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -35,36 +39,28 @@ import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.anyList
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations
import java.util.concurrent.Executor
import org.mockito.kotlin.any
import org.mockito.kotlin.mock

@SmallTest
@RunWith(AndroidJUnit4::class)
@RunWithLooper(setAsMainLooper = true)
class AccessPointControllerImplTest : SysuiTestCase() {

    @Mock
    private lateinit var userManager: UserManager
    @Mock
    private lateinit var userTracker: UserTracker
    @Mock
    private lateinit var wifiPickerTrackerFactory:
            WifiPickerTrackerFactory
    @Mock
    private lateinit var wifiPickerTracker: WifiPickerTracker
    @Mock
    private lateinit var callback: AccessPointController.AccessPointCallback
    @Mock
    private lateinit var otherCallback: AccessPointController.AccessPointCallback
    @Mock
    private lateinit var wifiEntryConnected: WifiEntry
    @Mock
    private lateinit var wifiEntryOther: WifiEntry
    @Captor
    private lateinit var wifiEntryListCaptor: ArgumentCaptor<List<WifiEntry>>
    @Mock private lateinit var userManager: UserManager
    @Mock private lateinit var userTracker: UserTracker
    @Mock private lateinit var wifiPickerTrackerFactory: WifiPickerTrackerFactory
    @Mock private lateinit var wifiPickerTracker: WifiPickerTracker
    @Mock private lateinit var callback: AccessPointController.AccessPointCallback
    @Mock private lateinit var otherCallback: AccessPointController.AccessPointCallback
    @Mock private lateinit var wifiEntryConnected: WifiEntry
    @Mock private lateinit var wifiEntryOther: WifiEntry
    @Captor private lateinit var wifiEntryListCaptor: ArgumentCaptor<List<WifiEntry>>

    private val instantExecutor = Executor { it.run() }
    private lateinit var controller: AccessPointControllerImpl
@@ -72,18 +68,20 @@ class AccessPointControllerImplTest : SysuiTestCase() {
    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        `when`(wifiPickerTrackerFactory.create(any(), any(), any())).thenReturn(wifiPickerTracker)
        `when`(wifiPickerTrackerFactory.create(any(), any(), any(), any()))
            .thenReturn(wifiPickerTracker)

        `when`(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntryConnected)
        `when`(wifiPickerTracker.wifiEntries).thenReturn(ArrayList<WifiEntry>().apply {
            add(wifiEntryOther)
        })
        `when`(wifiPickerTracker.wifiEntries)
            .thenReturn(ArrayList<WifiEntry>().apply { add(wifiEntryOther) })

        controller = AccessPointControllerImpl(
        controller =
            AccessPointControllerImpl(
                mContext,
                userManager,
                userTracker,
                instantExecutor,
                wifiPickerTrackerFactory
                wifiPickerTrackerFactory,
            )

        controller.init()
@@ -183,12 +181,14 @@ class AccessPointControllerImplTest : SysuiTestCase() {

    @Test
    fun testReturnEmptyListWhenNoWifiPickerTracker() {
        `when`(wifiPickerTrackerFactory.create(any(), any(), any())).thenReturn(null)
        val otherController = AccessPointControllerImpl(
        `when`(wifiPickerTrackerFactory.create(any(), any(), any(), any())).thenReturn(null)
        val otherController =
            AccessPointControllerImpl(
                mContext,
                userManager,
                userTracker,
                instantExecutor,
                wifiPickerTrackerFactory
                wifiPickerTrackerFactory,
            )
        otherController.init()

@@ -244,4 +244,19 @@ class AccessPointControllerImplTest : SysuiTestCase() {
        verify(wifiEntryOther).connect(any())
        verify(callback, never()).onSettingsActivityTriggered(any())
    }

    @Test
    @EnableFlags(FLAG_MULTIUSER_WIFI_PICKER_TRACKER_SUPPORT)
    fun switchUsers() {
        val primaryUserMockContext = mock<Context>()
        mContext.prepareCreateContextAsUser(UserHandle.of(PRIMARY_USER_ID), primaryUserMockContext)
        controller.onUserSwitched(PRIMARY_USER_ID)
        // Create is expected to be called once when the test starts and a second time when the user
        // is switched.
        verify(wifiPickerTrackerFactory, times(2)).create(any(), any(), any(), any())
    }

    private companion object {
        private const val PRIMARY_USER_ID = 1
    }
}
+7 −6
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoMod
import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoWifiRepository
import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.model.FakeWifiEventModel
import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl
import com.android.systemui.user.data.repository.FakeUserRepository
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.kotlinArgumentCaptor
@@ -71,6 +72,7 @@ class WifiRepositorySwitcherTest : SysuiTestCase() {
    private val demoModelFlow = MutableStateFlow<FakeWifiEventModel?>(null)

    private val mainExecutor = FakeExecutor(FakeSystemClock())
    private val userRepository = FakeUserRepository()

    private val testDispatcher = UnconfinedTestDispatcher()
    private val testScope = TestScope(testDispatcher)
@@ -82,10 +84,13 @@ class WifiRepositorySwitcherTest : SysuiTestCase() {
        // Never start in demo mode
        whenever(demoModeController.isInDemoMode).thenReturn(false)

        whenever(wifiPickerTrackerFactory.create(any(), any(), any())).thenReturn(wifiPickerTracker)
        whenever(wifiPickerTrackerFactory.create(any(), any(), any(), any()))
            .thenReturn(wifiPickerTracker)

        realImpl =
            WifiRepositoryImpl(
                mContext,
                userRepository,
                testScope.backgroundScope,
                mainExecutor,
                testDispatcher,
@@ -97,11 +102,7 @@ class WifiRepositorySwitcherTest : SysuiTestCase() {

        whenever(demoModeWifiDataSource.wifiEvents).thenReturn(demoModelFlow)

        demoImpl =
            DemoWifiRepository(
                demoModeWifiDataSource,
                testScope.backgroundScope,
            )
        demoImpl = DemoWifiRepository(demoModeWifiDataSource, testScope.backgroundScope)

        underTest =
            WifiRepositorySwitcher(
+24 −1
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.systemui.statusbar.connectivity;

import static com.android.systemui.Flags.multiuserWifiPickerTrackerSupport;

import android.content.Context;
import android.content.Intent;
import android.os.UserHandle;
import android.os.UserManager;
@@ -65,13 +68,16 @@ public class AccessPointControllerImpl implements AccessPointController,
    private final LifecycleRegistry mLifecycle = new LifecycleRegistry(this);

    private int mCurrentUser;
    private Context mContext;

    public AccessPointControllerImpl(
            Context context,
            UserManager userManager,
            UserTracker userTracker,
            Executor mainExecutor,
            WifiPickerTrackerFactory wifiPickerTrackerFactory
    ) {
        mContext = context;
        mUserManager = userManager;
        mUserTracker = userTracker;
        mCurrentUser = userTracker.getUserId();
@@ -87,7 +93,11 @@ public class AccessPointControllerImpl implements AccessPointController,
     */
    public void init() {
        if (mWifiPickerTracker == null) {
            mWifiPickerTracker = mWifiPickerTrackerFactory.create(this.getLifecycle(), this, TAG);
            // We are creating the WifiPickerTracker during init to make sure we have one
            // available at all times however we expect this to be recreated very quickly
            // with a user-specific context in onUserSwitched.
            mWifiPickerTracker =
                mWifiPickerTrackerFactory.create(mContext, this.getLifecycle(), this, TAG);
        }
    }

@@ -116,6 +126,19 @@ public class AccessPointControllerImpl implements AccessPointController,

    void onUserSwitched(int newUserId) {
        mCurrentUser = newUserId;
        // Return early if multiuser support is not enabled.
        if (!multiuserWifiPickerTrackerSupport()) {
            return;
        }

        if (mWifiPickerTracker != null) {
            mMainExecutor.execute(() -> mLifecycle.setCurrentState(Lifecycle.State.CREATED));
        }
        Context context = mContext.createContextAsUser(UserHandle.of(newUserId), /* flags= */ 0);
        mWifiPickerTracker = mWifiPickerTrackerFactory.create(context, mLifecycle, this, TAG);
        if (!mCallbacks.isEmpty()) {
            mMainExecutor.execute(() -> mLifecycle.setCurrentState(Lifecycle.State.STARTED));
        }
    }

    @Override
+12 −3
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.net.wifi.WifiManager
import android.os.Handler
import android.os.SimpleClock
import androidx.lifecycle.Lifecycle
import com.android.systemui.Flags.multiuserWifiPickerTrackerSupport
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.util.concurrency.ThreadFactory
@@ -41,7 +42,7 @@ import javax.inject.Inject
class WifiPickerTrackerFactory
@Inject
constructor(
    private val context: Context,
    private val applicationContext: Context,
    private val wifiManager: WifiManager?,
    private val connectivityManager: ConnectivityManager,
    private val systemClock: SystemClock,
@@ -64,16 +65,23 @@ constructor(
     * @return a new [WifiPickerTracker] or null if [WifiManager] is null.
     */
    fun create(
        userContext: Context,
        lifecycle: Lifecycle,
        listener: WifiPickerTrackerCallback,
        name: String,
    ): WifiPickerTracker? {
        return if (wifiManager == null) {
            null
        } else
        } else {
            val contextToUse =
                if (multiuserWifiPickerTrackerSupport()) {
                    userContext
                } else {
                    applicationContext
                }
            WifiPickerTracker(
                lifecycle,
                context,
                contextToUse,
                wifiManager,
                connectivityManager,
                mainHandler,
@@ -87,6 +95,7 @@ constructor(
                listener,
            )
        }
    }

    companion object {
        /** Max age of tracked WifiEntries. */
Loading