Merge changes from topics "presubmit-am-3fca48eecdb74a8e96804b9a78256e56", "presubmit-am-563ae16077714dd0a7da266e4a698052", "presubmit-am-9cc0354ba3f24063b26fb042cc9dbf89" into tm-dev
* changes: [Media TTT] Fix the generic icon on the receiver chip by making it smaller so it fits in the circle. [Media TTT] Add a ripple to the undo button. [Media TTT] Update the error message string.
This commit is contained in:
committed by
Android (Google) Code Review
commit
c2e841793c
@@ -14,9 +14,14 @@
|
|||||||
~ See the License for the specific language governing permissions and
|
~ See the License for the specific language governing permissions and
|
||||||
~ limitations under the License.
|
~ limitations under the License.
|
||||||
-->
|
-->
|
||||||
<shape
|
<ripple
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
|
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
|
||||||
<solid android:color="?androidprv:attr/colorAccentPrimary" />
|
android:color="?android:textColorPrimary">
|
||||||
<corners android:radius="24dp" />
|
<item android:id="@android:id/background">
|
||||||
</shape>
|
<shape>
|
||||||
|
<solid android:color="?androidprv:attr/colorAccentPrimary"/>
|
||||||
|
<corners android:radius="24dp" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</ripple>
|
||||||
|
|||||||
@@ -1008,6 +1008,9 @@
|
|||||||
<!-- Media tap-to-transfer chip for receiver device -->
|
<!-- Media tap-to-transfer chip for receiver device -->
|
||||||
<dimen name="media_ttt_chip_size_receiver">100dp</dimen>
|
<dimen name="media_ttt_chip_size_receiver">100dp</dimen>
|
||||||
<dimen name="media_ttt_icon_size_receiver">95dp</dimen>
|
<dimen name="media_ttt_icon_size_receiver">95dp</dimen>
|
||||||
|
<!-- Since the generic icon isn't circular, we need to scale it down so it still fits within
|
||||||
|
the circular chip. -->
|
||||||
|
<dimen name="media_ttt_generic_icon_size_receiver">70dp</dimen>
|
||||||
|
|
||||||
<!-- Window magnification -->
|
<!-- Window magnification -->
|
||||||
<dimen name="magnification_border_drag_size">35dp</dimen>
|
<dimen name="magnification_border_drag_size">35dp</dimen>
|
||||||
|
|||||||
@@ -2184,7 +2184,7 @@
|
|||||||
<!-- Text informing the user that their media is now playing on this device. [CHAR LIMIT=50] -->
|
<!-- Text informing the user that their media is now playing on this device. [CHAR LIMIT=50] -->
|
||||||
<string name="media_transfer_playing_this_device">Playing on this phone</string>
|
<string name="media_transfer_playing_this_device">Playing on this phone</string>
|
||||||
<!-- Text informing the user that the media transfer has failed because something went wrong. [CHAR LIMIT=50] -->
|
<!-- Text informing the user that the media transfer has failed because something went wrong. [CHAR LIMIT=50] -->
|
||||||
<string name="media_transfer_failed">Something went wrong</string>
|
<string name="media_transfer_failed">Something went wrong. Try again.</string>
|
||||||
|
|
||||||
<!-- Error message indicating that a control timed out while waiting for an update [CHAR_LIMIT=30] -->
|
<!-- 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>
|
<string name="controls_error_timeout">Inactive, check app</string>
|
||||||
|
|||||||
@@ -128,19 +128,21 @@ class MediaTttCommandLineHelper @Inject constructor(
|
|||||||
as StatusBarManager
|
as StatusBarManager
|
||||||
val routeInfo = MediaRoute2Info.Builder("id", "Test Name")
|
val routeInfo = MediaRoute2Info.Builder("id", "Test Name")
|
||||||
.addFeature("feature")
|
.addFeature("feature")
|
||||||
.setPackageName(TEST_PACKAGE_NAME)
|
if (args.size >= 2 && args[1] == "useAppIcon=true") {
|
||||||
.build()
|
routeInfo.setPackageName(TEST_PACKAGE_NAME)
|
||||||
|
}
|
||||||
|
|
||||||
statusBarManager.updateMediaTapToTransferReceiverDisplay(
|
statusBarManager.updateMediaTapToTransferReceiverDisplay(
|
||||||
displayState,
|
displayState,
|
||||||
routeInfo,
|
routeInfo.build(),
|
||||||
null,
|
null,
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun help(pw: PrintWriter) {
|
override fun help(pw: PrintWriter) {
|
||||||
pw.println("Usage: adb shell cmd statusbar $RECEIVER_COMMAND <chipState>")
|
pw.println("Usage: adb shell cmd statusbar $RECEIVER_COMMAND " +
|
||||||
|
"<chipState> useAppIcon=[true|false]")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import android.view.MotionEvent
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
|
import android.widget.LinearLayout
|
||||||
import com.android.internal.widget.CachingIconView
|
import com.android.internal.widget.CachingIconView
|
||||||
import com.android.settingslib.Utils
|
import com.android.settingslib.Utils
|
||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
@@ -136,6 +137,11 @@ abstract class MediaTttChipControllerCommon<T : ChipInfoCommon>(
|
|||||||
*/
|
*/
|
||||||
abstract fun updateChipView(chipInfo: T, currentChipView: ViewGroup)
|
abstract fun updateChipView(chipInfo: T, currentChipView: ViewGroup)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the size that the icon should be, or null if no size override is needed.
|
||||||
|
*/
|
||||||
|
open fun getIconSize(isAppIcon: Boolean): Int? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An internal method to set the icon on the view.
|
* An internal method to set the icon on the view.
|
||||||
*
|
*
|
||||||
@@ -151,35 +157,47 @@ abstract class MediaTttChipControllerCommon<T : ChipInfoCommon>(
|
|||||||
appNameOverride: CharSequence? = null,
|
appNameOverride: CharSequence? = null,
|
||||||
) {
|
) {
|
||||||
val appIconView = currentChipView.requireViewById<CachingIconView>(R.id.app_icon)
|
val appIconView = currentChipView.requireViewById<CachingIconView>(R.id.app_icon)
|
||||||
val appInfo = getAppInfo(appPackageName)
|
val iconInfo = getIconInfo(appPackageName)
|
||||||
appIconView.contentDescription = appNameOverride ?: appInfo.appName
|
|
||||||
appIconView.setImageDrawable(appIconDrawableOverride ?: appInfo.appIcon)
|
getIconSize(iconInfo.isAppIcon)?.let { size ->
|
||||||
|
val lp = appIconView.layoutParams
|
||||||
|
lp.width = size
|
||||||
|
lp.height = size
|
||||||
|
appIconView.layoutParams = lp
|
||||||
|
}
|
||||||
|
|
||||||
|
appIconView.contentDescription = appNameOverride ?: iconInfo.iconName
|
||||||
|
appIconView.setImageDrawable(appIconDrawableOverride ?: iconInfo.icon)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the app name and icon of the app playing media, or a default name and icon if we
|
* Returns the information needed to display the icon.
|
||||||
* can't find the app name/icon.
|
*
|
||||||
|
* The information will either contain app name and icon of the app playing media, or a default
|
||||||
|
* name and icon if we can't find the app name/icon.
|
||||||
*/
|
*/
|
||||||
private fun getAppInfo(appPackageName: String?): AppInfo {
|
private fun getIconInfo(appPackageName: String?): IconInfo {
|
||||||
if (appPackageName != null) {
|
if (appPackageName != null) {
|
||||||
try {
|
try {
|
||||||
return AppInfo(
|
return IconInfo(
|
||||||
appName = context.packageManager.getApplicationInfo(
|
iconName = context.packageManager.getApplicationInfo(
|
||||||
appPackageName, PackageManager.ApplicationInfoFlags.of(0)
|
appPackageName, PackageManager.ApplicationInfoFlags.of(0)
|
||||||
).loadLabel(context.packageManager).toString(),
|
).loadLabel(context.packageManager).toString(),
|
||||||
appIcon = context.packageManager.getApplicationIcon(appPackageName)
|
icon = context.packageManager.getApplicationIcon(appPackageName),
|
||||||
|
isAppIcon = true
|
||||||
)
|
)
|
||||||
} catch (e: PackageManager.NameNotFoundException) {
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
Log.w(TAG, "Cannot find package $appPackageName", e)
|
Log.w(TAG, "Cannot find package $appPackageName", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return AppInfo(
|
return IconInfo(
|
||||||
appName = context.getString(R.string.media_output_dialog_unknown_launch_app_name),
|
iconName = context.getString(R.string.media_output_dialog_unknown_launch_app_name),
|
||||||
appIcon = context.resources.getDrawable(R.drawable.ic_cast).apply {
|
icon = context.resources.getDrawable(R.drawable.ic_cast).apply {
|
||||||
this.setTint(
|
this.setTint(
|
||||||
Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary)
|
Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary)
|
||||||
)
|
)
|
||||||
}
|
},
|
||||||
|
isAppIcon = false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,7 +221,9 @@ object MediaTttRemovalReason {
|
|||||||
const val REASON_SCREEN_TAP = "SCREEN_TAP"
|
const val REASON_SCREEN_TAP = "SCREEN_TAP"
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class AppInfo(
|
private data class IconInfo(
|
||||||
val appName: String,
|
val iconName: String,
|
||||||
val appIcon: Drawable
|
val icon: Drawable,
|
||||||
|
/** True if [icon] is the app's icon, and false if [icon] is some generic default icon. */
|
||||||
|
val isAppIcon: Boolean
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -127,6 +127,15 @@ class MediaTttChipControllerReceiver @Inject constructor(
|
|||||||
chipInfo.appNameOverride
|
chipInfo.appNameOverride
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getIconSize(isAppIcon: Boolean): Int? =
|
||||||
|
context.resources.getDimensionPixelSize(
|
||||||
|
if (isAppIcon) {
|
||||||
|
R.dimen.media_ttt_icon_size_receiver
|
||||||
|
} else {
|
||||||
|
R.dimen.media_ttt_generic_icon_size_receiver
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
data class ChipReceiverInfo(
|
data class ChipReceiverInfo(
|
||||||
|
|||||||
@@ -192,9 +192,9 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
|
|||||||
|
|
||||||
verify(windowManager, never()).removeView(any())
|
verify(windowManager, never()).removeView(any())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun displayChip_nullAppIconDrawableAndNullPackageName_stillHasIcon() {
|
fun setIcon_nullAppIconDrawableAndNullPackageName_stillHasIcon() {
|
||||||
controllerCommon.displayChip(getState())
|
controllerCommon.displayChip(getState())
|
||||||
val chipView = getChipView()
|
val chipView = getChipView()
|
||||||
|
|
||||||
@@ -204,7 +204,7 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun displayChip_nullAppIconDrawableAndInvalidPackageName_stillHasIcon() {
|
fun setIcon_nullAppIconDrawableAndInvalidPackageName_stillHasIcon() {
|
||||||
controllerCommon.displayChip(getState())
|
controllerCommon.displayChip(getState())
|
||||||
val chipView = getChipView()
|
val chipView = getChipView()
|
||||||
|
|
||||||
@@ -226,7 +226,7 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun displayChip_hasAppIconDrawable_iconIsDrawable() {
|
fun setIcon_hasAppIconDrawable_iconIsDrawable() {
|
||||||
controllerCommon.displayChip(getState())
|
controllerCommon.displayChip(getState())
|
||||||
val chipView = getChipView()
|
val chipView = getChipView()
|
||||||
|
|
||||||
@@ -237,7 +237,7 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun displayChip_nullAppNameAndNullPackageName_stillHasContentDescription() {
|
fun setIcon_nullAppNameAndNullPackageName_stillHasContentDescription() {
|
||||||
controllerCommon.displayChip(getState())
|
controllerCommon.displayChip(getState())
|
||||||
val chipView = getChipView()
|
val chipView = getChipView()
|
||||||
|
|
||||||
@@ -247,7 +247,7 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun displayChip_nullAppNameAndInvalidPackageName_stillHasContentDescription() {
|
fun setIcon_nullAppNameAndInvalidPackageName_stillHasContentDescription() {
|
||||||
controllerCommon.displayChip(getState())
|
controllerCommon.displayChip(getState())
|
||||||
val chipView = getChipView()
|
val chipView = getChipView()
|
||||||
|
|
||||||
@@ -259,7 +259,7 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun displayChip_nullAppName_iconContentDescriptionIsFromPackageName() {
|
fun setIcon_nullAppName_iconContentDescriptionIsFromPackageName() {
|
||||||
controllerCommon.displayChip(getState())
|
controllerCommon.displayChip(getState())
|
||||||
val chipView = getChipView()
|
val chipView = getChipView()
|
||||||
|
|
||||||
@@ -269,7 +269,7 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun displayChip_hasAppName_iconContentDescriptionIsAppNameOverride() {
|
fun setIcon_hasAppName_iconContentDescriptionIsAppNameOverride() {
|
||||||
controllerCommon.displayChip(getState())
|
controllerCommon.displayChip(getState())
|
||||||
val chipView = getChipView()
|
val chipView = getChipView()
|
||||||
|
|
||||||
@@ -279,6 +279,21 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
|
|||||||
assertThat(chipView.getAppIconView().contentDescription).isEqualTo(appName)
|
assertThat(chipView.getAppIconView().contentDescription).isEqualTo(appName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun setIcon_iconSizeMatchesGetIconSize() {
|
||||||
|
controllerCommon.displayChip(getState())
|
||||||
|
val chipView = getChipView()
|
||||||
|
|
||||||
|
controllerCommon.setIcon(chipView, PACKAGE_NAME)
|
||||||
|
chipView.measure(
|
||||||
|
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
|
||||||
|
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
|
||||||
|
)
|
||||||
|
|
||||||
|
assertThat(chipView.getAppIconView().measuredWidth).isEqualTo(ICON_SIZE)
|
||||||
|
assertThat(chipView.getAppIconView().measuredHeight).isEqualTo(ICON_SIZE)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun tapGestureDetected_outsideViewBounds_viewHidden() {
|
fun tapGestureDetected_outsideViewBounds_viewHidden() {
|
||||||
controllerCommon.displayChip(getState())
|
controllerCommon.displayChip(getState())
|
||||||
@@ -344,6 +359,8 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
|
|||||||
override fun updateChipView(chipInfo: ChipInfo, currentChipView: ViewGroup) {
|
override fun updateChipView(chipInfo: ChipInfo, currentChipView: ViewGroup) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getIconSize(isAppIcon: Boolean): Int? = ICON_SIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class ChipInfo : ChipInfoCommon {
|
inner class ChipInfo : ChipInfoCommon {
|
||||||
@@ -354,3 +371,4 @@ class MediaTttChipControllerCommonTest : SysuiTestCase() {
|
|||||||
private const val PACKAGE_NAME = "com.android.systemui"
|
private const val PACKAGE_NAME = "com.android.systemui"
|
||||||
private const val APP_NAME = "Fake App Name"
|
private const val APP_NAME = "Fake App Name"
|
||||||
private const val TIMEOUT_MS = 10000L
|
private const val TIMEOUT_MS = 10000L
|
||||||
|
private const val ICON_SIZE = 47
|
||||||
@@ -174,12 +174,47 @@ class MediaTttChipControllerReceiverTest : SysuiTestCase() {
|
|||||||
verify(logger).logStateChange(any(), any())
|
verify(logger).logStateChange(any(), any())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun setIcon_isAppIcon_usesAppIconSize() {
|
||||||
|
controllerReceiver.displayChip(getChipReceiverInfo())
|
||||||
|
val chipView = getChipView()
|
||||||
|
|
||||||
|
controllerReceiver.setIcon(chipView, PACKAGE_NAME)
|
||||||
|
chipView.measure(
|
||||||
|
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
|
||||||
|
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
|
||||||
|
)
|
||||||
|
|
||||||
|
val expectedSize = controllerReceiver.getIconSize(isAppIcon = true)
|
||||||
|
assertThat(chipView.getAppIconView().measuredWidth).isEqualTo(expectedSize)
|
||||||
|
assertThat(chipView.getAppIconView().measuredHeight).isEqualTo(expectedSize)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun setIcon_notAppIcon_usesGenericIconSize() {
|
||||||
|
controllerReceiver.displayChip(getChipReceiverInfo())
|
||||||
|
val chipView = getChipView()
|
||||||
|
|
||||||
|
controllerReceiver.setIcon(chipView, appPackageName = null)
|
||||||
|
chipView.measure(
|
||||||
|
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
|
||||||
|
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
|
||||||
|
)
|
||||||
|
|
||||||
|
val expectedSize = controllerReceiver.getIconSize(isAppIcon = false)
|
||||||
|
assertThat(chipView.getAppIconView().measuredWidth).isEqualTo(expectedSize)
|
||||||
|
assertThat(chipView.getAppIconView().measuredHeight).isEqualTo(expectedSize)
|
||||||
|
}
|
||||||
|
|
||||||
private fun getChipView(): ViewGroup {
|
private fun getChipView(): ViewGroup {
|
||||||
val viewCaptor = ArgumentCaptor.forClass(View::class.java)
|
val viewCaptor = ArgumentCaptor.forClass(View::class.java)
|
||||||
verify(windowManager).addView(viewCaptor.capture(), any())
|
verify(windowManager).addView(viewCaptor.capture(), any())
|
||||||
return viewCaptor.value as ViewGroup
|
return viewCaptor.value as ViewGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getChipReceiverInfo(): ChipReceiverInfo =
|
||||||
|
ChipReceiverInfo(routeInfo, null, null)
|
||||||
|
|
||||||
private fun ViewGroup.getAppIconView() = this.requireViewById<ImageView>(R.id.app_icon)
|
private fun ViewGroup.getAppIconView() = this.requireViewById<ImageView>(R.id.app_icon)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user