Loading packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttLogger.kt +17 −4 Original line number Diff line number Diff line Loading @@ -28,28 +28,41 @@ class MediaTttLogger( private val deviceTypeTag: String, private val buffer: LogBuffer ){ private val bufferTag = BASE_TAG + deviceTypeTag /** Logs a change in the chip state for the given [mediaRouteId]. */ fun logStateChange(stateName: String, mediaRouteId: String) { fun logStateChange(stateName: String, mediaRouteId: String, packageName: String?) { buffer.log( BASE_TAG + deviceTypeTag, bufferTag, LogLevel.DEBUG, { str1 = stateName str2 = mediaRouteId str3 = packageName }, { "State changed to $str1 for ID=$str2" } { "State changed to $str1 for ID=$str2 package=$str3" } ) } /** Logs that we removed the chip for the given [reason]. */ fun logChipRemoval(reason: String) { buffer.log( BASE_TAG + deviceTypeTag, bufferTag, LogLevel.DEBUG, { str1 = reason }, { "Chip removed due to $str1" } ) } /** Logs that we couldn't find information for [packageName]. */ fun logPackageNotFound(packageName: String) { buffer.log( bufferTag, LogLevel.DEBUG, { str1 = packageName }, { "Package $str1 could not be found" } ) } } private const val BASE_TAG = "MediaTtt" packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt 0 → 100644 +107 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.media.taptotransfer.common import android.content.Context import android.content.pm.PackageManager import android.graphics.drawable.Drawable import com.android.internal.widget.CachingIconView import com.android.settingslib.Utils import com.android.systemui.R /** Utility methods for media tap-to-transfer. */ class MediaTttUtils { companion object { /** * Returns the information needed to display the 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. * * @param appPackageName the package name of the app playing the media. * @param logger the logger to use for any errors. */ fun getIconInfoFromPackageName( context: Context, appPackageName: String?, logger: MediaTttLogger ): IconInfo { if (appPackageName != null) { try { val contentDescription = context.packageManager .getApplicationInfo( appPackageName, PackageManager.ApplicationInfoFlags.of(0) ) .loadLabel(context.packageManager) .toString() return IconInfo( contentDescription, drawable = context.packageManager.getApplicationIcon(appPackageName), isAppIcon = true ) } catch (e: PackageManager.NameNotFoundException) { logger.logPackageNotFound(appPackageName) } } return IconInfo( contentDescription = context.getString(R.string.media_output_dialog_unknown_launch_app_name), drawable = context.resources.getDrawable(R.drawable.ic_cast).apply { this.setTint( Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary) ) }, isAppIcon = false ) } /** * Sets an icon to be displayed by the given view. * * @param iconSize the size in pixels that the icon should be. If null, the size of * [appIconView] will not be adjusted. */ fun setIcon( appIconView: CachingIconView, icon: Drawable, iconContentDescription: CharSequence, iconSize: Int? = null, ) { iconSize?.let { size -> val lp = appIconView.layoutParams lp.width = size lp.height = size appIconView.layoutParams = lp } appIconView.contentDescription = iconContentDescription appIconView.setImageDrawable(icon) } } } data class IconInfo( val contentDescription: String, val drawable: Drawable, /** * True if [drawable] is the app's icon, and false if [drawable] is some generic default icon. */ val isAppIcon: Boolean ) packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt +21 −16 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import com.android.systemui.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.media.taptotransfer.common.MediaTttLogger import com.android.systemui.media.taptotransfer.common.MediaTttUtils import com.android.systemui.statusbar.CommandQueue import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.temporarydisplay.DEFAULT_TIMEOUT_MILLIS Loading Loading @@ -107,7 +108,7 @@ class MediaTttChipControllerReceiver @Inject constructor( ) { val chipState: ChipStateReceiver? = ChipStateReceiver.getReceiverStateFromId(displayState) val stateName = chipState?.name ?: "Invalid" logger.logStateChange(stateName, routeInfo.id) logger.logStateChange(stateName, routeInfo.id, routeInfo.clientPackageName) if (chipState == null) { Log.e(RECEIVER_TAG, "Unhandled MediaTransferReceiverState $displayState") Loading Loading @@ -137,13 +138,26 @@ class MediaTttChipControllerReceiver @Inject constructor( override fun updateView(newInfo: ChipReceiverInfo, currentView: ViewGroup) { super.updateView(newInfo, currentView) val iconName = setIcon( currentView, newInfo.routeInfo.clientPackageName, newInfo.appIconDrawableOverride, newInfo.appNameOverride val iconInfo = MediaTttUtils.getIconInfoFromPackageName( context, newInfo.routeInfo.clientPackageName, logger ) val iconDrawable = newInfo.appIconDrawableOverride ?: iconInfo.drawable val iconContentDescription = newInfo.appNameOverride ?: iconInfo.contentDescription val iconSize = context.resources.getDimensionPixelSize( if (iconInfo.isAppIcon) { R.dimen.media_ttt_icon_size_receiver } else { R.dimen.media_ttt_generic_icon_size_receiver } ) MediaTttUtils.setIcon( currentView.requireViewById(R.id.app_icon), iconDrawable, iconContentDescription, iconSize, ) currentView.contentDescription = iconName } override fun animateViewIn(view: ViewGroup) { Loading @@ -161,15 +175,6 @@ class MediaTttChipControllerReceiver @Inject constructor( startRipple(view.requireViewById(R.id.ripple)) } 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 } ) /** Returns the amount that the chip will be translated by in its intro animation. */ private fun getTranslationAmount(): Int { return context.resources.getDimensionPixelSize(R.dimen.media_ttt_receiver_vert_translation) Loading packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt +14 −11 Original line number Diff line number Diff line Loading @@ -34,8 +34,7 @@ import com.android.systemui.temporarydisplay.DEFAULT_TIMEOUT_MILLIS * @property stateInt the integer from [StatusBarManager] corresponding with this state. * @property stringResId the res ID of the string that should be displayed in the chip. Null if the * state should not have the chip be displayed. * @property isMidTransfer true if the state represents that a transfer is currently ongoing. * @property isTransferFailure true if the state represents that the transfer has failed. * @property transferStatus the transfer status that the chip state represents. * @property timeout the amount of time this chip should display on the screen before it times out * and disappears. */ Loading @@ -43,8 +42,7 @@ enum class ChipStateSender( @StatusBarManager.MediaTransferSenderState val stateInt: Int, val uiEvent: UiEventLogger.UiEventEnum, @StringRes val stringResId: Int?, val isMidTransfer: Boolean = false, val isTransferFailure: Boolean = false, val transferStatus: TransferStatus, val timeout: Long = DEFAULT_TIMEOUT_MILLIS ) { /** Loading @@ -56,6 +54,7 @@ enum class ChipStateSender( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST, MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_START_CAST, R.string.media_move_closer_to_start_cast, transferStatus = TransferStatus.NOT_STARTED, ), /** Loading @@ -68,6 +67,7 @@ enum class ChipStateSender( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST, MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_END_CAST, R.string.media_move_closer_to_end_cast, transferStatus = TransferStatus.NOT_STARTED, ), /** Loading @@ -78,7 +78,7 @@ enum class ChipStateSender( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED, MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_TRIGGERED, R.string.media_transfer_playing_different_device, isMidTransfer = true, transferStatus = TransferStatus.IN_PROGRESS, timeout = TRANSFER_TRIGGERED_TIMEOUT_MILLIS ), Loading @@ -90,7 +90,7 @@ enum class ChipStateSender( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED, MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_TRIGGERED, R.string.media_transfer_playing_this_device, isMidTransfer = true, transferStatus = TransferStatus.IN_PROGRESS, timeout = TRANSFER_TRIGGERED_TIMEOUT_MILLIS ), Loading @@ -100,7 +100,8 @@ enum class ChipStateSender( TRANSFER_TO_RECEIVER_SUCCEEDED( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED, R.string.media_transfer_playing_different_device R.string.media_transfer_playing_different_device, transferStatus = TransferStatus.SUCCEEDED, ) { override fun undoClickListener( controllerSender: MediaTttChipControllerSender, Loading Loading @@ -135,7 +136,8 @@ enum class ChipStateSender( TRANSFER_TO_THIS_DEVICE_SUCCEEDED( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, R.string.media_transfer_playing_this_device R.string.media_transfer_playing_this_device, transferStatus = TransferStatus.SUCCEEDED, ) { override fun undoClickListener( controllerSender: MediaTttChipControllerSender, Loading Loading @@ -169,7 +171,7 @@ enum class ChipStateSender( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED, MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED, R.string.media_transfer_failed, isTransferFailure = true transferStatus = TransferStatus.FAILED, ), /** A state representing that a transfer back to this device has failed. */ Loading @@ -177,14 +179,15 @@ enum class ChipStateSender( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED, MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_FAILED, R.string.media_transfer_failed, isTransferFailure = true transferStatus = TransferStatus.FAILED, ), /** A state representing that this device is far away from any receiver device. */ FAR_FROM_RECEIVER( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER, MediaTttSenderUiEvents.MEDIA_TTT_SENDER_FAR_FROM_RECEIVER, stringResId = null stringResId = null, transferStatus = TransferStatus.TOO_FAR, ); /** Loading packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt +21 −9 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import com.android.systemui.animation.ViewHierarchyAnimator import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.media.taptotransfer.common.MediaTttLogger import com.android.systemui.media.taptotransfer.common.MediaTttUtils import com.android.systemui.statusbar.CommandQueue import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.temporarydisplay.TemporaryDisplayRemovalReason Loading Loading @@ -94,7 +95,7 @@ class MediaTttChipControllerSender @Inject constructor( ) { val chipState: ChipStateSender? = ChipStateSender.getSenderStateFromId(displayState) val stateName = chipState?.name ?: "Invalid" logger.logStateChange(stateName, routeInfo.id) logger.logStateChange(stateName, routeInfo.id, routeInfo.clientPackageName) if (chipState == null) { Log.e(SENDER_TAG, "Unhandled MediaTransferSenderState $displayState") Loading @@ -118,7 +119,14 @@ class MediaTttChipControllerSender @Inject constructor( val chipState = newInfo.state // App icon val iconName = setIcon(currentView, newInfo.routeInfo.clientPackageName) val iconInfo = MediaTttUtils.getIconInfoFromPackageName( context, newInfo.routeInfo.clientPackageName, logger ) MediaTttUtils.setIcon( currentView.requireViewById(R.id.app_icon), iconInfo.drawable, iconInfo.contentDescription ) // Text val otherDeviceName = newInfo.routeInfo.name.toString() Loading @@ -127,7 +135,7 @@ class MediaTttChipControllerSender @Inject constructor( // Loading currentView.requireViewById<View>(R.id.loading).visibility = chipState.isMidTransfer.visibleIfTrue() (chipState.transferStatus == TransferStatus.IN_PROGRESS).visibleIfTrue() // Undo val undoView = currentView.requireViewById<View>(R.id.undo) Loading @@ -139,12 +147,12 @@ class MediaTttChipControllerSender @Inject constructor( // Failure currentView.requireViewById<View>(R.id.failure_icon).visibility = chipState.isTransferFailure.visibleIfTrue() (chipState.transferStatus == TransferStatus.FAILED).visibleIfTrue() // For accessibility currentView.requireViewById<ViewGroup>( R.id.media_ttt_sender_chip_inner ).contentDescription = "$iconName $chipText" ).contentDescription = "${iconInfo.contentDescription} $chipText" } override fun animateViewIn(view: ViewGroup) { Loading @@ -162,10 +170,14 @@ class MediaTttChipControllerSender @Inject constructor( } override fun removeView(removalReason: String) { // Don't remove the chip if we're mid-transfer since the user should still be able to // see the status of the transfer. (But do remove it if it's finally timed out.) if (info?.state?.isMidTransfer == true && removalReason != TemporaryDisplayRemovalReason.REASON_TIMEOUT) { // Don't remove the chip if we're in progress or succeeded, since the user should still be // able to see the status of the transfer. (But do remove it if it's finally timed out.) val transferStatus = info?.state?.transferStatus if ( (transferStatus == TransferStatus.IN_PROGRESS || transferStatus == TransferStatus.SUCCEEDED) && removalReason != TemporaryDisplayRemovalReason.REASON_TIMEOUT ) { return } super.removeView(removalReason) Loading Loading
packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttLogger.kt +17 −4 Original line number Diff line number Diff line Loading @@ -28,28 +28,41 @@ class MediaTttLogger( private val deviceTypeTag: String, private val buffer: LogBuffer ){ private val bufferTag = BASE_TAG + deviceTypeTag /** Logs a change in the chip state for the given [mediaRouteId]. */ fun logStateChange(stateName: String, mediaRouteId: String) { fun logStateChange(stateName: String, mediaRouteId: String, packageName: String?) { buffer.log( BASE_TAG + deviceTypeTag, bufferTag, LogLevel.DEBUG, { str1 = stateName str2 = mediaRouteId str3 = packageName }, { "State changed to $str1 for ID=$str2" } { "State changed to $str1 for ID=$str2 package=$str3" } ) } /** Logs that we removed the chip for the given [reason]. */ fun logChipRemoval(reason: String) { buffer.log( BASE_TAG + deviceTypeTag, bufferTag, LogLevel.DEBUG, { str1 = reason }, { "Chip removed due to $str1" } ) } /** Logs that we couldn't find information for [packageName]. */ fun logPackageNotFound(packageName: String) { buffer.log( bufferTag, LogLevel.DEBUG, { str1 = packageName }, { "Package $str1 could not be found" } ) } } private const val BASE_TAG = "MediaTtt"
packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt 0 → 100644 +107 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.systemui.media.taptotransfer.common import android.content.Context import android.content.pm.PackageManager import android.graphics.drawable.Drawable import com.android.internal.widget.CachingIconView import com.android.settingslib.Utils import com.android.systemui.R /** Utility methods for media tap-to-transfer. */ class MediaTttUtils { companion object { /** * Returns the information needed to display the 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. * * @param appPackageName the package name of the app playing the media. * @param logger the logger to use for any errors. */ fun getIconInfoFromPackageName( context: Context, appPackageName: String?, logger: MediaTttLogger ): IconInfo { if (appPackageName != null) { try { val contentDescription = context.packageManager .getApplicationInfo( appPackageName, PackageManager.ApplicationInfoFlags.of(0) ) .loadLabel(context.packageManager) .toString() return IconInfo( contentDescription, drawable = context.packageManager.getApplicationIcon(appPackageName), isAppIcon = true ) } catch (e: PackageManager.NameNotFoundException) { logger.logPackageNotFound(appPackageName) } } return IconInfo( contentDescription = context.getString(R.string.media_output_dialog_unknown_launch_app_name), drawable = context.resources.getDrawable(R.drawable.ic_cast).apply { this.setTint( Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary) ) }, isAppIcon = false ) } /** * Sets an icon to be displayed by the given view. * * @param iconSize the size in pixels that the icon should be. If null, the size of * [appIconView] will not be adjusted. */ fun setIcon( appIconView: CachingIconView, icon: Drawable, iconContentDescription: CharSequence, iconSize: Int? = null, ) { iconSize?.let { size -> val lp = appIconView.layoutParams lp.width = size lp.height = size appIconView.layoutParams = lp } appIconView.contentDescription = iconContentDescription appIconView.setImageDrawable(icon) } } } data class IconInfo( val contentDescription: String, val drawable: Drawable, /** * True if [drawable] is the app's icon, and false if [drawable] is some generic default icon. */ val isAppIcon: Boolean )
packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt +21 −16 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import com.android.systemui.R import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.media.taptotransfer.common.MediaTttLogger import com.android.systemui.media.taptotransfer.common.MediaTttUtils import com.android.systemui.statusbar.CommandQueue import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.temporarydisplay.DEFAULT_TIMEOUT_MILLIS Loading Loading @@ -107,7 +108,7 @@ class MediaTttChipControllerReceiver @Inject constructor( ) { val chipState: ChipStateReceiver? = ChipStateReceiver.getReceiverStateFromId(displayState) val stateName = chipState?.name ?: "Invalid" logger.logStateChange(stateName, routeInfo.id) logger.logStateChange(stateName, routeInfo.id, routeInfo.clientPackageName) if (chipState == null) { Log.e(RECEIVER_TAG, "Unhandled MediaTransferReceiverState $displayState") Loading Loading @@ -137,13 +138,26 @@ class MediaTttChipControllerReceiver @Inject constructor( override fun updateView(newInfo: ChipReceiverInfo, currentView: ViewGroup) { super.updateView(newInfo, currentView) val iconName = setIcon( currentView, newInfo.routeInfo.clientPackageName, newInfo.appIconDrawableOverride, newInfo.appNameOverride val iconInfo = MediaTttUtils.getIconInfoFromPackageName( context, newInfo.routeInfo.clientPackageName, logger ) val iconDrawable = newInfo.appIconDrawableOverride ?: iconInfo.drawable val iconContentDescription = newInfo.appNameOverride ?: iconInfo.contentDescription val iconSize = context.resources.getDimensionPixelSize( if (iconInfo.isAppIcon) { R.dimen.media_ttt_icon_size_receiver } else { R.dimen.media_ttt_generic_icon_size_receiver } ) MediaTttUtils.setIcon( currentView.requireViewById(R.id.app_icon), iconDrawable, iconContentDescription, iconSize, ) currentView.contentDescription = iconName } override fun animateViewIn(view: ViewGroup) { Loading @@ -161,15 +175,6 @@ class MediaTttChipControllerReceiver @Inject constructor( startRipple(view.requireViewById(R.id.ripple)) } 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 } ) /** Returns the amount that the chip will be translated by in its intro animation. */ private fun getTranslationAmount(): Int { return context.resources.getDimensionPixelSize(R.dimen.media_ttt_receiver_vert_translation) Loading
packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt +14 −11 Original line number Diff line number Diff line Loading @@ -34,8 +34,7 @@ import com.android.systemui.temporarydisplay.DEFAULT_TIMEOUT_MILLIS * @property stateInt the integer from [StatusBarManager] corresponding with this state. * @property stringResId the res ID of the string that should be displayed in the chip. Null if the * state should not have the chip be displayed. * @property isMidTransfer true if the state represents that a transfer is currently ongoing. * @property isTransferFailure true if the state represents that the transfer has failed. * @property transferStatus the transfer status that the chip state represents. * @property timeout the amount of time this chip should display on the screen before it times out * and disappears. */ Loading @@ -43,8 +42,7 @@ enum class ChipStateSender( @StatusBarManager.MediaTransferSenderState val stateInt: Int, val uiEvent: UiEventLogger.UiEventEnum, @StringRes val stringResId: Int?, val isMidTransfer: Boolean = false, val isTransferFailure: Boolean = false, val transferStatus: TransferStatus, val timeout: Long = DEFAULT_TIMEOUT_MILLIS ) { /** Loading @@ -56,6 +54,7 @@ enum class ChipStateSender( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_START_CAST, MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_START_CAST, R.string.media_move_closer_to_start_cast, transferStatus = TransferStatus.NOT_STARTED, ), /** Loading @@ -68,6 +67,7 @@ enum class ChipStateSender( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_ALMOST_CLOSE_TO_END_CAST, MediaTttSenderUiEvents.MEDIA_TTT_SENDER_ALMOST_CLOSE_TO_END_CAST, R.string.media_move_closer_to_end_cast, transferStatus = TransferStatus.NOT_STARTED, ), /** Loading @@ -78,7 +78,7 @@ enum class ChipStateSender( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_TRIGGERED, MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_TRIGGERED, R.string.media_transfer_playing_different_device, isMidTransfer = true, transferStatus = TransferStatus.IN_PROGRESS, timeout = TRANSFER_TRIGGERED_TIMEOUT_MILLIS ), Loading @@ -90,7 +90,7 @@ enum class ChipStateSender( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_TRIGGERED, MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_TRIGGERED, R.string.media_transfer_playing_this_device, isMidTransfer = true, transferStatus = TransferStatus.IN_PROGRESS, timeout = TRANSFER_TRIGGERED_TIMEOUT_MILLIS ), Loading @@ -100,7 +100,8 @@ enum class ChipStateSender( TRANSFER_TO_RECEIVER_SUCCEEDED( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_SUCCEEDED, MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_SUCCEEDED, R.string.media_transfer_playing_different_device R.string.media_transfer_playing_different_device, transferStatus = TransferStatus.SUCCEEDED, ) { override fun undoClickListener( controllerSender: MediaTttChipControllerSender, Loading Loading @@ -135,7 +136,8 @@ enum class ChipStateSender( TRANSFER_TO_THIS_DEVICE_SUCCEEDED( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_SUCCEEDED, R.string.media_transfer_playing_this_device R.string.media_transfer_playing_this_device, transferStatus = TransferStatus.SUCCEEDED, ) { override fun undoClickListener( controllerSender: MediaTttChipControllerSender, Loading Loading @@ -169,7 +171,7 @@ enum class ChipStateSender( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_RECEIVER_FAILED, MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_RECEIVER_FAILED, R.string.media_transfer_failed, isTransferFailure = true transferStatus = TransferStatus.FAILED, ), /** A state representing that a transfer back to this device has failed. */ Loading @@ -177,14 +179,15 @@ enum class ChipStateSender( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_TRANSFER_TO_THIS_DEVICE_FAILED, MediaTttSenderUiEvents.MEDIA_TTT_SENDER_TRANSFER_TO_THIS_DEVICE_FAILED, R.string.media_transfer_failed, isTransferFailure = true transferStatus = TransferStatus.FAILED, ), /** A state representing that this device is far away from any receiver device. */ FAR_FROM_RECEIVER( StatusBarManager.MEDIA_TRANSFER_SENDER_STATE_FAR_FROM_RECEIVER, MediaTttSenderUiEvents.MEDIA_TTT_SENDER_FAR_FROM_RECEIVER, stringResId = null stringResId = null, transferStatus = TransferStatus.TOO_FAR, ); /** Loading
packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt +21 −9 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ import com.android.systemui.animation.ViewHierarchyAnimator import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.media.taptotransfer.common.MediaTttLogger import com.android.systemui.media.taptotransfer.common.MediaTttUtils import com.android.systemui.statusbar.CommandQueue import com.android.systemui.statusbar.policy.ConfigurationController import com.android.systemui.temporarydisplay.TemporaryDisplayRemovalReason Loading Loading @@ -94,7 +95,7 @@ class MediaTttChipControllerSender @Inject constructor( ) { val chipState: ChipStateSender? = ChipStateSender.getSenderStateFromId(displayState) val stateName = chipState?.name ?: "Invalid" logger.logStateChange(stateName, routeInfo.id) logger.logStateChange(stateName, routeInfo.id, routeInfo.clientPackageName) if (chipState == null) { Log.e(SENDER_TAG, "Unhandled MediaTransferSenderState $displayState") Loading @@ -118,7 +119,14 @@ class MediaTttChipControllerSender @Inject constructor( val chipState = newInfo.state // App icon val iconName = setIcon(currentView, newInfo.routeInfo.clientPackageName) val iconInfo = MediaTttUtils.getIconInfoFromPackageName( context, newInfo.routeInfo.clientPackageName, logger ) MediaTttUtils.setIcon( currentView.requireViewById(R.id.app_icon), iconInfo.drawable, iconInfo.contentDescription ) // Text val otherDeviceName = newInfo.routeInfo.name.toString() Loading @@ -127,7 +135,7 @@ class MediaTttChipControllerSender @Inject constructor( // Loading currentView.requireViewById<View>(R.id.loading).visibility = chipState.isMidTransfer.visibleIfTrue() (chipState.transferStatus == TransferStatus.IN_PROGRESS).visibleIfTrue() // Undo val undoView = currentView.requireViewById<View>(R.id.undo) Loading @@ -139,12 +147,12 @@ class MediaTttChipControllerSender @Inject constructor( // Failure currentView.requireViewById<View>(R.id.failure_icon).visibility = chipState.isTransferFailure.visibleIfTrue() (chipState.transferStatus == TransferStatus.FAILED).visibleIfTrue() // For accessibility currentView.requireViewById<ViewGroup>( R.id.media_ttt_sender_chip_inner ).contentDescription = "$iconName $chipText" ).contentDescription = "${iconInfo.contentDescription} $chipText" } override fun animateViewIn(view: ViewGroup) { Loading @@ -162,10 +170,14 @@ class MediaTttChipControllerSender @Inject constructor( } override fun removeView(removalReason: String) { // Don't remove the chip if we're mid-transfer since the user should still be able to // see the status of the transfer. (But do remove it if it's finally timed out.) if (info?.state?.isMidTransfer == true && removalReason != TemporaryDisplayRemovalReason.REASON_TIMEOUT) { // Don't remove the chip if we're in progress or succeeded, since the user should still be // able to see the status of the transfer. (But do remove it if it's finally timed out.) val transferStatus = info?.state?.transferStatus if ( (transferStatus == TransferStatus.IN_PROGRESS || transferStatus == TransferStatus.SUCCEEDED) && removalReason != TemporaryDisplayRemovalReason.REASON_TIMEOUT ) { return } super.removeView(removalReason) Loading