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

Commit f96dd83b authored by Chaohui Wang's avatar Chaohui Wang
Browse files

Correct the page title for TalkBack

Update the activity title so TalkBack can read correctly.

Fix: 282093840
Test: Manually with TalkBack
Test: Unit test
Change-Id: I9aa31b210a183562c52aa3617a23a1ffcca93bc2
parent f45c4830
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ fun SearchScaffold(
    actions: @Composable RowScope.() -> Unit = {},
    content: @Composable (bottomPadding: Dp, searchQuery: State<String>) -> Unit,
) {
    ActivityTitle(title)
    var isSearchMode by rememberSaveable { mutableStateOf(false) }
    val viewModel: SearchScaffoldViewModel = viewModel()

+25 −0
Original line number Diff line number Diff line
@@ -16,6 +16,9 @@

package com.android.settingslib.spa.widget.scaffold

import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
@@ -25,8 +28,10 @@ import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Scaffold
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import com.android.settingslib.spa.framework.compose.horizontalValues
import com.android.settingslib.spa.framework.compose.verticalValues
@@ -44,6 +49,7 @@ fun SettingsScaffold(
    actions: @Composable RowScope.() -> Unit = {},
    content: @Composable (PaddingValues) -> Unit,
) {
    ActivityTitle(title)
    val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
    Scaffold(
        modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
@@ -55,6 +61,25 @@ fun SettingsScaffold(
    }
}

/**
 * Sets a title for the activity.
 *
 * So the TalkBack can read out the correct page title.
 */
@Composable
internal fun ActivityTitle(title: String) {
    val context = LocalContext.current
    LaunchedEffect(true) {
        context.getActivity()?.title = title
    }
}

private fun Context.getActivity(): Activity? = when (this) {
    is Activity -> this
    is ContextWrapper -> baseContext.getActivity()
    else -> null
}

@Preview
@Composable
private fun SettingsScaffoldPreview() {
+25 −1
Original line number Diff line number Diff line
@@ -16,9 +16,12 @@

package com.android.settingslib.spa.widget.scaffold

import android.app.Activity
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.material3.Text
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.SideEffect
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.test.assertIsDisplayed
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
@@ -29,12 +32,22 @@ import com.google.common.truth.Truth.assertThat
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit
import org.mockito.junit.MockitoRule

@RunWith(AndroidJUnit4::class)
class SettingsScaffoldTest {
    @get:Rule
    val composeTestRule = createComposeRule()

    @get:Rule
    val mockito: MockitoRule = MockitoJUnit.rule()

    @Mock
    private lateinit var activity: Activity

    @Test
    fun settingsScaffold_titleIsDisplayed() {
        composeTestRule.setContent {
@@ -78,7 +91,18 @@ class SettingsScaffoldTest {
        assertThat(actualPaddingValues.calculateRightPadding(LayoutDirection.Rtl)).isEqualTo(0.dp)
    }

    @Test
    fun activityTitle() {
        composeTestRule.setContent {
            CompositionLocalProvider(LocalContext provides activity) {
                ActivityTitle(title = TITLE)
            }
        }

        verify(activity).title = TITLE
    }

    private companion object {
        const val TITLE = "title"
        const val TITLE = "Title"
    }
}