Merge "[View binding] Add ContentDescription as part of the Icon viewmodel." into tm-qpr-dev am: 001f5e8ca6

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/19790133

Change-Id: I35060be6f13a9350562c43417582d6d278db78c2
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
Caitlin Shkuratov
2022-09-08 20:46:14 +00:00
committed by Automerger Merge Worker
11 changed files with 57 additions and 36 deletions

View File

@@ -83,7 +83,11 @@ private fun fakeFooterActionsViewModel(
flowOf(
securityText?.let { text ->
SecurityButtonConfig(
icon = Icon.Resource(R.drawable.ic_info_outline),
icon =
Icon.Resource(
R.drawable.ic_info_outline,
contentDescription = null,
),
text = text,
isClickable = securityClickable,
)

View File

@@ -24,11 +24,15 @@ import android.graphics.drawable.Drawable
* [Icon.Resource] to a resource.
*/
sealed class Icon {
abstract val contentDescription: ContentDescription?
data class Loaded(
val drawable: Drawable,
override val contentDescription: ContentDescription?,
) : Icon()
data class Resource(
@DrawableRes val res: Int,
override val contentDescription: ContentDescription?,
) : Icon()
}

View File

@@ -21,14 +21,16 @@ import com.android.systemui.common.shared.model.ContentDescription
object ContentDescriptionViewBinder {
fun bind(
contentDescription: ContentDescription,
contentDescription: ContentDescription?,
view: View,
) {
when (contentDescription) {
is ContentDescription.Loaded -> view.contentDescription = contentDescription.description
is ContentDescription.Resource -> {
view.contentDescription = view.context.resources.getString(contentDescription.res)
view.contentDescription =
when (contentDescription) {
null -> null
is ContentDescription.Loaded -> contentDescription.description
is ContentDescription.Resource -> {
view.context.resources.getString(contentDescription.res)
}
}
}
}
}

View File

@@ -24,6 +24,7 @@ object IconViewBinder {
icon: Icon,
view: ImageView,
) {
ContentDescriptionViewBinder.bind(icon.contentDescription, view)
when (icon) {
is Icon.Loaded -> view.setImageDrawable(icon.drawable)
is Icon.Resource -> view.setImageResource(icon.res)

View File

@@ -97,7 +97,8 @@ public class QSSecurityFooter extends ViewController<View>
super(rootView);
mFooterText = mView.findViewById(R.id.footer_text);
mPrimaryFooterIcon = mView.findViewById(R.id.primary_footer_icon);
mFooterIcon = new Icon.Resource(R.drawable.ic_info_outline);
mFooterIcon = new Icon.Resource(
R.drawable.ic_info_outline, /* contentDescription= */ null);
mContext = rootView.getContext();
mSecurityController = securityController;
mMainHandler = mainHandler;

View File

@@ -75,6 +75,7 @@ import com.android.internal.jank.InteractionJankMonitor;
import com.android.systemui.R;
import com.android.systemui.animation.DialogCuj;
import com.android.systemui.animation.DialogLaunchAnimator;
import com.android.systemui.common.shared.model.ContentDescription;
import com.android.systemui.common.shared.model.Icon;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Application;
@@ -243,16 +244,17 @@ public class QSSecurityFooterUtils implements DialogInterface.OnClickListener {
isWorkProfileOn).toString();
Icon icon;
ContentDescription contentDescription = null;
if (isParentalControlsEnabled) {
icon = new Icon.Loaded(securityModel.getDeviceAdminIcon());
icon = new Icon.Loaded(securityModel.getDeviceAdminIcon(), contentDescription);
} else if (vpnName != null || vpnNameWorkProfile != null) {
if (securityModel.isVpnBranded()) {
icon = new Icon.Resource(R.drawable.stat_sys_branded_vpn);
icon = new Icon.Resource(R.drawable.stat_sys_branded_vpn, contentDescription);
} else {
icon = new Icon.Resource(R.drawable.stat_sys_vpn_ic);
icon = new Icon.Resource(R.drawable.stat_sys_vpn_ic, contentDescription);
}
} else {
icon = new Icon.Resource(R.drawable.ic_info_outline);
icon = new Icon.Resource(R.drawable.ic_info_outline, contentDescription);
}
return new SecurityButtonConfig(icon, text, isClickable);

View File

@@ -31,7 +31,6 @@ import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.R
import com.android.systemui.common.ui.binder.ContentDescriptionViewBinder
import com.android.systemui.common.ui.binder.IconViewBinder
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.people.ui.view.PeopleViewBinder.bind
@@ -233,10 +232,8 @@ object FooterActionsViewBinder {
val icon = model.icon
val iconView = button.icon
val contentDescription = model.contentDescription
IconViewBinder.bind(icon, iconView)
ContentDescriptionViewBinder.bind(contentDescription, iconView)
if (model.iconTint != null) {
iconView.setColorFilter(model.iconTint, PorterDuff.Mode.SRC_IN)
} else {

View File

@@ -18,7 +18,6 @@ package com.android.systemui.qs.footer.ui.viewmodel
import android.annotation.DrawableRes
import android.view.View
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
/**
@@ -29,7 +28,6 @@ data class FooterActionsButtonViewModel(
val icon: Icon,
val iconTint: Int?,
@DrawableRes val background: Int,
val contentDescription: ContentDescription,
// TODO(b/230830644): Replace View by an Expandable interface that can expand in either dialog
// or activity.
val onClick: (View) -> Unit,

View File

@@ -138,10 +138,12 @@ class FooterActionsViewModel(
/** The model for the settings button. */
val settings: FooterActionsButtonViewModel =
FooterActionsButtonViewModel(
Icon.Resource(R.drawable.ic_settings),
Icon.Resource(
R.drawable.ic_settings,
ContentDescription.Resource(R.string.accessibility_quick_settings_settings)
),
iconTint = null,
R.drawable.qs_footer_action_circle,
ContentDescription.Resource(R.string.accessibility_quick_settings_settings),
this::onSettingsButtonClicked,
)
@@ -149,14 +151,16 @@ class FooterActionsViewModel(
val power: FooterActionsButtonViewModel? =
if (showPowerButton) {
FooterActionsButtonViewModel(
Icon.Resource(android.R.drawable.ic_lock_power_off),
Icon.Resource(
android.R.drawable.ic_lock_power_off,
ContentDescription.Resource(R.string.accessibility_quick_settings_power_menu)
),
iconTint =
Utils.getColorAttrDefaultColor(
context,
com.android.internal.R.attr.textColorOnAccent,
),
R.drawable.qs_footer_action_circle_color,
ContentDescription.Resource(R.string.accessibility_quick_settings_power_menu),
this::onPowerButtonClicked,
)
} else {
@@ -252,10 +256,12 @@ class FooterActionsViewModel(
}
return FooterActionsButtonViewModel(
Icon.Loaded(icon),
Icon.Loaded(
icon,
ContentDescription.Loaded(userSwitcherContentDescription(status.currentUserName)),
),
iconTint,
R.drawable.qs_footer_action_circle,
ContentDescription.Loaded(userSwitcherContentDescription(status.currentUserName)),
this::onUserSwitcherClicked,
)
}

View File

@@ -72,7 +72,8 @@ class WifiViewModel @Inject constructor(
isForceHidden ||
iconResId == null ||
iconResId <= 0 -> null
else -> Icon.Resource(iconResId)
// TODO(b/238425913): Implement the content description.
else -> Icon.Resource(iconResId, /* contentDescription= */ null)
}
}

View File

@@ -70,9 +70,13 @@ class FooterActionsViewModelTest : SysuiTestCase() {
val underTest = utils.footerActionsViewModel(showPowerButton = false)
val settings = underTest.settings
assertThat(settings.contentDescription)
.isEqualTo(ContentDescription.Resource(R.string.accessibility_quick_settings_settings))
assertThat(settings.icon).isEqualTo(Icon.Resource(R.drawable.ic_settings))
assertThat(settings.icon)
.isEqualTo(
Icon.Resource(
R.drawable.ic_settings,
ContentDescription.Resource(R.string.accessibility_quick_settings_settings)
)
)
assertThat(settings.background).isEqualTo(R.drawable.qs_footer_action_circle)
assertThat(settings.iconTint).isNull()
}
@@ -87,11 +91,13 @@ class FooterActionsViewModelTest : SysuiTestCase() {
val underTestWithPower = utils.footerActionsViewModel(showPowerButton = true)
val power = underTestWithPower.power
assertThat(power).isNotNull()
assertThat(power!!.contentDescription)
assertThat(power!!.icon)
.isEqualTo(
ContentDescription.Resource(R.string.accessibility_quick_settings_power_menu)
Icon.Resource(
android.R.drawable.ic_lock_power_off,
ContentDescription.Resource(R.string.accessibility_quick_settings_power_menu)
)
)
assertThat(power.icon).isEqualTo(Icon.Resource(android.R.drawable.ic_lock_power_off))
assertThat(power.background).isEqualTo(R.drawable.qs_footer_action_circle_color)
assertThat(power.iconTint)
.isEqualTo(
@@ -164,14 +170,13 @@ class FooterActionsViewModelTest : SysuiTestCase() {
utils.setUserSwitcherEnabled(settings, true, userId)
val userSwitcher = currentUserSwitcher()
assertThat(userSwitcher).isNotNull()
assertThat(userSwitcher!!.contentDescription)
.isEqualTo(ContentDescription.Loaded("Signed in as foo"))
assertThat(userSwitcher.icon).isEqualTo(Icon.Loaded(picture))
assertThat(userSwitcher!!.icon)
.isEqualTo(Icon.Loaded(picture, ContentDescription.Loaded("Signed in as foo")))
assertThat(userSwitcher.background).isEqualTo(R.drawable.qs_footer_action_circle)
// Change the current user name.
userSwitcherControllerWrapper.currentUserName = "bar"
assertThat(currentUserSwitcher()?.contentDescription)
assertThat(currentUserSwitcher()?.icon?.contentDescription)
.isEqualTo(ContentDescription.Loaded("Signed in as bar"))
fun iconTint(): Int? = currentUserSwitcher()!!.iconTint
@@ -243,7 +248,7 @@ class FooterActionsViewModelTest : SysuiTestCase() {
// Map any SecurityModel into a non-null SecurityButtonConfig.
val buttonConfig =
SecurityButtonConfig(
icon = Icon.Resource(0),
icon = Icon.Resource(res = 0, contentDescription = null),
text = "foo",
isClickable = true,
)
@@ -340,7 +345,7 @@ class FooterActionsViewModelTest : SysuiTestCase() {
assertThat(foregroundServices.displayText).isTrue()
securityToConfig = {
SecurityButtonConfig(
icon = Icon.Resource(0),
icon = Icon.Resource(res = 0, contentDescription = null),
text = "foo",
isClickable = true,
)