Fix SettingsFontFamily when config is empty
Some device or when Compose preview, the font config is empty. Use the default font family when the config is empty to fix. Bug: 235727273 Test: Unit test Test: Manual with Gallery App Change-Id: Ifd9c5bbc3d446e5fdb5f393ad994c7545656ead6
This commit is contained in:
@@ -21,45 +21,51 @@ package com.android.settingslib.spa.framework.theme
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalInspectionMode
|
||||
import androidx.compose.ui.text.ExperimentalTextApi
|
||||
import androidx.compose.ui.text.font.DeviceFontFamilyName
|
||||
import androidx.compose.ui.text.font.Font
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import com.android.settingslib.spa.framework.compose.rememberContext
|
||||
|
||||
internal data class SettingsFontFamily(
|
||||
val brand: FontFamily = FontFamily.Default,
|
||||
val plain: FontFamily = FontFamily.Default,
|
||||
val brand: FontFamily,
|
||||
val plain: FontFamily,
|
||||
)
|
||||
|
||||
private fun Context.getSettingsFontFamily(inInspection: Boolean): SettingsFontFamily {
|
||||
if (inInspection) {
|
||||
return SettingsFontFamily()
|
||||
}
|
||||
private fun Context.getSettingsFontFamily(): SettingsFontFamily {
|
||||
return SettingsFontFamily(
|
||||
brand = FontFamily(
|
||||
Font(getFontFamilyName("config_headlineFontFamily"), FontWeight.Normal),
|
||||
Font(getFontFamilyName("config_headlineFontFamilyMedium"), FontWeight.Medium),
|
||||
brand = getFontFamily(
|
||||
configFontFamilyNormal = "config_headlineFontFamily",
|
||||
configFontFamilyMedium = "config_headlineFontFamilyMedium",
|
||||
),
|
||||
plain = FontFamily(
|
||||
Font(getFontFamilyName("config_bodyFontFamily"), FontWeight.Normal),
|
||||
Font(getFontFamilyName("config_bodyFontFamilyMedium"), FontWeight.Medium),
|
||||
plain = getFontFamily(
|
||||
configFontFamilyNormal = "config_bodyFontFamily",
|
||||
configFontFamilyMedium = "config_bodyFontFamilyMedium",
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun Context.getFontFamilyName(configName: String): DeviceFontFamilyName {
|
||||
private fun Context.getFontFamily(
|
||||
configFontFamilyNormal: String,
|
||||
configFontFamilyMedium: String,
|
||||
): FontFamily {
|
||||
val fontFamilyNormal = getAndroidConfig(configFontFamilyNormal)
|
||||
val fontFamilyMedium = getAndroidConfig(configFontFamilyMedium)
|
||||
if (fontFamilyNormal.isEmpty() || fontFamilyMedium.isEmpty()) return FontFamily.Default
|
||||
return FontFamily(
|
||||
Font(DeviceFontFamilyName(fontFamilyNormal), FontWeight.Normal),
|
||||
Font(DeviceFontFamilyName(fontFamilyMedium), FontWeight.Medium),
|
||||
)
|
||||
}
|
||||
|
||||
private fun Context.getAndroidConfig(configName: String): String {
|
||||
@SuppressLint("DiscouragedApi")
|
||||
val configId = resources.getIdentifier(configName, "string", "android")
|
||||
return DeviceFontFamilyName(resources.getString(configId))
|
||||
return resources.getString(configId)
|
||||
}
|
||||
|
||||
@Composable
|
||||
internal fun rememberSettingsFontFamily(): SettingsFontFamily {
|
||||
val context = LocalContext.current
|
||||
val inInspection = LocalInspectionMode.current
|
||||
return remember { context.getSettingsFontFamily(inInspection) }
|
||||
return rememberContext(Context::getSettingsFontFamily)
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ android_test {
|
||||
"androidx.compose.runtime_runtime",
|
||||
"androidx.compose.ui_ui-test-junit4",
|
||||
"androidx.compose.ui_ui-test-manifest",
|
||||
"mockito-target-minus-junit4",
|
||||
"truth-prebuilt",
|
||||
],
|
||||
kotlincflags: ["-Xjvm-default=all"],
|
||||
|
||||
@@ -58,9 +58,10 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
androidTestImplementation(project(":spa"))
|
||||
androidTestImplementation 'androidx.test.ext:junit-ktx:1.1.3'
|
||||
androidTestImplementation("androidx.compose.ui:ui-test-junit4:$jetpack_compose_version")
|
||||
androidTestImplementation 'com.google.truth:truth:1.1.3'
|
||||
androidTestImplementation project(":spa")
|
||||
androidTestImplementation "androidx.test.ext:junit-ktx:1.1.3"
|
||||
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$jetpack_compose_version"
|
||||
androidTestImplementation "com.google.truth:truth:1.1.3"
|
||||
androidTestImplementation "org.mockito:mockito-android:3.4.6"
|
||||
androidTestDebugImplementation "androidx.compose.ui:ui-test-manifest:$jetpack_compose_version"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.settingslib.spa.framework.theme
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Resources
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Typography
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.test.junit4.createComposeRule
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Before
|
||||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.anyInt
|
||||
import org.mockito.junit.MockitoJUnit
|
||||
import org.mockito.junit.MockitoRule
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class SettingsThemeTest {
|
||||
@get:Rule
|
||||
val mockito: MockitoRule = MockitoJUnit.rule()
|
||||
|
||||
@get:Rule
|
||||
val composeTestRule = createComposeRule()
|
||||
|
||||
@Mock
|
||||
private lateinit var context: Context
|
||||
|
||||
@Mock
|
||||
private lateinit var resources: Resources
|
||||
|
||||
private var nextMockResId = 1
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
whenever(context.resources).thenReturn(resources)
|
||||
whenever(resources.getString(anyInt())).thenReturn("")
|
||||
}
|
||||
|
||||
private fun mockAndroidConfig(configName: String, configValue: String) {
|
||||
whenever(resources.getIdentifier(configName, "string", "android"))
|
||||
.thenReturn(nextMockResId)
|
||||
whenever(resources.getString(nextMockResId)).thenReturn(configValue)
|
||||
nextMockResId++
|
||||
}
|
||||
|
||||
@Test
|
||||
fun noFontFamilyConfig_useDefaultFontFamily() {
|
||||
val fontFamily = getFontFamily()
|
||||
|
||||
assertThat(fontFamily.headlineLarge.fontFamily).isSameInstanceAs(FontFamily.Default)
|
||||
assertThat(fontFamily.bodyLarge.fontFamily).isSameInstanceAs(FontFamily.Default)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hasFontFamilyConfig_useConfiguredFontFamily() {
|
||||
mockAndroidConfig("config_headlineFontFamily", "HeadlineNormal")
|
||||
mockAndroidConfig("config_headlineFontFamilyMedium", "HeadlineMedium")
|
||||
mockAndroidConfig("config_bodyFontFamily", "BodyNormal")
|
||||
mockAndroidConfig("config_bodyFontFamilyMedium", "BodyMedium")
|
||||
|
||||
val fontFamily = getFontFamily()
|
||||
|
||||
val headlineFontFamily = fontFamily.headlineLarge.fontFamily.toString()
|
||||
assertThat(headlineFontFamily).contains("HeadlineNormal")
|
||||
assertThat(headlineFontFamily).contains("HeadlineMedium")
|
||||
val bodyFontFamily = fontFamily.bodyLarge.fontFamily.toString()
|
||||
assertThat(bodyFontFamily).contains("BodyNormal")
|
||||
assertThat(bodyFontFamily).contains("BodyMedium")
|
||||
}
|
||||
|
||||
private fun getFontFamily(): Typography {
|
||||
lateinit var typography: Typography
|
||||
composeTestRule.setContent {
|
||||
CompositionLocalProvider(LocalContext provides context) {
|
||||
SettingsTheme {
|
||||
typography = MaterialTheme.typography
|
||||
}
|
||||
}
|
||||
}
|
||||
return typography
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user