Loading packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt +1 −0 Original line number Diff line number Diff line Loading @@ -372,6 +372,7 @@ class PasswordBouncerViewModelTest : SysuiTestCase() { nonAuxiliarySubtypes: Int, ): InputMethodModel { return InputMethodModel( userId = UUID.randomUUID().mostSignificantBits.toInt(), imeId = UUID.randomUUID().toString(), subtypes = List(auxiliarySubtypes + nonAuxiliarySubtypes) { Loading packages/SystemUI/multivalentTests/src/com/android/systemui/inputmethod/data/repository/InputMethodRepositoryTest.kt +24 −13 Original line number Diff line number Diff line Loading @@ -56,9 +56,6 @@ class InputMethodRepositoryTest : SysuiTestCase() { fun setUp() { MockitoAnnotations.initMocks(this) whenever(inputMethodManager.getEnabledInputMethodSubtypeList(eq(null), anyBoolean())) .thenReturn(listOf()) underTest = InputMethodRepositoryImpl( backgroundDispatcher = kosmos.testDispatcher, Loading @@ -71,10 +68,16 @@ class InputMethodRepositoryTest : SysuiTestCase() { testScope.runTest { whenever(inputMethodManager.getEnabledInputMethodListAsUser(eq(USER_HANDLE))) .thenReturn(listOf()) whenever(inputMethodManager.getEnabledInputMethodSubtypeList(any(), anyBoolean())) whenever( inputMethodManager.getEnabledInputMethodSubtypeListAsUser( any(), anyBoolean(), eq(USER_HANDLE) ) ) .thenReturn(listOf()) assertThat(underTest.enabledInputMethods(USER_ID, fetchSubtypes = true).count()) assertThat(underTest.enabledInputMethods(USER_HANDLE, fetchSubtypes = true).count()) .isEqualTo(0) } Loading @@ -83,11 +86,20 @@ class InputMethodRepositoryTest : SysuiTestCase() { testScope.runTest { val subtypeId = 123 val isAuxiliary = true val selectedImiId = "imiId" val selectedImi = mock<InputMethodInfo>() whenever(selectedImi.id).thenReturn(selectedImiId) whenever(inputMethodManager.getCurrentInputMethodInfoAsUser(eq(USER_HANDLE))) .thenReturn(selectedImi) whenever(inputMethodManager.getEnabledInputMethodListAsUser(eq(USER_HANDLE))) .thenReturn(listOf(mock<InputMethodInfo>())) whenever(inputMethodManager.getEnabledInputMethodSubtypeList(any(), anyBoolean())) .thenReturn(listOf()) whenever(inputMethodManager.getEnabledInputMethodSubtypeList(eq(null), anyBoolean())) .thenReturn(listOf(selectedImi)) whenever( inputMethodManager.getEnabledInputMethodSubtypeListAsUser( eq(selectedImiId), anyBoolean(), eq(USER_HANDLE) ) ) .thenReturn( listOf( InputMethodSubtype.InputMethodSubtypeBuilder() Loading @@ -97,7 +109,7 @@ class InputMethodRepositoryTest : SysuiTestCase() { ) ) val result = underTest.selectedInputMethodSubtypes() val result = underTest.selectedInputMethodSubtypes(USER_HANDLE) assertThat(result).hasSize(1) assertThat(result.first().subtypeId).isEqualTo(subtypeId) assertThat(result.first().isAuxiliary).isEqualTo(isAuxiliary) Loading @@ -118,7 +130,6 @@ class InputMethodRepositoryTest : SysuiTestCase() { } companion object { private const val USER_ID = 100 private val USER_HANDLE = UserHandle.of(USER_ID) private val USER_HANDLE = UserHandle.of(100) } } packages/SystemUI/multivalentTests/src/com/android/systemui/inputmethod/domain/interactor/InputMethodInteractorTest.kt +1 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,7 @@ class InputMethodInteractorTest : SysuiTestCase() { nonAuxiliarySubtypes: Int, ): InputMethodModel { return InputMethodModel( userId = UUID.randomUUID().mostSignificantBits.toInt(), imeId = UUID.randomUUID().toString(), subtypes = List(auxiliarySubtypes + nonAuxiliarySubtypes) { Loading packages/SystemUI/src/com/android/systemui/inputmethod/data/model/InputMethodModel.kt +2 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ package com.android.systemui.inputmethod.data.model * @see android.view.inputmethod.InputMethodInfo */ data class InputMethodModel( /** A unique ID for the user associated with this input method. */ val userId: Int, /** A unique ID for this input method. */ val imeId: String, /** The subtypes of this IME (may be empty). */ Loading packages/SystemUI/src/com/android/systemui/inputmethod/data/repository/InputMethodRepository.kt +39 −19 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.systemui.inputmethod.data.repository import android.annotation.SuppressLint import android.os.UserHandle import android.view.inputmethod.InputMethodInfo import android.view.inputmethod.InputMethodManager import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background Loading @@ -34,18 +33,27 @@ import kotlinx.coroutines.withContext /** Provides access to input-method related application state in the bouncer. */ interface InputMethodRepository { /** * Creates and returns a new `Flow` of installed input methods that are enabled for the * specified user. * * @param user The user to query. * @param fetchSubtypes Whether to fetch the IME Subtypes as well (requires an additional IPC * call for each IME, avoid if not needed). * @see InputMethodManager.getEnabledInputMethodListAsUser */ suspend fun enabledInputMethods(userId: Int, fetchSubtypes: Boolean): Flow<InputMethodModel> suspend fun enabledInputMethods( user: UserHandle, fetchSubtypes: Boolean, ): Flow<InputMethodModel> /** Returns enabled subtypes for the currently selected input method. */ suspend fun selectedInputMethodSubtypes(): List<InputMethodModel.Subtype> /** * Returns enabled subtypes for the currently selected input method. * * @param user The user to query. */ suspend fun selectedInputMethodSubtypes(user: UserHandle): List<InputMethodModel.Subtype> /** * Shows the system's input method picker dialog. Loading @@ -67,20 +75,22 @@ constructor( ) : InputMethodRepository { override suspend fun enabledInputMethods( userId: Int, user: UserHandle, fetchSubtypes: Boolean ): Flow<InputMethodModel> { return withContext(backgroundDispatcher) { inputMethodManager.getEnabledInputMethodListAsUser(UserHandle.of(userId)) inputMethodManager.getEnabledInputMethodListAsUser(user) } .asFlow() .map { inputMethodInfo -> InputMethodModel( userId = user.identifier, imeId = inputMethodInfo.id, subtypes = if (fetchSubtypes) { enabledInputMethodSubtypes( inputMethodInfo, user = user, imeId = inputMethodInfo.id, allowsImplicitlyEnabledSubtypes = true ) } else { Loading @@ -90,12 +100,20 @@ constructor( } } override suspend fun selectedInputMethodSubtypes(): List<InputMethodModel.Subtype> { return enabledInputMethodSubtypes( inputMethodInfo = null, // Fetch subtypes for the currently-selected IME. override suspend fun selectedInputMethodSubtypes( user: UserHandle, ): List<InputMethodModel.Subtype> { val selectedIme = inputMethodManager.getCurrentInputMethodInfoAsUser(user) return if (selectedIme == null) { emptyList() } else { enabledInputMethodSubtypes( user = user, imeId = selectedIme.id, allowsImplicitlyEnabledSubtypes = false ) } } @SuppressLint("MissingPermission") override suspend fun showInputMethodPicker(displayId: Int, showAuxiliarySubtypes: Boolean) { Loading @@ -107,21 +125,23 @@ constructor( /** * Returns a list of enabled input method subtypes for the specified input method info. * * @param inputMethodInfo The [InputMethodInfo] whose subtypes list will be returned. If `null`, * returns enabled subtypes for the currently selected [InputMethodInfo]. * @param user The user to query. * @param imeId The ID of the input method whose subtypes list will be returned. * @param allowsImplicitlyEnabledSubtypes Whether to allow to return the implicitly enabled * subtypes. If an input method info doesn't have enabled subtypes, the framework will * implicitly enable subtypes according to the current system language. * @see InputMethodManager.getEnabledInputMethodSubtypeList * @see InputMethodManager.getEnabledInputMethodSubtypeListAsUser */ private suspend fun enabledInputMethodSubtypes( inputMethodInfo: InputMethodInfo?, user: UserHandle, imeId: String, allowsImplicitlyEnabledSubtypes: Boolean ): List<InputMethodModel.Subtype> { return withContext(backgroundDispatcher) { inputMethodManager.getEnabledInputMethodSubtypeList( inputMethodInfo, allowsImplicitlyEnabledSubtypes inputMethodManager.getEnabledInputMethodSubtypeListAsUser( imeId, allowsImplicitlyEnabledSubtypes, user ) } .map { Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/bouncer/ui/viewmodel/PasswordBouncerViewModelTest.kt +1 −0 Original line number Diff line number Diff line Loading @@ -372,6 +372,7 @@ class PasswordBouncerViewModelTest : SysuiTestCase() { nonAuxiliarySubtypes: Int, ): InputMethodModel { return InputMethodModel( userId = UUID.randomUUID().mostSignificantBits.toInt(), imeId = UUID.randomUUID().toString(), subtypes = List(auxiliarySubtypes + nonAuxiliarySubtypes) { Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/inputmethod/data/repository/InputMethodRepositoryTest.kt +24 −13 Original line number Diff line number Diff line Loading @@ -56,9 +56,6 @@ class InputMethodRepositoryTest : SysuiTestCase() { fun setUp() { MockitoAnnotations.initMocks(this) whenever(inputMethodManager.getEnabledInputMethodSubtypeList(eq(null), anyBoolean())) .thenReturn(listOf()) underTest = InputMethodRepositoryImpl( backgroundDispatcher = kosmos.testDispatcher, Loading @@ -71,10 +68,16 @@ class InputMethodRepositoryTest : SysuiTestCase() { testScope.runTest { whenever(inputMethodManager.getEnabledInputMethodListAsUser(eq(USER_HANDLE))) .thenReturn(listOf()) whenever(inputMethodManager.getEnabledInputMethodSubtypeList(any(), anyBoolean())) whenever( inputMethodManager.getEnabledInputMethodSubtypeListAsUser( any(), anyBoolean(), eq(USER_HANDLE) ) ) .thenReturn(listOf()) assertThat(underTest.enabledInputMethods(USER_ID, fetchSubtypes = true).count()) assertThat(underTest.enabledInputMethods(USER_HANDLE, fetchSubtypes = true).count()) .isEqualTo(0) } Loading @@ -83,11 +86,20 @@ class InputMethodRepositoryTest : SysuiTestCase() { testScope.runTest { val subtypeId = 123 val isAuxiliary = true val selectedImiId = "imiId" val selectedImi = mock<InputMethodInfo>() whenever(selectedImi.id).thenReturn(selectedImiId) whenever(inputMethodManager.getCurrentInputMethodInfoAsUser(eq(USER_HANDLE))) .thenReturn(selectedImi) whenever(inputMethodManager.getEnabledInputMethodListAsUser(eq(USER_HANDLE))) .thenReturn(listOf(mock<InputMethodInfo>())) whenever(inputMethodManager.getEnabledInputMethodSubtypeList(any(), anyBoolean())) .thenReturn(listOf()) whenever(inputMethodManager.getEnabledInputMethodSubtypeList(eq(null), anyBoolean())) .thenReturn(listOf(selectedImi)) whenever( inputMethodManager.getEnabledInputMethodSubtypeListAsUser( eq(selectedImiId), anyBoolean(), eq(USER_HANDLE) ) ) .thenReturn( listOf( InputMethodSubtype.InputMethodSubtypeBuilder() Loading @@ -97,7 +109,7 @@ class InputMethodRepositoryTest : SysuiTestCase() { ) ) val result = underTest.selectedInputMethodSubtypes() val result = underTest.selectedInputMethodSubtypes(USER_HANDLE) assertThat(result).hasSize(1) assertThat(result.first().subtypeId).isEqualTo(subtypeId) assertThat(result.first().isAuxiliary).isEqualTo(isAuxiliary) Loading @@ -118,7 +130,6 @@ class InputMethodRepositoryTest : SysuiTestCase() { } companion object { private const val USER_ID = 100 private val USER_HANDLE = UserHandle.of(USER_ID) private val USER_HANDLE = UserHandle.of(100) } }
packages/SystemUI/multivalentTests/src/com/android/systemui/inputmethod/domain/interactor/InputMethodInteractorTest.kt +1 −0 Original line number Diff line number Diff line Loading @@ -143,6 +143,7 @@ class InputMethodInteractorTest : SysuiTestCase() { nonAuxiliarySubtypes: Int, ): InputMethodModel { return InputMethodModel( userId = UUID.randomUUID().mostSignificantBits.toInt(), imeId = UUID.randomUUID().toString(), subtypes = List(auxiliarySubtypes + nonAuxiliarySubtypes) { Loading
packages/SystemUI/src/com/android/systemui/inputmethod/data/model/InputMethodModel.kt +2 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ package com.android.systemui.inputmethod.data.model * @see android.view.inputmethod.InputMethodInfo */ data class InputMethodModel( /** A unique ID for the user associated with this input method. */ val userId: Int, /** A unique ID for this input method. */ val imeId: String, /** The subtypes of this IME (may be empty). */ Loading
packages/SystemUI/src/com/android/systemui/inputmethod/data/repository/InputMethodRepository.kt +39 −19 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.systemui.inputmethod.data.repository import android.annotation.SuppressLint import android.os.UserHandle import android.view.inputmethod.InputMethodInfo import android.view.inputmethod.InputMethodManager import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Background Loading @@ -34,18 +33,27 @@ import kotlinx.coroutines.withContext /** Provides access to input-method related application state in the bouncer. */ interface InputMethodRepository { /** * Creates and returns a new `Flow` of installed input methods that are enabled for the * specified user. * * @param user The user to query. * @param fetchSubtypes Whether to fetch the IME Subtypes as well (requires an additional IPC * call for each IME, avoid if not needed). * @see InputMethodManager.getEnabledInputMethodListAsUser */ suspend fun enabledInputMethods(userId: Int, fetchSubtypes: Boolean): Flow<InputMethodModel> suspend fun enabledInputMethods( user: UserHandle, fetchSubtypes: Boolean, ): Flow<InputMethodModel> /** Returns enabled subtypes for the currently selected input method. */ suspend fun selectedInputMethodSubtypes(): List<InputMethodModel.Subtype> /** * Returns enabled subtypes for the currently selected input method. * * @param user The user to query. */ suspend fun selectedInputMethodSubtypes(user: UserHandle): List<InputMethodModel.Subtype> /** * Shows the system's input method picker dialog. Loading @@ -67,20 +75,22 @@ constructor( ) : InputMethodRepository { override suspend fun enabledInputMethods( userId: Int, user: UserHandle, fetchSubtypes: Boolean ): Flow<InputMethodModel> { return withContext(backgroundDispatcher) { inputMethodManager.getEnabledInputMethodListAsUser(UserHandle.of(userId)) inputMethodManager.getEnabledInputMethodListAsUser(user) } .asFlow() .map { inputMethodInfo -> InputMethodModel( userId = user.identifier, imeId = inputMethodInfo.id, subtypes = if (fetchSubtypes) { enabledInputMethodSubtypes( inputMethodInfo, user = user, imeId = inputMethodInfo.id, allowsImplicitlyEnabledSubtypes = true ) } else { Loading @@ -90,12 +100,20 @@ constructor( } } override suspend fun selectedInputMethodSubtypes(): List<InputMethodModel.Subtype> { return enabledInputMethodSubtypes( inputMethodInfo = null, // Fetch subtypes for the currently-selected IME. override suspend fun selectedInputMethodSubtypes( user: UserHandle, ): List<InputMethodModel.Subtype> { val selectedIme = inputMethodManager.getCurrentInputMethodInfoAsUser(user) return if (selectedIme == null) { emptyList() } else { enabledInputMethodSubtypes( user = user, imeId = selectedIme.id, allowsImplicitlyEnabledSubtypes = false ) } } @SuppressLint("MissingPermission") override suspend fun showInputMethodPicker(displayId: Int, showAuxiliarySubtypes: Boolean) { Loading @@ -107,21 +125,23 @@ constructor( /** * Returns a list of enabled input method subtypes for the specified input method info. * * @param inputMethodInfo The [InputMethodInfo] whose subtypes list will be returned. If `null`, * returns enabled subtypes for the currently selected [InputMethodInfo]. * @param user The user to query. * @param imeId The ID of the input method whose subtypes list will be returned. * @param allowsImplicitlyEnabledSubtypes Whether to allow to return the implicitly enabled * subtypes. If an input method info doesn't have enabled subtypes, the framework will * implicitly enable subtypes according to the current system language. * @see InputMethodManager.getEnabledInputMethodSubtypeList * @see InputMethodManager.getEnabledInputMethodSubtypeListAsUser */ private suspend fun enabledInputMethodSubtypes( inputMethodInfo: InputMethodInfo?, user: UserHandle, imeId: String, allowsImplicitlyEnabledSubtypes: Boolean ): List<InputMethodModel.Subtype> { return withContext(backgroundDispatcher) { inputMethodManager.getEnabledInputMethodSubtypeList( inputMethodInfo, allowsImplicitlyEnabledSubtypes inputMethodManager.getEnabledInputMethodSubtypeListAsUser( imeId, allowsImplicitlyEnabledSubtypes, user ) } .map { Loading