Loading packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt +16 −1 Original line number Diff line number Diff line Loading @@ -36,6 +36,8 @@ import android.widget.AdapterView import android.widget.ArrayAdapter import android.widget.ImageView import android.widget.TextView import android.window.OnBackInvokedCallback import android.window.OnBackInvokedDispatcher import androidx.activity.ComponentActivity import androidx.constraintlayout.helper.widget.Flow import androidx.lifecycle.ViewModelProvider Loading Loading @@ -67,7 +69,7 @@ private const val USER_VIEW = "user_view" /** * Support a fullscreen user switcher */ class UserSwitcherActivity @Inject constructor( open class UserSwitcherActivity @Inject constructor( private val userSwitcherController: UserSwitcherController, private val broadcastDispatcher: BroadcastDispatcher, private val falsingCollector: FalsingCollector, Loading @@ -83,6 +85,7 @@ class UserSwitcherActivity @Inject constructor( private var popupMenu: UserSwitcherPopupMenu? = null private lateinit var addButton: View private var addUserRecords = mutableListOf<UserRecord>() private val onBackCallback = OnBackInvokedCallback { finish() } private val userSwitchedCallback: UserTracker.Callback = object : UserTracker.Callback { override fun onUserChanged(newUser: Int, userContext: Context) { finish() Loading @@ -105,7 +108,11 @@ class UserSwitcherActivity @Inject constructor( override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) createActivity() } @VisibleForTesting fun createActivity() { setContentView(R.layout.user_switcher_fullscreen) window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION Loading Loading @@ -148,6 +155,9 @@ class UserSwitcherActivity @Inject constructor( } } onBackInvokedDispatcher.registerOnBackInvokedCallback( OnBackInvokedDispatcher.PRIORITY_DEFAULT, onBackCallback) userSwitcherController.init(parent) initBroadcastReceiver() Loading Loading @@ -278,7 +288,12 @@ class UserSwitcherActivity @Inject constructor( if (isUsingModernArchitecture()) { return } destroyActivity() } @VisibleForTesting fun destroyActivity() { onBackInvokedDispatcher.unregisterOnBackInvokedCallback(onBackCallback) broadcastDispatcher.unregisterReceiver(broadcastReceiver) userTracker.removeCallback(userSwitchedCallback) } Loading packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt +66 −2 Original line number Diff line number Diff line Loading @@ -16,11 +16,17 @@ package com.android.systemui.user import android.app.Application import android.os.UserManager import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import android.view.LayoutInflater import android.view.View import android.view.Window import android.window.OnBackInvokedCallback import android.window.OnBackInvokedDispatcher import androidx.test.filters.SmallTest import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.classifier.FalsingCollector Loading @@ -29,12 +35,25 @@ import com.android.systemui.plugins.FalsingManager import com.android.systemui.settings.UserTracker import com.android.systemui.statusbar.policy.UserSwitcherController import com.android.systemui.user.ui.viewmodel.UserSwitcherViewModel import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor import org.mockito.Captor import org.mockito.Mock import org.mockito.Mockito.`when` import org.mockito.Mockito.any import org.mockito.Mockito.anyInt import org.mockito.Mockito.doNothing import org.mockito.Mockito.eq import org.mockito.Mockito.mock import org.mockito.Mockito.spy import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations import java.util.concurrent.Executor @SmallTest @RunWith(AndroidTestingRunner::class) Loading @@ -60,11 +79,22 @@ class UserSwitcherActivityTest : SysuiTestCase() { private lateinit var flags: FeatureFlags @Mock private lateinit var viewModelFactoryLazy: dagger.Lazy<UserSwitcherViewModel.Factory> @Mock private lateinit var onBackDispatcher: OnBackInvokedDispatcher @Mock private lateinit var decorView: View @Mock private lateinit var window: Window @Mock private lateinit var userSwitcherRootView: UserSwitcherRootView @Captor private lateinit var onBackInvokedCallback: ArgumentCaptor<OnBackInvokedCallback> var isFinished = false @Before fun setUp() { MockitoAnnotations.initMocks(this) activity = UserSwitcherActivity( activity = spy(object : UserSwitcherActivity( userSwitcherController, broadcastDispatcher, falsingCollector, Loading @@ -73,7 +103,21 @@ class UserSwitcherActivityTest : SysuiTestCase() { userTracker, flags, viewModelFactoryLazy, ) ) { override fun getOnBackInvokedDispatcher() = onBackDispatcher override fun getMainExecutor(): Executor = FakeExecutor(FakeSystemClock()) override fun finish() { isFinished = true } }) `when`(activity.window).thenReturn(window) `when`(window.decorView).thenReturn(decorView) `when`(activity.findViewById<UserSwitcherRootView>(R.id.user_switcher_root)) .thenReturn(userSwitcherRootView) `when`(activity.findViewById<View>(R.id.cancel)).thenReturn(mock(View::class.java)) `when`(activity.findViewById<View>(R.id.add)).thenReturn(mock(View::class.java)) `when`(activity.application).thenReturn(mock(Application::class.java)) doNothing().`when`(activity).setContentView(anyInt()) } @Test Loading @@ -85,4 +129,24 @@ class UserSwitcherActivityTest : SysuiTestCase() { assertThat(activity.getMaxColumns(7)).isEqualTo(4) assertThat(activity.getMaxColumns(9)).isEqualTo(5) } @Test fun onCreate_callbackRegistration() { activity.createActivity() verify(onBackDispatcher).registerOnBackInvokedCallback( eq(OnBackInvokedDispatcher.PRIORITY_DEFAULT), any()) activity.destroyActivity() verify(onBackDispatcher).unregisterOnBackInvokedCallback(any()) } @Test fun onBackInvokedCallback_finishesActivity() { activity.createActivity() verify(onBackDispatcher).registerOnBackInvokedCallback( eq(OnBackInvokedDispatcher.PRIORITY_DEFAULT), onBackInvokedCallback.capture()) onBackInvokedCallback.value.onBackInvoked() assertThat(isFinished).isTrue() } } Loading
packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt +16 −1 Original line number Diff line number Diff line Loading @@ -36,6 +36,8 @@ import android.widget.AdapterView import android.widget.ArrayAdapter import android.widget.ImageView import android.widget.TextView import android.window.OnBackInvokedCallback import android.window.OnBackInvokedDispatcher import androidx.activity.ComponentActivity import androidx.constraintlayout.helper.widget.Flow import androidx.lifecycle.ViewModelProvider Loading Loading @@ -67,7 +69,7 @@ private const val USER_VIEW = "user_view" /** * Support a fullscreen user switcher */ class UserSwitcherActivity @Inject constructor( open class UserSwitcherActivity @Inject constructor( private val userSwitcherController: UserSwitcherController, private val broadcastDispatcher: BroadcastDispatcher, private val falsingCollector: FalsingCollector, Loading @@ -83,6 +85,7 @@ class UserSwitcherActivity @Inject constructor( private var popupMenu: UserSwitcherPopupMenu? = null private lateinit var addButton: View private var addUserRecords = mutableListOf<UserRecord>() private val onBackCallback = OnBackInvokedCallback { finish() } private val userSwitchedCallback: UserTracker.Callback = object : UserTracker.Callback { override fun onUserChanged(newUser: Int, userContext: Context) { finish() Loading @@ -105,7 +108,11 @@ class UserSwitcherActivity @Inject constructor( override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) createActivity() } @VisibleForTesting fun createActivity() { setContentView(R.layout.user_switcher_fullscreen) window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION Loading Loading @@ -148,6 +155,9 @@ class UserSwitcherActivity @Inject constructor( } } onBackInvokedDispatcher.registerOnBackInvokedCallback( OnBackInvokedDispatcher.PRIORITY_DEFAULT, onBackCallback) userSwitcherController.init(parent) initBroadcastReceiver() Loading Loading @@ -278,7 +288,12 @@ class UserSwitcherActivity @Inject constructor( if (isUsingModernArchitecture()) { return } destroyActivity() } @VisibleForTesting fun destroyActivity() { onBackInvokedDispatcher.unregisterOnBackInvokedCallback(onBackCallback) broadcastDispatcher.unregisterReceiver(broadcastReceiver) userTracker.removeCallback(userSwitchedCallback) } Loading
packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt +66 −2 Original line number Diff line number Diff line Loading @@ -16,11 +16,17 @@ package com.android.systemui.user import android.app.Application import android.os.UserManager import android.testing.AndroidTestingRunner import android.testing.TestableLooper.RunWithLooper import android.view.LayoutInflater import android.view.View import android.view.Window import android.window.OnBackInvokedCallback import android.window.OnBackInvokedDispatcher import androidx.test.filters.SmallTest import com.android.systemui.R import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.classifier.FalsingCollector Loading @@ -29,12 +35,25 @@ import com.android.systemui.plugins.FalsingManager import com.android.systemui.settings.UserTracker import com.android.systemui.statusbar.policy.UserSwitcherController import com.android.systemui.user.ui.viewmodel.UserSwitcherViewModel import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.ArgumentCaptor import org.mockito.Captor import org.mockito.Mock import org.mockito.Mockito.`when` import org.mockito.Mockito.any import org.mockito.Mockito.anyInt import org.mockito.Mockito.doNothing import org.mockito.Mockito.eq import org.mockito.Mockito.mock import org.mockito.Mockito.spy import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations import java.util.concurrent.Executor @SmallTest @RunWith(AndroidTestingRunner::class) Loading @@ -60,11 +79,22 @@ class UserSwitcherActivityTest : SysuiTestCase() { private lateinit var flags: FeatureFlags @Mock private lateinit var viewModelFactoryLazy: dagger.Lazy<UserSwitcherViewModel.Factory> @Mock private lateinit var onBackDispatcher: OnBackInvokedDispatcher @Mock private lateinit var decorView: View @Mock private lateinit var window: Window @Mock private lateinit var userSwitcherRootView: UserSwitcherRootView @Captor private lateinit var onBackInvokedCallback: ArgumentCaptor<OnBackInvokedCallback> var isFinished = false @Before fun setUp() { MockitoAnnotations.initMocks(this) activity = UserSwitcherActivity( activity = spy(object : UserSwitcherActivity( userSwitcherController, broadcastDispatcher, falsingCollector, Loading @@ -73,7 +103,21 @@ class UserSwitcherActivityTest : SysuiTestCase() { userTracker, flags, viewModelFactoryLazy, ) ) { override fun getOnBackInvokedDispatcher() = onBackDispatcher override fun getMainExecutor(): Executor = FakeExecutor(FakeSystemClock()) override fun finish() { isFinished = true } }) `when`(activity.window).thenReturn(window) `when`(window.decorView).thenReturn(decorView) `when`(activity.findViewById<UserSwitcherRootView>(R.id.user_switcher_root)) .thenReturn(userSwitcherRootView) `when`(activity.findViewById<View>(R.id.cancel)).thenReturn(mock(View::class.java)) `when`(activity.findViewById<View>(R.id.add)).thenReturn(mock(View::class.java)) `when`(activity.application).thenReturn(mock(Application::class.java)) doNothing().`when`(activity).setContentView(anyInt()) } @Test Loading @@ -85,4 +129,24 @@ class UserSwitcherActivityTest : SysuiTestCase() { assertThat(activity.getMaxColumns(7)).isEqualTo(4) assertThat(activity.getMaxColumns(9)).isEqualTo(5) } @Test fun onCreate_callbackRegistration() { activity.createActivity() verify(onBackDispatcher).registerOnBackInvokedCallback( eq(OnBackInvokedDispatcher.PRIORITY_DEFAULT), any()) activity.destroyActivity() verify(onBackDispatcher).unregisterOnBackInvokedCallback(any()) } @Test fun onBackInvokedCallback_finishesActivity() { activity.createActivity() verify(onBackDispatcher).registerOnBackInvokedCallback( eq(OnBackInvokedDispatcher.PRIORITY_DEFAULT), onBackInvokedCallback.capture()) onBackInvokedCallback.value.onBackInvoked() assertThat(isFinished).isTrue() } }