Loading packages/SystemUI/src/com/android/systemui/common/shared/model/TintedIcon.kt 0 → 100644 +25 −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.common.shared.model import androidx.annotation.AttrRes /** Models an icon with a specific tint. */ data class TintedIcon( val icon: Icon, @AttrRes val tintAttr: Int?, ) packages/SystemUI/src/com/android/systemui/common/ui/binder/TintedIconViewBinder.kt 0 → 100644 +42 −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.common.ui.binder import android.widget.ImageView import com.android.settingslib.Utils import com.android.systemui.common.shared.model.TintedIcon object TintedIconViewBinder { /** * Binds the given tinted icon to the view. * * [TintedIcon.tintAttr] will always be applied, meaning that if it is null, then the tint * *will* be reset to null. */ fun bind( tintedIcon: TintedIcon, view: ImageView, ) { IconViewBinder.bind(tintedIcon.icon, view) view.imageTintList = if (tintedIcon.tintAttr != null) { Utils.getColorAttr(view.context, tintedIcon.tintAttr) } else { null } } } packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt +42 −37 Original line number Diff line number Diff line Loading @@ -19,10 +19,12 @@ package com.android.systemui.media.taptotransfer.common import android.content.Context import android.content.pm.PackageManager import android.graphics.drawable.Drawable import com.android.settingslib.Utils import androidx.annotation.AttrRes import androidx.annotation.DrawableRes import com.android.systemui.R import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.TintedIcon /** Utility methods for media tap-to-transfer. */ class MediaTttUtils { Loading @@ -33,23 +35,6 @@ class MediaTttUtils { const val WAKE_REASON_SENDER = "MEDIA_TRANSFER_ACTIVATED_SENDER" const val WAKE_REASON_RECEIVER = "MEDIA_TRANSFER_ACTIVATED_RECEIVER" /** * Returns the information needed to display the icon in [Icon] form. * * See [getIconInfoFromPackageName]. */ fun getIconFromPackageName( context: Context, appPackageName: String?, logger: MediaTttLogger, ): Icon { val iconInfo = getIconInfoFromPackageName(context, appPackageName, logger) return Icon.Loaded( iconInfo.drawable, ContentDescription.Loaded(iconInfo.contentDescription) ) } /** * Returns the information needed to display the icon. * Loading @@ -65,18 +50,22 @@ class MediaTttUtils { logger: MediaTttLogger ): IconInfo { if (appPackageName != null) { val packageManager = context.packageManager try { val contentDescription = context.packageManager ContentDescription.Loaded( packageManager .getApplicationInfo( appPackageName, PackageManager.ApplicationInfoFlags.of(0) ) .loadLabel(context.packageManager) .loadLabel(packageManager) .toString() ) return IconInfo( contentDescription, drawable = context.packageManager.getApplicationIcon(appPackageName), MediaTttIcon.Loaded(packageManager.getApplicationIcon(appPackageName)), tintAttr = null, isAppIcon = true ) } catch (e: PackageManager.NameNotFoundException) { Loading @@ -84,25 +73,41 @@ class MediaTttUtils { } } 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) ) }, ContentDescription.Resource(R.string.media_output_dialog_unknown_launch_app_name), MediaTttIcon.Resource(R.drawable.ic_cast), tintAttr = android.R.attr.textColorPrimary, isAppIcon = false ) } } } /** Stores all the information for an icon shown with media TTT. */ data class IconInfo( val contentDescription: String, val drawable: Drawable, val contentDescription: ContentDescription, val icon: MediaTttIcon, @AttrRes val tintAttr: Int?, /** * True if [drawable] is the app's icon, and false if [drawable] is some generic default icon. */ val isAppIcon: Boolean ) ) { /** Converts this into a [TintedIcon]. */ fun toTintedIcon(): TintedIcon { val iconOutput = when (icon) { is MediaTttIcon.Loaded -> Icon.Loaded(icon.drawable, contentDescription) is MediaTttIcon.Resource -> Icon.Resource(icon.res, contentDescription) } return TintedIcon(iconOutput, tintAttr) } } /** * Mimics [com.android.systemui.common.shared.model.Icon] but without the content description, since * the content description may need to be overridden. */ sealed interface MediaTttIcon { data class Loaded(val drawable: Drawable) : MediaTttIcon data class Resource(@DrawableRes val res: Int) : MediaTttIcon } packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt +19 −5 Original line number Diff line number Diff line Loading @@ -33,9 +33,12 @@ import android.view.accessibility.AccessibilityManager import com.android.internal.widget.CachingIconView import com.android.settingslib.Utils import com.android.systemui.R import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.ui.binder.TintedIconViewBinder import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.media.taptotransfer.MediaTttFlags import com.android.systemui.media.taptotransfer.common.MediaTttIcon import com.android.systemui.media.taptotransfer.common.MediaTttLogger import com.android.systemui.media.taptotransfer.common.MediaTttUtils import com.android.systemui.statusbar.CommandQueue Loading Loading @@ -161,11 +164,23 @@ open class MediaTttChipControllerReceiver @Inject constructor( } override fun updateView(newInfo: ChipReceiverInfo, currentView: ViewGroup) { val iconInfo = MediaTttUtils.getIconInfoFromPackageName( var iconInfo = MediaTttUtils.getIconInfoFromPackageName( context, newInfo.routeInfo.clientPackageName, logger ) val iconDrawable = newInfo.appIconDrawableOverride ?: iconInfo.drawable val iconContentDescription = newInfo.appNameOverride ?: iconInfo.contentDescription if (newInfo.appNameOverride != null) { iconInfo = iconInfo.copy( contentDescription = ContentDescription.Loaded(newInfo.appNameOverride.toString()) ) } if (newInfo.appIconDrawableOverride != null) { iconInfo = iconInfo.copy( icon = MediaTttIcon.Loaded(newInfo.appIconDrawableOverride), isAppIcon = true, ) } val iconPadding = if (iconInfo.isAppIcon) { 0 Loading @@ -175,8 +190,7 @@ open class MediaTttChipControllerReceiver @Inject constructor( val iconView = currentView.getAppIconView() iconView.setPadding(iconPadding, iconPadding, iconPadding, iconPadding) iconView.setImageDrawable(iconDrawable) iconView.contentDescription = iconContentDescription TintedIconViewBinder.bind(iconInfo.toTintedIcon(), iconView) } override fun animateViewIn(view: ViewGroup) { Loading packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt +3 −1 Original line number Diff line number Diff line Loading @@ -153,7 +153,9 @@ constructor( return ChipbarInfo( // Display the app's icon as the start icon startIcon = MediaTttUtils.getIconFromPackageName(context, packageName, logger), startIcon = MediaTttUtils.getIconInfoFromPackageName(context, packageName, logger) .toTintedIcon(), text = chipStateSender.getChipTextString(context, otherDeviceName), endItem = when (chipStateSender.endItem) { Loading Loading
packages/SystemUI/src/com/android/systemui/common/shared/model/TintedIcon.kt 0 → 100644 +25 −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.common.shared.model import androidx.annotation.AttrRes /** Models an icon with a specific tint. */ data class TintedIcon( val icon: Icon, @AttrRes val tintAttr: Int?, )
packages/SystemUI/src/com/android/systemui/common/ui/binder/TintedIconViewBinder.kt 0 → 100644 +42 −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.common.ui.binder import android.widget.ImageView import com.android.settingslib.Utils import com.android.systemui.common.shared.model.TintedIcon object TintedIconViewBinder { /** * Binds the given tinted icon to the view. * * [TintedIcon.tintAttr] will always be applied, meaning that if it is null, then the tint * *will* be reset to null. */ fun bind( tintedIcon: TintedIcon, view: ImageView, ) { IconViewBinder.bind(tintedIcon.icon, view) view.imageTintList = if (tintedIcon.tintAttr != null) { Utils.getColorAttr(view.context, tintedIcon.tintAttr) } else { null } } }
packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt +42 −37 Original line number Diff line number Diff line Loading @@ -19,10 +19,12 @@ package com.android.systemui.media.taptotransfer.common import android.content.Context import android.content.pm.PackageManager import android.graphics.drawable.Drawable import com.android.settingslib.Utils import androidx.annotation.AttrRes import androidx.annotation.DrawableRes import com.android.systemui.R import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.TintedIcon /** Utility methods for media tap-to-transfer. */ class MediaTttUtils { Loading @@ -33,23 +35,6 @@ class MediaTttUtils { const val WAKE_REASON_SENDER = "MEDIA_TRANSFER_ACTIVATED_SENDER" const val WAKE_REASON_RECEIVER = "MEDIA_TRANSFER_ACTIVATED_RECEIVER" /** * Returns the information needed to display the icon in [Icon] form. * * See [getIconInfoFromPackageName]. */ fun getIconFromPackageName( context: Context, appPackageName: String?, logger: MediaTttLogger, ): Icon { val iconInfo = getIconInfoFromPackageName(context, appPackageName, logger) return Icon.Loaded( iconInfo.drawable, ContentDescription.Loaded(iconInfo.contentDescription) ) } /** * Returns the information needed to display the icon. * Loading @@ -65,18 +50,22 @@ class MediaTttUtils { logger: MediaTttLogger ): IconInfo { if (appPackageName != null) { val packageManager = context.packageManager try { val contentDescription = context.packageManager ContentDescription.Loaded( packageManager .getApplicationInfo( appPackageName, PackageManager.ApplicationInfoFlags.of(0) ) .loadLabel(context.packageManager) .loadLabel(packageManager) .toString() ) return IconInfo( contentDescription, drawable = context.packageManager.getApplicationIcon(appPackageName), MediaTttIcon.Loaded(packageManager.getApplicationIcon(appPackageName)), tintAttr = null, isAppIcon = true ) } catch (e: PackageManager.NameNotFoundException) { Loading @@ -84,25 +73,41 @@ class MediaTttUtils { } } 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) ) }, ContentDescription.Resource(R.string.media_output_dialog_unknown_launch_app_name), MediaTttIcon.Resource(R.drawable.ic_cast), tintAttr = android.R.attr.textColorPrimary, isAppIcon = false ) } } } /** Stores all the information for an icon shown with media TTT. */ data class IconInfo( val contentDescription: String, val drawable: Drawable, val contentDescription: ContentDescription, val icon: MediaTttIcon, @AttrRes val tintAttr: Int?, /** * True if [drawable] is the app's icon, and false if [drawable] is some generic default icon. */ val isAppIcon: Boolean ) ) { /** Converts this into a [TintedIcon]. */ fun toTintedIcon(): TintedIcon { val iconOutput = when (icon) { is MediaTttIcon.Loaded -> Icon.Loaded(icon.drawable, contentDescription) is MediaTttIcon.Resource -> Icon.Resource(icon.res, contentDescription) } return TintedIcon(iconOutput, tintAttr) } } /** * Mimics [com.android.systemui.common.shared.model.Icon] but without the content description, since * the content description may need to be overridden. */ sealed interface MediaTttIcon { data class Loaded(val drawable: Drawable) : MediaTttIcon data class Resource(@DrawableRes val res: Int) : MediaTttIcon }
packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt +19 −5 Original line number Diff line number Diff line Loading @@ -33,9 +33,12 @@ import android.view.accessibility.AccessibilityManager import com.android.internal.widget.CachingIconView import com.android.settingslib.Utils import com.android.systemui.R import com.android.systemui.common.shared.model.ContentDescription import com.android.systemui.common.ui.binder.TintedIconViewBinder import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.media.taptotransfer.MediaTttFlags import com.android.systemui.media.taptotransfer.common.MediaTttIcon import com.android.systemui.media.taptotransfer.common.MediaTttLogger import com.android.systemui.media.taptotransfer.common.MediaTttUtils import com.android.systemui.statusbar.CommandQueue Loading Loading @@ -161,11 +164,23 @@ open class MediaTttChipControllerReceiver @Inject constructor( } override fun updateView(newInfo: ChipReceiverInfo, currentView: ViewGroup) { val iconInfo = MediaTttUtils.getIconInfoFromPackageName( var iconInfo = MediaTttUtils.getIconInfoFromPackageName( context, newInfo.routeInfo.clientPackageName, logger ) val iconDrawable = newInfo.appIconDrawableOverride ?: iconInfo.drawable val iconContentDescription = newInfo.appNameOverride ?: iconInfo.contentDescription if (newInfo.appNameOverride != null) { iconInfo = iconInfo.copy( contentDescription = ContentDescription.Loaded(newInfo.appNameOverride.toString()) ) } if (newInfo.appIconDrawableOverride != null) { iconInfo = iconInfo.copy( icon = MediaTttIcon.Loaded(newInfo.appIconDrawableOverride), isAppIcon = true, ) } val iconPadding = if (iconInfo.isAppIcon) { 0 Loading @@ -175,8 +190,7 @@ open class MediaTttChipControllerReceiver @Inject constructor( val iconView = currentView.getAppIconView() iconView.setPadding(iconPadding, iconPadding, iconPadding, iconPadding) iconView.setImageDrawable(iconDrawable) iconView.contentDescription = iconContentDescription TintedIconViewBinder.bind(iconInfo.toTintedIcon(), iconView) } override fun animateViewIn(view: ViewGroup) { Loading
packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderCoordinator.kt +3 −1 Original line number Diff line number Diff line Loading @@ -153,7 +153,9 @@ constructor( return ChipbarInfo( // Display the app's icon as the start icon startIcon = MediaTttUtils.getIconFromPackageName(context, packageName, logger), startIcon = MediaTttUtils.getIconInfoFromPackageName(context, packageName, logger) .toTintedIcon(), text = chipStateSender.getChipTextString(context, otherDeviceName), endItem = when (chipStateSender.endItem) { Loading