[Media TTT] Add more info in talkback of receiver icon

Adds (Casting) before the app name in the content description to make
the talkback say more details about the UI event.

Bug: 265635955
Test: atest MediaTttUtilsTest
Test: Checked using adb commends. video with the fix in bug link.
Change-Id: I166cacd5959b01038bba1d96c2ef2be1a647e026
This commit is contained in:
Michael Mikhail
2023-02-01 22:30:24 +00:00
parent 71592cf7ff
commit d24f0951f7
6 changed files with 157 additions and 20 deletions

View File

@@ -2382,6 +2382,10 @@
<string name="media_transfer_loading">Loading</string>
<!-- Default name of the device. [CHAR LIMIT=30] -->
<string name="media_ttt_default_device_type">tablet</string>
<!-- Description of media transfer icon of unknown app appears in receiver devices. [CHAR LIMIT=NONE]-->
<string name="media_transfer_receiver_content_description_unknown_app">Casting your media</string>
<!-- Description of media transfer icon appears in receiver devices. [CHAR LIMIT=NONE]-->
<string name="media_transfer_receiver_content_description_with_app_name">Casting <xliff:g id="app_label" example="Spotify">%1$s</xliff:g></string>
<!-- Error message indicating that a control timed out while waiting for an update [CHAR_LIMIT=30] -->
<string name="controls_error_timeout">Inactive, check app</string>

View File

