From 303c96cb1da15ef994a39e5faba2b70da99806e7 Mon Sep 17 00:00:00 2001 From: Candice Lo Date: Mon, 6 Feb 2023 07:24:01 +0000 Subject: [PATCH] Implement Font Scaling Quick Settings Tile (4/n) Setup the dialog panel for font scaling - Slider: The number of steps in the slider refers to the values options for font scaling. Changing the progress of the seekbar will change the size of fonts including the ones on the dialog panel. - Title and Done button: Update font size when onConfigurationChanged. Bug: 242326166 Test: Attach a video to the bug Test: atest FontScalingDialogTest Change-Id: I9004aa933ff1d8021f3087a015ebc23bb8724871 --- .../fontscaling/FontScalingDialog.kt | 73 +++++++++++- .../ui/view/SeekBarWithIconButtonsView.java | 7 ++ .../systemui/qs/tiles/FontScalingTile.kt | 6 +- .../fontscaling/FontScalingDialogTest.kt | 107 ++++++++++++++++++ .../qs/tiles/dialog/FontScalingTileTest.kt | 4 +- 5 files changed, 193 insertions(+), 4 deletions(-) create mode 100644 packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt b/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt index f521839be50b0..54f933ae6d09c 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt +++ b/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt @@ -16,13 +16,32 @@ package com.android.systemui.accessibility.fontscaling import android.content.Context +import android.content.pm.ActivityInfo +import android.content.res.Configuration import android.os.Bundle +import android.provider.Settings import android.view.LayoutInflater +import android.widget.Button +import android.widget.SeekBar +import android.widget.SeekBar.OnSeekBarChangeListener +import android.widget.TextView import com.android.systemui.R +import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView import com.android.systemui.statusbar.phone.SystemUIDialog +import com.android.systemui.util.settings.SystemSettings /** The Dialog that contains a seekbar for changing the font size. */ -class FontScalingDialog(context: Context) : SystemUIDialog(context) { +class FontScalingDialog(context: Context, private val systemSettings: SystemSettings) : + SystemUIDialog(context) { + private val strEntryValues: Array = + context.resources.getStringArray(com.android.settingslib.R.array.entryvalues_font_size) + private lateinit var title: TextView + private lateinit var doneButton: Button + private lateinit var seekBarWithIconButtonsView: SeekBarWithIconButtonsView + + private val configuration: Configuration = + Configuration(context.getResources().getConfiguration()) + override fun onCreate(savedInstanceState: Bundle?) { setTitle(R.string.font_scaling_dialog_title) setView(LayoutInflater.from(context).inflate(R.layout.font_scaling_dialog, null)) @@ -32,5 +51,57 @@ class FontScalingDialog(context: Context) : SystemUIDialog(context) { /* dismissOnClick = */ true ) super.onCreate(savedInstanceState) + + title = requireViewById(com.android.internal.R.id.alertTitle) + doneButton = requireViewById(com.android.internal.R.id.button1) + seekBarWithIconButtonsView = requireViewById(R.id.font_scaling_slider) + + seekBarWithIconButtonsView.setMax((strEntryValues).size - 1) + + val currentScale = systemSettings.getFloat(Settings.System.FONT_SCALE, 1.0f) + seekBarWithIconButtonsView.setProgress(fontSizeValueToIndex(currentScale)) + + seekBarWithIconButtonsView.setOnSeekBarChangeListener( + object : OnSeekBarChangeListener { + override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { + systemSettings.putString(Settings.System.FONT_SCALE, strEntryValues[progress]) + } + + override fun onStartTrackingTouch(seekBar: SeekBar) { + // Do nothing + } + + override fun onStopTrackingTouch(seekBar: SeekBar) { + // Do nothing + } + } + ) + doneButton.setOnClickListener { dismiss() } + } + + private fun fontSizeValueToIndex(value: Float): Int { + var lastValue = strEntryValues[0].toFloat() + for (i in 1 until strEntryValues.size) { + val thisValue = strEntryValues[i].toFloat() + if (value < lastValue + (thisValue - lastValue) * .5f) { + return i - 1 + } + lastValue = thisValue + } + return strEntryValues.size - 1 + } + + override fun onConfigurationChanged(configuration: Configuration) { + super.onConfigurationChanged(configuration) + + val configDiff = configuration.diff(this.configuration) + this.configuration.setTo(configuration) + + if (configDiff and ActivityInfo.CONFIG_FONT_SCALE != 0) { + title.post { + title.setTextAppearance(R.style.TextAppearance_Dialog_Title) + doneButton.setTextAppearance(R.style.Widget_Dialog_Button) + } + } } } diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java b/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java index e8288a0d2a875..826253947ce1c 100644 --- a/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java +++ b/packages/SystemUI/src/com/android/systemui/common/ui/view/SeekBarWithIconButtonsView.java @@ -152,6 +152,13 @@ public class SeekBarWithIconButtonsView extends LinearLayout { setIconViewAndFrameEnabled(mIconEnd, progress < mSeekbar.getMax()); } + /** + * Sets max to the seekbar in the layout. + */ + public void setMax(int max) { + mSeekbar.setMax(max); + } + /** * Sets progress to the seekbar in the layout. * If the progress is smaller than or equals to 0, the IconStart will be disabled. If the diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt index ce5e4055e840e..b9cd535b97656 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt @@ -35,6 +35,7 @@ import com.android.systemui.qs.QSHost import com.android.systemui.qs.logging.QSLogger import com.android.systemui.qs.tileimpl.QSTileImpl import com.android.systemui.statusbar.phone.SystemUIDialog +import com.android.systemui.util.settings.SystemSettings import javax.inject.Inject class FontScalingTile @@ -48,7 +49,8 @@ constructor( statusBarStateController: StatusBarStateController, activityStarter: ActivityStarter, qsLogger: QSLogger, - private val dialogLaunchAnimator: DialogLaunchAnimator + private val dialogLaunchAnimator: DialogLaunchAnimator, + private val systemSettings: SystemSettings ) : QSTileImpl( host, @@ -74,7 +76,7 @@ constructor( override fun handleClick(view: View?) { mUiHandler.post { - val dialog: SystemUIDialog = FontScalingDialog(mContext) + val dialog: SystemUIDialog = FontScalingDialog(mContext, systemSettings) if (view != null) { dialogLaunchAnimator.showFromView( dialog, diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt new file mode 100644 index 0000000000000..777dd4e0b4a3c --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2023 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.systemui.accessibility.fontscaling + +import android.os.Handler +import android.provider.Settings +import android.testing.AndroidTestingRunner +import android.testing.TestableLooper +import android.widget.ImageView +import android.widget.SeekBar +import androidx.test.filters.SmallTest +import com.android.systemui.R +import com.android.systemui.SysuiTestCase +import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView +import com.android.systemui.util.settings.FakeSettings +import com.android.systemui.util.settings.SystemSettings +import com.google.common.truth.Truth.assertThat +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +/** Tests for [FontScalingDialog]. */ +@SmallTest +@RunWith(AndroidTestingRunner::class) +@TestableLooper.RunWithLooper(setAsMainLooper = true) +class FontScalingDialogTest : SysuiTestCase() { + private lateinit var fontScalingDialog: FontScalingDialog + private lateinit var systemSettings: SystemSettings + private val fontSizeValueArray: Array = + mContext + .getResources() + .getStringArray(com.android.settingslib.R.array.entryvalues_font_size) + + @Before + fun setUp() { + val mainHandler = Handler(TestableLooper.get(this).getLooper()) + systemSettings = FakeSettings() + fontScalingDialog = FontScalingDialog(mContext, systemSettings as FakeSettings) + } + + @Test + fun showTheDialog_seekbarIsShowingCorrectProgress() { + fontScalingDialog.show() + + val seekBar: SeekBar = fontScalingDialog.findViewById(R.id.seekbar)!! + val progress: Int = seekBar.getProgress() + val currentScale = systemSettings.getFloat(Settings.System.FONT_SCALE, /* def = */ 1.0f) + + assertThat(currentScale).isEqualTo(fontSizeValueArray[progress].toFloat()) + + fontScalingDialog.dismiss() + } + + @Test + fun progressIsZero_clickIconEnd_seekBarProgressIncreaseOne_fontSizeScaled() { + fontScalingDialog.show() + + val iconEnd: ImageView = fontScalingDialog.findViewById(R.id.icon_end)!! + val seekBarWithIconButtonsView: SeekBarWithIconButtonsView = + fontScalingDialog.findViewById(R.id.font_scaling_slider)!! + val seekBar: SeekBar = fontScalingDialog.findViewById(R.id.seekbar)!! + + seekBarWithIconButtonsView.setProgress(0) + + iconEnd.performClick() + + val currentScale = systemSettings.getFloat(Settings.System.FONT_SCALE, /* def = */ 1.0f) + assertThat(seekBar.getProgress()).isEqualTo(1) + assertThat(currentScale).isEqualTo(fontSizeValueArray[1].toFloat()) + + fontScalingDialog.dismiss() + } + + @Test + fun progressIsMax_clickIconStart_seekBarProgressDecreaseOne_fontSizeScaled() { + fontScalingDialog.show() + + val iconStart: ImageView = fontScalingDialog.findViewById(R.id.icon_start)!! + val seekBarWithIconButtonsView: SeekBarWithIconButtonsView = + fontScalingDialog.findViewById(R.id.font_scaling_slider)!! + val seekBar: SeekBar = fontScalingDialog.findViewById(R.id.seekbar)!! + + seekBarWithIconButtonsView.setProgress(fontSizeValueArray.size - 1) + + iconStart.performClick() + + val currentScale = systemSettings.getFloat(Settings.System.FONT_SCALE, /* def = */ 1.0f) + assertThat(seekBar.getProgress()).isEqualTo(fontSizeValueArray.size - 2) + assertThat(currentScale) + .isEqualTo(fontSizeValueArray[fontSizeValueArray.size - 2].toFloat()) + + fontScalingDialog.dismiss() + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/FontScalingTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/FontScalingTileTest.kt index f97ccab5fc1fe..57abae0889cae 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/FontScalingTileTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/dialog/FontScalingTileTest.kt @@ -28,6 +28,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.qs.QSTileHost import com.android.systemui.qs.logging.QSLogger import com.android.systemui.qs.tiles.FontScalingTile +import com.android.systemui.util.settings.FakeSettings import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test @@ -65,7 +66,8 @@ class FontScalingTileTest : SysuiTestCase() { statusBarStateController, activityStarter, qsLogger, - dialogLaunchAnimator + dialogLaunchAnimator, + FakeSettings() ) fontScalingTile.initialize() }