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

Commit c7bde954 authored by Alex Kingsborough's avatar Alex Kingsborough Committed by Android (Google) Code Review
Browse files

Merge "Make instant hotspot multi user" into main

parents fe1997fc 88074f36
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