@@ -44,25 +44,37 @@ class MediaTttUtils {
* @param appPackageName the package name of the app playing the media.
* @param onPackageNotFoundException a function run if a
* [PackageManager.NameNotFoundException] occurs.
* @param isReceiver indicates whether the icon is displayed in a receiver view.
*/
fun getIconInfoFromPackageName(
context: Context,
appPackageName: String?,
isReceiver: Boolean,
onPackageNotFoundException: () -> Unit,
): IconInfo {
if (appPackageName != null) {
val packageManager = context.packageManager
try {
val appName =
packageManager
.getApplicationInfo(
appPackageName,
PackageManager.ApplicationInfoFlags.of(0),
)
.loadLabel(packageManager)
.toString()
val contentDescription =
ContentDescription.Loaded(
packageManager
.getApplicationInfo(
appPackageName,
PackageManager.ApplicationInfoFlags.of(0)
if (isReceiver) {
ContentDescription.Loaded(
context.getString(
R.string
.media_transfer_receiver_content_description_with_app_name,
appName
)
.loadLabel(packageManager)
.toString()
)
)
} else {
ContentDescription.Loaded(appName)
}
return IconInfo(
contentDescription,
MediaTttIcon.Loaded(packageManager.getApplicationIcon(appPackageName)),
@@ -74,7 +86,15 @@ class MediaTttUtils {
}
}
return IconInfo(
ContentDescription.Resource(R.string.media_output_dialog_unknown_launch_app_name),
if (isReceiver) {
ContentDescription.Resource(
R.string.media_transfer_receiver_content_description_unknown_app
)
} else {
ContentDescription.Resource(
R.string.media_output_dialog_unknown_launch_app_name
)
},
MediaTttIcon.Resource(R.drawable.ic_cast),
tintAttr = android.R.attr.textColorPrimary,
isAppIcon = false

View File

@@ -173,7 +173,11 @@ open class MediaTttChipControllerReceiver @Inject constructor(
override fun updateView(newInfo: ChipReceiverInfo, currentView: ViewGroup) {
val packageName = newInfo.routeInfo.clientPackageName
var iconInfo = MediaTttUtils.getIconInfoFromPackageName(context, packageName) {
var iconInfo = MediaTttUtils.getIconInfoFromPackageName(
context,
packageName,
isReceiver = true,
) {
logger.logPackageNotFound(packageName)
}

View File

@@ -161,7 +161,7 @@ constructor(
routeInfo.name.toString()
}
val icon =
MediaTttUtils.getIconInfoFromPackageName(context, packageName) {
MediaTttUtils.getIconInfoFromPackageName(context, packageName, isReceiver = false) {
logger.logPackageNotFound(packageName)
}

View File

@@ -65,7 +65,13 @@ class MediaTttUtilsTest : SysuiTestCase() {
@Test
fun getIconInfoFromPackageName_nullPackageName_returnsDefault() {
val iconInfo = MediaTttUtils.getIconInfoFromPackageName(context, appPackageName = null) {}
val iconInfo =
MediaTttUtils.getIconInfoFromPackageName(
context,
appPackageName = null,
isReceiver = false,
) {
}
assertThat(iconInfo.isAppIcon).isFalse()
assertThat(iconInfo.contentDescription.loadContentDescription(context))
@@ -73,11 +79,33 @@ class MediaTttUtilsTest : SysuiTestCase() {
assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Resource(R.drawable.ic_cast))
}
@Test
fun getIconInfoFromPackageName_nullPackageName_isReceiver_returnsDefault() {
val iconInfo =
MediaTttUtils.getIconInfoFromPackageName(
context,
appPackageName = null,
isReceiver = true,
) {
}
assertThat(iconInfo.isAppIcon).isFalse()
assertThat(iconInfo.contentDescription.loadContentDescription(context))
.isEqualTo(
context.getString(R.string.media_transfer_receiver_content_description_unknown_app)
)
assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Resource(R.drawable.ic_cast))
}
@Test
fun getIconInfoFromPackageName_nullPackageName_exceptionFnNotTriggered() {
var exceptionTriggered = false
MediaTttUtils.getIconInfoFromPackageName(context, appPackageName = null) {
MediaTttUtils.getIconInfoFromPackageName(
context,
appPackageName = null,
isReceiver = false,
) {
exceptionTriggered = true
}
@@ -86,7 +114,13 @@ class MediaTttUtilsTest : SysuiTestCase() {
@Test
fun getIconInfoFromPackageName_invalidPackageName_returnsDefault() {
val iconInfo = MediaTttUtils.getIconInfoFromPackageName(context, "fakePackageName") {}
val iconInfo =
MediaTttUtils.getIconInfoFromPackageName(
context,
appPackageName = "fakePackageName",
isReceiver = false,
) {
}
assertThat(iconInfo.isAppIcon).isFalse()
assertThat(iconInfo.contentDescription.loadContentDescription(context))
@@ -94,31 +128,102 @@ class MediaTttUtilsTest : SysuiTestCase() {
assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Resource(R.drawable.ic_cast))
}
@Test
fun getIconInfoFromPackageName_invalidPackageName_isReceiver_returnsDefault() {
val iconInfo =
MediaTttUtils.getIconInfoFromPackageName(
context,
appPackageName = "fakePackageName",
isReceiver = true,
) {
}
assertThat(iconInfo.isAppIcon).isFalse()
assertThat(iconInfo.contentDescription.loadContentDescription(context))
.isEqualTo(
context.getString(R.string.media_transfer_receiver_content_description_unknown_app)
)
assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Resource(R.drawable.ic_cast))
}
@Test
fun getIconInfoFromPackageName_invalidPackageName_exceptionFnTriggered() {
var exceptionTriggered = false
MediaTttUtils.getIconInfoFromPackageName(context, appPackageName = "fakePackageName") {
exceptionTriggered = true
}
MediaTttUtils.getIconInfoFromPackageName(
context,
appPackageName = "fakePackageName",
isReceiver = false
) { exceptionTriggered = true }
assertThat(exceptionTriggered).isTrue()
}
@Test
fun getIconInfoFromPackageName_invalidPackageName_isReceiver_exceptionFnTriggered() {
var exceptionTriggered = false
MediaTttUtils.getIconInfoFromPackageName(
context,
appPackageName = "fakePackageName",
isReceiver = true
) { exceptionTriggered = true }
assertThat(exceptionTriggered).isTrue()
}
@Test
fun getIconInfoFromPackageName_validPackageName_returnsAppInfo() {
val iconInfo = MediaTttUtils.getIconInfoFromPackageName(context, PACKAGE_NAME) {}
val iconInfo =
MediaTttUtils.getIconInfoFromPackageName(
context,
PACKAGE_NAME,
isReceiver = false,
) {
}
assertThat(iconInfo.isAppIcon).isTrue()
assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Loaded(appIconFromPackageName))
assertThat(iconInfo.contentDescription.loadContentDescription(context)).isEqualTo(APP_NAME)
}
@Test
fun getIconInfoFromPackageName_validPackageName_isReceiver_returnsAppInfo() {
val iconInfo =
MediaTttUtils.getIconInfoFromPackageName(
context,
PACKAGE_NAME,
isReceiver = true,
) {
}
assertThat(iconInfo.isAppIcon).isTrue()
assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Loaded(appIconFromPackageName))
assertThat(iconInfo.contentDescription.loadContentDescription(context))
.isEqualTo(
context.getString(
R.string.media_transfer_receiver_content_description_with_app_name,
APP_NAME
)
)
}
@Test
fun getIconInfoFromPackageName_validPackageName_exceptionFnNotTriggered() {
var exceptionTriggered = false
MediaTttUtils.getIconInfoFromPackageName(context, PACKAGE_NAME) {
MediaTttUtils.getIconInfoFromPackageName(context, PACKAGE_NAME, isReceiver = false) {
exceptionTriggered = true
}
assertThat(exceptionTriggered).isFalse()
}
@Test
fun getIconInfoFromPackageName_validPackageName_isReceiver_exceptionFnNotTriggered() {
var exceptionTriggered = false
MediaTttUtils.getIconInfoFromPackageName(context, PACKAGE_NAME, isReceiver = true) {
exceptionTriggered = true
}

View File

@@ -354,7 +354,11 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
val view = getChipView()
assertThat(view.getAppIconView().drawable).isEqualTo(fakeAppIconDrawable)
assertThat(view.getAppIconView().contentDescription).isEqualTo(APP_NAME)
assertThat(view.getAppIconView().contentDescription)
.isEqualTo(context.getString(
R.string.media_transfer_receiver_content_description_with_app_name,
APP_NAME,
))
}
@Test