From 80aab1d8a2a6cf1fbc1b6402837db89269c356b2 Mon Sep 17 00:00:00 2001 From: Darrell Shi Date: Wed, 13 Jul 2022 16:18:19 +0000 Subject: [PATCH] Add content description for weather complication. This change sets the content description of the weather complication for a11y, so that TalkBack reads both the weather condition (which is presented as an icon visually), and the temperature. Bug: 228406334 Fix: 228406334 Test: turn on TalkBack and verify weather complication reads both weather condition and temperature Test: atest DreamWeatherComplicationTest Change-Id: I9d94b01776c59484eb5084e879634ac0742ae2bb --- packages/SystemUI/res/values/strings.xml | 4 +++ .../DreamWeatherComplication.java | 27 ++++++++++++++++--- .../DreamWeatherComplicationComponent.java | 10 +++++++ .../DreamWeatherComplicationTest.java | 3 ++- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index ef672f3a62135..55736bb23b6f2 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -2560,6 +2560,10 @@ =1 {# notification} other {# notifications} } + + + %1$s, %2$s + Broadcasting diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java index 4eae3b928c64a..ce61b163dd17c 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamWeatherComplication.java @@ -24,6 +24,7 @@ import android.app.smartspace.SmartspaceAction; import android.app.smartspace.SmartspaceTarget; import android.content.Context; import android.content.Intent; +import android.content.res.Resources; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.text.TextUtils; @@ -133,16 +134,19 @@ public class DreamWeatherComplication implements Complication { private final ActivityStarter mActivityStarter; private final String mSmartspaceTrampolineActivityComponent; private SmartspaceTargetListener mSmartspaceTargetListener; + private final Resources mResources; @Inject DreamWeatherViewController( @Named(DREAM_WEATHER_COMPLICATION_VIEW) TextView view, @Named(SMARTSPACE_TRAMPOLINE_ACTIVITY_COMPONENT) String smartspaceTrampoline, ActivityStarter activityStarter, - DreamSmartspaceController smartspaceController + DreamSmartspaceController smartspaceController, + Resources resources ) { super(view); mActivityStarter = activityStarter; + mResources = resources; mSmartSpaceController = smartspaceController; mSmartspaceTrampolineActivityComponent = smartspaceTrampoline; } @@ -161,8 +165,10 @@ public class DreamWeatherComplication implements Complication { return; } - String temperature = headerAction.getTitle().toString(); + final CharSequence temperature = headerAction.getTitle(); mView.setText(temperature); + mView.setContentDescription(getFormattedContentDescription(temperature, + headerAction.getContentDescription())); final Icon icon = headerAction.getIcon(); if (icon != null) { final int iconSize = @@ -174,7 +180,6 @@ public class DreamWeatherComplication implements Complication { mView.setCompoundDrawablePadding( getResources().getDimensionPixelSize( R.dimen.smart_action_button_icon_padding)); - } mView.setOnClickListener(v -> { final Intent intent = headerAction.getIntent(); @@ -196,5 +201,21 @@ public class DreamWeatherComplication implements Complication { protected void onViewDetached() { mSmartSpaceController.removeUnfilteredListener(mSmartspaceTargetListener); } + + /** + * Returns a formatted content description for accessibility of the weather condition and + * temperature. + */ + private CharSequence getFormattedContentDescription(CharSequence temperature, + CharSequence weatherCondition) { + if (TextUtils.isEmpty(temperature)) { + return weatherCondition; + } else if (TextUtils.isEmpty(weatherCondition)) { + return temperature; + } + + return mResources.getString(R.string.dream_overlay_weather_complication_desc, + weatherCondition, temperature); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamWeatherComplicationComponent.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamWeatherComplicationComponent.java index 7ab3ad1a621a6..f1a16897fdbc4 100644 --- a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamWeatherComplicationComponent.java +++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamWeatherComplicationComponent.java @@ -19,12 +19,14 @@ package com.android.systemui.dreams.complication.dagger; import static java.lang.annotation.RetentionPolicy.RUNTIME; +import android.content.res.Resources; import android.view.LayoutInflater; import android.view.ViewGroup; import android.widget.TextView; import com.android.internal.util.Preconditions; import com.android.systemui.R; +import com.android.systemui.dagger.qualifiers.Main; import com.android.systemui.dreams.complication.ComplicationLayoutParams; import com.android.systemui.dreams.complication.DreamWeatherComplication.DreamWeatherViewHolder; @@ -34,6 +36,7 @@ import java.lang.annotation.Retention; import javax.inject.Named; import javax.inject.Scope; +import dagger.Binds; import dagger.Module; import dagger.Provides; import dagger.Subcomponent; @@ -106,5 +109,12 @@ public interface DreamWeatherComplicationComponent { ComplicationLayoutParams.DIRECTION_END, INSERT_ORDER_WEIGHT, /* snapToGuide= */ true); } + + /** + * Binds resources in the dream weather complication scope. + */ + @Binds + @DreamWeatherComplicationScope + Resources getResources(@Main Resources resources); } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java index 883bec4658159..a23c4b50082f2 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamWeatherComplicationTest.java @@ -21,6 +21,7 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import android.content.Context; +import android.content.res.Resources; import android.testing.AndroidTestingRunner; import android.widget.TextView; @@ -79,7 +80,7 @@ public class DreamWeatherComplicationTest extends SysuiTestCase { final DreamWeatherComplication.DreamWeatherViewController controller = new DreamWeatherComplication.DreamWeatherViewController(mock( TextView.class), TRAMPOLINE_COMPONENT, mock(ActivityStarter.class), - mDreamSmartspaceController); + mDreamSmartspaceController, mock(Resources.class)); controller.onViewAttached(); verify(mDreamSmartspaceController).addUnfilteredListener(any()); controller.onViewDetached();