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

Commit a6b4065e authored by Danny Burakov's avatar Danny Burakov Committed by Android (Google) Code Review
Browse files

Merge "[flexiglass] Fetch InputMethod subtypes using the explicit user ID." into main

parents 83ee8994 c95ef489
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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) {
+24 −13
Original line number Diff line number Diff line
@@ -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,
@@ -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)
        }

@@ -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()
@@ -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)
@@ -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)
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -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) {
+2 −0
Original line number Diff line number Diff line
@@ -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). */
+39 −19
Original line number Diff line number Diff line
@@ -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
@@ -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.
@@ -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 {
@@ -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) {
@@ -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