Use larger frame of settings button for clicks

That way, the tappable area is of the minimum size. Additionally, set
the accessibility class name of the SettingsButton (now an ImageView) to
be Button, so the description matches the other buttons in the
FooterActions.

Test: manual
Test: Accessibility Scanner
Test: FooterActionsControllerTest
Fixes: 227536054
Change-Id: If412d7a5bdb53c363728f06e404fd70725b8c15a
This commit is contained in:
Fabian Kozynski
2022-04-08 13:17:00 -04:00
parent 3fda2bf279
commit 638f61a57a
5 changed files with 37 additions and 16 deletions

View File

@@ -73,6 +73,9 @@
android:layout_height="@dimen/qs_footer_icon_size"
android:layout_gravity="center"
android:background="@android:color/transparent"
android:focusable="false"
android:clickable="false"
android:importantForAccessibility="yes"
android:contentDescription="@string/accessibility_quick_settings_settings"
android:scaleType="centerInside"
android:src="@drawable/ic_settings"

View File

@@ -38,7 +38,6 @@ import com.android.systemui.qs.dagger.QSFlagsModule.PM_LITE_ENABLED
import com.android.systemui.qs.dagger.QSScope
import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.phone.MultiUserSwitchController
import com.android.systemui.statusbar.phone.SettingsButton
import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.systemui.statusbar.policy.UserInfoController
import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener
@@ -89,8 +88,7 @@ internal class FooterActionsController @Inject constructor(
updateVisibility()
}
private val settingsButton: SettingsButton = view.findViewById(R.id.settings_button)
private val settingsButtonContainer: View? = view.findViewById(R.id.settings_button_container)
private val settingsButtonContainer: View = view.findViewById(R.id.settings_button_container)
private val securityFootersContainer: ViewGroup? =
view.findViewById(R.id.security_footers_container)
private val powerMenuLite: View = view.findViewById(R.id.pm_lite)
@@ -121,7 +119,7 @@ internal class FooterActionsController @Inject constructor(
if (!visible || falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
return@OnClickListener
}
if (v === settingsButton) {
if (v === settingsButtonContainer) {
if (!deviceProvisionedController.isCurrentUserSetup) {
// If user isn't setup just unlock the device and dump them back at SUW.
activityStarter.postQSRunnableDismissingKeyguard {}
@@ -166,7 +164,7 @@ internal class FooterActionsController @Inject constructor(
} else {
powerMenuLite.visibility = View.GONE
}
settingsButton.setOnClickListener(onClickListener)
settingsButtonContainer.setOnClickListener(onClickListener)
multiUserSetting.isListening = true
val securityFooter = securityFooterController.view

View File

@@ -29,7 +29,6 @@ import com.android.settingslib.Utils
import com.android.settingslib.drawable.UserIconDrawable
import com.android.systemui.R
import com.android.systemui.statusbar.phone.MultiUserSwitch
import com.android.systemui.statusbar.phone.SettingsButton
/**
* Quick Settings bottom buttons placed in footer (aka utility bar) - always visible in expanded QS,
@@ -38,7 +37,6 @@ import com.android.systemui.statusbar.phone.SettingsButton
*/
class FooterActionsView(context: Context?, attrs: AttributeSet?) : LinearLayout(context, attrs) {
private lateinit var settingsContainer: View
private lateinit var settingsButton: SettingsButton
private lateinit var multiUserSwitch: MultiUserSwitch
private lateinit var multiUserAvatar: ImageView
@@ -47,15 +45,14 @@ class FooterActionsView(context: Context?, attrs: AttributeSet?) : LinearLayout(
override fun onFinishInflate() {
super.onFinishInflate()
settingsButton = findViewById(R.id.settings_button)
settingsContainer = findViewById(R.id.settings_button_container)
multiUserSwitch = findViewById(R.id.multi_user_switch)
multiUserAvatar = multiUserSwitch.findViewById(R.id.multi_user_avatar)
// RenderThread is doing more harm than good when touching the header (to expand quick
// settings), so disable it for this view
if (settingsButton.background is RippleDrawable) {
(settingsButton.background as RippleDrawable).setForceSoftware(true)
if (settingsContainer.background is RippleDrawable) {
(settingsContainer.background as RippleDrawable).setForceSoftware(true)
}
importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_YES
}
@@ -82,7 +79,7 @@ class FooterActionsView(context: Context?, attrs: AttributeSet?) : LinearLayout(
private fun updateClickabilities() {
multiUserSwitch.isClickable = multiUserSwitch.visibility == VISIBLE
settingsButton.isClickable = settingsButton.visibility == VISIBLE
settingsContainer.isClickable = settingsContainer.visibility == VISIBLE
}
private fun updateVisibilities(
@@ -91,7 +88,7 @@ class FooterActionsView(context: Context?, attrs: AttributeSet?) : LinearLayout(
settingsContainer.visibility = if (qsDisabled) GONE else VISIBLE
multiUserSwitch.visibility = if (multiUserEnabled) VISIBLE else GONE
val isDemo = UserManager.isDeviceInDemoMode(context)
settingsButton.visibility = if (isDemo) INVISIBLE else VISIBLE
settingsContainer.visibility = if (isDemo) INVISIBLE else VISIBLE
}
fun onUserInfoChanged(picture: Drawable?, isGuestUser: Boolean) {

View File

@@ -24,13 +24,15 @@ import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.Button;
import com.android.keyguard.AlphaOptimizedImageButton;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.statusbar.AlphaOptimizedImageView;
public class SettingsButton extends AlphaOptimizedImageButton {
public class SettingsButton extends AlphaOptimizedImageView {
private static final boolean TUNER_ENABLE_AVAILABLE = false;
@@ -170,6 +172,12 @@ public class SettingsButton extends AlphaOptimizedImageButton {
mAnimator.start();
}
@Override
public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfoInternal(info);
info.setClassName(Button.class.getName());
}
private final Runnable mLongPressCallback = new Runnable() {
@Override
public void run() {

View File

@@ -1,5 +1,6 @@
package com.android.systemui.qs
import android.content.Intent
import android.os.Handler
import android.os.UserManager
import android.provider.Settings
@@ -14,6 +15,7 @@ import com.android.internal.logging.MetricsLogger
import com.android.internal.logging.UiEventLogger
import com.android.internal.logging.testing.FakeMetricsLogger
import com.android.systemui.R
import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.classifier.FalsingManagerFake
import com.android.systemui.globalactions.GlobalActionsDialogLite
import com.android.systemui.plugins.ActivityStarter
@@ -136,12 +138,25 @@ class FooterActionsControllerTest : LeakCheckedTest() {
.log(GlobalActionsDialogLite.GlobalActionsEvent.GA_OPEN_QS)
}
@Test
fun testSettings() {
val captor = ArgumentCaptor.forClass(Intent::class.java)
whenever(deviceProvisionedController.isCurrentUserSetup).thenReturn(true)
view.findViewById<View>(R.id.settings_button_container).performClick()
verify(activityStarter)
.startActivity(capture(captor), anyBoolean(), any<ActivityLaunchAnimator.Controller>())
assertThat(captor.value.action).isEqualTo(Settings.ACTION_SETTINGS)
}
@Test
fun testSettings_UserNotSetup() {
whenever(deviceProvisionedController.isCurrentUserSetup).thenReturn(false)
view.findViewById<View>(R.id.settings_button).performClick()
view.findViewById<View>(R.id.settings_button_container).performClick()
// Verify Settings wasn't launched.
verify<ActivityStarter>(activityStarter, Mockito.never()).startActivity(any(), anyBoolean())
verify(activityStarter, never())
.startActivity(any(), anyBoolean(), any<ActivityLaunchAnimator.Controller>())
}
@Test